|
1、介绍
目前很多单片机调试都是采用串口,而有些设备的调试接口不会暴露在外边,为此我设计了一款无线调试器,可以通过无线的方式监测设备信息数据。同时搭配了锂电池,实现真无线调试,锂电池没电的时候可以通过TypeC进行充电。
2、硬件准备
这次选用了4.3英寸迪文科技COF串口屏DMG80480F043_01W
设计了一块电路板,电路板上有ESP32-C3 WIFI芯片还有PCF8563时钟芯片,其中ESP32-C3和迪文屏采用串口通信,PCF8563和迪文屏采用IIC通信,电路原理图如下:
屏幕选择了一个白色的,所以电路板也设计了一个白色的。
3、界面设计
界面采用了科技风,让其更富有科技感,界面设计的AI工作如下:
接下来就是界面的设计,首先就是首页,有一个进入按钮。
接下来是调试界面,左上角是显示当前时间,右上角有一个进入WIFI设置的按钮,右边显示页数,还有显示时间戳,最下面是清除当前界面,左边部分就是显示调试信息,可以显示连接的设备情况。
WIFI信息部分,主要显示WIFI信息,有修改名字和密码的按钮。
点击修改WIFI名字,就可以进入WIFI名字修改界面,设计的是全字母+数字以及一些字符
修改WIFI密码类似,最多可以设计32位。
为了按钮显示效果好,还修改了设计了按下的界面,按键边缘发黑。
4、程序设计
程序分为Dwin和ESP32,Dwin主要是接收串口数据,然后显示出来,同时获取PCF8563时钟芯片的数据,主要代码如下:
- /*协议
- AA 03 31 32 33
- AA为协议,添加显示内容
- 03为后续内容长度
- 31 32 33为内容
- */
- //u8 rec_data_g[40];
- void esp32_analysis(u8 rec_data[])
- {
- int i = 0;
- int pass = 0;
- u8 date_temp[256] = {0};
- if(rec_data[0] == 0xAA) //显示内容
- {
- if(display_time == 0)
- {
- memcpy(date_temp, &rec_data[2], rec_data[1]);
- }
- else
- {
- getTimeStr(date_temp);
- memcpy(&date_temp[10], &rec_data[2], rec_data[1]);
- }
- display_current_line += line_check(date_temp);
- if(display_current_line > 10)
- {
- display_current_line = 1;
- if(display_page_total < 10)
- {
- if(display_page_current == display_page_total)
- {
- display_page_current++;
- }
- display_page_total++;
- }
- else
- {
- for(i = 0;i < 9;i++)
- {
- memcpy(display_data[i], display_data[i+1], 512);
- }
- memset(display_data[9], 0, 512);
- if(display_page_current != display_page_total)
- {
- if(display_page_current > 1)
- {
- display_page_current--;
- }
- }
- }
- display_page_str[0] = display_page_current / 10 + 0x30;
- display_page_str[1] = display_page_current % 10 + 0x30;
- display_page_str[3] = display_page_total / 10 + 0x30;
- display_page_str[4] = display_page_total % 10 + 0x30;
- write_dgus_vp(0x2120, display_page_str, 8);
- }
- memcpy(&display_data[display_page_total - 1][strlen(display_data[display_page_total - 1])], date_temp, strlen(date_temp));
- write_dgus_vp(0x3000, display_data[display_page_current - 1], strlen(display_data[display_page_current - 1]));
- }
- else if(rec_data[0] == 0xAB) //wifi名字和密码
- {
- memset(wifi_ssid, 0, 32);
- memset(wifi_pass, 0, 32);
- for(i = 0;i < rec_data[1];i++)
- {
- if(rec_data[i + 2] != ',')
- {
- if(pass == 0)
- {
- wifi_ssid[strlen(wifi_ssid)] = rec_data[i + 2];
- }
- else
- {
- wifi_pass[strlen(wifi_pass)] = rec_data[i + 2];
- }
- }
- else
- {
- pass = 1;
- }
- }
- refresh_wifi_ssid();
- refresh_wifi_pass();
- }
- else if(rec_data[0] == 0xAC)
- {
- myTime.year = RTC_BinToBcd2((rec_data[4] - 0x30) * 10 + (rec_data[5] - 0x30));
- myTime.mon = RTC_BinToBcd2((rec_data[7] - 0x30) * 10 + (rec_data[8] - 0x30));
- myTime.day = RTC_BinToBcd2((rec_data[10] - 0x30) * 10 + (rec_data[11] - 0x30));
- myTime.hour = RTC_BinToBcd2((rec_data[13] - 0x30) * 10 + (rec_data[14] - 0x30));
- myTime.min = RTC_BinToBcd2((rec_data[16] - 0x30) * 10 + (rec_data[17] - 0x30));
- myTime.sec = RTC_BinToBcd2((rec_data[19] - 0x30) * 10 + (rec_data[20] - 0x30));
- SetRealTime(&myTime);
- }
- }
- //发送wifi名字
- void send_wifi_ssid(u8 wifi_temp[])
- {
- u8 wifi_send[40] = {0xAA};
- wifi_send[1] = strlen(wifi_temp) + 1;
- wifi_send[2] = 0x01;
- memcpy(&wifi_send[3], wifi_temp, strlen(wifi_temp));
- Uatr_Send_Data(4, wifi_send, wifi_send[1] + 2);
- }
- //发送wifi密码
- void send_wifi_pass(u8 wifi_temp[])
- {
- u8 wifi_send[40] = {0xAA};
- wifi_send[1] = strlen(wifi_temp) + 1;
- wifi_send[2] = 0x02;
- memcpy(&wifi_send[3], wifi_temp, strlen(wifi_temp));
- Uatr_Send_Data(4, wifi_send, wifi_send[1] + 2);
- }
- void refresh_time()
- {
- GetRealTime(&myTime);
- Write_Dgus(0x2100, 2);
- Write_Dgus(0x2102, 0);
- Write_Dgus(0x2104, myTime.year/16%10);
- Write_Dgus(0x2106, myTime.year%16);
- Write_Dgus(0x210A, RTC_Bcd2ToBin(myTime.mon)/10%10);
- Write_Dgus(0x210C, RTC_Bcd2ToBin(myTime.mon)%10);
- Write_Dgus(0x2110, RTC_Bcd2ToBin(myTime.day)/10%10);
- Write_Dgus(0x2112, RTC_Bcd2ToBin(myTime.day)%10);
- Write_Dgus(0x2114, RTC_Bcd2ToBin(myTime.hour)/10%10);
- Write_Dgus(0x2116, RTC_Bcd2ToBin(myTime.hour)%10);
- Write_Dgus(0x211A, RTC_Bcd2ToBin(myTime.min)/10%10);
- Write_Dgus(0x211C, RTC_Bcd2ToBin(myTime.min)%10);
- }
复制代码 ESP32则是保存WIFI名称和密码,同时将WIFI的情况通过串口发送给Dwin屏,主要代码如下:
- static void udp_server_task(void *pvParameters)
- {
- char rx_buffer[120];
- char addr_str[120];
- int addr_family = (int)pvParameters;
- int ip_protocol = 0;
- struct sockaddr_in6 dest_addr;
- while (1) {
- if (addr_family == AF_INET) {
- struct sockaddr_in *dest_addr_ip4 = (struct sockaddr_in *)&dest_addr;
- dest_addr_ip4->sin_addr.s_addr = htonl(INADDR_ANY);
- dest_addr_ip4->sin_family = AF_INET;
- dest_addr_ip4->sin_port = htons(BROADCAST_PORT);
- ip_protocol = IPPROTO_IP;
- } else if (addr_family == AF_INET6) {
- bzero(&dest_addr.sin6_addr.un, sizeof(dest_addr.sin6_addr.un));
- dest_addr.sin6_family = AF_INET6;
- dest_addr.sin6_port = htons(BROADCAST_PORT);
- ip_protocol = IPPROTO_IPV6;
- }
- int sock = socket(addr_family, SOCK_DGRAM, ip_protocol);
- if (sock < 0) {
- ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
- break;
- }
- ESP_LOGI(TAG, "Socket created");
- #if defined(CONFIG_LWIP_NETBUF_RECVINFO) && !defined(CONFIG_EXAMPLE_IPV6)
- int enable = 1;
- lwip_setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &enable, sizeof(enable));
- #endif
- #if defined(CONFIG_EXAMPLE_IPV4) && defined(CONFIG_EXAMPLE_IPV6)
- if (addr_family == AF_INET6) {
- // Note that by default IPV6 binds to both protocols, it is must be disabled
- // if both protocols used at the same time (used in CI)
- int opt = 1;
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
- setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
- }
- #endif
- // Set timeout
- struct timeval timeout;
- timeout.tv_sec = 10;
- timeout.tv_usec = 0;
- setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout);
- int err = bind(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
- if (err < 0) {
- ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
- }
- ESP_LOGI(TAG, "Socket bound, port %d", BROADCAST_PORT);
- struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6
- socklen_t socklen = sizeof(source_addr);
- #if defined(CONFIG_LWIP_NETBUF_RECVINFO) && !defined(CONFIG_EXAMPLE_IPV6)
- struct iovec iov;
- struct msghdr msg;
- struct cmsghdr *cmsgtmp;
- u8_t cmsg_buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
- iov.iov_base = rx_buffer;
- iov.iov_len = sizeof(rx_buffer);
- msg.msg_control = cmsg_buf;
- msg.msg_controllen = sizeof(cmsg_buf);
- msg.msg_flags = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_name = (struct sockaddr *)&source_addr;
- msg.msg_namelen = socklen;
- #endif
- while (1) {
- ESP_LOGI(TAG, "Waiting for data");
- #if defined(CONFIG_LWIP_NETBUF_RECVINFO) && !defined(CONFIG_EXAMPLE_IPV6)
- int len = recvmsg(sock, &msg, 0);
- #else
- int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen);
- #endif
- // Error occurred during receiving
- if (len < 0) {
- ESP_LOGE(TAG, "recvfrom failed: errno %d", errno);
- break;
- }
- // Data received
- else {
- // Get the sender's ip address as string
- if (source_addr.ss_family == PF_INET) {
- inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr, addr_str, sizeof(addr_str) - 1);
- #if defined(CONFIG_LWIP_NETBUF_RECVINFO) && !defined(CONFIG_EXAMPLE_IPV6)
- for ( cmsgtmp = CMSG_FIRSTHDR(&msg); cmsgtmp != NULL; cmsgtmp = CMSG_NXTHDR(&msg, cmsgtmp) ) {
- if ( cmsgtmp->cmsg_level == IPPROTO_IP && cmsgtmp->cmsg_type == IP_PKTINFO ) {
- struct in_pktinfo *pktinfo;
- pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgtmp);
- ESP_LOGI(TAG, "dest ip: %s", inet_ntoa(pktinfo->ipi_addr));
- }
- }
- #endif
- } else if (source_addr.ss_family == PF_INET6) {
- inet6_ntoa_r(((struct sockaddr_in6 *)&source_addr)->sin6_addr, addr_str, sizeof(addr_str) - 1);
- }
- rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string...
- ESP_LOGI(TAG, "Received %d bytes from %s:", len, addr_str);
- ESP_LOGI(TAG, "%s", rx_buffer);
- char send_data[256] = {0};
- sprintf(send_data, "[R]%s:%s\r\n", addr_str, rx_buffer);
- ESP_LOGI(TAG, "send_data: %s", send_data);
- dwin_screen_display(send_data, strlen(send_data));
- if(rx_buffer[0] == 't' && rx_buffer[1] == 'i' && rx_buffer[2] == 'm' && rx_buffer[3] == 'e' && rx_buffer[4] == ':' )
- {
- dwin_screen_datetime(&rx_buffer[5], 19);
- }
- // int err = sendto(sock, rx_buffer, len, 0, (struct sockaddr *)&source_addr, sizeof(source_addr));
- // if (err < 0) {
- // ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
- // break;
- // }
- }
- }
- if (sock != -1) {
- ESP_LOGE(TAG, "Shutting down socket and restarting...");
- shutdown(sock, 0);
- close(sock);
- }
- }
- vTaskDelete(NULL);
- }
- // Mount path for the partition
- const char *base_path = "/spiflash";
- // Handle of the wear levelling library instance
- static wl_handle_t s_wl_handle = WL_INVALID_HANDLE;
- void wifi_write_flash()
- {
- char write_data[65] = {0};
- ESP_LOGI(TAG, "Opening file write");
- FILE *f;
-
- f = fopen(device_filename, "wb");
- if (f == NULL) {
- ESP_LOGE(TAG, "Failed to open file for writing");
- return;
- }
- sprintf(write_data, "%s,%s", wifi_ssid, wifi_pass);
- fprintf(f, write_data);
- fclose(f);
- }
- void app_main(void)
- {
- //Initialize NVS
- esp_err_t ret = nvs_flash_init();
- if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
- ESP_ERROR_CHECK(nvs_flash_erase());
- ret = nvs_flash_init();
- }
- ESP_ERROR_CHECK(ret);
- vTaskDelay(1000 / portTICK_PERIOD_MS); //100ms
- dwin_init();
- vTaskDelay(2000 / portTICK_PERIOD_MS); //100ms
- ESP_LOGI(TAG, "Mounting FAT filesystem");
- // To mount device we need name of device partition, define base_path
- // and allow format partition in case if it is new one and was not formatted before
- const esp_vfs_fat_mount_config_t mount_config = {
- .max_files = 4,
- .format_if_mount_failed = false,
- .allocation_unit_size = CONFIG_WL_SECTOR_SIZE
- };
- esp_err_t err;
- if (EXAMPLE_FATFS_MODE_READ_ONLY){
- err = esp_vfs_fat_spiflash_mount_ro(base_path, "storage", &mount_config);
- } else {
- err = esp_vfs_fat_spiflash_mount_rw_wl(base_path, "storage", &mount_config, &s_wl_handle);
- }
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
- return;
- }
- char line[128];
-
- ESP_LOGI(TAG, "Opening file write");
- // Open file for reading
- ESP_LOGI(TAG, "Reading file read");
- FILE *f;
- f = fopen(device_filename, "rb");
- if (f != NULL) {
- // ESP_LOGE(TAG, "Failed to open file for reading");
- fgets(line, sizeof(line), f);
- fclose(f);
- // strip newline
- char *pos = strchr(line, '\n');
- if (pos) {
- *pos = '\0';
- }
- ESP_LOGI(TAG, "Read from file: '%s'", line);
- int split_cnt = 0;
- while(line[split_cnt] != ',')
- {
- split_cnt++;
- }
- memcpy(wifi_ssid, line, split_cnt);
- memcpy(wifi_pass, &line[split_cnt + 1], strlen(line) - split_cnt);
- dwin_screen_wifi(line, strlen(line)); //给屏幕发送WIFI
- // dwin_screen_wifi(line, strlen(line)); //给屏幕发送WIFI
- // dwin_screen_wifi(line, strlen(line)); //给屏幕发送WIFI
- wifi_ssid[split_cnt] = '\0';
- wifi_pass[strlen(line) - split_cnt] = '\0';
- }
-
- wifi_init_softap();
-
- xTaskCreate(udp_server_task, "udp_server", 4096, (void*)AF_INET, 5, NULL);
- xTaskCreate(softap_check_ip_task, "softap_check_ip", 4096, (void*)AF_INET, 5, NULL);
- }
复制代码
演示视频:
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|