这里就不对MQTT协议本身作过多的讲解了,网上也有很多更加详细的对MQTT博文的讲解,当然更直接的就是参看协议文件。
这里直接贴一篇写的比较完整的博客和菜鸟教材对协议的讲解,可以参考学习。
菜鸟教程,MQTT协议入门
MQTT协议详解

之前买了一块超纬电子出的一款开发板,进行ESP8266、以太网、WiFi和MQTT协议连接云平台相关实验的学习。原本MQTT协议的源代码是一个比较大的的工程,适用于多个平台,所以在使用的时候实际上也只用了一部分功能,它对其进行了单独封装,所以可读性和适用性更强,所以我主要参看了这部分代码,实现了我的目的。实现我手上的开发板和电信云平台的交互功能!

MQTT工程包括这么多文件。

主函数

前面的联网,使用以太网或者WIFI都可以,具体过程这里就省略了。直接从连接后的代码开始,当初学习的代码,注释很详细。

switch(getSn_SR(SOCK_TCPS))                              //获取TCP链接端口的状态
{case SOCK_INIT:        if(Connect_flag==0){ ret1 = connect(SOCK_TCPS,ServerIP,ServerPort);   //链接服务器printf("%d.%d.%d.%d\r\n",ServerIP[0],ServerIP[1],ServerIP[2],ServerIP[3]);      //串口输出信息printf("ServerPort = %d\r\n",ServerPort);       //串口输出信息printf("连接服务器返回码:%d\r\n",ret1);       //串口输出信息}break;case SOCK_ESTABLISHED:                                           // Socket处于连接建立状态if(getSn_IR(SOCK_TCPS) & Sn_IR_CON)                    {printf("连接已建立\r\n"); MQTT_Buff_Init();                        //初始化接收,发送,命令数据的 缓冲区 以及各状态参数setSn_IR(SOCK_TCPS, Sn_IR_CON);                    // Sn_IR的CON位置1,通知W5500连接已建立Connect_flag = 1;                                     //链接标志=1}ret2 = recv(SOCK_TCPS,gDATABUF,DATA_BUF_SIZE);      //接收数据if(ret2 > 0){                                     //如果ret大于0,表示有数据来         memcpy(&MQTT_RxDataInPtr[2],gDATABUF,ret2);      //拷贝数据到接收缓冲区MQTT_RxDataInPtr[0] = ret2/256;                  //记录数据长度MQTT_RxDataInPtr[1] = ret2%256;                  //记录数据长度 MQTT_RxDataInPtr+=RBUFF_UNIT;                   //指针下移     if(MQTT_RxDataInPtr==MQTT_RxDataEndPtr)         //如果指针到缓冲区尾部了MQTT_RxDataInPtr = MQTT_RxDataBuf[0];           //指针归位到缓冲区开头}if(Connect_flag==1){     /*-------------------------------------------------------------*//*                     处理发送缓冲区数据                      *//*-------------------------------------------------------------*/if(MQTT_TxDataOutPtr != MQTT_TxDataInPtr){                //if成立的话,说明发送缓冲区有数据了//3种情况可进入if//第1种:0x10 连接报文//第2种:0x82 订阅报文,且ConnectPack_flag置位,表示连接报文成功//第3种:SubcribePack_flag置位,说明连接和订阅均成功,其他报文可发if((MQTT_TxDataOutPtr[2]==0x10)||((MQTT_TxDataOutPtr[2]==0x82)&&(ConnectPack_flag==1))||(SubcribePack_flag==1)){      printf("发送数据:0x%x\r\n",MQTT_TxDataOutPtr[2]);  //串口提示信息MQTT_TxData(MQTT_TxDataOutPtr);                       //发送数据MQTT_TxDataOutPtr += TBUFF_UNIT;                       //指针下移if(MQTT_TxDataOutPtr==MQTT_TxDataEndPtr)              //如果指针到缓冲区尾部了MQTT_TxDataOutPtr = MQTT_TxDataBuf[0];            //指针归位到缓冲区开头}               }/*-------------------------------------------------------------*//*                     处理接收缓冲区数据                      *//*-------------------------------------------------------------*/if(MQTT_RxDataOutPtr != MQTT_RxDataInPtr){  //if成立的话,说明接收缓冲区有数据了                                                     printf("接收到数据: \r\n");/*-----------------------------------------------------*//*                    处理CONNACK报文                  *//*-----------------------------------------------------*/             //if判断,如果一共接收了4个字节,第一个字节是0x20,表示收到的是CONNACK报文//接着我们要判断第4个字节,看看CONNECT报文是否成功if(MQTT_RxDataOutPtr[2]==0x20 && ConnectPack_flag == 0){                         switch(MQTT_RxDataOutPtr[5]){                   case 0x00 : printf("CONNECT报文成功\r\n");                            //串口输出信息    ConnectPack_flag = 1;                                        //CONNECT报文成功,订阅报文可发//             MQTT_Subscribe(S_TOPIC_NAME,1);                   //发送缓冲区添加订阅topic,等级1
//                                                          printf("new  MQTT_TxDataOutPtr[6]: %x\r\n", MQTT_TxDataOutPtr[6]);break;                                                       //跳出分支case 0x00                                              case 0x01 : printf("连接已拒绝,不支持的协议版本,准备重启\r\n");     //串口输出信息NVIC_SystemReset();                                             //重启break;                                                       //跳出分支case 0x01   case 0x02 : printf("连接已拒绝,不合格的客户端标识符,准备重启\r\n"); //串口输出信息NVIC_SystemReset();                                             //重启break;                                                       //跳出分支case 0x02 case 0x03 : printf("连接已拒绝,服务端不可用,准备重启\r\n");         //串口输出信息NVIC_SystemReset();                                           //重启break;                                                       //跳出分支case 0x03case 0x04 : printf("连接已拒绝,无效的用户名或密码,准备重启\r\n");   //串口输出信息NVIC_SystemReset();                                           //重启break;                                                       //跳出分支case 0x04case 0x05 : printf("连接已拒绝,未授权,准备重启\r\n");               //串口输出信息NVIC_SystemReset();                                             //重启break;                                                       //跳出分支case 0x05       default   : printf("连接已拒绝,未知状态,准备重启\r\n");             //串口输出信息 NVIC_SystemReset();                                          //重启break;                                                       //跳出分支case default                                }               }           //if判断,如果一共接收了5个字节,第一个字节是0x90,表示收到的是SUBACK报文//接着我们要判断订阅回复,看看是不是成功else if(MQTT_RxDataOutPtr[2]==0x90){ switch(MQTT_RxDataOutPtr[6]){                   case 0x00 :case 0x01 : printf("订阅成功+++\r\n");            //串口输出信息SubcribePack_flag = 1;                //SubcribePack_flag置1,表示订阅报文成功,其他报文可发送//TIM3_ENABLE_30S();                    //启动30s的PING定时器break;                                //跳出分支                                             default: printf("订阅失败,准备重启\r\n");  //串口输出信息 NVIC_SystemReset();                     //重启break;                                //跳出分支                              }                   }//if判断,如果一共接收了2个字节,第一个字节是0xD0,表示收到的是PINGRESP报文else if(MQTT_RxDataOutPtr[2]==0xD0){ printf("PING报文回复\r\n");    }   //if判断,如果第一个字节是0x30,表示收到的是服务器发来的推送数据//我们要提取控制命令else if(MQTT_RxDataOutPtr[2]==0x30){ printf("服务器等级0推送\r\n");               //串口输出信息 MQTT_DealPushdata_Qs0(MQTT_RxDataOutPtr);       //处理等级0推送数据}                                           MQTT_RxDataOutPtr += RBUFF_UNIT;                     //指针下移if(MQTT_RxDataOutPtr==MQTT_RxDataEndPtr)            //如果指针到缓冲区尾部了MQTT_RxDataOutPtr = MQTT_RxDataBuf[0];          //指针归位到缓冲区开头                        }//处理接收缓冲区数据的else if分支结尾                   /*-------------------------------------------------------------*//*                     处理命令缓冲区数据                      *//*-------------------------------------------------------------*/if(MQTT_CMDOutPtr != MQTT_CMDInPtr){                             //if成立的话,说明命令缓冲区有数据了 if(Upload_data_succeed == 0){Upload_data();printf("Upload_data succeed+++ \r\n");}printf("命令:%s\r\n",&MQTT_CMDOutPtr[2]); MQTT_CMDOutPtr += CBUFF_UNIT;                               //指针下移if(MQTT_CMDOutPtr==MQTT_CMDEndPtr)                          //如果指针到缓冲区尾部了MQTT_CMDOutPtr = MQTT_CMDBuf[0];                          //指针归位到缓冲区开头               }if(Upload_data_succeed == 0 && SubcribePack_flag == 1){Upload_data();Upload_data_succeed = 1;}}       break;
case SOCK_CLOSE_WAIT:                                                 // Socket处于等待关闭状态disconnect(SOCK_TCPS);   break;
case SOCK_CLOSED:                                                       // Socket处于关闭状态socket(SOCK_TCPS,Sn_MR_TCP,5000,0x00);       // 打开Socket0,打开一个本地端口                mqtt1_flag=0;NTP_Timeouttimer_Start=1;break;
}

下面是对应的功能函数,基本上是从原来的工程文件中提取出来的。

云平台的相关参数初始化

/*----------------------------------------------------------*/
/*函数名:云初始化参数,得到客户端ID,用户名和密码          */
/*参  数:无                                                */
/*返回值:无                                                */
/*----------------------------------------------------------*/
void IoT_Parameter_Init(void)
{   memset(ClientID,128,0);                           //客户端ID的缓冲区全部清零sprintf(ClientID,"%s",PROJECTID);                //构建客户端ID,并存入缓冲区ClientID_len = strlen(ClientID);                  //计算客户端ID的长度memset(Username,128,0);                           //用户名的缓冲区全部清零sprintf(Username,"%s",DEVICENAME);                    //构建用户名,并存入缓冲区Username_len = strlen(Username);                  //计算用户名的长度memset(Passward,128,0);                           //密码的缓冲区全部清零sprintf(Passward,"%s",DEVICESECRE);               //构建密码   Passward_len = strlen(Passward);                  //计算密码的长度memset(ServerName,128,0); sprintf((char*)ServerName,"chongqing-mqtt.ctwing.cn");  //构建服务器域名ServerPort = 1883;                                                   //服务器端口号1883printf("服 务 器:%s\r\n",ServerName); printf("客户端ID:%s\r\n",ClientID); printf("用 户 名:%s\r\n",Username);printf("密    码:%s\r\n",Passward);
}

连接服务器报文

/*----------------------------------------------------------*/
/*函数名:连接服务器报文                                    */
/*参  数:无                                                */
/*返回值:无                                                */
/*----------------------------------------------------------*/
void MQTT_ConectPack(void)
{   int temp,Remaining_len;Fixed_len = 1;                                                        //连接报文中,固定报头长度暂时先=1Variable_len = 10;                                                    //连接报文中,可变报头长度=10Payload_len = 2 + ClientID_len + 2 + Username_len + 2 + Passward_len; //连接报文中,负载长度      Remaining_len = Variable_len + Payload_len;                           //剩余长度=可变报头长度+负载长度temp_buff[0]=0x10;                       //固定报头第1个字节 :固定0x01      do{                                      //循环处理固定报头中的剩余长度字节,字节量根据剩余字节的真实长度变化temp = Remaining_len%128;            //剩余长度取余128Remaining_len = Remaining_len/128;   //剩余长度取整128if(Remaining_len>0)                 temp |= 0x80;                    //按协议要求位7置位          temp_buff[Fixed_len] = temp;         //剩余长度字节记录一个数据Fixed_len++;                        //固定报头总长度+1    }while(Remaining_len>0);                 //如果Remaining_len>0的话,再次进入循环temp_buff[Fixed_len+0]=0x00;    //可变报头第1个字节 :固定0x00             temp_buff[Fixed_len+1]=0x04;    //可变报头第2个字节 :固定0x04temp_buff[Fixed_len+2]=0x4D;  //可变报头第3个字节 :固定0x4Dtemp_buff[Fixed_len+3]=0x51;    //可变报头第4个字节 :固定0x51temp_buff[Fixed_len+4]=0x54;    //可变报头第5个字节 :固定0x54temp_buff[Fixed_len+5]=0x54;    //可变报头第6个字节 :固定0x54temp_buff[Fixed_len+6]=0x04;    //可变报头第7个字节 :固定0x04temp_buff[Fixed_len+7]=0xC2;    //可变报头第8个字节 :使能用户名和密码校验,不使用遗嘱,不保留会话temp_buff[Fixed_len+8]=0x00;  //可变报头第9个字节 :保活时间高字节 0x00temp_buff[Fixed_len+9]=0x64;  //可变报头第10个字节:保活时间高字节 0x64   100s/*     CLIENT_ID      */temp_buff[Fixed_len+10] = ClientID_len/256;                                            //客户端ID长度高字节temp_buff[Fixed_len+11] = ClientID_len%256;                                           //客户端ID长度低字节memcpy(&temp_buff[Fixed_len+12],ClientID,ClientID_len);                            //复制过来客户端ID字串   /*     用户名        */temp_buff[Fixed_len+12+ClientID_len] = Username_len/256;                             //用户名长度高字节temp_buff[Fixed_len+13+ClientID_len] = Username_len%256;                           //用户名长度低字节memcpy(&temp_buff[Fixed_len+14+ClientID_len],Username,Username_len);                //复制过来用户名字串 /*      密码        */temp_buff[Fixed_len+14+ClientID_len+Username_len] = Passward_len/256;               //密码长度高字节temp_buff[Fixed_len+15+ClientID_len+Username_len] = Passward_len%256;              //密码长度低字节memcpy(&temp_buff[Fixed_len+16+ClientID_len+Username_len],Passward,Passward_len);   //复制过来密码字串TxDataBuf_Deal(temp_buff, Fixed_len + Variable_len + Payload_len);                  //加入发送数据缓冲区
}

SUBSCRIBE订阅topic报文

/*----------------------------------------------------------*/
/*函数名:SUBSCRIBE订阅topic报文                            */
/*参  数:QoS:订阅等级                                     */
/*参  数:topic_name:订阅topic报文名称                     */
/*返回值:无                                                */
/*----------------------------------------------------------*/
void MQTT_Subscribe(char *topic_name, int QoS)
{   Fixed_len = 2;                              //SUBSCRIBE报文中,固定报头长度=2Variable_len = 2;                           //SUBSCRIBE报文中,可变报头长度=2    Payload_len = 2 + strlen(topic_name) + 1;   //计算有效负荷长度 = 2字节(topic_name长度)+ topic_name字符串的长度 + 1字节服务等级temp_buff[0]=0x82;                                    //第1个字节 :固定0x82                      temp_buff[1]=Variable_len + Payload_len;              //第2个字节 :可变报头+有效负荷的长度    temp_buff[2]=0x00;                                    //第3个字节 :报文标识符高字节,固定使用0x00temp_buff[3]=0x01;                                    //第4个字节 :报文标识符低字节,固定使用0x01temp_buff[4]=strlen(topic_name)/256;                  //第5个字节 :topic_name长度高字节temp_buff[5]=strlen(topic_name)%256;                 //第6个字节 :topic_name长度低字节memcpy(&temp_buff[6],topic_name,strlen(topic_name));  //第7个字节开始 :复制过来topic_name字串       temp_buff[6+strlen(topic_name)]=QoS;                  //最后1个字节:订阅等级TxDataBuf_Deal(temp_buff, Fixed_len + Variable_len + Payload_len);  //加入发送数据缓冲区printf("存储订阅成功=================\r\n");
}

等级0 发布消息报文

/*----------------------------------------------------------*/
/*函数名:等级0 发布消息报文                                */
/*参  数:topic_name:topic名称                             */
/*参  数:data:数据                                        */
/*参  数:data_len:数据长度                                */
/*返回值:无                                                */
/*----------------------------------------------------------*/
void MQTT_PublishQs0(char *topic, char *data, int data_len)
{   int temp,Remaining_len;Fixed_len = 1;                              //固定报头长度暂时先等于:1字节Variable_len = 2 + strlen(topic);           //可变报头长度:2字节(topic长度)+ topic字符串的长度Payload_len = data_len;                     //有效负荷长度:就是data_lenRemaining_len = Variable_len + Payload_len; //剩余长度=可变报头长度+负载长度temp_buff[0]=0x30;                       //固定报头第1个字节 :固定0x30       do{                                      //循环处理固定报头中的剩余长度字节,字节量根据剩余字节的真实长度变化temp = Remaining_len%128;            //剩余长度取余128Remaining_len = Remaining_len/128;   //剩余长度取整128if(Remaining_len>0)                 temp |= 0x80;                    //按协议要求位7置位          temp_buff[Fixed_len] = temp;         //剩余长度字节记录一个数据Fixed_len++;                        //固定报头总长度+1    }while(Remaining_len>0);                 //如果Remaining_len>0的话,再次进入循环temp_buff[Fixed_len+0]=strlen(topic)/256;                      //可变报头第1个字节     :topic长度高字节temp_buff[Fixed_len+1]=strlen(topic)%256;                      //可变报头第2个字节     :topic长度低字节memcpy(&temp_buff[Fixed_len+2],topic,strlen(topic));           //可变报头第3个字节开始 :拷贝topic字符串   memcpy(&temp_buff[Fixed_len+2+strlen(topic)],data,data_len);   //有效负荷:拷贝data数据TxDataBuf_Deal(temp_buff, Fixed_len + Variable_len + Payload_len);  //加入发送数据缓冲区
}

处理服务器发来的等级0的推送

/*----------------------------------------------------------*/
/*函数名:处理服务器发来的等级0的推送                       */
/*参  数:redata:接收的数据                                */
/*返回值:无                                                */
/*----------------------------------------------------------*/
void MQTT_DealPushdata_Qs0(unsigned char *redata)
{int  re_len;                              //定义一个变量,存放接收的数据总长度int  pack_num;                         //定义一个变量,当多个推送一起过来时,保存推送的个数int  temp,temp_len;                    //定义一个变量,暂存数据int  totle_len;                        //定义一个变量,存放已经统计的推送的总数据量int  topic_len;                       //定义一个变量,存放推送中主题的长度int  cmd_len;                          //定义一个变量,存放推送中包含的命令数据的长度int  cmd_loca;                         //定义一个变量,存放推送中包含的命令的起始位置int  i;                                //定义一个变量,用于for循环int  local,multiplier;unsigned char tempbuff[RBUFF_UNIT];       //临时缓冲区unsigned char *data;                   //redata过来的时候,第一个字节是数据总量,data用于指向redata的第2个字节,真正的数据开始的地方re_len = redata[0]*256+redata[1];                               //获取接收的数据总长度        data = &redata[2];                                              //data指向redata的第2个字节,真正的数据开始的 pack_num = temp_len = totle_len = temp = 0;                       //各个变量清零local = 1;multiplier = 1;do{pack_num++;                                                 //开始循环统计推送的个数,每次循环推送的个数+1   do{temp = data[totle_len + local];   temp_len += (temp & 127) * multiplier;multiplier *= 128;local++;}while ((temp & 128) != 0);totle_len += (temp_len + local);                             //累计统计的总的推送的数据长度re_len -= (temp_len + local) ;                              //接收的数据总长度 减去 本次统计的推送的总长度      local = 1;multiplier = 1;temp_len = 0;}while(re_len!=0);                                           //如果接收的数据总长度等于0了,说明统计完毕了printf("本次接收了%d个推送数据\r\n",pack_num);//串口输出信息temp_len = totle_len = 0;                                        //各个变量清零local = 1;multiplier = 1;for(i=0;i<pack_num;i++){                                        //已经统计到了接收的推送个数,开始for循环,取出每个推送的数据        do{temp = data[totle_len + local];   temp_len += (temp & 127) * multiplier;multiplier *= 128;local++;}while ((temp & 128) != 0);                topic_len = data[local+totle_len]*256+data[local+1+totle_len] + 2;    //计算本次推送数据中主题占用的数据量cmd_len = temp_len-topic_len;                               //计算本次推送数据中命令数据占用的数据量cmd_loca = totle_len + local +  topic_len;                  //计算本次推送数据中命令数据开始的位置memcpy(tempbuff,&data[cmd_loca],cmd_len);                   //命令数据拷贝出来                       CMDBuf_Deal(tempbuff, cmd_len);                             //加入命令到缓冲区totle_len += (temp_len+local);                              //累计已经统计的推送的数据长度local = 1;multiplier = 1;temp_len = 0;}
}

PING报文,心跳包

/*----------------------------------------------------------*/
/*函数名:PING报文,心跳包                                  */
/*参  数:无                                                */
/*返回值:无                                                */
/*----------------------------------------------------------*/
void MQTT_PingREQ(void)
{temp_buff[0]=0xC0;              //第1个字节 :固定0xC0                      temp_buff[1]=0x00;              //第2个字节 :固定0x00 TxDataBuf_Deal(temp_buff, 2);   //加入数据到缓冲区

处理发送缓冲区

/*----------------------------------------------------------*/
/*函数名:处理发送缓冲区                                    */
/*参  数:data:数据                                        */
/*参  数:size:数据长度                                    */
/*返回值:无                                                */
/*----------------------------------------------------------*/
void TxDataBuf_Deal(unsigned char *data, int size)
{int i;memcpy(&MQTT_TxDataInPtr[2],data,size);      //拷贝数据到发送缓冲区    MQTT_TxDataInPtr[0] = size/256;              //记录数据长度MQTT_TxDataInPtr[1] = size%256;              //记录数据长度printf("MQTT_TxDataInPtr=");for(i = 0; i<size; i++){printf("%x ", MQTT_TxDataInPtr[i]);}MQTT_TxDataInPtr+=TBUFF_UNIT;                 //指针下移if(MQTT_TxDataInPtr==MQTT_TxDataEndPtr)      //如果指针到缓冲区尾部了MQTT_TxDataInPtr = MQTT_TxDataBuf[0];    //指针归位到缓冲区开头}

处理命令缓冲区

/*----------------------------------------------------------*/
/*函数名:处理命令缓冲区                                    */
/*参  数:data:数据                                        */
/*参  数:size:数据长度                                    */
/*返回值:无                                                */
/*----------------------------------------------------------*/
void CMDBuf_Deal(unsigned char *data, int size)
{memcpy(&MQTT_CMDInPtr[2],data,size);      //拷贝数据到命令缓冲区MQTT_CMDInPtr[0] = size/256;              //记录数据长度MQTT_CMDInPtr[1] = size%256;              //记录数据长度MQTT_CMDInPtr[size+2] = '\0';             //加入字符串结束符MQTT_CMDInPtr+=CBUFF_UNIT;                 //指针下移if(MQTT_CMDInPtr==MQTT_CMDEndPtr)         //如果指针到缓冲区尾部了MQTT_CMDInPtr = MQTT_CMDBuf[0];       //指针归位到缓冲区开头
}

总结

具体的功能代码可以根据自己的需要进行改写,如果需要相关学习源代码和学习视频可以私信我,对应的MQTT协议可在我的资源里面寻找!

模块学习4:(1)通过MQTT协议和电信云平台的通信(内附MQTT协议V3.1.1的原版和中文参考资料)相关推荐

  1. micropython mqtt_MicroPython使用MQTT协议接入OneNET云平台

    MicroPython使用MQTT协议接入OneNET云平台 [复制链接] 本帖最后由 hanyeguxingwo 于 2016-11-22 11:33 编辑 之前使用Arduino+ESP8266使 ...

  2. 物联网云平台用到的那些基本协议

    MQTT 最大的优点是简单易用,针对物联网开发,详细可搜索MQTT相关资料. 基本使用场景: 终端设备和云平台之间可采用此通讯协议,需要具备联网能力,一般为网关或带网络模块的终端设备. 例如:监控设备 ...

  3. 关于微赞,微擎,微动力模块安装时出现 版权保护,未在云平台注册 的解决办法

    关于微赞,微擎,微动力模块安装时出现 版权保护,未在云平台注册 等如下之类提示: 您的程序需要在微赞云服务平台注册你的站点资料, 来接入云平台服务后才能使用相应功能. 此模块已设置版权保护,您只能通过 ...

  4. 微擎跳过云平台_微擎最新版本2.09“此模块已设置版权保护,您只能通过云平台来安装”版权保护问题的解决方法...

    在微擎的本地搭建及测试时,有时会遇到模块安装时出现,版权保护,未在云平台注册等等一类的问题.现在我将解决方法贴出,与大家分享. 不管是新版本,还是老版本,问题解决根本方法是修改微擎内部的cloud.m ...

  5. MQTT网关连接阿里云平台案例教程

    MQTT协议网关网口连接西门子SMART200PLC 前言:MQTT是一个基于客户端-服务器的消息发布/订阅传输协议.MQTT协议的特点是轻量.简单.开放和易于实现的,同时,西门子PLC广泛应于工业控 ...

  6. 骐俊CAT1模组 - MQTT接入腾讯云平台篇

    本次实验使用骐俊ML110S系列模组及开发底板,通过MQTT协议采用密钥的方式接入腾讯云平台,实现消息的发布及订阅,可分为接入注册及动态注册两种方式.   设备注册(接入注册) A.进入腾讯云平台注册 ...

  7. Esp32读取温湿度数据通过mqtt上传阿里云平台

    目录 前言 一.esp32刷MicroPython固件库 二.创建阿里云产品 1.注册阿里云账号并登录控制台 2.找到物联网平台中的公共实例进入 3.创建产品及设备 4.编辑物模型并发布 5.最后找到 ...

  8. 交通部809协议服务器代码,部标平台检测(三).交通部部标809协议测试和运行测试 | 车载GPS和视频平台产品经理...

    本身交通部在制定jt/t 809协议文档时,过度设计,采用双链路的复杂的通信架构,文档中文字抽象,而且歧义是很多的,开发者很容易疑惑,产生各种不确定和疑惑,又没有人答疑,全靠摸索.在加上交通部部表80 ...

  9. 视频联网云平台EasyCVR集成海康EHome协议:Ehome协议预览流程

    之前我们讲了EasyCVR视频平台集成了海康EHome协议系统配置,EasyCVR集成海康EHome私有协议内容繁杂琐碎,测试内容众多,所以我们特地开辟一个系列,如果大家有兴趣,可以翻阅以往的博客了解 ...

最新文章

  1. 【CSON原创】HTML5游戏框架cnGameJS开发实录(外部输入模块篇)
  2. 打马赛克就安全了吗?AI消除马赛克,GitHub开源项目上线三天收获近7000星
  3. MyBatis SQL语句操作Mysql
  4. 她说要介绍10000个开源项目?来!一起监督他!
  5. 改变Error tip的背景色.
  6. 翘课老黄历——设计文档
  7. 云炬随笔20211016(4)
  8. sgu 126 Boxes
  9. 为什么文本文件以换行符结尾?
  10. PowerBuilder 2018
  11. 京东分类页面部分的实现
  12. Maven使用本地jar包(三种方式)
  13. 服务器系统试用,“雪豹”安装篇(3)
  14. 华东师范计算机模拟考试题答案,《计算机入门》模拟卷C答案-华东师范大学
  15. python操作pdf——pdfplumber/PyPDF2
  16. 人生一定要知道的十大“博弈”!
  17. BlockingQueue的用法
  18. Java ScriptEngineManager
  19. 分析Adobe Illustrator CC(AI)中的橡皮擦和直线工具
  20. 中国人民银行招聘计算机水平,2019中国人民银行招聘计算机模拟试题及答案

热门文章

  1. MIT6.828学习之homework9:Barriers
  2. 微软2011年4月最有价值专家(MVP)名单 51CTO十七位用户当选
  3. mysql的cpu使用率突然增高_mysql cpu使用率过高解决方法
  4. 精进3步:破除我执,重塑我想,实现我行,普通人逆袭必看
  5. Workspaces can only be enabled in private projects.
  6. 仿网易云音乐部分UI实现
  7. 面向2018年的设计趋势
  8. 蓝桥杯嵌入式开发经验分享(1.嵌入式学习准备)
  9. 物理竞赛应该怎么准备?3个步骤教你敲响名牌大学门!
  10. 数组循环向左移动k位的算法