1. 程式人生 > >MQTT For ESP8266的調試

MQTT For ESP8266的調試

網絡協議棧 aps ddr drive endif 串口 force free 開頭

MQTT For ESP8266 的調試

一、準備工作:

1、按之前的筆記搭建開發和調試環境:

  • ESP8266開發環境搭建
  • Window 下的 MQTT服務器搭建以及調試

  • MQTT Windosw下的 進一步調試

  因為NONOS的SDK涉及到網絡協議棧,太過復雜,所以這裏直接用集成度較高的FreeRTOS的SDK進行調試

二、修改SDK

1.eclipse工程的構建:

  • 拷貝ESP8266_RTOS_SDK-master\examples\mqtt_demo到ESP8266_RTOS_SDK-master\(主要為了編譯)
  • 按照 “ESP8266開發環境搭建” 中的方法修改C/C++ Build選項
  • 在mqtt_demo\Makefile這個文件的開頭添加如下export語句:
 1 #############################################################
 2 # Required variables for each makefile
 3 # Discard this section from all parent makefiles
 4 # Expected variables (with automatic defaults):
 5 #   CSRCS (all "C" files in the dir)
 6 #   SUBDIRS (all subdirs with a Makefile)
7 # GEN_LIBS - list of libs to be generated () 8 # GEN_IMAGES - list of object file images to be generated () 9 # GEN_BINS - list of binaries to be generated () 10 # COMPONENTS_xxx - a list of libs/objs in the form 11 # subdir/lib to be extracted and rolled up into 12 # a generated lib/image xxx.a ()
13 # 14 TARGET = eagle 15 #FLAVOR = release 16 FLAVOR = debug 17 18 export SDK_PATH=/cygdrive/d/03_MyEsp8266Projects/ESP8266_RTOS_SDK-master/ 19 export BIN_PATH=/cygdrive/d/03_MyEsp8266Projects/ESP8266_RTOS_SDK-master/bin/ 20 #EXTRA_CCFLAGS += -u

其中工程結構如下:

技術分享圖片

  進行編譯,如果沒有報錯工程就構建完成了

2.修改Demo代碼:

  • 中的mqtt_demo\include下的user_config.h中的SSID和PASSWORD改成路由器的WIFI名和密碼如:
#define SSID     "wifiname"
#define PASSWORD "wifipassword"

  • 修改mqtt_demo\user\MQTTEcho.c中定義的MQTT的服務器IP地址(似乎可以用主機名,但是這裏沒有進行嘗試了)
#define MQTT_BROKER  "192.168.43.39"  /* Address of the MQTT Broker to be connected*/
  • 在任務回掉函數 -- mqtt_client_thread 修改MQTT服務器的TCP端口:
if ((rc = NetworkConnect(&network, address, 61613)) != 0)  //MQTT服務器的端口為61613
            printf("Return code from network connect is %d\n", rc);

  • 繼續在mqtt_client_thread函數中添加MQTT服務的賬號和密碼:
    connectData.MQTTVersion = 3;    // mqtt的版本或者說level, 服務器是4,這裏給3也可以用
    connectData.clientID.cstring = "ESP8266_sample"; // mqtt客戶端id
    connectData.username.cstring = "admin"; // 連接賬號
    connectData.password.cstring = "password"; // 連接密碼 

3.補充說明:

  • 可以直接用Window 下的 MQTT服務器搭建以及調試中的方法直接搭建MQTT服務器,但是要保證PC和ESP8266連接到同一局域網
  • 客戶端的MQTT的服務器地址要填PC的實際使用的網卡IP地址,PC最好使用WIFI連接路由器,然後MQTT服務器地址就是WLAN的IP地址
  • 固件的燒錄地址要和編譯後的提示一致,官方文檔上有錯誤,不能完全按照官方文檔上的做。

技術分享圖片

技術分享圖片

  • 調試截圖:

ESP8266的串口數據:

技術分享圖片

  Paho中訂閱主題”ESP8266/sample/pub“之後收到的數據:

技術分享圖片

此外還可以用paho發布主題 ”ESP8266/sample/sub“,ESP8266會收到並通過串口打印

  • 最後貼出兩個個文件的全部代碼:
