stm32 mqtt

記錄兩種是stm32 mqtt實現方法

1.使用keil自帶庫MQTTPacket實現

安裝install

安裝完成後點擊運行時環境按鈕

選中MQTTpacket

代碼實現添加和使用

首先包含頭文件  #include "MQTTPacket.h"
static MQTTTransport mytransport;  //定義MQTT全局傳輸結構體
static uint8_t  mqtt_parse_buf[1024]   = {0};  臨時解析數據數組大小自己看數據包大小

實現兩個函數:
//4g發送數據  阻塞發送
void transport_sendPacketBuffer(unsigned char* buf, int buflen)
{
	HAL_UART_Transmit(&huart_4g, buf, buflen, 5000);
	HAL_UART_Receive_IT(&huart_4g, &temp_value_4g, 1);
}
//4g獲取數據  沒有數據返回0
int transport_getdatanb(void *sck, unsigned char* buf, int count)  
{
	if(mqtt_4f_buf_index >= count && HAL_GetTick() - mqtt_4g_tick >= 3) {
		memcpy(buf, mqtt_4g_buf, count);
		memcpy(mqtt_4g_buf, mqtt_4g_buf + count, mqtt_4f_buf_index - count);  //複製到前面
		mqtt_4f_buf_index = mqtt_4f_buf_index - count;
		return count;
	}
	return 0;
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == HUART_4G){
		mqtt_4g_buf[mqtt_4f_buf_index++] = temp_value_4g;
		mqtt_4f_buf_index = mqtt_4f_buf_index >= sizeof(mqtt_4g_buf) ? 0 : mqtt_4f_buf_index;  //超出緩衝區
		HAL_UART_Receive_IT(&huart_4g, &temp_value_4g, 1);
		mqtt_4g_tick = HAL_GetTick();
	}
}

發送採用阻塞,接收採用中斷,發送完成後必須重新開始中斷接收不然會出現不能接收的現象。

數據通信採用4G串口透傳,其他方式以此類推都可以使用

先初始化4G模塊或者其他模塊或者socket
初始化連接到服務器
//MQTT init
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
	int buflen = sizeof(mqtt_parse_buf);
	mytransport.getfn = transport_getdatanb;
	mytransport.state = 0;
	//
	data.keepAliveInterval = 180;
	data.cleansession = 1;
	data.clientID.cstring = CCID;    //clientId唯一id
	data.username.cstring = "admin";
	data.password.cstring = "123456";
	//連接
	int len = MQTTSerialize_connect(mqtt_parse_buf, buflen, &data);
	transport_sendPacketBuffer(mqtt_parse_buf, len);

	//等待確認
	while(1) {
		int frc = MQTTPacket_readnb(mqtt_parse_buf, buflen, &mytransport);
		if (frc == CONNACK){
			unsigned char sessionPresent, connack_rc;
			if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, mqtt_parse_buf, buflen) != 1 || connack_rc != 0){
				printf("Unable to connect, return code %d\n", connack_rc);
				Soft_Reset();
			}
			break;
		}
		else if (frc == -1) {
			printf("mqtt login error\n");
		}
	}
	printf("MQTT OK");

初始換完成後執行MQTT循環

void MQTT_4G_POLL(void)
{
	static uint8_t no_reply_count = 0;
	static uint32_t mqtt_poll_tick = 0;
	static int len = 0, buflen = sizeof(mqtt_parse_buf);

	int msgtype = MQTTPacket_readnb(mqtt_parse_buf, buflen, &mytransport);
	switch(msgtype) {
		case -1:
			mqtt_4f_buf_index = 0;
			mytransport.state = 0;
			break;
		case PUBLISH:
		{
			unsigned char dup;
			int qos, len = 0;
			unsigned char retained;
			unsigned short msgid;
			int payloadlen_in = 0;
			unsigned char* payload_in;
			MQTTString receivedTopic;
			MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic, &payload_in, &payloadlen_in, mqtt_parse_buf, sizeof(mqtt_parse_buf));
			
			mqtt_recive_publish(receivedTopic.lenstring.data, receivedTopic.lenstring.len, (char *)payload_in, payloadlen_in);
			if(qos == 1) {
				len = MQTTSerialize_ack(mqtt_parse_buf, sizeof(mqtt_parse_buf), PUBACK, dup, msgid);
				transport_sendPacketBuffer(mqtt_parse_buf, len);
			}
			if(qos == 2) {
				len = MQTTSerialize_ack(mqtt_parse_buf, sizeof(mqtt_parse_buf), PUBREC, dup, msgid);
				transport_sendPacketBuffer(mqtt_parse_buf, len);
			}
			break;
		}
		case SUBACK:
		{
			unsigned short packet_id = 0;
			int count = 0, req_qos = 0;
			if(MQTTDeserialize_suback(&packet_id, 1, &count, &req_qos, mqtt_parse_buf, sizeof(mqtt_parse_buf)) == 1 && packet_id > 0) {
				//printf("subsucess:%d\n", subscribe_devices[254]);
			}
			break;
		}
		case PINGRESP:
			no_reply_count = 0;  //收到心跳回復
			break;
		default:
			break;
	}
	//50s 發送心跳
	if(HAL_GetTick() - mqtt_poll_tick > 50000) {

		if(no_reply_count > 3) {
			Soft_Reset();
		}			
		len = MQTTSerialize_pingreq(mqtt_parse_buf, buflen);
		transport_sendPacketBuffer(mqtt_parse_buf, len);
		no_reply_count++;
		mqtt_poll_tick = HAL_GetTick();  //更新檢測時間
	}
}


發佈和訂閱函數實現

//發佈消息
static void publish(char * topic, unsigned char * payload) 
{
	MQTTString topicString = MQTTString_initializer;
	topicString.cstring = topic;
	int len = MQTTSerialize_publish(mqtt_parse_buf, sizeof(mqtt_parse_buf), 0, 0, 0, 0, topicString, payload, strlen((char *)payload));
  transport_sendPacketBuffer(mqtt_parse_buf, len);
}
//訂閱
static void subscribe(char * subtopic_buf)
{
	static uint16_t picket_id = 1;
	
	MQTTString topicString = MQTTString_initializer;
	int req_qos = 1, len = 0;
	int buflen = sizeof(mqtt_parse_buf);
	//訂閱
	topicString.cstring = subtopic_buf;
	len = MQTTSerialize_subscribe(mqtt_parse_buf, buflen, 0, ++picket_id, 1, &topicString, &req_qos);
	transport_sendPacketBuffer(mqtt_parse_buf, len);
}






 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章