【微信小程序控制硬件第1篇 】 全网首发,借助 emq 消息服务器带你如何搭建微信小程序的mqtt服务器,轻松控制智能硬件!
【微信小程序控制硬件第2篇 】 开始微信小程序之旅,导入小程序Mqtt客户端源码,实现简单的验证和通信于服务器!
【微信小程序控制硬件第3篇 】 从软件到硬件搭建一个微信小程序控制esp8266的项目,自定义通信协议,为面试职位和比赛项目加分!
【微信小程序控制硬件第4篇 】 深度剖析微信公众号配网 Airkiss 原理与过程,esp8266如何自定义回调参数给微信,实现绑定设备第一步!
【微信小程序控制硬件第5篇 】理清接下来必须走的架构思想,学习下 JavaScript 的观察者模式,在微信小程序多页面同时接收到设备推送事件!
【微信小程序控制硬件第6篇 】服务器如何集成七牛云存储SDK,把用户自定义设备图片存储在第三方服务器!
【微信小程序控制硬件第7篇 】动起来作一个微信小程序Mqtt协议控制智能硬件的框架,为本身内心全栈工程师梦想浇水!!
【微信小程序控制硬件第8篇 】微信小程序以 websocket 链接阿里云IOT物联网平台mqtt服务器,封装起来使用就是这么简单!
【微信小程序控制硬件第9篇 】巧借阿里云物联网平台的免费链接,从微信小程序颜色采集控制 esp8266 输出七彩灯效果,中秋节来个直播如何?!
【微信公众号控制硬件 第10篇 】如何在微信公众号网页实现链接mqtt服务器教程!!
【微信小程序控制硬件 第11篇 】全网首发,微信小程序ble蓝牙控制esp32,实现无需网络也能够控制亮度开关。css
H5+css+js
,从上个星期给你们带来的服务器搭建,今天有幸给你们带来个人小项目,对于学习微信小程序控制智能硬件(包括esp8266
)的原理与过程,我以为对你有必定的启发!esp8266
最小系统一个,LED一个,2
个轻触开关,杜邦线若干;wss
即websocket+ssl
,并且该端口必须是443
,为了你们方便,我这里教你们怎么接入百度天工服务器,由于百度天工已经支持微信小程序了!固然了,你能够看我第一篇怎么搭建属于本身域名的微信小程序MQTT
服务器,用本身的服务器做为桥梁也行!看业务须要!H5+css+javaSrcipt
,微信的小程序开发和这个很是类似!若是想入门微信小程序开发,本身能够去琢磨!主题 | 发送端 | 接收端 | 消息(JSON格式) | 消息含义 |
---|---|---|---|---|
/light/deviceOut | 微信小程序 | esp8266 | “{“change”:“power”,“value”:true}” | 开灯 |
“{“change”:“power”,“value”:“false”}” | 关灯 | |||
“{“change”:“pwm”,“value”:50}” | 调节亮度:value为亮度值 ,范围 [0,100] | |||
“{“change”:“query”,“value”:0}” | 微信小程序主动请求最新状态 |
主题 | 发送端 | 接收端 | 消息(JSON格式) | 消息含义 |
---|---|---|---|---|
/light/deviceIn | esp8266 | 微信小程序 | “{“power”:“false”,“brightNess”:50}” | power为灯的状态,brightNess是亮度值,范围 [0,100] |
MQTT
硬件服务器!仍是啰嗦一句,若是您有本身的服务器,那么这个章节能够不看!第一步:在百度云:https://console.bce.baidu.com 注册帐号,找到 物接入 loT Hub。html
第二步:这个 物接入 loT Hub接入也不是彻底免费的,是按照流量收费的,我选择为1元一个月的流量而后付款一年才十元,足够本身一我的用了!以后选择建立项目,按照以下步骤:前端
第三步:在认真观看了上面协议的通信协议以后,咱们按照上面的协议来建立策略。java
第四步:以后咱们要去建立身份,拿到
MQTT
链接的密码和帐号!吐槽下,真麻烦,还要说什么是身份列表,呵呵。web
第五步:建立策略后,咱们还须要建立用户!过程当中的身份、策略选择都是上几个步骤建立的便可!而后,咱们点击设备测试下;面试
第六步:同样的步骤,咱们一共要建立2个用户,一个是设备
esp8266
,一个是微信小程序链接客户端;json
MQTT
的帐号密码确定须要的!那么上面已经拿到了帐号和密码,那么域名和端口号在哪呢?看下图:UI
同步工做。connect: function() { var that = this; //获取全局变量,server_domain是MQTT服务器的域名 var client = new Client(app.globalData.server_domain, "DeviceId-7zne322b0g"); client.connect({ useSSL: true, //使用SSL cleanSession: true, //清理会话为true keepAliveInterval: 60, //心跳 userName: '7qfp623/wechatapp', //用户名 password: '5bXUJ3FfTJdK95sdh9', //用户密码 onSuccess: function() { wx.showToast({ title: '链接成功' }) that.data.client = client // 服务器下发消息回调匿名回调处理 client.onMessageArrived = function(msg) { if (typeof that.data.onMessageArrived === 'function') { return that.data.onMessageArrived(msg) } console.log("收到消息:" + msg.payloadString); var jsonObj = JSON.parse(msg.payloadString); if (typeof jsonObj.power == "boolean") console.log("解析 power :" + jsonObj.power); if (typeof jsonObj.brightNess == "number") console.log("解析 brightNess :" + jsonObj.brightNess); //根据esp8266发过来的 power字段内容作不一样的图片显示 var temp; if (jsonObj.power == true) { temp = '../pic/light_on.jpg'; //开灯图片加载显示 } else temp = '../pic/light_off.jpg'; //关灯图片加载显示 //开始同步界面显示处理 that.setData({ valueSlier: jsonObj.brightNess, lightValue: jsonObj.brightNess, isOpen: jsonObj.power, valuePic:temp, }) } //开始订阅主题 that.subscribe(app.globalData.subTopic, { qos: 1 }) //链接异常断开,咱们要作重连服务器的逻辑 client.onConnectionLost = function(responseObject) { if (typeof that.data.onConnectionLost === 'function') { return that.data.onConnectionLost(responseObject) } if (responseObject.errorCode !== 0) { console.log("onConnectionLost:" + responseObject.errorMessage); //检测到与服务器断开链接,设置定时函数一秒后从新链接服务器 setTimeout(function() { _self.connect(); }, 1000) } } //每次链接服务器都要主动查询设备的最新状态,保证界面是最新状态! var obj = new Object(); obj.change = "query"; obj.value = 0; that.publish(app.globalData.pubTopic, JSON.stringify(obj), 1, false) } }); }
<view class="container"> <view> <image src="{{valuePic}}" class='imgLight'></image> </view> <view class='item-power'> <text class='ele_text'>电源:</text> <switch bindchange="onSwitch" checked="{{isOpen}}" class='ele_switch' /> </view> <view class='line'></view> <view class='item_adjust_light'> <text class="section_title">当前亮度:{{lightValue}}</text> <slider value="{{valueSlier}}"class='slider' block-size="20" activeColor="#00BFFF" bindchange="eventSlider"/> </view> </view>
CSS
样式代码,我就不贴了!//拖动条点击下发 eventSlider: function(e) { console.log("发生 change 事件,携带值为:" + e.detail.value); this.setData({ lightValue: e.detail.value }) //开始构造json数据 var obj = new Object(); obj.change = "pwm"; obj.value = e.detail.value; //开始发布消息 this.publish(app.globalData.pubTopic, JSON.stringify(obj), 1, false) }, //按键触发 onSwitch: function(e) { console.log("onSwitch success :" + e.detail.value); //开始构造json数据 var jsonObj = new Object(); jsonObj.change = "power"; jsonObj.value = "" + e.detail.value + ""; //开始发布消息 this.publish(app.globalData.pubTopic, JSON.stringify(jsonObj), 1, false) },
esp8266
工程代码部分详解;Rtos 2.2
的 ,不是 3.0
版本的哈!并且MQTT
链接库是我提供的,在个人GitHub
有,稳定性不得说很好哈!
smartConfig
,短按就是调节亮度的明暗,很好!pwm
调节方法输入的参数duty
是0到1023,可是咱们的微信小程序发来的是0到100,因此要转换一下,这样就能够了:pwm_set_duty(1023 * apkPwm / 100, 0);
,其中apkPwm
是微信小程序发来的数值!//按键一短按的回调逻辑处理 static void key_13_short_press(void) { INFO("short press.."); //每次pwm百分比输出加10,若是大于100强制为最大值100! apkPwm += 10; if (apkPwm > 100) { apkPwm = 100; } pwm_set_duty(1023 * apkPwm / 100, 0); //由于微信发来的是 0到100,咱们取百分比以后再相乘 1023 pwm_start(); //上报当前状态服务器 post_data_to_clouds(); } //按键一长按3秒的回调逻辑处理 static void key_13_long_press(void) { INFO("long press.. into smartConfig.."); //标志位设置为5,下次开机读取标志位,若是为5就进去配网模式 u8 saveNumber[4]; saveNumber[0] = 5; spi_flash_erase_sector(520); spi_flash_write(520 * 4096, (uint32 *) &saveNumber, 4); //重启 system_restart(); } //按键二短按的回调逻辑处理 static void key_sw2_short_press(void) { INFO("short press.."); //每次减去百分比10的亮度,当小于0强制为0; apkPwm -= 10; if (apkPwm < 0) { apkPwm = 0; } pwm_set_duty(1023 * apkPwm / 100, 0); //由于微信发来的是 0到100,咱们取百分比以后再相乘 1023 pwm_start(); //上报当前状态服务器 post_data_to_clouds(); } //按键二长按3秒的回调逻辑处理 static void key_sw2_long_press(void) { INFO("long press.. into smartConfig.."); //标志位设置为5,下次开机读取标志位,若是为5就进去配网模式 u8 saveNumber[4]; saveNumber[0] = 5; spi_flash_erase_sector(520); spi_flash_write(520 * 4096, (uint32 *) &saveNumber, 4); //重启 system_restart(); }
TCP
的,因此端口号是1883
,以此同时,订阅的主题发布的主题和微信小程序刚刚是相反的!//MQTT服务器设置 //MQTT ip地址或域名 #define MQTT_BROKER_HOST "7qfp6898.mqtt.iot.gz.baidubce.com" //端口号 #define MQTT_BROKER_PORT 1883 //userName #define MQTT_USER_NAME "7qfp6898/esp8266" //userPassword #define MQTT_USER_PASSWORD "5bXUJ3FfTJdKs8h9"
//收到消息 INFO("topic:\"%s\"", rMsg.topic); INFO("payload(%3d)---> %s", rMsg.payloadlen, rMsg.payload); /** * 解析 "{"change":"power","value":true}" */ cJSON *pRoot = cJSON_Parse(rMsg.payload); if (NULL == pRoot) { INFO("arrive Error get Json : [%s] ", cJSON_GetErrorPtr()); cJSON_Delete(pRoot); break; } INFO("-----------arrive ok get Json-------------"); cJSON *pJSON_change = cJSON_GetObjectItem(pRoot, "change"); if (!pJSON_change) { cJSON_Delete(pRoot); INFO("- error parse Json : pJSON_change --"); break;; } cJSON *pJSON_value = cJSON_GetObjectItem(pRoot, "value"); //判断是否开关按钮 if (strcmp(pJSON_change->valuestring, "power") == 0) { INFO("--arrive ok get Json --> power-------------"); if (strcmp(pJSON_value->valuestring, "true") == 0) { pwm_set_duty(512, 0); //开灯 pwm_start(); apkPwm = 50; } else { apkPwm = 0; pwm_set_duty(0, 0); //关灯 pwm_start(); } post_data_to_clouds();//同步上报服务器 //判断是否调节亮度 } else if (strcmp(pJSON_change->valuestring, "pwm") == 0) { INFO("---arrive ok get Json --> pwm-------------"); u8 value = pJSON_value->valueint; apkPwm = value; pwm_set_duty(1023 * value / 100, 0); //由于微信发来的是 0到100,咱们取百分比以后再相乘 1023 pwm_start(); post_data_to_clouds();//同步上报服务器 } else if (strcmp(pJSON_change->valuestring, "query") == 0) { post_data_to_clouds(); //同步上报服务器 } cJSON_Delete(pRoot);
//按键初始化 TaskKeyInit(); //station模式开启 wifi_set_opmode(STATION_MODE); u8 tempSaveData[4]; spi_flash_read(520 * 4096, (uint32 *) &tempSaveData, 4); //若是标志位读取失败 if (tempSaveData[0] == -1) { tempSaveData[0] = 1; spi_flash_erase_sector(520); spi_flash_write(520 * 4096, (uint32 *) &tempSaveData, 4); } printf("spi_flash_read tempSaveData--> %d \n" ,tempSaveData[0]); if (tempSaveData[0] == 5 ) { //进去配网模式 xTaskCreate(TaskSmartConfig, "TaskSmartConfig", 512, NULL, 2, NULL); //记得恢复标志为0 u8 saveNumber[4]; saveNumber[0]=0; spi_flash_erase_sector(520); spi_flash_write(520 * 4096, (uint32 *) &saveNumber, 4); } else { //不然则自动链接上次过的路由器 wifi_set_event_handler_cb(wifi_event_handler_cb); //设置自动链接 wifi_station_connect(); } uint32 pwm_duty_init[1] = { 0 }; uint32 io_info[][3] = { { PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12, 12 } }; //GPIO12做为pwm输出脚位 pwm_init(1000, pwm_duty_init, 1, io_info); //初始化 PWM pwm_set_duty(1023, 0); //最大亮度 pwm_start();
原理图很是简单:小程序
①:gpio0
和gpio2
都要上拉,虽然内部已经上拉。微信小程序
②:按键的另外一端都是接地,咱们代码是降低沿触发中断!七牛云存储
效果图:
Bug
个人代码,因此,我小费出售,下面是联系方式!