單芯片解決方案,開啟全新體驗——W55MH32 高性能以太網單片機
W55MH32是WIZnet重磅推出的高性能以太網單片機,它為用戶帶來前所未有的集成化體驗。這顆芯片將強大的組件集于一身,具體來說,一顆W55MH32內置高性能Arm? Cortex-M3核心,其主頻最高可達216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲與數據處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協議棧、內置MAC以及PHY,擁有獨立的32KB以太網收發緩存,可供8個獨立硬件socket使用。如此配置,真正實現了All-in-One解決方案,為開發者提供極大便利。
在封裝規格上,W55MH32 提供了兩種選擇:QFN100和QFN68。
W55MH32L采用QFN100封裝版本,尺寸為12x12mm,其資源豐富,專為各種復雜工控場景設計。它擁有66個GPIO、3個ADC、12通道DMA、17個定時器、2個I2C、5個串口、2個SPI接口(其中1個帶I2S接口復用)、1個CAN、1個USB2.0以及1個SDIO接口。如此豐富的外設資源,能夠輕松應對工業控制中多樣化的連接需求,無論是與各類傳感器、執行器的通信,還是對復雜工業協議的支持,都能游刃有余,成為復雜工控領域的理想選擇。同系列還有QFN68封裝的W55MH32Q版本,該版本體積更小,僅為8x8mm,成本低,適合集成度高的網關模組等場景,軟件使用方法一致。更多信息和資料請進入http://www.w5500.com/網站或者私信獲取。
此外,本W55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應用,涵蓋TCP SSL、HTTP SSL以及 MQTT SSL等,為網絡通信安全再添保障。
為助力開發者快速上手與深入開發,基于W55MH32L這顆芯片,WIZnet精心打造了配套開發板。開發板集成WIZ-Link芯片,借助一根USB C口數據線,就能輕松實現調試、下載以及串口打印日志等功能。開發板將所有外設全部引出,拓展功能也大幅提升,便于開發者全面評估芯片性能。
若您想獲取芯片和開發板的更多詳細信息,包括產品特性、技術參數以及價格等,歡迎訪問官方網頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。
第二十二章 W55MH32 MQTT&Aliyun示例
本篇文章,我們將詳細介紹如何在W55MH32芯片上面實現MQTT協議。并通過實戰例程,為大家講解如何使用W55MH32的MQTT協議連接阿里云平臺,實現與阿里云物模型的數據交互。
該例程用到的其他網絡協議,例如DHCP和DNS,請參考相關章節。有關 W55MH32的初始化過程,請參考Network Install章節,這里將不再贅述。
1 MQTT簡介
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸協議)是一種輕量級的、基于發布/訂閱模式的消息傳輸協議,廣泛應用于物聯網(IoT)領域,尤其是在網絡帶寬受限、設備資源有限的環境中。它由IBM在1999年提出,主要用于遠程監控和控制系統中的設備通信。MQTT協議具有低帶寬、低功耗、低延遲等優點,特別適用于嵌入式系統和物聯網設備的通信。
2 MQTT特點
輕量級:MQTT協議采用極簡的協議頭,減少了消息頭的大小,適合帶寬有限和計算資源有限的設備。
可靠性:MQTT支持三種服務質量(QoS)級別,能夠確保數據可靠送達。
實時性:MQTT適合低延遲應用場景,消息會盡可能地實時推送到訂閱者。
保留消息:MQTT支持“保留消息”功能,代理會保存最后一條發布的消息,當有新設備訂閱某個主題時,代理會立即發送保留的消息。
持久會話:MQTT允許客戶端在斷開后恢復會話狀態,斷開期間的消息可以在客戶端重新連接后繼續接收。
3 MQTT應用場景
工業自動化:在工業環境中,生產設備、傳感器、控制器等都需要進行數據交換,MQTT協議適用于在復雜的工業自動化系統中提供實時通信。
智能電網:智能電網應用中,電力設備(如變電站、智能電表、開關設備等)通過以太網與控制中心進行實時數據交換,使用MQTT協議進行遠程監控和控制。
遠程設備監控與管理:適用于需要遠程監控和管理的設備,如遠程氣象站、環境監測設備等。通過MQTT協議實時獲取設備的傳感器數據。
4 MQTT發布/訂閱模式
發布訂閱模式(Publish-Subscribe Pattern)是一種消息傳遞模式,它將發送消息的客戶端(發布者)與接收消息的客戶端(訂閱者)解耦,使得兩者不需要建立直接的聯系也不需要知道對方的存在。
MQTT發布/訂閱模式的精髓在于由一個被稱為代理(Broker)的中間角色負責所有消息的路由和分發工作,發布者將帶有主題的消息發送給代理,訂閱者則向代理訂閱主題來接收感興趣的消息。
在 MQTT中,主題和訂閱無法被提前注冊或創建,所以代理也無法預知某一個主題之后是否會有訂閱者,以及會有多少訂閱者,所以只能將消息轉發給當前的訂閱者,如果當前不存在任何訂閱,那么消息將被直接丟棄。
MQTT發布/訂閱模式有 4個主要組成部分:發布者、訂閱者、代理和主題。
發布者(Publisher):負責將消息發布到主題上,發布者一次只能向一個主題發送數據,發布者發布消息時也無需關心訂閱者是否在線。
訂閱者(Subscriber):訂閱者通過訂閱主題接收消息,且可一次訂閱多個主題。
代理(Broker):負責接收發布者的消息,并將消息轉發至符合條件的訂閱者。另外,代理也需要負責處理客戶端發起的連接、斷開連接、訂閱、取消訂閱等請求。
主題(Topic):主題是 MQTT進行消息路由的基礎,它類似 URL路徑,使用斜杠 /進行分層,比如sensor/1/temperature。一個主題可以有多個訂閱者,代理會將該主題下的消息轉發給所有訂閱者;一個主題也可以有多個發布者,代理將按照消息到達的順序轉發。
MQTT協議的通信流程如下圖:
5 MQTT QoS詳解
QoS 0:消息最多傳遞一次,可能會丟失,且不做重試。這是最基本的QoS級別,不保證消息的傳送或順序。
使用場景:實時傳輸的更新數據,如溫度、濕度等,消息丟失對應用的影響較小。
QoS 1:消息至少傳送一次。為了確保消息到達,發送方會重復發送消息,直到收到接收方的確認應答(PUBACK)。可能會導致消息重復接收。
使用場景:電力監測數據,或需要確保狀態信息準確傳輸的應用場景。
QoS 2:確保消息只能被傳遞一次,且只傳遞一次。該級別保證了消息的可靠性、唯一性和順序性。通過四次握手過程確保消息不丟失、不會重復。
適用場景:高安全要求的應用,如支付系統、重要的設備控制等,不能容忍消息重復或丟失。
6 MQTT消息
在 MQTT中,客戶端可以在連接時在服務端中注冊一個遺囑消息,與普通消息類似,我們可以設置遺囑消息的主題、有效載荷等等。當該客戶端意外斷開連接,服務端就會向其他訂閱了相應主題的客戶端發送此遺囑消息。這些接收者也因此可以及時地采取行動。這一特性通常用于檢測和響應客戶端故障或掉線事件,特別適合在需要高可靠性的物聯網系統和實時監控場景中使用。
有關MQTT協議的報文,可以參考:Introduction · MQTT協議中文版,本文不再贅述。
7阿里云物聯網平臺簡介
阿里云物聯網平臺(Alibaba Cloud IoT Platform)是阿里云推出的一款面向物聯網(IoT)行業的綜合性服務平臺,旨在幫助企業實現物聯網設備的連接、管理、監控和數據分析等多種功能。通過該平臺,企業可以將各種智能設備接入云端,并進行統一的管理和數據處理。
在設備接入上,支持 MQTT、CoAP 等多種協議,具備直連、網關代理等接入方式,能實現全球毫秒級就近接入。設備管理方面,覆蓋設備全生命周期,借助設備影子保障弱網下狀態一致,設備可靈活轉移歸屬。數據服務中,實現冷熱存儲分離,支持可視化數據解析與 EB級離線分析。監控運維能力強,提供近百項監控指標,能一鍵跟蹤消息流轉,保障 OTA升級成功率。
8阿里云物模型介紹
阿里云物模型是阿里云物聯網平臺(IoT Platform)提供的一種用于描述和管理設備功能的抽象模型。物模型通過定義設備的屬性、服務和事件,幫助開發者統一描述設備能力,簡化設備管理和數據交互流程。阿里云物模型是設備數字化管理的核心概念之一,廣泛應用于智慧城市、工業物聯網、智能家居等領域。
9 MQTT連接阿里云收發數據流程
1.準備階段
注冊與實名認證:用戶需要在阿里云平臺注冊賬號,并完成實名認證。
創建產品和添加物模型:登錄阿里云物聯網平臺,創建產品并在產品下添加以下物模型功能。
創建設備:在剛剛創建的產品下創建一個設備。
2.記錄參數
連接參數:在剛剛創建的設備詳情頁中找到MQTT連接參數。
訂閱主題:/sys/ieojgBm5q2c/${deviceName}/thing/service/property/set(屬性設置主題)
發布主題:/sys/ieojgBm5q2c/${deviceName}/thing/event/property/post(上報消息主題)
注意:上面兩個主題中的${deviceName}需要替換成設備名。
3.連接、訂閱和發布消息
接著我們可以使用上面記錄的連接參數進行連接,當連接成功后,訂閱上面的訂閱主題。并通過發布主題上報物模型數據。
在阿里云平臺,如果產品創建階段選擇的數據格式為Alink JSON格式時,接收和發送數據格式都會遵守下面這個格式:
{ "method":"thing.event.property.post", "id":"2241348", "params":{ "prop_float":1.25, "prop_int16":4658, "prop_bool":1 }, "version":"1.0" }
method表示該消息的操作類型是上報設備屬性事件;id:值為"2241348",這是一個唯一的標識符;params是一個包含設備屬性數據的對象用于上報物模型數據;version:值為 "1.0",表示該消息所遵循的協議版本。
4.接收消息處理
接收消息:當接收到消息時,我們只需要按照上面的json格式進行解析,然后進行相應的處理即可。
10實現過程
接下來,我們看看在W55MH32上如何實現MQTT連接阿里云,并進行訂閱、發布消息以及接收消息處理。
注意:因為本示例需要訪問互聯網,請確保W55MH32的網絡環境及配置能夠正常訪問互聯網。
步驟1:注冊MQTT定時中斷函數MilliTimer_Handler()到1ms定時器中斷中
void TIM3_IRQHandler(void) { static uint32_t tim3_1ms_count = 0; if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { tim3_1ms_count++; MilliTimer_Handler(); if (tim3_1ms_count >= 1000) { DHCP_time_handler(); DNS_time_handler(); tim3_1ms_count = 0; } TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } }
步驟2:mqtt初始化
mqttconn mqtt_params = { .mqttHostUrl = "iot-06z00dbroeg8dx3.mqtt.iothub.aliyuncs.com", .server_ip = { 0, }, /*Define the Connection Server IP*/ .port = 1883, /*Define the connection service port number*/ .clientid = "ieojgBm5q2c.W55MH32|securemode=2,signmethod=hmacsha256,timestamp=1737098648080|", /*Define the client ID*/ .username = "W55MH32&ieojgBm5q2c", /*Define the user name*/ .passwd = "92c427a483f8bc09d20baf445505e319ae4d89ec94360710d23b8ab2f12c58c2", /*Define user passwords*/ .pubtopic = "/sys/ieojgBm5q2c/W55MH32/thing/event/property/post", /*Define the publication message*/ .subtopic = "/sys/ieojgBm5q2c/W55MH32/thing/service/property/set", /*Define subscription messages*/ .pubQoS = QOS0, /*Defines the class of service for publishing messages*/ }; /** * @brief Initializing the MQTT client side * * Initialize the MQTT client side with the given parameters, including network configuration and MQTT connection parameters. * * @param sn socket number * @param send_buf send buffer pointer * @param recv_buf recv buffer pointer */ void mqtt_init(uint8_t sn, uint8_t *send_buf, uint8_t *recv_buf) { wiz_NetInfo get_info = {0}; wizchip_getnetinfo(&get_info); /* DNS parsing */ if (do_dns(send_buf, (uint8_t *)mqtt_params.mqttHostUrl, mqtt_params.server_ip)) { while (1) { } } NewNetwork(&n, sn); /*Obtain network configuration information*/ ConnectNetwork(&n, mqtt_params.server_ip, mqtt_params.port); /*Connect to the MQTT server*/ MQTTClientInit(&c, &n, 1000, send_buf, MQTT_ETHERNET_MAX_SIZE, recv_buf, MQTT_ETHERNET_MAX_SIZE); data.will = willdata; data.willFlag = 0; /* will flag: If the will annotation bit is 0, the following will-related settings are invalid*/ willdata.qos = mqtt_params.willQoS; /* will QoS */ willdata.topicName.lenstring.data = mqtt_params.willtopic; /* will topic */ willdata.topicName.lenstring.len = strlen(willdata.topicName.lenstring.data); /* will topic len */ willdata.message.lenstring.data = mqtt_params.willmsg; /* will message */ willdata.message.lenstring.len = strlen(willdata.message.lenstring.data); /* will message len */ willdata.retained = 0; willdata.struct_version = 3; data.MQTTVersion = 4; data.clientID.cstring = mqtt_params.clientid; data.username.cstring = mqtt_params.username; data.password.cstring = mqtt_params.passwd; data.keepAliveInterval = 30; data.cleansession = 1; }
在這個函數中,需要傳入使用的socket號以及收發緩存數組。進入初始化函數后,首先會使用DNS解析MQTT服務器域名,然后進行MQTT參數初始化,將連接的參數填充到data結構體中,在這里需要注意的是,當data.willFlag=0時,則是關閉遺囑主題功能,反之則為開啟。
data結構體如下所示:
//data結構體 typedef struct { /** The eyecatcher for this structure. must be MQTC. */ char struct_id[4]; /** The version number of this structure. Must be 0 */ int struct_version; /** Version of MQTT to be used. 3 = 3.1 4 = 3.1.1 */ unsigned char MQTTVersion; MQTTString clientID; unsigned short keepAliveInterval; unsigned char cleansession; unsigned char willFlag; MQTTPacket_willOptions will; MQTTString username; MQTTString password; } MQTTPacket_connectData; //willdata結構體 /** * Defines the MQTT "Last Will and Testament" (LWT) settings for * the connect packet. */ typedef struct { /** The eyecatcher for this structure. must be MQTW. */ char struct_id[4]; /** The version number of this structure. Must be 0 */ int struct_version; /** The LWT topic to which the LWT message will be published. */ MQTTString topicName; /** The LWT payload. */ MQTTString message; /** * The retained flag for the LWT message (see MQTTAsync_message.retained). */ unsigned char retained; /** * The quality of service setting for the LWT message (see * MQTTAsync_message.qos and @ref qos). */ char qos; } MQTTPacket_willOptions;
步驟三:在主循環中執行do_mqtt()函數
void do_mqtt(void) { uint8_t ret; switch (run_status) { case CONN: { ret = MQTTConnect(&c, &data); /* Connect to the MQTT server */ printf("Connect to the MQTT server: %d.%d.%d.%d:%drn", mqtt_params.server_ip[0], mqtt_params.server_ip[1], mqtt_params.server_ip[2], mqtt_params.server_ip[3], mqtt_params.port); printf("Connected:%srnrn", ret == SUCCESSS ? "success" : "failed"); if (ret != SUCCESSS) { run_status = ERR; } else { run_status = SUB; } break; } case SUB: { ret = MQTTSubscribe(&c, mqtt_params.subtopic, mqtt_params.subQoS, messageArrived); /* Subscribe to Topics */ printf("Subscribing to %srn", mqtt_params.subtopic); printf("Subscribed:%srnrn", ret == SUCCESSS ? "success" : "failed"); if (ret != SUCCESSS) { run_status = ERR; } else { run_status = PUB_MESSAGE; } break; } case PUB_MESSAGE: { pubmessage.qos = QOS0; pubmessage.payload = "{"id":"123","version":"1.0","params":{"CurrentTemperature":26.6,},"method":"thing.event.property.post"}"; pubmessage.payloadlen = strlen(pubmessage.payload); ret = MQTTPublish(&c, (char *)&(mqtt_params.pubtopic), &pubmessage); /* Publish message */ if (ret != SUCCESSS) { run_status = ERR; } else { printf("publish:%s,%srnrn", mqtt_params.pubtopic, (char *)pubmessage.payload); run_status = KEEPALIVE; } break; } case KEEPALIVE: { if (MQTTYield(&c, 30) != SUCCESSS) /* keepalive MQTT */ { run_status = ERR; } } case RECV: { if (mqtt_recv_flag) { mqtt_recv_flag = 0; json_decode(mqtt_recv_msg); } break; } case ERR: /* Running error */ printf("system ERROR!"); delay_ms(1000); break; default: break; } }
do_mqtt()函數會執行一個狀態機,按照以下步驟進行工作:
CONN:執行連接操作,使用我們初始化好的參數使用MQTTConnect()函數去執行連接服務器操作,連接成功后進入訂閱主題步驟。
SUB:在這一步,我們會使用MQTTSubscribe()函數訂閱阿里云的物模型設置屬性主題,在這個函數中,需要傳入客戶端結構體,訂閱的主題名稱,訂閱的QoS等級,以及訂閱主題的回調函數messageArrived()。訂閱成功后進入發布消息步驟。
在收到訂閱主題的消息后,會執行回調函數messageArrived(),在這里我們打印出接收到的消息主題以及消息內容,并將消息拷貝到mqtt_recv_msg數組中,具體函數內容如下:
void TIM3_IRQHandler(void) { static uint32_t tim3_1ms_count = 0; if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { tim3_1ms_count++; MilliTimer_Handler(); if (tim3_1ms_count >= 1000) { DHCP_time_handler(); DNS_time_handler(); tim3_1ms_count = 0; } TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } }
PUB_MESSAGE:在這一步,我們會發布一個當前溫度到阿里云的物模型中。成功后進入保活和接收數據部分。
KEEPALIVE和RECV:在這一步,會不斷執行保活和監聽接收操作,當收到數據之后,會進入json_decode()函數進行處理。
json_decode()函數主要是使用CJSON將接收到的數據進行解析,然后執行對應的操作,具體內容如下:
void TIM3_IRQHandler(void) { static uint32_t tim3_1ms_count = 0; if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { tim3_1ms_count++; MilliTimer_Handler(); if (tim3_1ms_count >= 1000) { DHCP_time_handler(); DNS_time_handler(); tim3_1ms_count = 0; } TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } }
11運行結果
燒錄例程運行后,首先進行了PHY鏈路檢測,然后通過DHCP打印設置網絡信息,最后連接MQTT服務器進行回環測試,如下圖所示:
12總結
本文講解了如何在 W55MH32芯片上實現 MQTT協議并連接阿里云平臺,通過實戰例程展示了從準備工作、連接配置到消息訂閱、發布及接收處理的完整過程。文章詳細介紹了 MQTT協議的概念、特點、應用場景、發布 /訂閱模式、QoS級別,以及阿里云物聯網平臺和物模型相關知識,幫助讀者理解其在物聯網設備與云端數據交互中的實際應用價值。
下一篇文章將講解如何在W55MH32上實現MQTT協議并連接OneNET平臺,并實現與OneNET物模型的數據交互,敬請期待!
WIZnet是一家無晶圓廠半導體公司,成立于 1998年。產品包括互聯網處理器 iMCU?,它采用 TOE(TCP/IP卸載引擎)技術,基于獨特的專利全硬連線 TCP/IP。iMCU?面向各種應用中的嵌入式互聯網設備。
WIZnet在全球擁有 70多家分銷商,在香港、韓國、美國設有辦事處,提供技術支持和產品營銷。
香港辦事處管理的區域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。
審核編輯 黃宇
-
以太網
+關注
關注
41文章
5684瀏覽量
176252 -
物聯網
+關注
關注
2931文章
46306瀏覽量
393450 -
MQTT
+關注
關注
5文章
687瀏覽量
23744
發布評論請先 登錄
第二十二章 TIM——高級定時器

第二十二章 USB 全速設備接口(USB)

火力發電廠水汽分析方法 第二十二部分:化學耗氧量的測定(高錳
實時頻譜儀原理及操作指南
第二十二講 同步時序邏輯電路的分析方法

模擬電路網絡課件 第二十二節:功率放大電路的一般問題
第二章 W55MH32 DHCP示例

第九章 W55MH32 HTTP Server示例

第十二章 W55MH32 NetBIOS示例

第二十一章 W55MH32 PHY配置示例

第二十三章 W55MH32 MQTT_OneNET示例

第二十六章 W55MH32?上位機搜索和配置示例

第二十七章 W55MH32?Interrupt示例

第二十九章 W55MH32 Modbus_TCP_Server示例

第三十章 W55MH32 HTTP_Server&amp;NetBIOS示例

評論