精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

ESP8266純串口透傳,助力設備上云端

Q4MP_gh_c472c21 ? 來源:嵌入式ARM ? 作者:嵌入式ARM ? 2021-02-10 17:51 ? 次閱讀
項目有些久遠,前年的機器人上需要的功能,當時是需要將STM32上的數據上傳到服務器,比如機器人的速度,行駛距離,是否在拍照等等。便于管理者在PC或者手機上了解機器人的工作狀態,同時可以遠程下發指令給機器人,控制其完成相應動作。 因為所有的邏輯判斷和控制都在服務器或者STM32上面,作為中間的無線模塊僅僅需要上傳STM32的數據并接收服務器下發的指令即可,所以這里對WiFi模塊的要求不高,僅僅需要它作為透傳功能即可。當時在選型的時候試過好幾款WiFi模塊,最終敲定了安信可的ESP8266,價格便宜,開發簡單,但是搭建環境是真的不容易,深受其害 選擇好模塊就該考慮使用AT指令還是使用SDK開發,AT指令固然簡單,但是局限性非常大。如果使用AT指令,我那開發控制端的同事估計就要跳腳了,代碼里需要寫一大堆的AT指令,如果功能改變,指令代碼就需要重寫,煩不勝煩。 如果使用SDK開發,控制端只需發送簡單的數據就行,完全不用考慮其他任何東西,ESP8266完全當做一個中轉站,相對應的我的工作就會繁重,但是,我屈服了,選擇使用SDK。 于是就有了下面基于NONOS 2.0的ESP8266串口透傳。主要有以下幾個功能:
  • 純串口透傳,接收MCU串口數據,直接通過MQTT上傳到服務器,接收服務器數據下發給MCU。
  • smartconfig+airkiss配網,隨意使用,場景豐富。
  • 最多儲存5個WIFI賬號和密碼,自動尋找網絡連接。
  • 按鍵配網,長按重新配網,前一次WiFi自動儲存,添加配網指示燈。
  • OTA空中升級(待驗證)
從程序的入口開始:

//程序入口void ICACHE_FLASH_ATTR user_init(void){        uart_init(115200, 115200);        os_delay_us(60000);        keyInit();        set_uart_cb(uart_cb);
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); //GPIO12初始化        GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0);//低電平
    get_mac();//獲取MAC地址
        wifi_set_opmode(STATION_MODE);        //設置wifi信息存儲數量,最大為5個        wifi_station_ap_number_set(2);
    mqtt_init();
        set_wifistate_cb(wifi_connect_cb, wifi_disconnect_cb);}
程序的入口先進行串口初始化和按鍵的初始化,以及LED的初始化。串口要初始化波特率,按鍵初始化配網按鍵,用于短按配網,長按重新配網,LED只要用于判斷模塊是否進入配網模式以及是否配網完成。
初始化完成后會首先讀取MAC地址,該地址是唯一的,每個模塊都不一樣,用于填充進主題中,便于服務器區分不同設備,用于多臺量產設備的使用,在連接MQTT服務器時會自動填充。

951a5030-5f65-11eb-8b86-12bb97331649.png


