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就会调用一次。经过调试就可以用啦。
我的服务器是搭建在阿里云上的,这个可以提供一个搭建服务器的包。里面包括了安装步骤。需要的自行下载。
服务器搭建安装包

发布了7 篇原创文章 · 获赞 8 · 访问量 2884

猜你喜欢

转载自blog.csdn.net/oDuanYanGuHong/article/details/103345936