闲聊:

最近更新的有点慢了,工作上的事加上朋友的婚礼,还好我赶在参加婚礼前把前一个发了,不然两篇博客的周期就是二十多天了。以前想的是争取每周发一篇,现在想想我的工作性质不太现实了;还有一个考虑就是我确实不知道该写一些什么上来,低端的不想写,高端的写不了。(也可征集一下网友们的意见)    导致目前就有点被动,又想着最近疫情又有反复,自己一个人在家还是需要把学到的东西做一个积累,我还是把之后想做的写出来,也好和其他网友对比一下做项目的方式方法。

整体思路:

使用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();//初始化flashesp_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,建立apwifi_init_softap();
#else//client,建立stawifi_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准备建立servervTaskDelay(3000 / portTICK_RATE_MS);ESP_LOGI(TAG, "create tcp server");//建立serverint socket_ret = create_tcp_server(true);
#else//延时3S准备建立clienvTaskDelay(3000 / portTICK_RATE_MS);ESP_LOGI(TAG, "create tcp Client");//建立clientint socket_ret = create_tcp_client();
#endifif (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...");//建立serverif (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...");//建立clientint 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/ 复制此链接,打开抖音搜索,直接观看视频!

微信小程序和ESP32对接,实现手机远程控制灯的亮灭相关推荐

  1. 微信小程序:设置字体跟随手机系统

    小程序开发:全局设置跟随手机系统默认字体 前言 最近在开发一款微信小程序,发现字体不是跟随手机系统设置的字体,这样对用户很不友好,通过下面这行代码,就可以将页面的字体搞成系统默认字体了. 提示:要设置 ...

  2. 微信小程序上传后 进行性手机扫码阅览 发现白屏的解决

    目录 问题: 微信小程序上传后 进行性手机扫码阅览 发现白屏的解决 1.上传时没有勾选保护 2.请求的域名没有配置 问题: 微信小程序上传后 进行性手机扫码阅览 发现白屏的解决 1.上传时没有勾选保护 ...

  3. 微信小程序实现画布自适应各种手机尺寸

    微信小程序开发交流qq群   173683895    承接微信小程序开发.扫码加微信. 正文: 解决的问题:  画布,动画等js里面的操作,默认是px而不是rpx, 无法根据手机屏幕自适应 达到的效 ...

  4. 微信小程序有关于Linux的吗,微信小程序可以跳转到手机 app 啦!

    微信今天宣布开放从小程序跳转到手机应用的功能,具体来说,这项功能属于腾讯此前开放的"app 链接分享到微信"的延伸功能,用户通过某款 app 打开微信并直接跳转到小程序页面后,微信 ...

  5. H5及微信小程序实测可用——监听手机返回键操作

    目录 1.自定义导航(只能拦截左上角返回) 2.内嵌H5实现拦截物理键返回(均可监听) 微信小程序开发过程中我们经常遇到需要监听点击左上角返回.手机物理返回键或者左滑返回的需求 微信原生是没有API支 ...

  6. 微信小程序wx.createInnerAudioContext()在安卓手机不能播放语音文件问题解决

    本文介绍小程序安卓手机播放语音文件错误问题的分析过程与解决方案,该问题出现较多,问题隐藏较深,按本文方案可以解决该问题. 一.问题现象 微信小程序已经放弃了基于wx.createAudioContex ...

  7. 在微信小程序里自动获得当前手机所在的经纬度并转换成地址

    效果:我在手机上打开微信小程序,自动显示出我当前所在的地理位置: 具体步骤: 1. 使用微信jssdk提供的getLocation API拿到经纬度: 2. 调用高德地图的api使用经纬度去换取地址的 ...

  8. 微信小程序支付-java对接微信

    一共是两个方法: 一个方法后台生成预支付订单,得到预支付交易会话标识prepay_id,传给前端,让前端调起小程序支付: 一个是支付回调 目录 一.生成预支付订单 注意: 二. 支付回调 一.生成预支 ...

  9. 微信小程序获取Onenet温湿度数据并控制灯亮灭

    ​ 其实之前就写过类似的文章,但是看过我博客的朋友就知道,我是先写微信小程序获取onenet,然后再写esp32上云到onenet.一篇是ESP32-C3通过MQTT协议把温湿度上传到OneNet平台 ...

最新文章

  1. nginx header参数丢失_Nginx 性能优化有这篇就够了!
  2. .NET英文技术文章导读(2017-02-09)
  3. 《软件测试技术实战:设计、工具及管理》—第2章 2.2节运用决策表设计测试用例...
  4. 问题:c语言简单的循环和字符串,错在哪里了?结果怎么是0(已解决)
  5. 数据连接之--Datalist 的使用(查看、编辑、删除)
  6. java多线程队列_java多线程消费者生产者模式(BlockingQueue 通过阻塞队列实现)
  7. Python操作Jira提交BUG
  8. 我终于知道公司前端为啥不加班了…
  9. bigdecimal 科学计数转普通计数_通用计数器的应用价值
  10. linux-2.6.22.6 内核源代码包的文件目录介绍
  11. 综合金融服务方案模板
  12. S2B2C做得好,功劳全在一件代发功能
  13. OpenWrt旁路由设置教程
  14. python主页面_使用Wagtail CMS使用Python检测父页面和子页面...
  15. 将vim打造成强大的python和c的ide
  16. vue项目添加百度统计及设置埋点
  17. java向微信公众号---发送模板和图文消息
  18. 思科防火墙NAT——实验
  19. Connection接口
  20. java 台球_Java入门和一个台球小项目

热门文章

  1. Tomcat安装与部署
  2. java.util包详解
  3. getchar() 和 getch()
  4. html 自动排序表格,表格排序.html
  5. 5.4 BGP地址聚合
  6. (附源码)计算机毕业设计ssm个人人际关系管理软件
  7. Linux工具学习之【gcc/g++】
  8. 关于preempt_enable 和 preempt_disable
  9. TypeError: object of type ‘type‘ has no len()
  10. 《Focal Loss GHM Loss Dice Los》论文笔记