STM32发送MQTT请求到Onenet
前文已经阐述了从MQTTX的客户端发送 信息到OneNet。
下面就用STM32代替MQTTX的客户端 发送信息到OneNet
硬件接线
main的代码如下
int main(void)
{HAL_Init(); /* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */led_init(); /* 初始化LED灯 */uart1_init(115200);esp8266_init(115200);printf("hello world!\r\n");printf("MQTT初始化...\r\n");mqtt_init();printf("MQTT连接...\r\n");mqtt_connect(MQTT_ClientID, MQTT_UserName, MQTT_PassWord);uint8_t data_send[512] = {0};uint8_t dht11_data[4] = {0};while(1){ memset(dht11_data, 0, 4);dht11_read(dht11_data);sprintf((char *)data_send, "{\"id\":\"1386772172\",\"version\":\"1.0\",\"params\":{\"CurrentTemperature\":{\"value\":%d.%d},\"CurrentHumidity\":{\"value\":%d.%d}}}",dht11_data[2], dht11_data[3], dht11_data[0], dht11_data[1]);mqtt_publish_data(POST_TOPIC, (char *)data_send, 0);delay_ms(3000);printf("\r\n~~~~~~~~~~~~~~~~~·发送心跳包~~~~~~~~~~~~~~~~~\r\n");mqtt_send_heart();printf("\r\n~~~~~~~~~~~~~~~~~发送心跳包结束~~~~~~~~~~~~~~~~~\r\n");}
}
组成MQTT 的connect的报文格式;注意其中的长度字段,是后续的字节之和。采用长度字段,主要是因为解决TCP半包及粘包的需要。
Connect的包,头及body,都是采用同一个序列化的方式。都是字符串中每个字符转为ascii码。
与java中序列化的方式不完全一样。
java中,如果采用类的序列化,它不是完全转换为ascii码。
除非自定义类的序列化方式,自己来写序列化,可以把类中的每个属性,转为ascii码的方式
/*
º¯Êý¹¦ÄÜ: µÇ¼·þÎñÆ÷
º¯Êý·µ»ØÖµ: 0±íʾ³É¹¦ 1±íʾʧ°Ü
*/
uint8_t mqtt_connect(char *ClientID,char *Username,char *Password)
{
// uint8_t i;uint8_t j;int ClientIDLen = strlen(ClientID);int UsernameLen = strlen(Username);int PasswordLen = strlen(Password);int DataLen;mqtt_txlen=0;//¿É±ä±¨Í·+Payload ÿ¸ö×ֶΰüº¬Á½¸ö×ֽڵij¤¶È±êʶDataLen = 10 + (ClientIDLen+2) + (UsernameLen+2) + (PasswordLen+2);//¹Ì¶¨±¨Í·//¿ØÖƱ¨ÎÄÀàÐÍmqtt_txbuf[mqtt_txlen++] = 0x10; //MQTT Message Type CONNECT//Ê£Ó೤¶È(²»°üÀ¨¹Ì¶¨Í·²¿)do{uint8_t encodedByte = DataLen % 128;DataLen = DataLen / 128;// if there are more data to encode, set the top bit of this byteif ( DataLen > 0 )encodedByte = encodedByte | 128;mqtt_txbuf[mqtt_txlen++] = encodedByte;}while ( DataLen > 0 );//¿É±ä±¨Í·//ÐÒéÃûmqtt_txbuf[mqtt_txlen++] = 0; // Protocol Name Length MSB mqtt_txbuf[mqtt_txlen++] = 4; // Protocol Name Length LSB mqtt_txbuf[mqtt_txlen++] = 'M'; // ASCII Code for M mqtt_txbuf[mqtt_txlen++] = 'Q'; // ASCII Code for Q mqtt_txbuf[mqtt_txlen++] = 'T'; // ASCII Code for T mqtt_txbuf[mqtt_txlen++] = 'T'; // ASCII Code for T //ÐÒé¼¶±ðmqtt_txbuf[mqtt_txlen++] = 4; // MQTT Protocol version = 4 //Á¬½Ó±êÖ¾mqtt_txbuf[mqtt_txlen++] = 0xc2; // conn flags mqtt_txbuf[mqtt_txlen++] = 0; // Keep-alive Time Length MSB mqtt_txbuf[mqtt_txlen++] = 100; // Keep-alive Time Length LSB 100SÐÄÌø°ü mqtt_txbuf[mqtt_txlen++] = BYTE1(ClientIDLen);// Client ID length MSB mqtt_txbuf[mqtt_txlen++] = BYTE0(ClientIDLen);// Client ID length LSB memcpy(&mqtt_txbuf[mqtt_txlen],ClientID,ClientIDLen);mqtt_txlen += ClientIDLen;if(UsernameLen > 0){ mqtt_txbuf[mqtt_txlen++] = BYTE1(UsernameLen); //username length MSB mqtt_txbuf[mqtt_txlen++] = BYTE0(UsernameLen); //username length LSB memcpy(&mqtt_txbuf[mqtt_txlen],Username,UsernameLen);mqtt_txlen += UsernameLen;}if(PasswordLen > 0){ mqtt_txbuf[mqtt_txlen++] = BYTE1(PasswordLen); //password length MSB mqtt_txbuf[mqtt_txlen++] = BYTE0(PasswordLen); //password length LSB memcpy(&mqtt_txbuf[mqtt_txlen],Password,PasswordLen);mqtt_txlen += PasswordLen; } // for(i=0;i<10;i++)
// {memset(mqtt_rxbuf,0,mqtt_rxlen);mqtt_send_data(mqtt_txbuf,mqtt_txlen);for(j=0;j<10;j++)printf("%c",mqtt_txbuf[j]);for(j=0;j<10;j++){delay_ms(50);if (esp8266_wait_receive() == ESP8266_EOK)esp8266_copy_rxdata((char *)mqtt_rxbuf);//CONNECTif(mqtt_rxbuf[0]==parket_connetAck[0] && mqtt_rxbuf[1]==parket_connetAck[1] && mqtt_rxbuf[2]==parket_connetAck[2]) //Á¬½Ó³É¹¦{return 0;//Á¬½Ó³É¹¦}}
// }char name[]="stevenwrite";printf("before connect return:%s\n",name);return 1;
}
打开串口助手
在网页上,看到实时的温湿度
这样的场景,可以更加深入的理解,物联网上,温度传感器通过STM32,接ESP8266的wifi的功能上传到服务器的全过程。