技術分享圖片
  1 /*
  2  * ESPRESSIF MIT License
  3  *
  4  * Copyright (c) 2015 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
  5  *
  6  * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
  7  * it is free of charge, to any person obtaining a copy of this software and associated
  8  * documentation files (the "Software"), to deal in the Software without restriction, including
  9  * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 10  * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
 11  * to do so, subject to the following conditions:
 12  *
 13  * The above copyright notice and this permission notice shall be included in all copies or
 14  * substantial portions of the Software.
 15  *
 16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 22  *
 23  */
 24 
 25 #include "esp_common.h"
 26 #include "user_config.h"
 27 
 28 /******************************************************************************
 29  * FunctionName : user_rf_cal_sector_set
 30  * Description  : SDK just reversed 4 sectors, used for rf init data and paramters.
 31  *                We add this function to force users to set rf cal sector, since
 32  *                we don‘t know which sector is free in user‘s application.
 33  *                sector map for last several sectors : ABCCC
 34  *                A : rf cal
 35  *                B : rf init data
 36  *                C : sdk parameters
 37  * Parameters   : none
 38  * Returns      : rf cal sector
 39 *******************************************************************************/
 40 uint32 user_rf_cal_sector_set(void)
 41 {
 42     flash_size_map size_map = system_get_flash_size_map();
 43     uint32 rf_cal_sec = 0;
 44 
 45     switch (size_map) {
 46         case FLASH_SIZE_4M_MAP_256_256:
 47             rf_cal_sec = 128 - 5;
 48             break;
 49 
 50         case FLASH_SIZE_8M_MAP_512_512:
 51             rf_cal_sec = 256 - 5;
 52             break;
 53 
 54         case FLASH_SIZE_16M_MAP_512_512:
 55         case FLASH_SIZE_16M_MAP_1024_1024:
 56             rf_cal_sec = 512 - 5;
 57             break;
 58 
 59         case FLASH_SIZE_32M_MAP_512_512:
 60         case FLASH_SIZE_32M_MAP_1024_1024:
 61             rf_cal_sec = 1024 - 5;
 62             break;
 63         case FLASH_SIZE_64M_MAP_1024_1024:
 64             rf_cal_sec = 2048 - 5;
 65             break;
 66         case FLASH_SIZE_128M_MAP_1024_1024:
 67             rf_cal_sec = 4096 - 5;
 68             break;
 69         default:
 70             rf_cal_sec = 0;
 71             break;
 72     }
 73 
 74     return rf_cal_sec;
 75 }
 76 
 77 void wifi_event_handler_cb(System_Event_t *event)
 78 {
 79     if (event == NULL) {
 80         printf("wifi event == event\n ");
 81         return;
 82     }
 83     printf("wifi event handler cb default event->event_id = %d\n ",event->event_id);
 84     switch (event->event_id) {
 85         case EVENT_STAMODE_GOT_IP:
 86             printf("sta got ip ,create task and free heap size is %d\n", system_get_free_heap_size());
 87             user_conn_init();
 88             break;
 89 
 90         case EVENT_STAMODE_CONNECTED:
 91             printf("sta connected\n");
 92             break;
 93 
 94         case EVENT_STAMODE_DISCONNECTED:
 95             printf("wifi disconnected");
 96             wifi_station_connect();
 97             break;
 98 
 99         default:
100             printf("wifi event handler cb default\n ");
101             break;
102     }
103 }
104 
105 /******************************************************************************
106  * FunctionName : user_init
107  * Description  : entry of user application, init user function here
108  * Parameters   : none
109  * Returns      : none
110 *******************************************************************************/
111 void user_init(void)
112 {
113     printf("MY MQTT.V0.04.SDK version:%s %d\n", system_get_sdk_version(), system_get_free_heap_size());
114     printf("ssid:%s, password:%s \n",SSID, PASSWORD);
115     wifi_set_opmode_current(STATION_MODE);
116 
117     struct station_config config;
118     bzero(&config, sizeof(struct station_config));
119     sprintf(config.ssid, SSID);
120     sprintf(config.password, PASSWORD);
121     wifi_station_set_config(&config);
122 
123     wifi_set_event_handler_cb(wifi_event_handler_cb);
124 
125     wifi_station_connect();
126 }
user_main.c 技術分享圖片
  1 /*******************************************************************************
  2  * Copyright (c) 2014 IBM Corp.
  3  *
  4  * All rights reserved. This program and the accompanying materials
  5  * are made available under the terms of the Eclipse Public License v1.0
  6  * and Eclipse Distribution License v1.0 which accompany this distribution.
  7  *
  8  * The Eclipse Public License is available at
  9  *    http://www.eclipse.org/legal/epl-v10.html
 10  * and the Eclipse Distribution License is available at
 11  *   http://www.eclipse.org/org/documents/edl-v10.php.
 12  *
 13  * Contributors:
 14  *    Ian Craggs - initial API and implementation and/or initial documentation
 15  *******************************************************************************/
 16 
 17 #include <stddef.h>
 18 #include "freertos/FreeRTOS.h"
 19 #include "freertos/task.h"
 20 #include "mqtt/MQTTClient.h"
 21 
 22 #define MQTT_CLIENT_THREAD_NAME         "mqtt_client_thread"
 23 #define MQTT_CLIENT_THREAD_STACK_WORDS  2048
 24 #define MQTT_CLIENT_THREAD_PRIO         8
 25 LOCAL xTaskHandle mqttc_client_handle;
 26 
 27 #define MQTT_BROKER  "192.168.43.39"  /* Address of the MQTT Broker to be connected*/
 28 
 29 void messageArrived(MessageData* data)
 30 {
 31     printf("Message arrived: %s\n", data->message->payload);
 32 }
 33 
 34 static void mqtt_client_thread(void *pvParameters)
 35 {
 36     printf("mqtt client thread starts\n");
 37     MQTTClient client;
 38     Network network;
 39     unsigned char sendbuf[80], readbuf[80] = {0};
 40     int rc = 0, count = 0;
 41     MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;
 42     
 43     pvParameters = 0;
 44     NetworkInit(&network);
 45     MQTTClientInit(&client, &network, 30000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf));
 46     
 47     char* address = MQTT_BROKER;
 48 //    if ((rc = NetworkConnect(&network, address, 1883)) != 0)
 49 //        printf("Return code from network connect is %d\n", rc);
 50     if ((rc = NetworkConnect(&network, address, 61613)) != 0)
 51             printf("Return code from network connect is %d\n", rc);
 52 
 53 #if defined(MQTT_TASK)
 54     if ((rc = MQTTStartTask(&client)) != pdPASS)
 55         printf("Return code from start tasks is %d\n", rc);
 56     else 
 57         printf("Use MQTTStartTask\n");
 58 #endif
 59 
 60     connectData.MQTTVersion = 3;
 61     connectData.clientID.cstring = "ESP8266_sample";
 62     //-----------------------
 63             connectData.username.cstring = "admin";
 64             connectData.password.cstring = "password";
 65 
 66     if ((rc = MQTTConnect(&client, &connectData)) != 0)
 67         printf("Return code from MQTT connect is %d\n", rc);
 68     else
 69         printf("MQTT Connected\n");
 70 
 71     if ((rc = MQTTSubscribe(&client, "ESP8266/sample/sub", 2, messageArrived)) != 0)
 72         printf("Return code from MQTT subscribe is %d\n", rc);
 73     else
 74         printf("MQTT subscribe to topic \"ESP8266/sample/sub\"\n");
 75 
 76     while (++count) {
 77         MQTTMessage message;
 78         char payload[30];
 79 
 80         message.qos = QOS2;
 81         message.retained = 0;
 82         message.payload = payload;
 83         sprintf(payload, "message number %d", count);
 84         message.payloadlen = strlen(payload);
 85         
 86         if ((rc = MQTTPublish(&client, "ESP8266/sample/pub", &message)) != 0)
 87             printf("Return code from MQTT publish is %d\n", rc);
 88         else
 89             printf("MQTT publish topic \"ESP8266/sample/pub\", message number is %d\n", count);
 90 
 91 //        vTaskDelay(100000 / portTICK_RATE_MS);  //send every 100 seconds
 92         vTaskDelay(10000 / portTICK_RATE_MS);  //send every 10 seconds
 93     }
 94 
 95     printf("mqtt_client_thread going to be deleted\n");
 96     vTaskDelete(NULL);
 97     return;
 98 }
 99 
100 void user_conn_init(void)
101 {
102     int ret;
103     ret = xTaskCreate(mqtt_client_thread,
104                       MQTT_CLIENT_THREAD_NAME,
105                       MQTT_CLIENT_THREAD_STACK_WORDS,
106                       NULL,
107                       MQTT_CLIENT_THREAD_PRIO,
108                       &mqttc_client_handle);
109     if (ret != pdPASS)  {
110         printf("mqtt create client thread %s failed\n", MQTT_CLIENT_THREAD_NAME);
111     }
112 }
MQTTEcho.c

MQTT For ESP8266的調試