ESP8266 mqtt OS2.0調試源碼

ESP8266 mqtt OS2.0調試源碼

mqtt內部原理,請自行查閱相關資料。至於爲什麼不想說這些東西,請查看下圖1。
圖片2

我的代碼實在官網Demo下,發現一些問題,經過修改完善的。下面直接看代碼。

這個代碼就是一個任務,包括初始化以及發佈消息。我是使用了一個隊裏,有消息來了,就把消息發送出去。其中MQTT_BROKER是服務器IP地址。

typedef struct esp_mqtt_msg_type {
	long unsigned int len;
	char allData[1460];
} xMessage;

xMessage pMsg_temp;
static void mqtt_client_thread(void* pvParameters)
{
	vTaskSuspend(MQTTSubscribe_Monitor_handle);
	printf("mqtt client thread starts\n");
//	    MQTTClient mqtt_client;
	    Network network;
	    unsigned char sendbuf[2048], readbuf[2048] = {0};
	    int rc = 0, count = 0;
	    MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;

	    pvParameters = 0;
	    NetworkInit(&network);
	    MQTTClientInit(&mqtt_client, &network, 30000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf));


		for(;;){
		while (wifi_station_get_connect_status() != STATION_GOT_IP) {
			vTaskDelay(1000 / portTICK_RATE_MS);
		}
		char* address = MQTT_BROKER;
		connectData.MQTTVersion = 3;
		connectData.clientID.cstring = "admin";
		connectData.username.cstring = "admin";
		connectData.password.cstring = "public";
		connectData.keepAliveInterval = 40;
		connectData.cleansession = true;
		//底層的TCP開始連接
	    if ((rc = NetworkConnect(&network, address, MQTT_PORT)) != 0) {
	        printf("Return code from network connect is %d\n", rc);
	    }


	#if defined(MQTT_TASK)

	    if ((rc = MQTTStartTask(&mqtt_client)) != pdPASS) {
	        printf("Return code from start tasks is %d\n", rc);
	    } else {
	        printf("Use MQTTStartTask\n");
	    }

	#endif
	    //連接MQTT服務器
	    if ((rc = MQTTConnect(&mqtt_client, &connectData)) != 0) {
	        printf("Return code from MQTT connect is %d\n", rc);
	    } else {
	        printf("MQTT Connected\n");
	    }

	    vTaskResume(MQTTSubscribe_Monitor_handle);
	    xQueueReset(xQueue_mqtt_pb_handle);
	    while (1) {
	    	pMsg_Data_Typedef pMsg;
	    	xQueueReceive(xQueue_mqtt_pb_handle, &pMsg, portMAX_DELAY);
	    	pMsg_temp.len=pMsg.len;
			memcpy(pMsg_temp.allData,pMsg.addr,pMsg.len);
			
    		MQTTMessage message;
			message.qos = QOS2;
			message.retained = 0;
			message.payload = pMsg_temp.allData;
			message.payloadlen =(long unsigned int)pMsg_temp.len;
			rc = MQTTPublish(&mqtt_client, "ESP8266/sample/pub", &message);
			printf("%d ",pMsg_temp.len);
			printf("%d\r\n",rc);
				if(rc==SUCCESS){
				uint8_t CMD_Buf[]={0x43,0x4F,0x44,0x45,0x2E,0x01,0x00};
				server_recv_handler(CMD_Buf,7);
				}
				if (rc != 0) {
					break;
				}
	    	}
	    network.disconnect(&network);
}
	    printf("mqtt_client_thread going to be deleted\n");
	    vTaskDelete(NULL);
	    return;
}

這個是訂閱註冊回調函數

static void MessageArrived(MessageData* data)
{

    printf("Message arrived payload: %s\r\n", data->message->payload);
    printf("Message arrived payloadlen: %d\r\n", data->message->payloadlen);
   xRingbufferSend(spi_slave_tx_ring_buf, (void *) data->message->payload,data->message->payloadlen, portMAX_DELAY);

}

大家發現沒有,我上面還確實接收訂閱的代碼。其實就是MQTTSubscribe這個函數。在Demo裏,它是直接放在上面任務初始化裏。我後面調試發現,得每隔一段時間去調用這個函數才能接收到數據。如果只是初始化一次,回調函數是用不了的。然後我根據這個情況,重新定義了一個監視任務。

static void MQTTSubscribe_Monitor(void* pvParameters){
	int rc = 0;
	for(;;)
	{
		MQTTSubscribe(&mqtt_client, "ESP8266/sample/sub", QOS2, MessageArrived);
		vTaskDelay(1000 / portTICK_RATE_MS);
	}
}

這樣的話,每隔1S就會調用一次。經過調試就可以用啦。
我的服務器是搭建在阿里雲上的,這個可以提供一個搭建服務器的包。裏面包括了安裝步驟。需要的自行下載。
服務器搭建安裝包

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