微信小程序和ESP32对接,实现手机远程控制灯的亮灭
闲聊:最近更新的有点慢了,工作上的事加上朋友的婚礼,还好我赶在参加婚礼前把前一个发了,不然两篇博客的周期就是二十多天了。以前想的是争取每周发一篇,现在想想我的工作性质不太现实了;还有一个考虑就是我确实不知道该写一些什么上来,低端的不想写,高端的写不了。导致目前就有点被动,又想着最近疫情又有反复,自己一个人在家还是需要把学到的东西做一个积累,我还是把之后想做的写出来,也好和其他网友对比一下做项目的方
闲聊:
最近更新的有点慢了,工作上的事加上朋友的婚礼,还好我赶在参加婚礼前把前一个发了,不然两篇博客的周期就是二十多天了。以前想的是争取每周发一篇,现在想想我的工作性质不太现实了;还有一个考虑就是我确实不知道该写一些什么上来,低端的不想写,高端的写不了。(也可征集一下网友们的意见) 导致目前就有点被动,又想着最近疫情又有反复,自己一个人在家还是需要把学到的东西做一个积累,我还是把之后想做的写出来,也好和其他网友对比一下做项目的方式方法。
整体思路:
使用ESP32作为客户端连接路由器继而连接远程服务器,通过服务器后台程序对数据库做保存和读取,实现手机微信小程序访问远程服务器的数据库做状态设置和获取,ESP32连接远程服务器做底层设备的状态查询和开关量动作。我目前是在虚拟机里面安装的Ubuntu18.04,然后使用esp-idf-v3.3.1 VScode配置开发esp sdk开发。要是同样使用此方法开发的朋友门,可以搜一下 Ubuntu 搭建 ESP32 开发环境(vscode)。开发环境搭建,就不在本章文章中展现了。只需要做一个后台控制程序,然后做了一个网页版的设备管理平台就可以实现这个过程。
设备管理平台如下图,主要功能是添加设备,更改底层设备类型,绑定微信用户名,管理微信用户名下的底层设备。
源码链接:https://download.csdn.net/download/L_e_c/14141534
硬件设计:
淘宝购买的220转12V的模块,加上两个LDO,设计两路继电器,画的PCB之前想的是学习用处,所以把引脚都引出来了,比较大。有想学习的,也可以私信我,成品原价出。原理图及PCB效果图如下。
源码设计:
因为ESP32SDK开发,乐鑫提供的程序入口其实就是一个任务函数,所以启动后的任务名字是固定的,我们可以根据这个任务处理函数来做我们自己的程序,这样开发起来也更简单。我们主要使用了GPIO,UART,TCP,CJSON。主函数里面主要做一些初始化,然后建立WiFi_STA,创建客户端,然后设置一个连接服务器的任务,连接任务中做了一个底层设备注册函数Sign_IN_Device()和设备状态反馈函数Device_State()。在连接任务函数里面再设置两个接收任务,一个是串口调试用的,一个是网络接收任务,接收到的字符串放到processMessage()函数来处理,根据不同的键值和键值对反馈不同的结果,处理不同的命令。程序的源码差不多就只需要这么多,我只是分享了一个思路和基于乐鑫提供的源码上做的一个工程,要是想做这方面的还是需要多了解乐鑫源码或者WiFi协议。
void app_main(void)
{
//初始化IO口
gpio_pad_select_gpio(LED_R_IO);
gpio_set_direction(LED_R_IO,GPIO_MODE_OUTPUT); //设置IO为输出
//初始化串口,主要做调试使用
uart_init();
//初始化flash
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
#if TCP_SERVER_CLIENT_OPTION
//server,建立ap
wifi_init_softap();
#else
//client,建立sta
wifi_init_sta();
#endif
//新建一个tcp连接任务
xTaskCreate(&tcp_connect, "tcp_connect", 4096, NULL, 5, NULL);
}
static void tcp_connect(void *pvParameters)
{
while (1)
{
Sign_IN_State = 0;
g_rxtx_need_restart = false;
//等待WIFI连接信号量,死等
xEventGroupWaitBits(tcp_event_group, WIFI_CONNECTED_BIT, false, true, portMAX_DELAY);
ESP_LOGI(TAG, "start tcp connected");
TaskHandle_t tx_rx_task = NULL;
#if TCP_SERVER_CLIENT_OPTION
//延时3S准备建立server
vTaskDelay(3000 / portTICK_RATE_MS);
ESP_LOGI(TAG, "create tcp server");
//建立server
int socket_ret = create_tcp_server(true);
#else
//延时3S准备建立clien
vTaskDelay(3000 / portTICK_RATE_MS);
ESP_LOGI(TAG, "create tcp Client");
//建立client
int socket_ret = create_tcp_client();
#endif
if (socket_ret == ESP_FAIL)
{
//建立失败
ESP_LOGI(TAG, "create tcp socket error,stop...");
continue;
}
else
{
//建立成功
ESP_LOGI(TAG, "create tcp socket succeed...");
Sign_IN_Device();
//建立tcp接收数据任务
//创建串口2接收任务
xTaskCreate(uart2_rx_task, "uart2_rx_task", 1024*2, NULL, configMAX_PRIORITIES-1, NULL);
//串口2数据发送测试
uart_write_bytes(UART_NUM_2, "uart2 test OK ", strlen("uart2 test OK "));
if (pdPASS != xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task))
{
//建立失败
ESP_LOGI(TAG, "Recv task create fail!");
}
else
{
//建立成功
ESP_LOGI(TAG, "Recv task create succeed!");
}
}
while (1)
{
vTaskDelay(3000 / portTICK_RATE_MS);
#if TCP_SERVER_CLIENT_OPTION
//重新建立server,流程和上面一样
if (g_rxtx_need_restart)
{
ESP_LOGI(TAG, "tcp server error,some client leave,restart...");
//建立server
if (ESP_FAIL != create_tcp_server(false))
{
if (pdPASS != xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task))
{
ESP_LOGE(TAG, "tcp server Recv task create fail!");
}
else
{
ESP_LOGI(TAG, "tcp server Recv task create succeed!");
//重新建立完成,清除标记
g_rxtx_need_restart = false;
}
}
}
#else
//重新建立client,流程和上面一样
if (g_rxtx_need_restart)
{
Sign_IN_State=0;
vTaskDelay(3000 / portTICK_RATE_MS);
ESP_LOGI(TAG, "reStart create tcp client...");
//建立client
int socket_ret = create_tcp_client();
if (socket_ret == ESP_FAIL)
{
ESP_LOGE(TAG, "reStart create tcp socket error,stop...");
continue;
}
else
{
ESP_LOGI(TAG, "reStart create tcp socket succeed...");
//重新建立完成,清除标记
g_rxtx_need_restart = false;
//建立tcp接收数据任务
if (pdPASS != xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task))
{
ESP_LOGE(TAG, "reStart Recv task create fail!");
}
else
{
ESP_LOGI(TAG, "reStart Recv task create succeed!");
}
}
}
else
{
if(Sign_IN_State==0)
{
Send_Count=0;
Sign_IN_Device();
ESP_LOGI(TAG, "delay_3s!");
}
else
{
if(++Send_Count>=3)
{
Send_Count=0;
Device_State();
ESP_LOGI(TAG, "delay_9s!");
}
}
}
#endif
}
}
vTaskDelete(NULL);
}
void Sign_IN_Device(void)
{
cJSON *pRoot = cJSON_CreateObject();
//新增一个字段TYPE到根点
cJSON_AddStringToObject(pRoot,"TYPE","HS");
cJSON_AddStringToObject(pRoot,"CID","bangongshi");
char *s = cJSON_Print(pRoot);
send(connect_socket, s, strlen(s), 0);
//释放内存
cJSON_free((void *) s);
cJSON_Delete(pRoot);
}
void Device_State(void)
{
cJSON *pRoot = cJSON_CreateObject();
//新增一个字段TYPE到根点
cJSON_AddStringToObject(pRoot,"TYPE","STATE");
cJSON_AddNumberToObject(pRoot,"state",1);
cJSON_AddNumberToObject(pRoot,"relay",Relay_Num);
char *s = cJSON_Print(pRoot);
send(connect_socket, s, strlen(s), 0);
//释放内存
cJSON_free((void *) s);
cJSON_Delete(pRoot);
}
int processMessage(char *msg) {
cJSON *jsonObj=cJSON_Parse(msg);
cJSON *method;
cJSON *typ;
char *m;
int x;
//json字符串解析失败,直接退出
if(!jsonObj)
{
cJSON_Delete(jsonObj);
return 0;
}
method = cJSON_GetObjectItem(jsonObj, "TYPE");
m = method->valuestring;
if(strncmp(m, "AUTHERROR", 9) == 0 ) //设备未注册,重新注册
{
cJSON_Delete(jsonObj);
return 1;
// char *content = cJSON_GetObjectItem(jsonObj, "DATA")->valuestring;
// if(strncmp(content, "No identity", 4) == 0)
// {
//
// }
}
if(strncmp(m, "HSOK", 4) == 0 ) //注册信息返回
{
char *content = cJSON_GetObjectItem(jsonObj, "DATA")->valuestring;
if(strncmp(content, "HSOK", 4) == 0)
{
cJSON_Delete(jsonObj);
return 2;
}
}
if(strncmp(m, "DATAOK", 6) == 0 ) //
{
char *content = cJSON_GetObjectItem(jsonObj, "TYPE")->valuestring;
if(strncmp(content, "DATAOK", 6) == 0)
{
// Resert_Cnt_10S=0; //重启时间清零
cJSON_Delete(jsonObj);
return 3;
}
}
if(strncmp(m, "CDATA", 5) == 0 ) //
{
typ = cJSON_GetObjectItem(jsonObj, "relay");
x=typ->valueint;
// if(strncmp(m, "1", 1) == 0 )
if(x==0) //关灯
{
return 4;
}
else if(x==1) //
{
return 5;
}
}
// if(jsonObj)
cJSON_Delete(jsonObj);
return 0;
}
调试结果:
视频演示地址:微信小程序远程控制家用设备开关。esp32 SDK开发,CSDN上有文章介绍。%电子产品 %孤独的最高境界 https://v.douyin.com/JnkgxVw/ 复制此链接,打开抖音搜索,直接观看视频!
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)