日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

物联网学习之旅:微信小程序控制STM32(二)--ESP8266连接mqtt服务端

發(fā)布時(shí)間:2023/12/20 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 物联网学习之旅:微信小程序控制STM32(二)--ESP8266连接mqtt服务端 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

ESP8266連接mqtt服務(wù)端

微信小程序控制STM32的第二步,就是要編寫ESP8266固件,來連接已經(jīng)搭建好的物聯(lián)網(wǎng)服務(wù)器。也有別的方式,只要你足夠了解mqtt協(xié)議,可以通過使用ESP8266原生的AT指令來連接,因?yàn)镋SP8266連接mqtt服務(wù)端中mqtt協(xié)議也是通過建立TCP連接,發(fā)送相應(yīng)的協(xié)議報(bào)文來連接服務(wù)端。但是樂鑫官方提供的SDK中含有連接mqtt服務(wù)端的實(shí)例代碼,要做的就是根據(jù)自己的功能要求去修改代碼。
我修改的固件是ESP8266與STM32之間進(jìn)行串口通信,以透?jìng)鞯姆绞交ハ鄠鬟f數(shù)據(jù),然后ESP8266作為中轉(zhuǎn)把數(shù)據(jù)發(fā)到相應(yīng)的目的地。

  • 硬件準(zhǔn)備
    我用的是ESP8266-01這款模塊

    ESP8266有UART 下載模式和Flash 運(yùn)行模式 ,接線不一樣的地方就是在下載模式時(shí)GPIO0要接低電平,運(yùn)行模式時(shí)懸空即可,每次運(yùn)行模式和下載模式切換都需要重啟一下模塊,才能第二次燒寫或者運(yùn)行。

    我是采用這樣的連接方式來燒寫固件,運(yùn)行程序時(shí)把GPIO0拔掉,然后拔掉esp8266的vcc線,然后又插上,重啟一下就可以了。燒寫的時(shí)候把GPIO0接共地端,然后拔掉esp8266的vcc線,然后又插上,重啟一下,就可以燒寫程序了。至于我為什么要用這么復(fù)雜的接線方式來燒寫程序,那是因?yàn)橘I這個(gè)esp8266調(diào)試器的時(shí)候,不懂,圖便宜(根本也是因?yàn)槲姨F了,哈哈哈),然而這個(gè)用來運(yùn)行調(diào)試是最合適的,直接插上去即可。不過這樣也能燒寫固件。也可以用TTL轉(zhuǎn)串口來燒寫,都是可以的,原理都一樣。
  • 搭建ESP8266開發(fā)環(huán)境
    進(jìn)入安信可ESP8266 系列模組專題,按照開發(fā)環(huán)境搭建的步驟搭建開發(fā)環(huán)境。


    點(diǎn)擊藍(lán)色文字下載ESP8266_NONOS_SDK-v3.0.0,也可以選擇在樂鑫官網(wǎng)上下載最新版本的SDK,根據(jù)需要下載開發(fā)文檔,我用到了這兩個(gè)文檔。

    值得注意的是,本項(xiàng)目用到的是esp_mqtt_proj這個(gè)例程,所以在構(gòu)建工程文件時(shí),需要將examples/esp_mqtt_proj目錄工程目錄的頂層文件中,其它的按照安信可提供的步驟搭建即可,編譯沒有錯(cuò)誤之后,其實(shí)example文件夾就可以刪除掉了,這個(gè)項(xiàng)目只用到mqtt部分,其它例程刪掉后編譯仍然是成功的。
  • 編寫ESP8266固件
    打開編譯通過的工程,需要修改的有這幾個(gè)地方
    1)user_main.c中修改
  • void mqttConnectedCb(uint32_t *args) {MQTT_Client* client = (MQTT_Client*)args;mqttclient=client;INFO("MQTT: Connected\r\n");MQTT_Subscribe(client, "Topic0", 0); //訂閱Topic0主題,用于接收微信小程序的數(shù)據(jù)MQTT_Publish(client, "Topic1", "hello1", 6, 0, 0); //發(fā)布消息//Topic0用于下行通道,Topic1用于上行通道 } void mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len) { //接收到數(shù)據(jù)時(shí)執(zhí)行char *topicBuf = (char*)os_zalloc(topic_len+1),*dataBuf = (char*)os_zalloc(data_len+1);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;os_printf("%s\r\n",dataBuf); //串口打印接收到的消息os_free(topicBuf);os_free(dataBuf); } MQTT_Client* mqttclient; //此指針會(huì)用在uart.c中

    2)uart.c中修改
    通過user_main.c文件中的uart_init()定位到uart.c文件,然后對(duì)這里面進(jìn)行修改。首先需要引入user_main.c定義的“MQTT_Client* mqttclient;”,這樣下面在串口處理函數(shù)中,當(dāng)從串口接收完數(shù)據(jù)之后,通過引入的mqtt客戶端指針,將數(shù)據(jù)發(fā)到特定的主題,然后別忘了引入“mqtt.h”,因?yàn)檫@里要用到這里面的函數(shù),將數(shù)據(jù)發(fā)送出去。

    extern MQTT_Client* mqttclient;

    最后修改串口中斷處理函數(shù)。

    LOCAL void uart0_rx_intr_handler(void *para) {/* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents* uart1 and uart0 respectively*/uint8_t RcvChar[256];uint8_t uart_no = UART0;//UartDev.buff_uart_no;uint8_t fifo_len = 0;uint8_t buf_idx = 0;uint8_t temp, cnt;if (UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)) {DBG1("FRM_ERR\r\n");WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);} else if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) {DBG("f");uart_rx_intr_disable(UART0);WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR);system_os_post(uart_recvTaskPrio, 0, 0);} else if (UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)) { //檢測(cè)到是超時(shí)中斷fifo_len=(READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; //獲取數(shù)據(jù)長(zhǎng)度buf_idx=0;for(buf_idx=0;buf_idx<fifo_len;buf_idx++){RcvChar[buf_idx]=READ_PERI_REG(UART_FIFO(UART0))&0xFF; //將數(shù)據(jù)儲(chǔ)存起來}if(RcvChar[0]=='A'){ //接收到詢問是否初始化完成的消息if(mqttState==1){ //初始化完成了os_printf("1111\r\n"); //串口發(fā)送初始化完成,如果發(fā)送字母就會(huì)亂碼}else{os_printf("2222\r\n");}}if(RcvChar[0]=='{'){MQTT_Publish(mqttclient, "Topic1", RcvChar, fifo_len, 0, 0); //把接收到的數(shù)據(jù)發(fā)送到mqtt服務(wù)端}if(RcvChar[0]=='T'){os_printf("\r\ntime:%s\r\n", time);}os_memset(RcvChar,0,256); //清除數(shù)據(jù)WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR); //清除超時(shí)中斷狀態(tài)} else if (UART_TXFIFO_EMPTY_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_TXFIFO_EMPTY_INT_ST)) {DBG("e");CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA); #if UART_BUFF_ENtx_start_uart_buffer(UART0); #endif//system_os_post(uart_recvTaskPrio, 1, 0);WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR);} else if (UART_RXFIFO_OVF_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_OVF_INT_ST)) {WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_OVF_INT_CLR);DBG1("RX OVF!!\r\n");}}

    問為什么要這樣改,官方文檔中做出了說明,參考esp8266技術(shù)參考手冊(cè),串口中斷狀態(tài)分為:接收 full 中斷、接收溢出中斷、接收超時(shí)中斷 tout、發(fā)送 fifo 空中斷、流量量控制狀態(tài)中斷。我只對(duì)接收超時(shí)中斷進(jìn)行了配置,因?yàn)檫@個(gè)足夠滿足需求,若考慮全面,可以適當(dāng)增加。手冊(cè)中也有一個(gè)中斷處理函數(shù)的例程,參照這個(gè)修改。

    上面代碼的注釋也寫的很清楚了。
    3)修改mqtt_config.h

    /*只有在持有人標(biāo)識(shí)和之前不同的情況下才會(huì)更新系統(tǒng)參數(shù),這就是為什么在配置文件這里修改MQTThost等內(nèi)容時(shí),燒進(jìn)去的程序沒有變化*/ #define CFG_HOLDER 0x00FF55A4 /* Change this value to load default configurations */#define MQTT_HOST "0.0.0.0" //改成自己服務(wù)器的公網(wǎng)IP #define MQTT_PORT 1883 // the listening port of your MQTT server or MQTT broker #define MQTT_CLIENT_ID "esp8266" // 自定義的clientID #define MQTT_USER "admin" // your MQTT login name, if MQTT server allow anonymous login,any string is OK, otherwise, please input valid login name which you had registered #define MQTT_PASS "public" // you MQTT login password, same as above #define STA_SSID "**********" //填自己的SSID #define STA_PASS "**********" // 你的AP/路由器的密碼

    記得要修改CFG_HOLDER,隨便更改某一個(gè)十六進(jìn)制數(shù)就行,否則出現(xiàn)修改的參數(shù)不生效的后果,我也是一步一步采坑過來的。

    不過還有一個(gè)坑,我現(xiàn)在才說,目的就是為了經(jīng)歷遇到問題,解決問題的過程。遇到問題之后自己解決,這樣可以學(xué)到更多的東西。修改完中斷處理函數(shù)之后,調(diào)試時(shí),似乎根本就不會(huì)進(jìn)入修改好的中斷處理函數(shù),找了各種原因:是不是沒有配置好串口的相關(guān)寄存器啊,是不是mqttclient不能傳遞到另一個(gè)文件中使用啊,等等等。最后找到答案,ESP8266 NONOS_SDK-3.0 開發(fā)中官方例程 UART0串口進(jìn)入不了中斷問題。因?yàn)楣こ虡?gòu)建得有問題,esp_mqtt_proj目錄中雖然有uart.h頭文件,但是根本不含有uart.c文件,我們所修改的不過是沒有引入到項(xiàng)目中的uart.c文件。所以我的解決方式是:
    1)將driver_lib下的driver復(fù)制到esp_mqtt_proj項(xiàng)目文件夾內(nèi)

    2)在Makefile文件中加入相應(yīng)的庫文件目錄。


    把對(duì)應(yīng)的二進(jìn)制文件燒錄進(jìn)esp8266

    4. 調(diào)試效果
    1)連接好ESP8266和串口調(diào)試器,插到電腦USB口上。

    2)打開串口調(diào)試助手(安信可官網(wǎng)開發(fā)工具清單中下載)。

    這樣表示mqtt服務(wù)端連接成功。
    3)模擬一下微信小程序與ESP8266之間進(jìn)行通信,首先在MQTTBox上添加mqtt客戶端用以模擬微信小程序端,配置如下:

    在MQTTBox上發(fā)布消息

    可以看到esp8266串口中打印出來了消息,如果esp8266接在STM32上,STM32只需要讀取串口數(shù)據(jù)就可以獲取到微信小程序發(fā)來的數(shù)據(jù)了、

    esp8266轉(zhuǎn)發(fā)串口數(shù)據(jù)(AT+RST)

    可以看到微信小程序訂閱的Topic1主題,接收到了消息。

    這樣這個(gè)環(huán)節(jié)就OK了。


    更新內(nèi)容
    問題:在最開始做這個(gè)項(xiàng)目的時(shí)候,有一個(gè)問題沒注意,后來調(diào)試之后,突然發(fā)現(xiàn)一個(gè)問題,當(dāng)Esp8266和STM32同時(shí)上電之后,不會(huì)發(fā)送上線消息,然后微信小程序就不會(huì)檢測(cè)到STM32是否上線,進(jìn)而無法控制STM32。這是因?yàn)樵谏想姾?#xff0c;stm32和esp8266各自執(zhí)行自己的代碼,沒有聯(lián)系,所以STM32初始化過程中發(fā)送在線信息時(shí),ESP8266還沒有連接上服務(wù)器,然后向串口發(fā)送在線信息時(shí),ESP8266不會(huì)轉(zhuǎn)發(fā)到主題上去。
    解決方法:更改STM32程序,在STM32初始化時(shí),向ESP8266串口發(fā)送詢問數(shù)據(jù),詢問ESP8266是否連接上服務(wù)器。更新ESP8266固件,當(dāng)串口接收到詢問數(shù)據(jù)后,在串口返回初始化完畢的狀態(tài)。
    更改后的代碼貼在下面。
    user_main.c

    void user_init(void) {uart_init(BIT_RATE_115200, BIT_RATE_115200);os_delay_us(60000);uart_rx_intr_disable(UART0); //先關(guān)閉串口中斷,待連接上服務(wù)器后再開啟,防止在連接服務(wù)器時(shí),不斷收到詢問是否初始化完成的數(shù)據(jù)CFG_Load();os_printf("\r\nSDKversion:%s\r\n",system_get_sdk_version());MQTT_InitConnection(&mqttClient, sysCfg.mqtt_host, sysCfg.mqtt_port, sysCfg.security);MQTT_InitClient(&mqttClient, sysCfg.device_id, sysCfg.mqtt_user, sysCfg.mqtt_pass, sysCfg.mqtt_keepalive, 1);MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0);MQTT_OnConnected(&mqttClient, mqttConnectedCb);MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb);MQTT_OnPublished(&mqttClient, mqttPublishedCb);MQTT_OnData(&mqttClient, mqttDataCb);WIFI_Connect(sysCfg.sta_ssid, sysCfg.sta_pwd, wifiConnectCb);INFO("\r\nSystem started ...\r\n"); }

    在mqtt.c里面mqtt_tcpclient_recv函數(shù),當(dāng)訂閱成功之后表示連接服務(wù)器成功,表示可以接收詢問數(shù)據(jù)了

    case MQTT_MSG_TYPE_SUBACK:if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id){mqttState=1;os_delay_us(60000);uart_rx_intr_enable(UART0);}break;

    個(gè)人能力有限,有錯(cuò)誤的地方歡迎指正,有問題也可以提,可以一起探討一下

    總結(jié)

    以上是生活随笔為你收集整理的物联网学习之旅:微信小程序控制STM32(二)--ESP8266连接mqtt服务端的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 三年中国片在线高清观看 | 91射射| 疯狂撞击丝袜人妻 | 国产一区二区三区四区视频 | 成人av手机在线 | 欧美一区三区三区高中清蜜桃 | 色婷婷精品国产一区二区三区 | 成人人人人人欧美片做爰 | 在线看免费毛片 | 亚洲色图国产 | 国产在线视频卡一卡二 | 亚洲一二三视频 | 欧美少妇喷水 | 999视频在线观看 | wwwxxx色| 99精品视频99 | 中文字幕在线不卡视频 | 欧美一级特黄aa大片 | 亚洲蜜桃在线 | 麻豆911| 国产成人午夜精品无码区久久 | 欧美日韩爱爱 | 99精品国产一区二区 | missav|免费高清av在线看 | 一级大片黄色 | 久久久久毛片 | 老色批av | 色一区二区三区四区 | 最新地址在线观看 | 天天综合网天天综合色 | 欧美乱论 | 免费吸乳羞羞网站视频 | 精品成人久久久 | 97精品人妻一区二区 | 性做久久 | 美女扒开腿免费视频 | 欧美日韩一区二区三区在线观看 | 韩国一级淫片 | 国产精品系列在线播放 | 久久精品国产成人av | 最近中文字幕免费 | 成人在线观看www | www.蜜桃av | 国产对白在线 | 国产aⅴ精品一区二区三区久久 | 久久婷婷伊人 | 欧美三极片 | 91手机视频在线观看 | 亚洲爱爱爱 | 日本少妇作爱视频 | 日韩av片免费观看 | 欧美日韩蜜桃 | 无码人妻丰满熟妇区五十路 | 欧美高清另类 | 2一3sex性hd | 国产又粗又猛又爽又黄又 | 青青草国产在线播放 | 五月婷婷六月天 | 日噜| julia在线播放88mav | 四虎影院在线免费播放 | 精品无码一区二区三区电影桃花 | 亚洲精品午夜 | 黑鬼大战白妞高潮喷白浆 | 女攻总攻大胸奶汁(高h) | 色涩色 | 视频在线91| 国产伦精品一区二区三区四区视频 | 91无打码| 国产一级黄色大片 | gai免费观看网站外网 | 色99色| 黄色三级av | 女女互慰吃奶互揉调教捆绑 | 在线免费观看一区 | 秋霞av鲁丝片一区二区 | 天天射天天干天天色 | 日本不卡一区二区 | 亚洲欧美日韩在线 | 欧美熟妇精品一区二区蜜桃视频 | 国产精品一区二区自拍 | 在线日韩视频 | 国产专区一区二区三区 | 欧美激情网站 | 欧美日韩一区二区电影 | www.xxxxx日本| 伊人精品久久 | 爱爱视频日本 | 成人性生交大片免费 | 亚洲va在线∨a天堂va欧美va | 香蕉视频在线观看黄 | 久久国产精品久久久久久 | 公妇借种乱htp109cc | 椎名由奈在线观看 | 精品欧美一区二区在线观看 | 国产午夜精品一区二区三区嫩草 | 国产精品影片 | 天堂网wwww| www.色就是色 |