每連接一次WiFi都會將WiFi信息保存在模塊內部,每次上電都會自動掃描暴露的WiFi,直接連接,就像手機的WIFI連接,目前最大支持五個WiFi信息的保存,超過5個會剔除最早的WiFi信息,通過短按D5(GPIO14)可進入配網模式。
/***         按鍵短按回調*/LOCAL void ICACHE_FLASH_ATTR key1ShortPress(void) {
        start_smartconfig(smartconfig_cd);        INFO("start_smartconfig
");}/***         按鍵長按回調*/LOCAL void ICACHE_FLASH_ATTR key1LongPress(void) {
        start_smartconfig(smartconfig_cd);        INFO("start_smartconfig
");}/***         按鍵初始化*/LOCAL void ICACHE_FLASH_ATTR keyInit(void) {
        //設置按鍵數量        set_key_num(1);        //長按、短按的按鍵回調        key_add(D5, NULL, key1ShortPress);        key_add(D5, NULL, key1LongPress);
}

由于找不到最新的代碼。這里的長按我沒做處理,應該是斷開WiFi重新進入配網模式, 或者軟復位模塊,再進入start_smartconfig()函數:
/*** 開始Smartconfig配置  * @param  cd: Smartconfig狀態回調* @retval None*/void ICACHE_FLASH_ATTR start_smartconfig(smartconfig_cd_t cd) {        smartconfig_flag = 1;        smartconfig_set_type(SC_TYPE_ESPTOUCH_AIRKISS); //SC_TYPE_ESPTOUCH,SC_TYPE_AIRKISS,SC_TYPE_ESPTOUCH_AIRKISS        wifi_station_disconnect();        wifi_set_opmode(STATION_MODE);        finish_cd = cd;        smartconfig_start(smartconfig_done);        os_timer_disarm(&OS_Timer_Wifichange);        // 關閉定時器
        if(connect_flag == 1){                w_disconnect();                connect_flag = 0;        }
        os_timer_disarm(&OS_Timer_SM);        // 關閉定時器        os_timer_setfn(&OS_Timer_SM, (os_timer_func_t *) sm_wait_time, NULL);// 設置定時器        os_timer_arm(&OS_Timer_SM, 1000, 1);  // 使能定時器}

9565e0cc-5f65-11eb-8b86-12bb97331649.png

smartconfig_set_type();函數可選3個參數:分別是:SC_TYPE_ESPTOUCH、SC_TYPE_AIRKISS和SC_TYPE_ESPTOUCH_AIRKISS
第一個是smartconfig配網(手機APP),第二個是airkiss配網(微信公眾號),最后一個兩者都可以。進入該函數會調用smartconfig_start();,該函數會調用smartconfig_done()函數進行配網,配網成功后會點亮LED燈。

/*** Smartconfig 狀態處理* @param  status: 狀態* @param  *pdata: AP數據* @retval None*/void ICACHE_FLASH_ATTRsmartconfig_done(sc_status status, void *pdata) {        switch (status) {        case SC_STATUS_WAIT:                INFO("SC_STATUS_WAIT
");                break;        case SC_STATUS_FIND_CHANNEL:                INFO("SC_STATUS_FIND_CHANNEL
");                break;        case SC_STATUS_GETTING_SSID_PSWD:                INFO("SC_STATUS_GETTING_SSID_PSWD
");                sc_type *type = pdata;                if (*type == SC_TYPE_ESPTOUCH) {                        INFO("SC_TYPE:SC_TYPE_ESPTOUCH
");                } else {                        INFO("SC_TYPE:SC_TYPE_AIRKISS
");                }                break;        case SC_STATUS_LINK:                INFO("SC_STATUS_LINK
");                sm_comfig_status = SM_STATUS_GETINFO;                struct station_config *sta_conf = pdata;                wifi_station_set_config(sta_conf);                wifi_station_disconnect();                wifi_station_connect();                break;        case SC_STATUS_LINK_OVER:                sm_comfig_status = SM_STATUS_FINISH;                INFO("SC_STATUS_LINK_OVER
");                if (pdata != NULL) {                        //SC_TYPE_ESPTOUCH                        uint8 phone_ip[4] = { 0 };                        os_memcpy(phone_ip, (uint8*) pdata, 4);                        INFO("Phone ip: %d.%d.%d.%d
", phone_ip[0], phone_ip[1],                                        phone_ip[2], phone_ip[3]);                } else {                        //SC_TYPE_AIRKISS - support airkiss v2.0                        airkiss_start_discover();                }                smartconfig_stop();                smartconfig_flag = 0;                connect_flag = 0;                os_timer_disarm(&OS_Timer_SM);        // 關閉定時器                finish_cd(sm_comfig_status);                os_timer_arm(&OS_Timer_Wifichange, 3000, 1);  // 使能定時器                break;        }
}
/***         WIFI連接回調*/void wifi_connect_cb(void){
        INFO("wifi connect!
");        os_printf("----- WiFi連接成功,打開綠燈---
");        GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1);        MQTT_Connect(&mqttClient);}
/***         WIFI斷開回調*/void wifi_disconnect_cb(void){        INFO("wifi disconnect!
");        os_printf("----- WiFi斷開,關閉綠燈---
");        GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0);        MQTT_Disconnect(&mqttClient);}

連接MQTT服務器:

網絡連接成功以后可以開始MQTT的初始化,初始化包涵一系列的連接初始化回調,連接成功或不成功回調,主題訂閱發布回調等等。

/***         MQTT初始化*/void ICACHE_FLASH_ATTR mqtt_init(void) {
        MQTT_InitConnection(&mqttClient, MQTT_HOST, MQTT_PORT, DEFAULT_SECURITY);        MQTT_InitClient(&mqttClient, mac_str, MQTT_USER,MQTT_PASS, MQTT_KEEPALIVE, 1);        MQTT_InitLWT(&mqttClient, lwt_topic, LWT_MESSAGE, 0, 0);        MQTT_OnConnected(&mqttClient, mqttConnectedCb);        MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb);        MQTT_OnPublished(&mqttClient, mqttPublishedCb);        MQTT_OnData(&mqttClient, mqttDataCb);}
void ICACHE_FLASH_ATTRMQTT_InitConnection(MQTT_Client *mqttClient, uint8_t* host, uint32_t port, uint8_t security){        uint32_t temp;        INFO("MQTT_InitConnection
");        os_memset(mqttClient, 0, sizeof(MQTT_Client));        temp = os_strlen(host);        mqttClient->host = (uint8_t*)os_zalloc(temp + 1);        os_strcpy(mqttClient->host, host);        mqttClient->host[temp] = 0;        mqttClient->port = port;        mqttClient->security = security;
}
void ICACHE_FLASH_ATTRMQTT_InitClient(MQTT_Client *mqttClient, uint8_t* client_id, uint8_t* client_user, uint8_t* client_pass, uint32_t keepAliveTime, uint8_t cleanSession){        uint32_t temp;        INFO("MQTT_InitClient
");        os_printf("CD MQTT_InitClient++++++++++++++++++++++
");        os_memset(&mqttClient->connect_info, 0, sizeof(mqtt_connect_info_t));
        temp = os_strlen(client_id);        mqttClient->connect_info.client_id = (uint8_t*)os_zalloc(temp + 1);        os_strcpy(mqttClient->connect_info.client_id, client_id);        mqttClient->connect_info.client_id[temp] = 0;
        if (client_user)        {                temp = os_strlen(client_user);                mqttClient->connect_info.username = (uint8_t*)os_zalloc(temp + 1);                os_strcpy(mqttClient->connect_info.username, client_user);                mqttClient->connect_info.username[temp] = 0;        }
        if (client_pass)        {                temp = os_strlen(client_pass);                mqttClient->connect_info.password = (uint8_t*)os_zalloc(temp + 1);                os_strcpy(mqttClient->connect_info.password, client_pass);                mqttClient->connect_info.password[temp] = 0;        }

        mqttClient->connect_info.keepalive = keepAliveTime;        mqttClient->connect_info.clean_session = cleanSession;
        mqttClient->mqtt_state.in_buffer = (uint8_t *)os_zalloc(MQTT_BUF_SIZE);        mqttClient->mqtt_state.in_buffer_length = MQTT_BUF_SIZE;        mqttClient->mqtt_state.out_buffer =  (uint8_t *)os_zalloc(MQTT_BUF_SIZE);        mqttClient->mqtt_state.out_buffer_length = MQTT_BUF_SIZE;        mqttClient->mqtt_state.connect_info = &mqttClient->connect_info;
        mqtt_msg_init(&mqttClient->mqtt_state.mqtt_connection, mqttClient->mqtt_state.out_buffer, mqttClient->mqtt_state.out_buffer_length);
        QUEUE_Init(&mqttClient->msgQueue, QUEUE_BUFFER_SIZE);
        system_os_task(MQTT_Task, MQTT_TASK_PRIO, mqtt_procTaskQueue, MQTT_TASK_QUEUE_SIZE);        system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)mqttClient);}

WiFi連接成功和失敗會觸發不同的回調函數:

/***         MQTT連接回調*/void mqttConnectedCb(uint32_t *args) {        MQTT_Client* client = (MQTT_Client*) args;
        INFO("MQTT: Connected
");        MQTT_Publish(client, birth_topic, BIRTH_MESSAGE, os_strlen(BIRTH_MESSAGE), 0,0);        MQTT_Subscribe(client,ota_topic, 0);        if(updata_status_check()){                MQTT_Publish(client, ota_topic, "updata_finish", os_strlen("updata_finish"), 0,0);        }}/**
*         MQTT斷開連接回調*/void mqttDisconnectedCb(uint32_t *args) {        MQTT_Client* client = (MQTT_Client*) args;        INFO("MQTT: Disconnected
");}
/***         MQTT發布消息回調*/void mqttPublishedCb(uint32_t *args) {        MQTT_Client* client = (MQTT_Client*) args;        INFO("MQTT: Published
");}
串口透傳:
當模塊的WiFi和MQTT服務器都連接上之后,模塊就開始監聽串口和服務器的數據,如果串口有數據過來便轉發到服務器或者進行OTA升級,如果服務器有指令下發就轉發給串口。

/***         MQTT接收數據回調(用于OTA升級和串口透傳)*/void mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len,                const char *data, uint32_t data_len) {        char *topicBuf = (char*) os_zalloc(topic_len + 1), *dataBuf =                        (char*) os_zalloc(data_len + 1);
        uint8 *pdata = (uint8*)data;        uint16 len = data_len;        uart0_tx_buffer(pdata, len);//串口輸出
        MQTT_Client* client = (MQTT_Client*) args;
        os_memcpy(topicBuf, topic, topic_len);        topicBuf[topic_len] = 0;
        os_memcpy(dataBuf, data, data_len);        dataBuf[data_len] = 0;
//        INFO("Receive topic: %s, data: %s 
", topicBuf, dataBuf);
        //data = {"url"="http://yourdomain.com:9001/ota/"}        if (os_strcmp(topicBuf, ota_topic) == 0) {                char url_data[200];                if(get_josn_str(dataBuf,"url",url_data)){//            INFO("ota_start
");            ota_upgrade(url_data,ota_finished_callback);                }        }
        os_free(topicBuf);        os_free(dataBuf);


}
/***         ota升級回調*/void ICACHE_FLASH_ATTR ota_finished_callback(void * arg) {        struct upgrade_server_info *update = arg;        if (update->upgrade_flag == true) {                INFO("OTA  Success ! rebooting!
");                system_upgrade_reboot();        } else {                INFO("OTA Failed!
");        }}
其他問題:連接的服務器地址,端口號等信息需要寫在代碼里燒錄進模塊,這些信息在在mqtt_config.h文件中定義。

95c8a590-5f65-11eb-8b86-12bb97331649.png


上電后可以在串口助手看到打印的MAC地址:

96055684-5f65-11eb-8b86-12bb97331649.png


按下配網按鍵(GPIO14接地),進入配網模式,使用APP或者微信公眾號將信息發給模塊便可聯網,聯網后自動連接MQTT服務器。

9631973a-5f65-11eb-8b86-12bb97331649.png

96d612b0-5f65-11eb-8b86-12bb97331649.png

至此連接完成,后續只需要串口發數據給模塊,便可在服務器收到信息,服務器下發指令,單片機串口也可以接收到數據。但是要記得訂閱主題哦。該透傳代碼燒錄完成可搭配任意MCU的串口使用。非常便捷。由于項目期較遠,可能介紹的不是很詳細,需要的大大們可以點擊閱讀原文回帖獲取源碼。自行查看。

責任編輯:xj

原文標題:什么?單片機還在裸奔?ESP8266純串口透傳,助力設備上云端

文章出處:【微信公眾號:嵌入式ARM】歡迎添加關注!文章轉載請注明出處。


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 單片機
    +關注

    關注

    6032

    文章

    44514

    瀏覽量

    632979
  • 云端
    +關注

    關注

    0

    文章

    118

    瀏覽量

    16845
  • ESP8266
    +關注

    關注

    50

    文章

    962

    瀏覽量

    44833

原文標題:什么?單片機還在裸奔?ESP8266純串口透傳,助力設備上云端

文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    DTU終端CATCOM-100云端轉發應用

    本文介紹DTU設備數據轉發應用,實現點對點通信。應用場景DTU設備數據
    的頭像 發表于 10-13 08:05 ?192次閱讀
    DTU終端CATCOM-100<b class='flag-5'>云端</b><b class='flag-5'>透</b><b class='flag-5'>傳</b>轉發應用

    ESP8266 太空人動畫的 OLED 顯示

    ESP8266 太空人動畫的 OLED 顯示
    的頭像 發表于 10-08 15:06 ?212次閱讀
    <b class='flag-5'>ESP8266</b> 太空人動畫的 OLED 顯示

    esp32和esp8266代碼共用嗎

    本文將介紹ESP32和ESP8266兩款流行的微控制器在代碼共用性方面的可能性與差異性。 一、引言 隨著物聯網技術的飛速發展,越來越多的智能設備開始進入我們的生活。其中,ESP32和
    的頭像 發表于 08-19 18:23 ?969次閱讀

    esp8266esp32區別是什么

    以下是關于ESP8266ESP32的主要區別: 處理器和架構 : ESP8266 :使用一個Tensilica L106 80MHz的處理器,屬于Xtensa架構。 ESP32 :使
    的頭像 發表于 08-19 18:16 ?4359次閱讀

    esp8266不燒錄可以使用嗎

    ,可以方便地與其他硬件設備進行連接。 2. ESP8266的硬件特性 處理器 :Tensilica L106,最高頻率160MHz 內存 :64KB SRAM,1MB Flash Wi-Fi :支持802.11 b/g/n協議,最高速
    的頭像 發表于 08-19 17:28 ?623次閱讀

    esp8266wifi模塊怎么連接手機

    ESP8266 : 使用USB轉TTL模塊將ESP8266模塊與電腦連接。 通過串口調試助手發送AT指令配置ESP8266,包括設置WiFi模式為STA模式(客戶端模式),連接指定的W
    的頭像 發表于 08-19 17:27 ?2209次閱讀

    ESP-WROOM-02云端設備控制失敗是什么原因?

    我使用的是ESP-WROOM-02的芯片,然后燒錄了ESP8266_RTOS_SDK_V1.4.0使用的是ESP8266_IOT_PLATFORM這個DEMO,參照文檔修改了里面的參數,下載了IOT
    發表于 07-15 08:06

    ESP8266模式是如何工作的?

    ,使用這個理論,如果我每 4 毫秒向 esp8266 發送一個值(7 字節),那么每 20 毫秒應該發送 35 個字節,如果我每 20 毫秒對 android 接收緩沖區進行采樣,那么我應該在這個緩沖區找到 35 個字節。這時
    發表于 07-15 07:48

    ESP8266如果要連接云端,需要把相關的key加入APK編譯嗎?

    如果要連接云端,需要把相關的key加入APK編譯嗎?利如owner key 我用的是ESP8266_NONOS_SDK,手機APK用的是1.2版本編譯出來的,連接云端成功,但是點擊進去會出現獲取
    發表于 07-15 07:03

    為什么ESP8266 TCP傳過程會丟包?

    為什么ESP8266 TCP傳過程會丟包?
    發表于 07-09 07:55

    請問ESP8266串口的最大速度能到多少?

    請問ESP8266串口的最大速度能到多少?
    發表于 07-08 06:30

    國產低成本Wi-Fi SoC解決方案芯片ESP8266ESP8285對比差異

    ESP8266ESP8285對比差異 ESP8285相當于在ESP8266基礎多加了1/2MB Flash,
    的頭像 發表于 05-17 11:44 ?1178次閱讀
    國產低成本Wi-Fi SoC解決方案芯片<b class='flag-5'>ESP8266</b>與<b class='flag-5'>ESP</b>8285對比差異

    確定ESP8266固件下載成功的方法

    在物聯網設備的開發過程中,確定esp8266固件是否成功下載至設備十分關鍵。以下是一種簡單有效的確認方法:機智云物聯網平臺首先,確保你的ESP8266模塊已經正確連接至計算機,并通過
    的頭像 發表于 05-16 08:10 ?512次閱讀
    確定<b class='flag-5'>ESP8266</b>固件下載成功的方法

    使用Wi-Fi ESP8266方案模組接入云平臺

    ESP8266的模塊芯片是基于無線通信協議的UARTWi-Fi模塊芯片,支持802.11b/g/n的無線標準,并帶有三種可選擇的工作模式。ESP8266模塊的控制是通過AT指令的形
    的頭像 發表于 05-10 08:20 ?1736次閱讀
    使用Wi-Fi <b class='flag-5'>ESP8266</b>方案模組接入云平臺

    STM32、ESP8266與MQTT連接阿里云物聯網的串口通信異常解析

    STM32、ESP8266與MQTT協議連接阿里云物聯網平臺時常見的串口通信異常介紹 在構建物聯網應用時,STM32、ESP8266與MQTT協議的結合是實現設備與網絡間穩定通信的關鍵
    的頭像 發表于 04-19 17:19 ?1369次閱讀