|
【开源】便携功率计
1.介绍
最近在研究测功率,正好用迪文屏做了一个功率计的Demo。
2.硬件准备
选择了2英寸迪文屏,型号如下:
电流电压检测传感器采用INA226模块
设计了一块主板,结合ESP32、INA226和迪文屏,增加一些检测接口。
3.界面设计
采用Adobe Illustrator设计界面UI,素材如下:
一共有6个界面,界面设计如下:
4.代码设计
这次代码只有ESP32,ESP32通过IIC采集INA226的数据,电流,电压和功率,将以上数据通过串口发送给迪文屏,同时通过UDP将数据发送至上位机。主要代码如下:
- <font face="宋体">static void wifi_event_handler(void* arg, esp_event_base_t event_base,
- int32_t event_id, void* event_data)
- {
- if (event_id == WIFI_EVENT_AP_STACONNECTED) {
- wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
- ESP_LOGI(TAG, "station "MACSTR" join, AID=%d",
- MAC2STR(event->mac), event->aid);
- } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
- wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
- ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d",
- MAC2STR(event->mac), event->aid);
- }
- }
- void wifi_init_softap(void)
- {
- ESP_ERROR_CHECK(esp_netif_init());
- ESP_ERROR_CHECK(esp_event_loop_create_default());
- esp_netif_create_default_wifi_ap();
- wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
- ESP_ERROR_CHECK(esp_wifi_init(&cfg));
- ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
- ESP_EVENT_ANY_ID,
- &wifi_event_handler,
- NULL,
- NULL));
- wifi_config_t wifi_config = {
- .ap = {
- .ssid = EXAMPLE_ESP_WIFI_SSID,
- .ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
- .channel = EXAMPLE_ESP_WIFI_CHANNEL,
- .password = EXAMPLE_ESP_WIFI_PASS,
- .max_connection = EXAMPLE_MAX_STA_CONN,
- .authmode = WIFI_AUTH_WPA_WPA2_PSK
- },
- };
- if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
- wifi_config.ap.authmode = WIFI_AUTH_OPEN;
- }
- ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
- ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
- ESP_ERROR_CHECK(esp_wifi_start());
- ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",
- EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL);
- }
- esp_ip4_addr_t ip_addr;
- static void udp_server_task(void *pvParameters)
- {
- // 将IPv4地址转换为字符串格式的IP地址
- char ip_addr_str[INET_ADDRSTRLEN];
- inet_ntoa_r(ip_addr.addr, ip_addr_str, sizeof(ip_addr_str));
- // 设置广播地址和接收方的端口号
- struct sockaddr_in broadcast_addr = {
- .sin_addr.s_addr = ip_addr.addr | htonl(0xFF), //广播地址,其类型为uint32_t
- .sin_family = AF_INET,
- .sin_port = htons(BROADCAST_PORT),
- };
- // 将广播地址转换为字符串
- ESP_LOGI(TAG, "broadcast_addr IP: %s", inet_ntoa(broadcast_addr.sin_addr.s_addr));
- // Create a socket for UDP broadcast
- int broadcast_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (broadcast_socket < 0) {
- ESP_LOGE(TAG, "Failed to create socket: %d", broadcast_socket);
- goto error;
- }
- // 设置套接字选项以启用地址重用
- int reuseEnable = 1;
- setsockopt(broadcast_socket, SOL_SOCKET, SO_REUSEADDR, &reuseEnable, sizeof(reuseEnable));
- // 使能广播
- int broadcast_enable = 1;
- if (setsockopt(broadcast_socket, SOL_SOCKET, SO_BROADCAST, &broadcast_enable, sizeof(broadcast_enable)) < 0) {
- ESP_LOGE(TAG, "Failed to enable broadcasting");
- close(broadcast_socket);
- goto error;
- }
- // Send the broadcast message every BROADCAST_INTERVAL_MS milliseconds
- while (1) {
- // 创建一个 JSON 对象,并添加三个属性
- cJSON *json = cJSON_CreateObject();
- cJSON_AddStringToObject(json, "device", "EZPower");
- cJSON_AddStringToObject(json, "ip", ip_addr_str);
- cJSON_AddNumberToObject(json, "port", 3334);
- // 将 JSON 数据转换为字符串
- char *json_str = cJSON_Print(json);
- ESP_LOGI(TAG, "Broadcasting message: %s", json_str);
- dwin_screen_send(json_str, strlen(json_str));
- int ret = sendto(broadcast_socket, json_str, strlen(json_str), 0, (struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr));
- if (ret < 0) {
- ESP_LOGE(TAG, "Failed to send broadcast message: %d", ret);
- }
- cJSON_Delete(json);
- free(json_str);
- vTaskDelay(2000 / portTICK_PERIOD_MS);
- }
- error:
- vTaskDelete(NULL);
- }
- 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);
- ESP_LOGI(TAG, "ESP_WIFI_MODE_AP");
- wifi_init_softap();
- ip_addr.addr = 0xFF04A8C0;
- dwin_init();
- xTaskCreate(udp_server_task, "udp_server", 4096, (void*)AF_INET, 5, NULL);
- }</font>
复制代码
5.总结
其实很多地方都会用到功率计,尤其是一些低功耗的产品,这个便携功率计其实就是为了记录和检验这些产品存在的。
演示视频效果:
备注说明:如需源码,请参考此链接:http://inforum.dwin.com.cn:20080/forum.php?mod=viewthread&tid=10600&extra=&_dsign=e227a7c6
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|