这里写目录标题

  • 项目介绍
  • mqtt服务器相关知识![在这里插入图片描述](https://img-blog.csdnimg.cn/9ad065fb8fac48b1b975fc3a48b99763.png)
  • 下位机代码
  • 项目需要的一些开发工具

项目介绍

本项目芯片使用STM32F103ZET6,微信小程序开发使用微信开发者工具。
stm32作为下位机,功能是每过一段时间上传温湿度以及光照度给mqtt服务器,然后微信小程序从mqtt服务器订阅对应的主题来接收下位机发过来的数据并进行处理,并在微信小程序中设置LED开关,以及蜂鸣器开关。

mqtt服务器相关知识

如图,汽车上有联网芯片,可以充当客户端,汽车采集到的数据可以发送到mqtt服务器,然后再搭建其他mqtt客户端(电脑,手机等设备),这些设备就可以从mqtt服务器获取汽车的数据。
这里的单片机和微信小程序都是客服端,他们连接上同一个服务器,然后通过订阅/发布对应的主题,来进行信息的交互。

主题:
用来区别接收的数据。比如汽车采集的速度,要传给mqtt服务器,就要给数据打上一个标签,即主题,然后其他mqtt客户端可以根据主题来获取数据。

发布:
客服端发布数据给服务端,并标上主题。

订阅:
客户端订阅主题,然后获取主题对应的数据。

每一个客户端都可以订阅/发布数据,即数据可以互相发送。

下位机代码

main.c

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "beep.h"
#include "adc.h"
#include "lsens.h"
#include "esp8266.h"
#include "MqttKit.h"
#include "onenet.h"uint8_t Usart_String[50];
uint8_t * dataPtr;
uint8_t tem_light_string[50];const char *subtopics[] = {"/iot/2462/sub/wsy"};//订阅主题
const char pubtopics[] = {"/iot/2462/pub/wsy"};//发布主题void dht11_exit()//判断dht11是否存在
{while(DHT11_Init())    //DHT11初始化  {LCD_ShowString(30,130,200,16,16,"DHT11 Error");delay_ms(200);LCD_Fill(30,130,239,130+16,WHITE);delay_ms(200);}
}
void Hardware_Init(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //中断控制器分组设置Usart1_Init(115200);                         //串口1,打印信息用Usart2_Init(115200);                          //串口2,驱动ESP8266用BEEP_Init();                                 //蜂鸣器初始化UsartPrintf(USART_DEBUG, " Hardware init OK\r\n");}int main(void){     u8 timeCount=0;               u8 temperature; //存放温度的值  u8 humidity;  //存放湿度的值u8 adcx;//存放光照值LED_Init();               //LED端口初始化delay_init();             //延时函数初始化    Hardware_Init();LCD_Init();    //LCD初始化LCD_Clear(WHITE); Lsens_Init();            //初始化光敏传感器LCD_ShowString(30,130,200,16,16,"DHT11 OK");POINT_COLOR=BLUE;//设置字体为蓝色 LCD_ShowString(30,150,200,16,16,"Temp:  C");   LCD_ShowString(30,170,200,16,16,"Humi:  %");LCD_ShowString(30,190,200,16,16,"LSENS_VAL:");  dht11_exit();ESP8266_Init();while(OneNet_DevLink())        //接入OneNETdelay_ms(500);//  BEEP=1;            //鸣叫提示接入成功
//      delay_ms(250);
//  BEEP=0;OneNet_Subscribe(subtopics, 1);while(1){        if(timeCount%40==0)           //每100ms读取一次{                                     DHT11_Read_Data(&temperature,&humidity);  //读取温湿度值        adcx=Lsens_Get_Val();          //读取光照强度LCD_ShowNum(30+40,150,temperature,2,16);   //显示温度             LCD_ShowNum(30+40,170,humidity,2,16);       //显示湿度      LCD_ShowNum(30+10*8,190,adcx,3,16);//显示光照度 }               if(++timeCount >= 200)            //发送间隔5s  5000ms/25ms=200{UsartPrintf(USART_DEBUG, "OneNet_Publish\r\n");//          OneNet_Publish((char *)pubtopics, "MQTT Publish Test");sprintf((char *)tem_light_string,"{\"tem\":%02d,\"hum\":%02d,\"light\":%d}",temperature,humidity,adcx);OneNet_Publish((char *)pubtopics, tem_light_string);timeCount = 0;ESP8266_Clear();}dataPtr = ESP8266_GetIPD(3);if(dataPtr != NULL)OneNet_RevPro(dataPtr);delay_ms(10);}
}

这里移植了Onenet平台的stm32芯片esp8266连接服务器的代码。
有需要的小伙伴可进入连接获取添加链接描述

esp8266.c

/*************************************************************************************************************************************************************************************** 文件名:     esp8266.c** 作者:      张继瑞**   日期:      2017-05-08**    版本:      V1.0**  说明:      ESP8266的简单驱动**  修改记录:    ************************************************************************************************************************************************************************************
**///单片机头文件
#include "stm32f10x.h"//网络设备驱动
#include "esp8266.h"//硬件驱动
#include "delay.h"
#include "usart.h"//C库
#include <string.h>
#include <stdio.h>#define ESP8266_WIFI_INFO       "AT+CWJAP=\"xxx\",\"xxxxxx\"\r\n"#define ESP8266_ONENET_INFO        "AT+CIPSTART=\"TCP\",\"xxxxxxx\",xxxxx\r\n"unsigned char esp8266_buf[128];
unsigned short esp8266_cnt = 0, esp8266_cntPre = 0;//==========================================================
//  函数名称:    ESP8266_Clear
//
//  函数功能:    清空缓存
//
//  入口参数:    无
//
//  返回参数:    无
//
//  说明:
//==========================================================
void ESP8266_Clear(void)
{memset(esp8266_buf, 0, sizeof(esp8266_buf));esp8266_cnt = 0;}//==========================================================
//  函数名称:    ESP8266_WaitRecive
//
//  函数功能:    等待接收完成
//
//  入口参数:    无
//
//  返回参数:    REV_OK-接收完成     REV_WAIT-接收超时未完成
//
//  说明:      循环调用检测是否接收完成
//==========================================================
_Bool ESP8266_WaitRecive(void)
{if(esp8266_cnt == 0)                             //如果接收计数为0 则说明没有处于接收数据中,所以直接跳出,结束函数return REV_WAIT;if(esp8266_cnt == esp8266_cntPre)                //如果上一次的值和这次相同,则说明接收完毕{esp8266_cnt = 0;                         //清0接收计数return REV_OK;                              //返回接收完成标志}esp8266_cntPre = esp8266_cnt;                   //置为相同return REV_WAIT;                              //返回接收未完成标志}//==========================================================
//  函数名称:    ESP8266_SendCmd
//
//  函数功能:    发送命令
//
//  入口参数:    cmd:命令
//              res:需要检查的返回指令
//
//  返回参数:    0-成功    1-失败
//
//  说明:
//==========================================================
_Bool ESP8266_SendCmd(char *cmd, char *res)
{unsigned char timeOut = 200;Usart_SendString(USART2, (unsigned char *)cmd, strlen((const char *)cmd));while(timeOut--){if(ESP8266_WaitRecive() == REV_OK)                           //如果收到数据{if(strstr((const char *)esp8266_buf, res) != NULL)        //如果检索到关键词{ESP8266_Clear();                                 //清空缓存return 0;}}delay_ms(10);}return 1;}//==========================================================
//  函数名称:    ESP8266_SendData
//
//  函数功能:    发送数据
//
//  入口参数:    data:数据
//              len:长度
//
//  返回参数:    无
//
//  说明:
//==========================================================
void ESP8266_SendData(unsigned char *data, unsigned short len)
{char cmdBuf[32];ESP8266_Clear();                               //清空接收缓存sprintf(cmdBuf, "AT+CIPSEND=%d\r\n", len);      //发送命令if(!ESP8266_SendCmd(cmdBuf, ">"))                //收到‘>’时可以发送数据{Usart_SendString(USART2, data, len);      //发送设备连接请求数据}}//==========================================================
//  函数名称:    ESP8266_GetIPD
//
//  函数功能:    获取平台返回的数据
//
//  入口参数:    等待的时间(乘以10ms)
//
//  返回参数:    平台返回的原始数据
//
//  说明:      不同网络设备返回的格式不同,需要去调试
//              如ESP8266的返回格式为  "+IPD,x:yyy" x代表数据长度,yyy是数据内容
//==========================================================
unsigned char *ESP8266_GetIPD(unsigned short timeOut)
{char *ptrIPD = NULL;do{if(ESP8266_WaitRecive() == REV_OK)                               //如果接收完成{ptrIPD = strstr((char *)esp8266_buf, "IPD,");               //搜索“IPD”头if(ptrIPD == NULL)                                          //如果没找到,可能是IPD头的延迟,还是需要等待一会,但不会超过设定的时间{//UsartPrintf(USART_DEBUG, "\"IPD\" not found\r\n");}else{ptrIPD = strchr(ptrIPD, ':');                          //找到':'if(ptrIPD != NULL){ptrIPD++;return (unsigned char *)(ptrIPD);}elsereturn NULL;}}delay_ms(5);                                                    //延时等待} while(timeOut--);return NULL;                                                       //超时还未找到,返回空指针}//==========================================================
//  函数名称:    ESP8266_Init
//
//  函数功能:    初始化ESP8266
//
//  入口参数:    无
//
//  返回参数:    无
//
//  说明:
//==========================================================
void ESP8266_Init(void)
{GPIO_InitTypeDef GPIO_Initure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//ESP8266复位引脚GPIO_Initure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Initure.GPIO_Pin = GPIO_Pin_14;                   //GPIOC14-复位GPIO_Initure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_Initure);GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_RESET);delay_ms(250);GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_SET);delay_ms(500);ESP8266_Clear();UsartPrintf(USART_DEBUG, "0. AT\r\n");while(ESP8266_SendCmd("AT\r\n", "OK"))delay_ms(500);UsartPrintf(USART_DEBUG, "1. RST\r\n");ESP8266_SendCmd("AT+RST\r\n", "");delay_ms(500);ESP8266_SendCmd("AT+CIPCLOSE\r\n", "");delay_ms(500);UsartPrintf(USART_DEBUG, "2. CWMODE\r\n");while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK"))delay_ms(500);UsartPrintf(USART_DEBUG, "3. AT+CWDHCP\r\n");while(ESP8266_SendCmd("AT+CWDHCP=1,1\r\n", "OK"))delay_ms(500);UsartPrintf(USART_DEBUG, "4. CWJAP\r\n");while(ESP8266_SendCmd(ESP8266_WIFI_INFO, "GOT IP"))delay_ms(500);UsartPrintf(USART_DEBUG, "5. CIPSTART\r\n");while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT"))delay_ms(500);UsartPrintf(USART_DEBUG, "6. ESP8266 Init OK\r\n");}//==========================================================
//  函数名称:    USART2_IRQHandler
//
//  函数功能:    串口2收发中断
//
//  入口参数:    无
//
//  返回参数:    无
//
//  说明:
//==========================================================
void USART2_IRQHandler(void)
{if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断{if(esp8266_cnt >= sizeof(esp8266_buf))   esp8266_cnt = 0; //防止串口被刷爆esp8266_buf[esp8266_cnt++] = USART2->DR;USART_ClearFlag(USART2, USART_FLAG_RXNE);}}

#define ESP8266_WIFI_INFO “AT+CWJAP=“xxx”,“xxxxxx”\r\n” //填入你要连接的wifi名字和密码

#define ESP8266_ONENET_INFO “AT+CIPSTART=“TCP”,“xxxxxxx”,xxxxx\r\n”//填入你要连接的服务器域名和端口号

onenet.c

/*************************************************************************************************************************************************************************************** 文件名:     onenet.c**  作者:      张继瑞**   日期:      2017-05-08**    版本:      V1.1**  说明:      与onenet平台的数据交互接口层** 修改记录:    V1.0:协议封装、返回判断都在同一个文件,并且不同协议接口不同。*                V1.1:提供统一接口供应用层使用,根据不同协议文件来封装协议相关的内容。************************************************************************************************************************************************************************************
**///单片机头文件
#include "stm32f10x.h"//网络设备
#include "esp8266.h"//协议文件
#include "onenet.h"
#include "mqttkit.h"//硬件驱动
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "beep.h"
//C库
#include <string.h>
#include <stdio.h>#include "cJSON.h"#define PROID       "0a15a6464f0fee359eadb8992ebb72d7"//设备号ID#define AUTH_INFO    "123456"//密码#define DEVID     "11"//随便写extern unsigned char esp8266_buf[128];//==========================================================
//  函数名称:    OneNet_DevLink
//
//  函数功能:    与onenet创建连接
//
//  入口参数:    无
//
//  返回参数:    1-成功    0-失败
//
//  说明:      与onenet平台建立连接
//==========================================================
_Bool OneNet_DevLink(void)
{MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};                   //协议包unsigned char *dataPtr;_Bool status = 1;UsartPrintf(USART_DEBUG, "OneNet_DevLink\r\n""PROID: %s,   AUIF: %s,   DEVID:%s\r\n", PROID, AUTH_INFO, DEVID);if(MQTT_PacketConnect(PROID, AUTH_INFO, DEVID, 256, 0, MQTT_QOS_LEVEL0, NULL, NULL, 0, &mqttPacket) == 0){ESP8266_SendData(mqttPacket._data, mqttPacket._len);           //上传平台dataPtr = ESP8266_GetIPD(250);                                   //等待平台响应if(dataPtr != NULL){if(MQTT_UnPacketRecv(dataPtr) == MQTT_PKT_CONNACK){switch(MQTT_UnPacketConnectAck(dataPtr)){case 0:UsartPrintf(USART_DEBUG, "Tips:  连接成功\r\n");status = 0;break;case 1:UsartPrintf(USART_DEBUG, "WARN:   连接失败:协议错误\r\n");break;case 2:UsartPrintf(USART_DEBUG, "WARN:   连接失败:非法的clientid\r\n");break;case 3:UsartPrintf(USART_DEBUG, "WARN:    连接失败:服务器失败\r\n");break;case 4:UsartPrintf(USART_DEBUG, "WARN:  连接失败:用户名或密码错误\r\n");break;case 5:UsartPrintf(USART_DEBUG, "WARN:   连接失败:非法链接(比如token非法)\r\n");break;default:UsartPrintf(USART_DEBUG, "ERR:    连接失败:未知错误\r\n");break;}}}MQTT_DeleteBuffer(&mqttPacket);                                //删包}elseUsartPrintf(USART_DEBUG, "WARN:   MQTT_PacketConnect Failed\r\n");return status;}//==========================================================
//  函数名称:    OneNet_Subscribe
//
//  函数功能:    订阅
//
//  入口参数:    topics:订阅的topic
//              topic_cnt:topic个数
//
//  返回参数:    SEND_TYPE_OK-成功 SEND_TYPE_SUBSCRIBE-需要重发
//
//  说明:
//==========================================================
void OneNet_Subscribe(const char *topics[], unsigned char topic_cnt)
{unsigned char i = 0;MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};                          //协议包for(; i < topic_cnt; i++)UsartPrintf(USART_DEBUG, "Subscribe Topic: %s\r\n", topics[i]);if(MQTT_PacketSubscribe(MQTT_SUBSCRIBE_ID, MQTT_QOS_LEVEL2, topics, topic_cnt, &mqttPacket) == 0){ESP8266_SendData(mqttPacket._data, mqttPacket._len);                    //向平台发送订阅请求MQTT_DeleteBuffer(&mqttPacket);                                          //删包}}//==========================================================
//  函数名称:    OneNet_Publish
//
//  函数功能:    发布消息
//
//  入口参数:    topic:发布的主题
//              msg:消息内容
//
//  返回参数:    SEND_TYPE_OK-成功 SEND_TYPE_PUBLISH-需要重送
//
//  说明:
//==========================================================
void OneNet_Publish(const char *topic, const char *msg)
{MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};                           //协议包UsartPrintf(USART_DEBUG, "Publish Topic: %s, Msg: %s\r\n", topic, msg);if(MQTT_PacketPublish(MQTT_PUBLISH_ID, topic, msg, strlen(msg), MQTT_QOS_LEVEL2, 0, 1, &mqttPacket) == 0){ESP8266_SendData(mqttPacket._data, mqttPacket._len);                  //向平台发送订阅请求MQTT_DeleteBuffer(&mqttPacket);                                          //删包}}//==========================================================
//  函数名称:    OneNet_RevPro
//
//  函数功能:    平台返回数据检测
//
//  入口参数:    dataPtr:平台返回的数据
//
//  返回参数:    无
//
//  说明:
//==========================================================
void OneNet_RevPro(unsigned char *cmd)
{MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};                               //协议包char *req_payload = NULL;char *cmdid_topic = NULL;unsigned short topic_len = 0;unsigned short req_len = 0;unsigned char type = 0;unsigned char qos = 0;static unsigned short pkt_id = 0;short result = 0;char *dataPtr = NULL;char numBuf[10];int num = 0;cJSON * json,*json_value;type = MQTT_UnPacketRecv(cmd);switch(type){case MQTT_PKT_CMD:                                                            //命令下发result = MQTT_UnPacketCmd(cmd, &cmdid_topic, &req_payload, &req_len);    //解出topic和消息体if(result == 0){UsartPrintf(USART_DEBUG, "cmdid: %s, req: %s, req_len: %d\r\n", cmdid_topic, req_payload, req_len);MQTT_DeleteBuffer(&mqttPacket);                                 //删包}break;case MQTT_PKT_PUBLISH:                                                       //接收的Publish消息result = MQTT_UnPacketPublish(cmd, &cmdid_topic, &topic_len, &req_payload, &req_len, &qos, &pkt_id);if(result == 0){UsartPrintf(USART_DEBUG, "topic: %s, topic_len: %d, payload: %s, payload_len: %d\r\n",cmdid_topic, topic_len, req_payload, req_len);//对数据包进行JSON格式解析json = cJSON_Parse(req_payload); if(!json)UsartPrintf(USART_DEBUG,"Error before: [%s]\n",cJSON_GetErrorPtr());else{//                  //解析开关值
//                  json_value = cJSON_GetObjectItem(json,"LED_SW");
//                  if(json_value -> valueint)//json_value大于等于0,且为整型
//                  {//                      LED0= 0;//打开LED0
//                  }
//                  else
//                  {//                      LED0= 1;//关闭LED0
//                  }//解析开关值json_value=cJSON_GetObjectItem(json,"target");UsartPrintf(USART_DEBUG,"json_value= %d\r\n",json_value->string);//先把键值输出来,就是看看叫什么名字UsartPrintf(USART_DEBUG,"json_value= %d\r\n",json_value->valuestring);//接着看看数值是多少//从value-int中获取结果if(strstr(json_value->valuestring,"led")!=NULL)//标准字符串判断,这个就是判断是不是控制LED的,如果是,就是控制LED,如果不是就是控制蜂鸣器{json_value=cJSON_GetObjectItem(json,"value");if(json_value->valueint)LED1=0;elseLED1=1;}else{json_value=cJSON_GetObjectItem(json,"value");if(json_value->valueint)BEEP=1;//蜂鸣器鸣叫elseBEEP=0;//蜂鸣器停止鸣叫}}cJSON_Delete(json);switch(qos){case 1:                                                          //收到publish的qos为1,设备需要回复Ackif(MQTT_PacketPublishAck(pkt_id, &mqttPacket) == 0){UsartPrintf(USART_DEBUG, "Tips:    Send PublishAck\r\n");ESP8266_SendData(mqttPacket._data, mqttPacket._len);MQTT_DeleteBuffer(&mqttPacket);}break;case 2:                                                            //收到publish的qos为2,设备先回复Rec//平台回复Rel,设备再回复Compif(MQTT_PacketPublishRec(pkt_id, &mqttPacket) == 0){UsartPrintf(USART_DEBUG, "Tips:   Send PublishRec\r\n");ESP8266_SendData(mqttPacket._data, mqttPacket._len);MQTT_DeleteBuffer(&mqttPacket);}break;default:break;}}break;case MQTT_PKT_PUBACK:                                                        //发送Publish消息,平台回复的Ackif(MQTT_UnPacketPublishAck(cmd) == 0)UsartPrintf(USART_DEBUG, "Tips:    MQTT Publish Send OK\r\n");break;case MQTT_PKT_PUBREC:                                                     //发送Publish消息,平台回复的Rec,设备需回复Rel消息if(MQTT_UnPacketPublishRec(cmd) == 0){UsartPrintf(USART_DEBUG, "Tips: Rev PublishRec\r\n");if(MQTT_PacketPublishRel(MQTT_PUBLISH_ID, &mqttPacket) == 0){UsartPrintf(USART_DEBUG, "Tips:   Send PublishRel\r\n");ESP8266_SendData(mqttPacket._data, mqttPacket._len);MQTT_DeleteBuffer(&mqttPacket);}}break;case MQTT_PKT_PUBREL:                                                     //收到Publish消息,设备回复Rec后,平台回复的Rel,设备需再回复Compif(MQTT_UnPacketPublishRel(cmd, pkt_id) == 0){UsartPrintf(USART_DEBUG, "Tips: Rev PublishRel\r\n");if(MQTT_PacketPublishComp(MQTT_PUBLISH_ID, &mqttPacket) == 0){UsartPrintf(USART_DEBUG, "Tips:  Send PublishComp\r\n");ESP8266_SendData(mqttPacket._data, mqttPacket._len);MQTT_DeleteBuffer(&mqttPacket);}}break;case MQTT_PKT_PUBCOMP:                                                       //发送Publish消息,平台返回Rec,设备回复Rel,平台再返回的Compif(MQTT_UnPacketPublishComp(cmd) == 0){UsartPrintf(USART_DEBUG, "Tips:  Rev PublishComp\r\n");}break;case MQTT_PKT_SUBACK:                                                     //发送Subscribe消息的Ackif(MQTT_UnPacketSubscribe(cmd) == 0)UsartPrintf(USART_DEBUG, "Tips:   MQTT Subscribe OK\r\n");elseUsartPrintf(USART_DEBUG, "Tips:   MQTT Subscribe Err\r\n");break;case MQTT_PKT_UNSUBACK:                                                     //发送UnSubscribe消息的Ackif(MQTT_UnPacketUnSubscribe(cmd) == 0)UsartPrintf(USART_DEBUG, "Tips:   MQTT UnSubscribe OK\r\n");elseUsartPrintf(USART_DEBUG, "Tips: MQTT UnSubscribe Err\r\n");break;default:result = -1;break;}ESP8266_Clear();                                  //清空缓存if(result == -1)return;dataPtr = strchr(req_payload, '}');                   //搜索'}'if(dataPtr != NULL && result != -1)                  //如果找到了{dataPtr++;while(*dataPtr >= '0' && *dataPtr <= '9')       //判断是否是下发的命令控制数据{numBuf[num++] = *dataPtr++;}num = atoi((const char *)numBuf);                //转为数值形式}if(type == MQTT_PKT_CMD || type == MQTT_PKT_PUBLISH){MQTT_FreeBuffer(cmdid_topic);MQTT_FreeBuffer(req_payload);}}

#define PROID “0a15a6464f0fee359eadb8992ebb72d7”//一些私人的服务器需要设备号ID

#define AUTH_INFO “123456”//密码

#define DEVID “11”//随便写,这里没有要求

项目需要的一些开发工具

1.微信开发者工具添加链接描述
2.mqtt.js插件 密码6666
3.onenet移植代码用来给下位机连接服务器使用

stm32智能家居+微信小程序接收控制相关推荐

  1. STM32+ESP8266+MQTT微信小程序SoftAP一键配网接入腾讯物联网平台

    STM32+ESP8266+MQTT微信小程序SoftAP一键配网接入腾讯物联网平台   Wi-Fi 配网,指由外部向 Wi-Fi 设备提供 SSID 和密码(PSW),让 Wi-Fi 设备可以连接指 ...

  2. 【微信小程序控制硬件 第12篇-项目篇】微信小程序蓝牙控制硬件应如何开始动手?为您全面解析微信小程序蓝牙API的使用;(附带demo)

    [微信小程序控制硬件第1篇 ] 全网首发,借助 emq 消息服务器带你如何搭建微信小程序的mqtt服务器,轻松控制智能硬件! [微信小程序控制硬件第2篇 ] 开始微信小程序之旅,导入小程序Mqtt客户 ...

  3. 泰凌微ble mesh蓝牙模组天猫精灵学习之旅 ② 如何实现 微信小程序蓝牙控制 Ble Mesh模组 安信可TB02,全部开源!

    本<泰凌微ble mesh蓝牙模组天猫精灵学习之旅>系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1.小 ...

  4. chatgpt智能问答微信小程序+后端源码+视频搭建教程

    chatgpt智能问答微信小程序+后端源码+视频搭建教程,这是一套微信小程序,后端是thinkphp框架为接口的,后端是前后端分离用elmentUI的源码框架. 小狐狸GPT付费体验系统是一款基于Th ...

  5. 许嵩音乐智能问答系统微信小程序之音乐播放器

    许嵩音乐智能问答系统微信小程序之音乐播放器 - 项目简介 项目简介. 音乐播放器搭建. 获取数据及文本分类. 智能客服聊天界面. 连接前端微信小程序输入和后端python,并返回值 连接知识图谱 你还 ...

  6. 许嵩音乐智能问答系统微信小程序之获取数据及文本分类

    许嵩音乐智能问答系统微信小程序之获取数据及文本分类 项目简介. 音乐播放器搭建. 获取数据及文本分类. 智能客服聊天界面. 连接前端微信小程序输入和后端python,并返回值 连接知识图谱 数据获取 ...

  7. 许嵩音乐智能问答系统微信小程序之客服聊天室

    许嵩音乐智能问答系统微信小程序之客服聊天室 项目简介. 音乐播放器搭建. 获取数据及文本分类. 智能客服聊天界面. 连接前端微信小程序输入和后端python,并返回值 连接知识图谱 你还在为因为性格腼 ...

  8. 微信小程序控制开关 控制io口 控制灯

    准备材料 8266 1个 按键 2个 led 1 个以上 扫描微信小程序 下载固件1.0.1 链接:https://pan.baidu.com/s/1em71pN_oXIT3o4wX_YUAag 提取 ...

  9. php socket主动推送消息,PHP使用WebSocket主动推送【微信小程序接收】

    WebSocket.jpeg Websocket是一种服务端和客户端可以持久连接的通信协议,我们可以利用WebSocket的特性实现服务器主动向客户端推送消息的功能. 这里我们用TP5.1框架结合Wo ...

最新文章

  1. 【二维树状数组】See you~
  2. Redis的常用命令——list的常用命令
  3. eclipse maven jetty启动修改默认端口
  4. 单链表基本操作在主函数中的实现
  5. python数据分析方法和命令_《利用Python进行数据分析》 —— (1)
  6. fmdb和mysql的区别_FMDB
  7. Swift-类、结构体、枚举
  8. keycloak中文使用文档_基于DOCKER安装配置keycloak
  9. ssis 包配置组织程序_如何停止失控的SSIS程序包
  10. ASMSupport教程4.7 生成关系运算符
  11. zlog日志库的简单封装,以及给debug级别添加颜色显示
  12. .NET之对接口和抽象类(二)
  13. 苹果手机屏幕助手_苹果手机屏幕坏点测试
  14. 图片复印如何去除黑底_手机拍的文字图片,打印出来都是灰底黑字,怎样才能变成白底黑字?...
  15. 【开源】百度中文依存句法分析工具DDParser重磅开源,快来体验一下吧
  16. 尺规作图将任意角度三等分
  17. CTR广告点击率预估
  18. Nginx+Tomcat集群:搭建Jpress(三)
  19. vue正式环境和测试环境切换
  20. 软考__第17章 战略管理

热门文章

  1. HistCite 导入类型 unknown 解决办法
  2. stew() setfill()
  3. 1.5-24:正常血压
  4. pywinauto java_pywinauto简单介绍
  5. 最新款!百度网盘迁移阿里云盘工具,亲测可用!
  6. RTKLIB软件源码学习(Kalman滤波最小二乘)
  7. 意义学 | 吾日四省吾身:合乎礼(情感/关系)义(智力/智慧)廉(身体/生活)耻(精神/边界)...
  8. 2022国赛C:古代玻璃制品的成分分析与鉴别
  9. 直线生成以及pcl直线拟合
  10. 太极创客小夜灯项目完成