一、前言
1.1 項(xiàng)目介紹
【1】項(xiàng)目功能
隨著全球農(nóng)業(yè)現(xiàn)代化進(jìn)程的加快,以及物聯(lián)網(wǎng)、人工智能等先進(jìn)技術(shù)的發(fā)展與應(yīng)用,智慧農(nóng)業(yè)已經(jīng)成為現(xiàn)代農(nóng)業(yè)發(fā)展的新趨勢(shì)?;诰珳?zhǔn)感知、智能控制和遠(yuǎn)程管理的智慧農(nóng)業(yè)系統(tǒng)能夠顯著提升農(nóng)作物生產(chǎn)效率,降低資源消耗,實(shí)現(xiàn)環(huán)境友好型可持續(xù)農(nóng)業(yè)生產(chǎn)。
在當(dāng)前背景下,我國(guó)正大力推進(jìn)數(shù)字鄉(xiāng)村建設(shè),智慧農(nóng)業(yè)管理系統(tǒng)作為其中的重要組成部分,對(duì)于提高農(nóng)業(yè)生產(chǎn)精細(xì)化管理水平,解決傳統(tǒng)農(nóng)業(yè)中信息獲取不及時(shí)、人工管理成本高、決策缺乏科學(xué)依據(jù)等問題具有重要作用。
本設(shè)計(jì)開發(fā)一套基于STM32F103RCT6主控芯片的智慧農(nóng)業(yè)管理系統(tǒng),通過集成DHT11溫濕度傳感器、BH1750光照強(qiáng)度傳感器以及土壤濕度檢測(cè)傳感器,實(shí)時(shí)監(jiān)測(cè)農(nóng)田環(huán)境和作物生長(zhǎng)狀態(tài),并在超出閾值時(shí)通過蜂鳴器報(bào)警,提醒管理人員進(jìn)行灌溉、施肥等操作。同時(shí),采用NBIoT通信技術(shù)(BC26模塊)將采集到的數(shù)據(jù)上傳至云端,利用EMQX開源MQTT服務(wù)器框架部署于華為云ECS服務(wù)器上的MQTT服務(wù)器,實(shí)現(xiàn)數(shù)據(jù)的遠(yuǎn)程展示與處理。
系統(tǒng)支持微信小程序遠(yuǎn)程控制功能,使得農(nóng)戶或管理者可以隨時(shí)隨地查看農(nóng)田環(huán)境參數(shù)、接收預(yù)警信息,并能遠(yuǎn)程手動(dòng)控制灌溉設(shè)備、補(bǔ)光燈等,大大提高了農(nóng)業(yè)生產(chǎn)的智能化和便捷性。此項(xiàng)目的實(shí)施不僅有助于推動(dòng)我國(guó)農(nóng)業(yè)信息化水平的提升,也有利于農(nóng)業(yè)資源的高效利用,對(duì)保障國(guó)家糧食安全、促進(jìn)農(nóng)業(yè)增效、農(nóng)民增收具有重要意義。
【2】設(shè)計(jì)實(shí)現(xiàn)的功能
(1)實(shí)時(shí)環(huán)境監(jiān)測(cè):系統(tǒng)通過集成的DHT11溫濕度傳感器、BH1750光照強(qiáng)度傳感器以及土壤濕度檢測(cè)傳感器,實(shí)時(shí)監(jiān)測(cè)農(nóng)田環(huán)境中的溫度、濕度、光照強(qiáng)度和土壤含水量等關(guān)鍵參數(shù)。當(dāng)這些參數(shù)超過或低于預(yù)設(shè)閾值時(shí),系統(tǒng)將自動(dòng)觸發(fā)蜂鳴器報(bào)警,提醒管理人員關(guān)注并采取相應(yīng)措施。
(2)自動(dòng)化管理與預(yù)警:根據(jù)土壤濕度傳感器檢測(cè)的數(shù)據(jù),如果土壤濕度低于設(shè)定的適宜作物生長(zhǎng)的含水量閥值,則系統(tǒng)會(huì)自動(dòng)提醒管理者進(jìn)行灌溉操作。同時(shí),可以按照預(yù)設(shè)周期發(fā)送施肥提醒,以確保農(nóng)作物在最佳時(shí)期得到充足的水分和養(yǎng)分供應(yīng)。
(3)遠(yuǎn)程控制功能:利用NBIoT通信技術(shù)(BC26模塊)將現(xiàn)場(chǎng)采集到的各項(xiàng)數(shù)據(jù)上傳至云端MQTT服務(wù)器,并通過微信小程序?qū)崿F(xiàn)遠(yuǎn)程訪問和展示。用戶可以通過微信小程序查看實(shí)時(shí)監(jiān)測(cè)數(shù)據(jù),以及對(duì)農(nóng)田設(shè)備進(jìn)行遠(yuǎn)程手動(dòng)控制,如啟動(dòng)或關(guān)閉5V抽水泵進(jìn)行灌溉,開啟或關(guān)閉白色LED補(bǔ)光燈調(diào)節(jié)光照條件。
(4)數(shù)據(jù)上云與分析:基于EMQX開源MQTT服務(wù)器框架搭建的MQTT服務(wù)器,能夠接收并處理STM32主控板傳輸?shù)霓r(nóng)業(yè)環(huán)境數(shù)據(jù),并對(duì)接微信小程序平臺(tái),為用戶提供直觀易懂的數(shù)據(jù)圖表和分析結(jié)果,便于農(nóng)戶或農(nóng)業(yè)技術(shù)人員進(jìn)行科學(xué)決策和精準(zhǔn)管理。
【3】項(xiàng)目硬件模塊組成
(1)主控模塊: 采用STM32F103RCT6微控制器作為核心控制單元,負(fù)責(zé)整個(gè)系統(tǒng)的運(yùn)行和管理。STM32F103RCT6具有豐富的外設(shè)接口、強(qiáng)大的處理能力和低功耗特性,能夠?qū)崟r(shí)處理傳感器數(shù)據(jù)、執(zhí)行邏輯判斷,并通過無線通信模塊發(fā)送和接收指令。
(2)環(huán)境監(jiān)測(cè)模塊:
- 溫濕度監(jiān)測(cè):使用DHT11溫濕度傳感器采集農(nóng)田環(huán)境的溫度和濕度信息。
- 光照強(qiáng)度監(jiān)測(cè):采用BH1750光照強(qiáng)度傳感器測(cè)量農(nóng)田的光照強(qiáng)度。
- 土壤濕度檢測(cè):使用土壤濕度檢測(cè)傳感器獲取作物生長(zhǎng)區(qū)域的土壤含水量數(shù)據(jù)。
(3)控制輸出模塊:
- 補(bǔ)光燈控制:配置白色LED燈作為補(bǔ)光光源,根據(jù)光照強(qiáng)度監(jiān)測(cè)結(jié)果,通過STM32主控板進(jìn)行智能調(diào)節(jié)或遠(yuǎn)程手動(dòng)控制。
- 灌溉系統(tǒng)控制:采用5V抽水泵配合繼電器實(shí)現(xiàn)灌溉功能,當(dāng)土壤濕度低于預(yù)設(shè)閾值時(shí),STM32主控板將控制繼電器閉合,啟動(dòng)抽水泵進(jìn)行灌溉;反之則停止灌溉。
(4)無線通信模塊: 集成NBIoT-BC26模塊,實(shí)現(xiàn)與云端服務(wù)器的數(shù)據(jù)交互。該模塊具備廣覆蓋、低功耗、大連接的特點(diǎn),可確保在各種復(fù)雜農(nóng)業(yè)環(huán)境中穩(wěn)定地傳輸數(shù)據(jù)至MQTT服務(wù)器。
(5)報(bào)警模塊: 系統(tǒng)配備蜂鳴器用于異常情況報(bào)警,當(dāng)環(huán)境參數(shù)超出設(shè)定范圍時(shí),主控板會(huì)驅(qū)動(dòng)蜂鳴器發(fā)出聲音警報(bào)。
1.2 設(shè)計(jì)思路
(1)系統(tǒng)需求分析:根據(jù)智慧農(nóng)業(yè)管理的實(shí)際需求,確定需要監(jiān)測(cè)的關(guān)鍵環(huán)境參數(shù)(溫度、濕度、光照強(qiáng)度和土壤濕度),以及必要的控制功能(灌溉、補(bǔ)光燈控制等)。同時(shí)考慮遠(yuǎn)程監(jiān)控與預(yù)警的需求,規(guī)劃通過NBIoT通信技術(shù)實(shí)現(xiàn)數(shù)據(jù)上傳及遠(yuǎn)程操控。
(2)硬件選型與設(shè)計(jì):
- 主控芯片選擇STM32F103RCT6,因其具有豐富的外設(shè)接口、強(qiáng)大的處理能力和低功耗特性,能夠滿足系統(tǒng)實(shí)時(shí)數(shù)據(jù)采集與控制的要求。
- 選用DHT11作為溫濕度傳感器,BH1750作為光照強(qiáng)度傳感器,以及土壤濕度檢測(cè)傳感器,分別獲取農(nóng)田環(huán)境的基本信息。
- 設(shè)計(jì)灌溉系統(tǒng),使用5V抽水泵配合繼電器控制灌溉,以響應(yīng)土壤濕度的監(jiān)測(cè)結(jié)果。
- 采用白色LED燈作為補(bǔ)光光源,并接入主控板進(jìn)行智能調(diào)節(jié)或遠(yuǎn)程控制。
- 配備蜂鳴器用于異常情況報(bào)警。
- 選用NBIoT-BC26模塊確保無線通信穩(wěn)定可靠,實(shí)現(xiàn)數(shù)據(jù)上云。
(3)軟件架構(gòu)設(shè)計(jì):
- 開發(fā)STM32的嵌入式軟件程序,負(fù)責(zé)讀取各傳感器數(shù)據(jù),執(zhí)行邏輯判斷,如環(huán)境參數(shù)超限時(shí)觸發(fā)報(bào)警、根據(jù)土壤濕度自動(dòng)或手動(dòng)控制灌溉、周期性提醒施肥等操作。
- 實(shí)現(xiàn)NBIoT通信協(xié)議棧,將現(xiàn)場(chǎng)采集的數(shù)據(jù)通過BC26模塊發(fā)送至云端MQTT服務(wù)器。
- 在云端部署EMQX開源MQTT服務(wù)器框架,接收并存儲(chǔ)前端設(shè)備發(fā)送的數(shù)據(jù)。
- 開發(fā)微信小程序客戶端,對(duì)接MQTT服務(wù)器,展示農(nóng)田環(huán)境的各項(xiàng)實(shí)時(shí)監(jiān)測(cè)數(shù)據(jù),提供遠(yuǎn)程手動(dòng)控制界面。
1.3 傳感器功能介紹
(1)DHT11溫濕度傳感器:
- 功能:用于實(shí)時(shí)監(jiān)測(cè)農(nóng)田環(huán)境中的溫度和相對(duì)濕度。
- 特點(diǎn):DHT11是一種低成本、低功耗的數(shù)字式溫濕度復(fù)合傳感器,提供了一體化的解決方案。它能夠直接輸出經(jīng)過校準(zhǔn)的數(shù)字信號(hào),便于微處理器直接讀取,無需復(fù)雜的信號(hào)處理電路。
(2)BH1750光照強(qiáng)度傳感器:
- 功能:測(cè)量農(nóng)田或溫室內(nèi)的光照強(qiáng)度(照度),以判斷當(dāng)前光照條件是否滿足作物生長(zhǎng)需求。
- 特點(diǎn):BH1750是一款I(lǐng)2C接口的數(shù)字光照強(qiáng)度傳感器,具有高精度和寬量程的特點(diǎn),可精確檢測(cè)光照強(qiáng)度,并支持多種分辨率模式切換以適應(yīng)不同的應(yīng)用場(chǎng)景。
(3)土壤濕度檢測(cè)傳感器:
- 功能:用于監(jiān)測(cè)種植區(qū)域土壤的水分含量,作為決定灌溉與否的重要依據(jù)。
- 特點(diǎn):這類傳感器通常采用電容式、電阻式或者頻域反射(FDR)等原理來檢測(cè)土壤濕度,通過轉(zhuǎn)換為電信號(hào)變化,從而實(shí)現(xiàn)對(duì)土壤含水量的非破壞性測(cè)定。其特點(diǎn)是能反映土壤實(shí)際濕潤(rùn)狀況,幫助實(shí)現(xiàn)精準(zhǔn)灌溉。
(4)蜂鳴器報(bào)警模塊:
- 功能:雖然不是傳統(tǒng)意義上的傳感器,但在本系統(tǒng)中作為報(bào)警裝置使用,當(dāng)環(huán)境參數(shù)超出預(yù)設(shè)閾值時(shí),由主控芯片STM32控制蜂鳴器發(fā)出聲音警報(bào),提醒管理人員及時(shí)處理異常情況。
(5)5V抽水泵與繼電器組合:
- 功能:抽水泵與繼電器配合實(shí)現(xiàn)灌溉功能,繼電器根據(jù)土壤濕度傳感器的數(shù)據(jù)反饋控制抽水泵的開關(guān)狀態(tài),達(dá)到智能灌溉的目的。
- 特點(diǎn):繼電器作為電子開關(guān),可以遠(yuǎn)程控制大電流設(shè)備如抽水泵的通斷,實(shí)現(xiàn)小電流控制大電流,同時(shí)隔離了主控制器與負(fù)載之間的電氣連接,提高了系統(tǒng)的安全性。
(6)NBIoT-BC26模塊:
- 功能:作為物聯(lián)網(wǎng)通信組件,負(fù)責(zé)將采集到的各種數(shù)據(jù)無線傳輸至云端服務(wù)器,同時(shí)也接收來自云端的控制指令,實(shí)現(xiàn)遠(yuǎn)程數(shù)據(jù)交互和控制。
- 特點(diǎn):NBIoT(窄帶物聯(lián)網(wǎng))技術(shù)具有低功耗、廣覆蓋、大連接的優(yōu)點(diǎn),特別適合于智慧農(nóng)業(yè)這種需要大面積部署且網(wǎng)絡(luò)連接要求穩(wěn)定的場(chǎng)景。BC26模塊是基于NBIoT標(biāo)準(zhǔn)的通信模塊,具備良好的網(wǎng)絡(luò)兼容性和穩(wěn)定性。
1.4 開發(fā)工具的選擇
STM32的編程語(yǔ)言選擇C語(yǔ)言,C語(yǔ)言執(zhí)行效率高,大學(xué)里主學(xué)的C語(yǔ)言,C語(yǔ)言編譯出來的可執(zhí)行文件最接近于機(jī)器碼,匯編語(yǔ)言執(zhí)行效率最高,但是匯編的移植性比較差,目前在一些操作系統(tǒng)內(nèi)核里還有一些低配的單片機(jī)使用的較多,平常的單片機(jī)編程還是以C語(yǔ)言為主。C語(yǔ)言的執(zhí)行效率僅次于匯編,語(yǔ)法理解簡(jiǎn)單、代碼通用性強(qiáng),也支持跨平臺(tái),在嵌入式底層、單片機(jī)編程里用的非常多,當(dāng)前的設(shè)計(jì)就是采用C語(yǔ)言開發(fā)。
開發(fā)工具選擇Keil,keil是一家世界領(lǐng)先的嵌入式微控制器軟件開發(fā)商,在2015年,keil被ARM公司收購(gòu)。因?yàn)楫?dāng)前芯片選擇的是STM32F103系列,STMF103是屬于ARM公司的芯片構(gòu)架、Cortex-M3內(nèi)核系列的芯片,所以使用Kile來開發(fā)STM32是有先天優(yōu)勢(shì)的,而keil在各大高校使用的也非常多,很多教科書里都是以keil來教學(xué),開發(fā)51單片機(jī)、STM32單片機(jī)等等。目前作為MCU芯片開發(fā)的軟件也不只是keil一家獨(dú)大,IAR在MCU微處理器開發(fā)領(lǐng)域里也使用的非常多,IAR擴(kuò)展性更強(qiáng),也支持STM32開發(fā),也支持其他芯片,比如:CC2530,51單片機(jī)的開發(fā)。從軟件的使用上來講,IAR比keil更加簡(jiǎn)潔,功能相對(duì)少一些。如果之前使用過keil,而且使用頻率較多,已經(jīng)習(xí)慣再使用IAR是有點(diǎn)不適應(yīng)界面的。
二、EMQX開源MQTT服務(wù)器框架
EMQX是一款開源的、云原生的分布式物聯(lián)網(wǎng)MQTT消息服務(wù)器,設(shè)計(jì)目標(biāo)是實(shí)現(xiàn)高可靠性,并支持承載海量物聯(lián)網(wǎng)終端的MQTT連接,以及在海量物聯(lián)網(wǎng)設(shè)備間實(shí)現(xiàn)低延時(shí)消息路由?;贓rlang/OTP平臺(tái)開發(fā),充分利用了Erlang/OTP的軟實(shí)時(shí)、低延時(shí)和分布式特性。
以下是EMQX服務(wù)器框架的詳細(xì)介紹:
(1)可擴(kuò)展性:EMQX支持億級(jí)的MQTT服務(wù)訂閱,單節(jié)點(diǎn)能夠支持500萬MQTT設(shè)備連接,集群可擴(kuò)展至1億并發(fā)MQTT連接。這種強(qiáng)大的擴(kuò)展能力使其能夠適應(yīng)不同規(guī)模的物聯(lián)網(wǎng)應(yīng)用。
(2)安全性:EMQX提供了多種安全機(jī)制,包括SSL/TLS、密碼認(rèn)證、增強(qiáng)認(rèn)證和ACL(訪問控制列表)等,以保障數(shù)據(jù)傳輸和訪問的安全性。
(3)規(guī)則引擎:EMQX內(nèi)置了基于SQL的規(guī)則引擎,能夠?qū)崟r(shí)過濾、轉(zhuǎn)換和處理消息,提供靈活的消息處理機(jī)制。這使得應(yīng)用程序能夠根據(jù)業(yè)務(wù)需求對(duì)消息進(jìn)行靈活處理。
(4)數(shù)據(jù)存儲(chǔ):EMQX企業(yè)版還提供了數(shù)據(jù)存儲(chǔ)功能,將客戶端上下線狀態(tài)、訂閱關(guān)系、離線消息、消息內(nèi)容以及消息回執(zhí)等操作記錄到各種數(shù)據(jù)庫(kù)中。這一功能在服務(wù)崩潰或客戶端異常離線后,能夠保留數(shù)據(jù),確保數(shù)據(jù)的完整性和可靠性。
(5)集群設(shè)計(jì):EMQX采用Masterless的大規(guī)模分布式集群架構(gòu),實(shí)現(xiàn)了系統(tǒng)的高可用性和水平擴(kuò)展。集群設(shè)計(jì)包括維護(hù)訂閱表、路由表和主題樹等數(shù)據(jù)結(jié)構(gòu),以實(shí)現(xiàn)消息轉(zhuǎn)發(fā)和投遞給各節(jié)點(diǎn)上的訂閱者。
(6)協(xié)議支持:EMQX完全支持MQTT 5.0和3.x協(xié)議標(biāo)準(zhǔn),提供了更好的伸縮性、安全性和可靠性。同時(shí),它還提供了對(duì)多種其他協(xié)議的支持,如WebSocket、TCP、SSL/TLS等。
(7)易用性:EMQX提供了豐富的API和插件管理功能,使得用戶可以方便地查看在線客戶端信息、踢出客戶端、管理插件狀態(tài)等。它還提供了可視化的管理界面和調(diào)試工具,方便用戶進(jìn)行監(jiān)控和管理。
三、購(gòu)買ECS云服務(wù)器
3.1 登錄官網(wǎng)
https://www.huaweicloud.com/
3.2 購(gòu)買ECS服務(wù)器
【1】選擇ECS彈性服務(wù)器
【2】選擇ECS服務(wù)器的區(qū)域、配置信息、操作系統(tǒng)(我選擇的Ubuntu18.04 64位)。
【3】購(gòu)買彈性公網(wǎng)IP,配置帶寬。
【4】配置密碼
【5】選擇購(gòu)買時(shí)長(zhǎng),我這里選擇了1個(gè)月時(shí)長(zhǎng)
【6】確認(rèn)付費(fèi)付款
收到郵件提醒,服務(wù)器創(chuàng)建成功。 (為了寫教程,花費(fèi)320元,買了一個(gè)月服務(wù)器)
【7】返回彈性服務(wù)器的控制臺(tái)
【8】點(diǎn)擊服務(wù)器名字,可以進(jìn)入到詳情頁(yè)面。
3.3 配置安全組
要確保MQTT服務(wù)器常用的幾個(gè)端口已經(jīng)開放出出來。
3.4 安裝FinalShell
Windows下安裝 FinalShell 終端,方便使用SSH協(xié)議遠(yuǎn)程登錄到云服務(wù)器。 (當(dāng)然,使用其他方式登錄也是一樣的)
3.5 遠(yuǎn)程登錄到云服務(wù)器終端
【1】新建連接,選擇SSH連接。
【2】填入IP地址、用戶名、密碼
這里的主機(jī)就是填服務(wù)器的公網(wǎng)IP地址,密碼就是創(chuàng)建服務(wù)器輸入的密碼,用戶名直接用root。
【3】點(diǎn)擊連接服務(wù)器
【4】第一次登錄會(huì)彈出提示框,選擇接受并保存
【5】接下來可以看到服務(wù)器已經(jīng)登錄成功了。
四、Linux下安裝EMQX
本章節(jié)將介紹如何在 Ubuntu 系統(tǒng)中下載安裝并啟動(dòng) EMQX。
支持的 Ubuntu 版本:
- Ubuntu 22.04
- Ubuntu 20.04
- Ubuntu 18.04
4.1 官網(wǎng)地址
鏈接:https://www.emqx.io/docs/zh/v5.2/deploy/install-ubuntu.html
4.2 通過Apt源安裝
EMQX 支持通過 Apt 源安裝,免除了用戶需要手動(dòng)處理依賴關(guān)系和更新軟件包等的困擾,具有更加方便、安全和易用等優(yōu)點(diǎn)。
在命令行終端,復(fù)制下面的命令過去,按下回車鍵。
【1】通過以下命令配置 EMQX Apt 源:
curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash
【2】運(yùn)行以下命令安裝 EMQX:
sudo apt-get install emqx
【3】運(yùn)行以下命令啟動(dòng) EMQX:
sudo systemctl start emqx
過程如下:
4.3 EMQX常用的命令
sudo systemctl emqx start 啟動(dòng)
sudo systemctl emqx stop 停止
sudo systemctl emqx restart 重啟
五、配置EMQX服務(wù)器
5.1 登錄EMQX內(nèi)置管理控制臺(tái)
EMQX 提供了一個(gè)內(nèi)置的管理控制臺(tái),即 EMQX Dashboard。方便用戶通過 Web 頁(yè)面就能輕松管理和監(jiān)控 EMQX 集群,并配置和使用所需的各項(xiàng)功能。
在瀏覽器里輸入: http://122.112.225.194:18083
就可以訪問EMQX的后臺(tái)管理頁(yè)面??梢怨芾硪赃B接的客戶端或檢查運(yùn)行狀態(tài)。
這里面的IP地址,就是自己ECS云服務(wù)器的公網(wǎng)IP地址。
打開瀏覽器后,輸入地址后打開的效果:
默認(rèn)用戶名和密碼:
用戶名:admin
密碼:public
第一次登錄會(huì)提示你修改新密碼,如果不想設(shè)置,也可以選擇跳過(公網(wǎng)服務(wù)器部署,還是要修改密碼安全些)。
下面修改新密碼:
登錄成功的頁(yè)面顯示如下:
5.2 MQTT配置
這里可以配置MQTT的一些參數(shù),根據(jù)自己的需求進(jìn)行配置。
5.3 測(cè)試MQTT通信
新建一個(gè)客戶端,點(diǎn)擊連接。
連接之后,然后點(diǎn)擊訂閱,和發(fā)布,如果下面消息能正常的接收。說明MQTT服務(wù)器通信是已經(jīng)正常,沒問題了。
并且在這個(gè)頁(yè)面也可以看到主題發(fā)布
和主題訂閱
的格式。
5.4 MQTT客戶端登錄服務(wù)器測(cè)試
接下來就打開我們自己的MQTT客戶端登錄MQTT服務(wù)器進(jìn)行測(cè)試數(shù)據(jù)的通信。
端口選擇: 1883
根據(jù)軟件參數(shù)填入?yún)?shù),登錄,進(jìn)行主題的發(fā)布和訂閱。
說明: 目前還沒有配置客戶端認(rèn)證,現(xiàn)在只要IP和端口輸入正確,MQTT三元組可以隨便輸入,都可以登錄上服務(wù)器的,服務(wù)器沒有對(duì)三元組做校驗(yàn)。
EMQ X 默認(rèn)配置中啟用了匿名認(rèn)證,任何客戶端都能接入 EMQX。沒有啟用認(rèn)證插件或認(rèn)證插件沒有顯式允許/拒絕(ignore)連接請(qǐng)求時(shí),EMQX 將根據(jù)匿名認(rèn)證啟用情況決定是否允許客戶端連接。
然后打開EMQX
的管理后臺(tái),可以看到我們的設(shè)備已經(jīng)登錄服務(wù)器了,名字為test1
。
在訂閱主題的頁(yè)面也可以看到我們客戶端設(shè)備訂閱的主題。
5.5 客戶端認(rèn)證配置
EMQX 默認(rèn)配置中啟用了匿名認(rèn)證,任何客戶端都能接入 EMQX。沒有啟用認(rèn)證插件或認(rèn)證插件沒有顯式允許/拒絕(ignore)連接請(qǐng)求時(shí),EMQX 將根據(jù)匿名認(rèn)證啟用情況決定是否允許客戶端連接。
在正式產(chǎn)品里肯定是要啟用認(rèn)證的,不然任何設(shè)備都能接入。
下面就介紹如何配置 客戶端認(rèn)證。
【1】打開客戶端認(rèn)證頁(yè)面
【2】選擇密碼認(rèn)證
【3】選擇內(nèi)置數(shù)據(jù)庫(kù)
【4】設(shè)置認(rèn)證方式(都可以默認(rèn),不用改),直接點(diǎn)擊創(chuàng)建。
【5】創(chuàng)建成功后,點(diǎn)擊用戶管理
【6】添加用戶
【7】添加成功
【8】添加完畢之后,打開MQTT客戶端可以進(jìn)行測(cè)試。
登錄的時(shí)候,MQTT用戶名和密碼必須輸入正確,按照上一步添加的信息進(jìn)行如實(shí)填寫,否則是無法登錄服務(wù)器的。
5.6 客戶端授權(quán)配置
客戶端授權(quán)頁(yè)面可以配置每個(gè)客戶端(設(shè)備)的主題發(fā)布,訂閱權(quán)限。限制它是否可以發(fā)布主題,訂閱主題。 如果有需要就可以進(jìn)行配置。
http://127.0.0.1:18083/#/authorization/detail/built_in_database?tab=users
【1】創(chuàng)建數(shù)據(jù)源
【2】選擇內(nèi)置數(shù)據(jù)庫(kù)
【3】完成創(chuàng)建
【4】點(diǎn)擊權(quán)限管理
【5】選擇客戶端ID,點(diǎn)擊添加
【6】配置權(quán)限
5.7 數(shù)據(jù)轉(zhuǎn)發(fā)(集成)
在集成選項(xiàng)里,可以對(duì)設(shè)備數(shù)據(jù)處理。 比如:轉(zhuǎn)發(fā)到自己的HTTP服務(wù)器,轉(zhuǎn)發(fā)到自己其他的MQTT服務(wù)器,創(chuàng)建規(guī)則,某些事件觸發(fā)某些動(dòng)作等等。
選擇數(shù)據(jù)橋接。
可以把數(shù)據(jù)發(fā)送端自己的HTTP服務(wù)器,或者發(fā)送到其他的MQTT服務(wù)器。
選擇HTTP服務(wù) (如果自己有HTTP服務(wù)器,可以將數(shù)據(jù)轉(zhuǎn)發(fā)給自己的HTTP服務(wù)器)。
七、MQTT客戶端消息互發(fā)測(cè)試
7.1 添加2個(gè)設(shè)備
為了方便測(cè)試設(shè)備間互相訂閱主題,數(shù)據(jù)收發(fā),在客戶端認(rèn)證頁(yè)面至少添加2個(gè)設(shè)備。我這里分別添加了test1
和test2
。
7.2 設(shè)備間測(cè)試
設(shè)備A訂閱設(shè)備B的主題,設(shè)備B訂閱設(shè)備A的主題,實(shí)現(xiàn)數(shù)據(jù)互發(fā)。
設(shè)備A的MQTT信息:
MQTT服務(wù)器地址:122.112.225.194
MQTT服務(wù)器端口號(hào):1883
MQTT客戶端ID:AAA
MQTT用戶名:test1
MQTT登錄密碼:12345678
訂閱主題:BBB/#
發(fā)布主題:AAA/1
發(fā)布的消息:{ "msg": "我是AAA設(shè)備" }
設(shè)備B的MQTT信息:
MQTT服務(wù)器地址:122.112.225.194
MQTT服務(wù)器端口號(hào):1883
MQTT客戶端ID:BBB
MQTT用戶名:test2
MQTT登錄密碼:12345678
訂閱主題:AAA/#
發(fā)布主題:BBB/1
發(fā)布的消息:{ "msg": "我是BBB設(shè)備" }
八、STM32硬件端開發(fā)
8.1 BC26模塊的AT指令調(diào)試過程
BC20/BC26 開啟GPS、連接MQTT服務(wù)器的AT指令發(fā)送流程。
(1)查詢模塊是否正常
AT
OK
(2)獲取卡號(hào),查詢卡是否插好
AT+CIMI
460041052911195
OK
(3)激活網(wǎng)絡(luò)
AT+CGATT=1
OK
(4)獲取網(wǎng)絡(luò)激活狀態(tài)
AT+CGATT?
+CGATT: 1
OK
(5)查詢網(wǎng)絡(luò)質(zhì)量
AT+CSQ
+CSQ: 26,0
OK
(6)檢查網(wǎng)絡(luò)狀態(tài)
AT+CEREG=? //檢查網(wǎng)絡(luò)狀態(tài)
+CEREG: 0,1 //找網(wǎng)成功
OK
(7)激活GPS
激活GPS,要等一段時(shí)間
AT+QGNSSC=1
OK
(8)查詢GPS激活狀態(tài)
查詢激活狀態(tài),1表示成功激活
AT+QGNSSC?
+QGNSSC: 1
OK
(9)獲取一次GPS定位語(yǔ)句
AT+QGNSSRD="NMEA/RMC"
+QGNSSRD: $GNRMC,120715.00,A,3150.78179,N,11711.93433,E,0.000,,310818,,,A,V*19
OK
(10)連接MQTT服務(wù)器
AT+QMTOPEN=0,"a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com",1883
OK
+QMTOPEN: 0,0
(11)登錄MQTT服務(wù)器
命令格式: AT+QMTCONN=<tcpconnectID>,<clientID>,<username>,<password>
AT+QMTCONN=0,"6210e8acde9933029be8facf_dev1_0_0_2022021913","6210e8acde9933029be8facf_dev1","6cea55404b463e666cd7a6060daba745bbaa17fe7078dfef45f8151cdf19673d"
OK
+QMTCONN: 0,0,0
(12)訂閱主題
命令格式: AT+QMTSUB=<tcpconnectID>,<msgID>,"<topic1>”,<qos1>[,"<topic2>”,<qos2>…]
AT+QMTSUB=0,1,"$oc/devices/6210e8acde9933029be8facf_dev1/sys/messages/down",2
OK
+QMTSUB: 0,1,0,2
(13)發(fā)布主題
命令格式:AT+QMTPUB=<tcpconnectID>,<msgID>,<qos>,<retain>,"<topic>","<msg>"
先發(fā)送指令:
AT+QMTPUB=0,0,0,0,"$oc/devices/6210e8acde9933029be8facf_dev1/sys/properties/repor"
等待返回 ">"
接著發(fā)送數(shù)據(jù).不需要加回車。
"{"services": [{"service_id": "gps","properties":{"longitude":12.345,"latitude":33.345}}]}"
數(shù)據(jù)發(fā)送完畢,再發(fā)送結(jié)束符。 十六進(jìn)制的值--0x1a 。某些串口調(diào)試助手可以適應(yīng)ctrl+z 快捷鍵輸入0xA
等待模塊返回"OK",到此數(shù)據(jù)發(fā)送完成。
OK
+QMTPUB: 0,0,0
8.2 BH1750傳感器
下面貼出的是BH1750核心讀取代碼,因?yàn)锽H1750本身就是標(biāo)準(zhǔn)的IIC協(xié)議,下面就不貼出IIC協(xié)議了,直接貼出封裝讀取光敏信息的代碼。
#include "bh1750.h"
float Read_BH1750_Data()
{
unsigned char t0;
unsigned char t1;
float t;
u8 r_s=0;
IIC_Start(); //發(fā)送起始信號(hào)
IIC_WriteOneByteData(0x46);
r_s=IIC_GetACK();//獲取應(yīng)答
if(r_s)printf("error:1rn");
IIC_WriteOneByteData(0x01);
r_s=IIC_GetACK();//獲取應(yīng)答
if(r_s)printf("error:2rn");
IIC_Stop(); //停止信號(hào)
IIC_Start(); //發(fā)送起始信號(hào)
IIC_WriteOneByteData(0x46);
r_s=IIC_GetACK();//獲取應(yīng)答
if(r_s)printf("error:3rn");
IIC_WriteOneByteData(0x01);
r_s=IIC_GetACK();//獲取應(yīng)答
if(r_s)printf("error:4rn");
IIC_Stop(); //停止信號(hào)
IIC_Start(); //發(fā)送起始信號(hào)
IIC_WriteOneByteData(0x46);
r_s=IIC_GetACK();//獲取應(yīng)答
if(r_s)printf("error:5rn");
IIC_WriteOneByteData(0x10);
r_s=IIC_GetACK();//獲取應(yīng)答
if(r_s)printf("error:6rn");
IIC_Stop(); //停止信號(hào)
DelayMs(100); //等待
IIC_Start(); //發(fā)送起始信號(hào)
IIC_WriteOneByteData(0x47);
r_s=IIC_GetACK();//獲取應(yīng)答
if(r_s)printf("error:7rn");
t0=IIC_ReadOneByteData(); //接收數(shù)據(jù)
IIC_SendACK(0); //發(fā)送應(yīng)答信號(hào)
t1=IIC_ReadOneByteData(); //接收數(shù)據(jù)
IIC_SendACK(1); //發(fā)送非應(yīng)答信號(hào)
IIC_Stop(); //停止信號(hào)
t=(((t0<<8)|t1)/1.2);
return t;
}
8.3 DHT11溫濕度模塊
下面貼出的是 DHT11 溫濕度傳感器驅(qū)動(dòng)代碼。
#include "dht11.h"
#include "delay.h"
//復(fù)位DHT11
void DHT11_Rst(void)
{
DHT11_IO_OUT(); //SET OUTPUT
DHT11_DQ_OUT=0; //拉低DQ
DelayMs(20); //拉低至少18ms
DHT11_DQ_OUT=1; //DQ=1
DelayUs(30); //主機(jī)拉高20~40us
}
//等待DHT11的回應(yīng)
//返回1:未檢測(cè)到DHT11的存在
//返回0:存在
u8 DHT11_Check(void)
{
u8 retry=0;
DHT11_IO_IN();//SET INPUT
while (DHT11_DQ_IN&&retry<100)//DHT11會(huì)拉低40~80us
{
retry++;
DelayUs(1);
};
if(retry>=100)return 1;
else retry=0;
while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后會(huì)再次拉高40~80us
{
retry++;
DelayUs(1);
};
if(retry>=100)return 1;
return 0;
}
//從DHT11讀取一個(gè)位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{
u8 retry=0;
while(DHT11_DQ_IN&&retry<100)//等待變?yōu)榈?a class="article-link" target="_blank" href="/baike/1465710.html">電平
{
retry++;
DelayUs(1);
}
retry=0;
while(!DHT11_DQ_IN&&retry<100)//等待變高電平
{
retry++;
DelayUs(1);
}
DelayUs(40);//等待40us
if(DHT11_DQ_IN)return 1;
else return 0;
}
//從DHT11讀取一個(gè)字節(jié)
//返回值:讀到的數(shù)據(jù)
u8 DHT11_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT11_Read_Bit();
}
return dat;
}
//從DHT11讀取一次數(shù)據(jù)
//temp:溫度值(范圍:0~50°)
//humi:濕度值(范圍:20%~90%)
//返回值:0,正常;1,讀取失敗
u8 DHT11_Read_Data(u8 *temp,u8 *humi)
{
u8 buf[5];
u8 i;
DHT11_Rst();
//printf("------------------------rn");
if(DHT11_Check()==0)
{
for(i=0;i<5;i++)//讀取40位數(shù)據(jù)
{
buf[i]=DHT11_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humi=buf[0];
*temp=buf[2];
}
}else return 1;
return 0;
}
//初始化DHT11的IO口 DQ 同時(shí)檢測(cè)DHT11的存在
//返回1:不存在
//返回0:存在
u8 DHT11_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA口時(shí)鐘
GPIOA->CRL&=0XFF0FFFFF;//PORTA.5 推挽輸出
GPIOA->CRL|=0X00300000;
GPIOA->ODR|=1<<5; //輸出1
DHT11_Rst();
return DHT11_Check();
}
8.4 土壤濕度傳感器
通過 ADC 模塊讀取土壤濕度代碼:
#include "stm32f1xx_hal.h"
#include "stdio.h"
ADC_HandleTypeDef hadc1;
UART_HandleTypeDef huart1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_ADC1_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_ADC1_Init();
uint16_t adc_value;
while (1)
{
HAL_ADC_Start(&hadc1); // 啟動(dòng) ADC 轉(zhuǎn)換
if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK)
{
adc_value = HAL_ADC_GetValue(&hadc1); // 讀取 ADC 值
char buffer[50];
sprintf(buffer, "Soil Moisture: %drn", adc_value);
HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY); // 通過串口打印土壤濕度數(shù)據(jù)
}
HAL_Delay(1000); // 延時(shí)1秒
}
}
void SystemClock_Config(void)
{
// 略,根據(jù)實(shí)際情況配置系統(tǒng)時(shí)鐘
}
static void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_0; // 修改為實(shí)際連接的通道
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5; // 根據(jù)實(shí)際情況調(diào)整采樣時(shí)間
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
void Error_Handler(void)
{
while (1)
{
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif
8.5 硬件連線
硬件連接方式:
1. TFT 1.44 寸彩屏接線
GND 電源地
VCC 接5V或3.3v電源
SCL 接PC8(SCL)
SDA 接PC9(SDA)
RST 接PC10
DC 接PB7
CS 接PB8
BL 接PB11
2. 板載LED燈接線
LED1---PA8
LED2---PD2 (被串口占用)
3. 板載按鍵接線
K0---PA0
K1---PC5
K2---PA15
4. ESP8266--WiFi模塊
ATK-ESP8266串口WIFI模塊與STM32的串口2相連接。
PA2(TX)--RXD 模塊接收腳
PA3(RX)--TXD 模塊發(fā)送腳
GND---GND 地
VCC---VCC 電源(3.3V~5.0V)
5. 環(huán)境光檢測(cè)檢測(cè):BH1750數(shù)字傳感器
SDA-----PB7
SCL-----PB6
GND---GND 地
VCC---VCC 電源(3.3V~5.0V)
6. 溫濕度傳感器: DHT11
VCC--VCC
GND---GND
DAT---PA5
7. 土壤濕度傳感器
VCC--->5V
GND--->GND
DAT--->PA1
8. 繼電器控制--水泵抽水
VCC--->5V
GND--->GND
DAT--->PA6
8.6 KEIL工程
8.7 取模軟件使用
本地設(shè)備的LCD顯示屏上會(huì)顯示各種傳感器數(shù)據(jù),需要用到中文、數(shù)字、字母。
當(dāng)前使用的取模軟件如下:
這是軟件的設(shè)置頁(yè)面:
8.8 核心代碼
while(1)
{
//按鍵可以手動(dòng)控制開啟水泵和補(bǔ)光燈
key=KEY_Scan();
if(key)printf("key=%drn",key);
//模式切換
if(key==2)
{
mode=!mode; //模式切換
printf("按鍵按下: 執(zhí)行模式切換: %drn",mode);
}
//控制水泵開關(guān)
if(key==1)
{
MOTOR=!MOTOR;
printf("控制水泵開關(guān): %drn",MOTOR);
}
//輪詢時(shí)間到達(dá)
if(time_cnt>20)
{
//模式顯示
if(mode) //自動(dòng)模式
{
LCD_ShowChineseFont(90,16*6+2,16,HZ_FONT_16[28],RED,0);
LCD_ShowChineseFont(90+16,16*6+2,16,HZ_FONT_16[29],RED,0);
}
else //手動(dòng)模式
{
LCD_ShowChineseFont(90,16*6+2,16,HZ_FONT_16[30],RED,0);
LCD_ShowChineseFont(90+16,16*6+2,16,HZ_FONT_16[31],RED,0);
}
//放到水里61,接觸空氣是135
//越濕潤(rùn)值越小,越干旱值越大
//土壤濕度
SOIL=GetAdcCHxDATA(1);
SOIL = 4095 - SOIL; //將干燥度轉(zhuǎn)為濕度
printf("土壤濕度:%drn",SOIL);
SOIL = (float)SOIL / (float)4095 * 100.0;
//【土壤濕度顯示】
sprintf(data_buff,"%5d",SOIL);
Gui_DrawFont_GBK16(72,16*4+2,RED,0,(u8*)data_buff);
//自動(dòng)模式下控制自動(dòng)澆水
if(mode)
{
//如果 SOIL <=0 表示是非法值,沒有放在土壤里
if(SOIL>1)
{
//根據(jù)濕度自動(dòng)開關(guān)水泵澆水
//這里的值根據(jù)自己實(shí)際測(cè)試情況修改
if(SOIL<MAX_SOIL)
{
//第一次進(jìn)來,才需要清除計(jì)數(shù)變量
if(motor_flag==0)
{
motor_sec_cnt=0;
}
motor_flag=1; //澆水
}
else
{
motor_flag=0; //停止?jié)菜?
}
}
}
//【濕度閥值顯示】
sprintf(data_buff,"%4d",MAX_SOIL);
Gui_DrawFont_GBK16(72,16*5+2,RED,0,(u8*)data_buff);
//【1】光強(qiáng)度
//讀取光強(qiáng)度
BH1750=Read_BH1750_Data();
printf("光強(qiáng)度:%drn",BH1750);
//顯示光強(qiáng)度
sprintf(data_buff,"%4d",BH1750);
Gui_DrawFont_GBK16(72,16*2+2,RED,0,(u8*)data_buff);
//【2】溫濕度
//讀取溫濕度
if(DHT11_Read_Data(&DHT11_T,&DHT11_H))
{
printf("溫度讀取失敗.rn");
}
printf("環(huán)境溫度:%drn環(huán)境濕度:%drn",DHT11_T,DHT11_H);
//顯示溫度
sprintf(data_buff,"%4d",DHT11_T);
Gui_DrawFont_GBK16(72,16*0+2,RED,0,(u8*)data_buff);
//顯示濕度
sprintf(data_buff,"%4d",DHT11_H);
Gui_DrawFont_GBK16(72,16*1+2,RED,0,(u8*)data_buff);
//土壤溫度
DS18B20=DS18B20_Get_Temp();
//轉(zhuǎn)換土壤溫度
sprintf(data_buff,"%d.%d",DS18B20>>4,DS18B20&0xF);
f_ds18b02=atof(data_buff);
//顯示土壤溫度
sprintf(data_buff,"%6.2f",f_ds18b02);
Gui_DrawFont_GBK16(72,16*4+2,RED,0,(u8*)data_buff);
printf("環(huán)境溫度:%d℃n",DHT11_T);
printf("環(huán)境濕度:%dn",DHT11_H);
printf("土壤濕度:%drn",SOIL);
printf("土壤溫度:%frn",f_ds18b02);
time_cnt=0;
LED1=!LED1;
//上報(bào)數(shù)據(jù)
sprintf(data_buff,"{"services": [{"service_id": "stm32","properties":{"DHT11_T":%d,"DHT11_H":%d,"BH1750":%d,"SOIL":%d,"DS18B20":%f,"MOTOR":%d,"mode":%d,"MAX_SOIL":%d}}]}",
DHT11_T,DHT11_H,BH1750,SOIL,f_ds18b02,MOTOR,mode,MAX_SOIL);
MQTT_PublishData(POST_TOPIC,data_buff,0);
printf("更新數(shù)據(jù).rn");
}
//接收WIFI返回的數(shù)據(jù)
if(USART3_RX_FLAG)
{
USART3_RX_BUFFER[USART3_RX_CNT]='?';
printf("WIFI收到數(shù)據(jù):rn");
//向串口打印服務(wù)器返回的數(shù)據(jù)
for(i=0;i<USART3_RX_CNT;i++)
{
printf("%c",USART3_RX_BUFFER[i]);
}
//如果是服務(wù)器下發(fā)了屬性事件
if(USART3_RX_CNT>5)
{
//開澆水電機(jī)
if(strstr((char*)&USART3_RX_BUFFER[5],""MOTOR":1"))
{
motor_sec_cnt=0;
motor_flag=1;
}
//關(guān)澆水電機(jī)
else if(strstr((char*)&USART3_RX_BUFFER[5],""MOTOR":0"))
{
motor_flag=0;
}
//設(shè)置濕度閥值
else if(strstr((char*)&USART3_RX_BUFFER[5],""MAX_SOIL":"))
{
find_p=strstr((char*)&USART3_RX_BUFFER[5],""MAX_SOIL":");
MAX_SOIL=atoi(find_p+11);
printf("設(shè)置濕度閥值:%drn",MAX_SOIL);
}
//自動(dòng)模式
if(strstr((char*)&USART3_RX_BUFFER[5],""mode":1"))
{
mode=1;
}
//手動(dòng)模式
else if(strstr((char*)&USART3_RX_BUFFER[5],""mode":0"))
{
mode=0;
}
//使用字符串查找函數(shù)
//設(shè)置屬性,澆水
//"motor":1
if(strstr((char*)&USART3_RX_BUFFER[5],"sys/commands/request_id="))
{
char *p=NULL;
p=strstr((char*)&USART3_RX_BUFFER[5],"request_id=");
if(p)
{
//解析數(shù)據(jù)
//$oc/devices/6434f5044f1d6803244e5db4_dev1/sys/commands/request_id=d2d11779-5bf6-42e5-a5b8-6efc91c7166c{"paras":{"MOTOR":1},"service_id":"stm32","command_name":"澆水電機(jī)控制"}
strncpy(request_id,p,47);
}
//上報(bào)數(shù)據(jù)
sprintf(mqtt_message,"{"result_code":0,"response_name":"COMMAND_RESPONSE","paras":{"result":"success"}}");
sprintf(data_buff,"$oc/devices/6434f5044f1d6803244e5db4_dev1/sys/commands/response/%s",
request_id);
MQTT_PublishData(data_buff,mqtt_message,0);
printf("發(fā)布主題:%srn",data_buff);
printf("發(fā)布數(shù)據(jù):%srn",mqtt_message);
}
}
USART3_RX_CNT=0;
USART3_RX_FLAG=0;
}
DelayMs(10);
time_cnt++;
}
8.9 程序正常運(yùn)行效果
設(shè)備運(yùn)行過程中會(huì)通過串口打印調(diào)試信息,我們可以通過串口打印了解程序是否正常。比如:ESP8266是否聯(lián)網(wǎng)成功,是否連接到服務(wù)器。
8.10 硬件技術(shù)問題
(1)STM32與物聯(lián)網(wǎng)服務(wù)器的交互協(xié)議
STM32硬件端與物聯(lián)網(wǎng)服務(wù)器通過WIFI進(jìn)行通信。每間隔一端時(shí)間,STM32就會(huì)向物聯(lián)網(wǎng)服務(wù)器上傳當(dāng)前傳感器的數(shù)據(jù)。
傳感器上傳組合的MQTT主題報(bào)文格式如下:
//上報(bào)數(shù)據(jù)
sprintf(data_buff,"{"services": [{"service_id": "stm32","properties":{"DHT11_T":%d,"DHT11_H":%d,"BH1750":%d,"SOIL":%d,"DS18B20":%f,"MOTOR":%d,"mode":%d,"MAX_SOIL":%d}}]}",
DHT11_T,DHT11_H,BH1750,SOIL,f_ds18b02,MOTOR,mode,MAX_SOIL);
MQTT_PublishData(POST_TOPIC,data_buff,0);
手機(jī)APP給STM32下發(fā)的消息:
len:162,Data:f$oc/devices/6434f5044f1d6803244e5db4_dev1/sys/commands/request_id=c1dc39a7-97d1-49f4-bee3-c6bc96e002c4{"paras":{"MOTOR":0},"service_id":null,"command_name":null}
len:166,Data:f$oc/devices/6434f5044f1d6803244e5db4_dev1/sys/commands/request_id=b5c6cee2-c3fc-4fc9-a9c5-8528e180ece4{"paras":{"MAX_SOIL":60},"service_id":null,"command_name":null}
len:166,Data:f$oc/devices/6434f5044f1d6803244e5db4_dev1/sys/commands/request_id=11715fde-1f5b-4864-8499-73cbedc24ec9{"paras":{"MAX_SOIL":89},"service_id":null,"command_name":null}
len:162,Data:f$oc/devices/6434f5044f1d6803244e5db4_dev1/sys/commands/request_id=29f10139-e414-4632-aeb1-4d17ac6a3959{"paras":{"MOTOR":1},"service_id":null,"command_name":null}
len:161,Data:f$oc/devices/6434f5044f1d6803244e5db4_dev1/sys/commands/request_id=86722292-d182-485a-a20f-e980643ead0e{"paras":{"mode":0},"service_id":null,"command_name":null}
(2)ESP8266-WIFI功能介紹
當(dāng)前項(xiàng)目采用ESP8266模塊完成與智慧大屏的通訊,ESP8266支持AP和STA模式;當(dāng)前項(xiàng)目里配置成STA模式,去連接指定的WIFI熱點(diǎn),連接之后配置成TCP客戶端模式,連接智慧大屏創(chuàng)建的TCP服務(wù)器,然后就可以進(jìn)行數(shù)據(jù)傳輸同通訊。ESP8266和智慧大屏必須在一個(gè)局域網(wǎng)里才可以連接,也就是需要連接同一個(gè)熱點(diǎn)。
下面是ESP8266的特點(diǎn)介紹:
ESP8266是一款Wi-Fi適用的可編程網(wǎng)絡(luò)單芯片,搭載一個(gè)Tensilica L106 32-位處理器,可支持802.11 b/g/n Wi-Fi 功能,還有一個(gè)低功耗的10-bit精度的模擬/數(shù)字信號(hào)處理器和高度集成的低功耗,高安全性的TLS/SSL協(xié)議核心,能夠支持用戶終端上的全功能的低成本IoT應(yīng)用。
(3)DHT11溫濕度傳感器
DHT11是一款有已校準(zhǔn)數(shù)字信號(hào)輸出的溫濕度傳感器。 其精度濕度±5%RH, 溫度±2℃,量程濕度5~95%RH, 溫度-20~+60℃。
DHT11應(yīng)用專用的數(shù)字模塊采集技術(shù)和溫濕度傳感技術(shù),確保產(chǎn)品具有極高的可靠性和卓越的長(zhǎng)期穩(wěn)定性。傳感器包括一個(gè)電阻式感濕元件和一個(gè)NTC測(cè)溫元件,并與一個(gè)高性能8位單片機(jī)相連接。因此該產(chǎn)品具有品質(zhì)卓越、超快響應(yīng)、抗干擾能力強(qiáng)、性價(jià)比極高等優(yōu)點(diǎn)。每個(gè)DHT11傳感器都在極為精確的濕度校驗(yàn)室中進(jìn)行校準(zhǔn)。校準(zhǔn)系數(shù)以程序的形式存在OTP內(nèi)存中,傳感器內(nèi)部在檢測(cè)信號(hào)的處理過程中要調(diào)用這些校準(zhǔn)系數(shù)。單線制串行接口,使系統(tǒng)集成變得簡(jiǎn)易快捷。超小的體積、極低的功耗,使其成為該類應(yīng)用中,在苛刻應(yīng)用場(chǎng)合的最佳選擇。產(chǎn)品為4針單排引腳封裝,連接方便。
該傳感器包括一個(gè)電阻式測(cè)濕元件和一個(gè) NTC測(cè)溫元件,并與一個(gè)高性能 8 位單片機(jī)相連接。通過單片機(jī)等微處理器簡(jiǎn)單的電路連接就能夠?qū)崟r(shí)的采集本地濕度和溫度。DHT11 與單片機(jī)之間能采用簡(jiǎn)單的單總線進(jìn)行通信,僅僅需要一個(gè) I/O 口。傳感器內(nèi)部濕度和溫度數(shù)據(jù) 40Bit 的數(shù)據(jù)一次性傳給單片機(jī),數(shù)據(jù)采用校驗(yàn)和方式進(jìn)行校驗(yàn),有效的保證數(shù)據(jù)傳輸?shù)臏?zhǔn)確性。DHT11 功耗很低,5V 電源電壓下,工作平均最大電流 0.5mA。
DHT11 的技術(shù)參數(shù)如下:
? 工作電壓范圍:3.3V-5.5V
? 工作電流 :平均 0.5mA
? 輸出:?jiǎn)慰偩€數(shù)字信號(hào)
? 測(cè)量范圍:濕度 20~90%RH,溫度 0~50℃
? 精度 :濕度±5%,溫度±2℃
? 分辨率 :濕度 1%,溫度 1℃
DHT11 數(shù)字濕溫度傳感器采用單總線數(shù)據(jù)格式。即,單個(gè)數(shù)據(jù)引腳端口完成輸入輸出雙向傳輸。其數(shù)據(jù)包由 5Byte(40Bit)組成。數(shù)據(jù)分小數(shù)部分和整數(shù)部分,一次完整的數(shù)據(jù)傳輸為40bit,高位先出。
DHT11 的數(shù)據(jù)格式為:8bit 濕度整數(shù)數(shù)據(jù)+8bit 濕度小數(shù)數(shù)據(jù)+8bit 溫度整數(shù)數(shù)據(jù)+8bit 溫度小數(shù)數(shù)據(jù)+8bit 校驗(yàn)和。其中校驗(yàn)和數(shù)據(jù)為前四個(gè)字節(jié)相加。
九、硬件選型
【1】母對(duì)母杜邦線
作用: 連接模塊與單片機(jī)。
鏈接:https://detail.tmall.com/item.htm?ali_refid=a3_430582_1006:1104520036:N:MsF9mE9KLTC2IibWJh%20K1A==:adaa6d3d7abe6f1f07b87a36416ee4fb&ali_trackid=1_adaa6d3d7abe6f1f07b87a36416ee4fb&id=14466195609&skuId=3936936817454&spm=a230r.1.14.1
【2】洞洞板
鏈接:https://detail.tmall.com/item.htm?spm=a230r.1.14.34.16b221829wBwAI&id=525489414251&ns=1&abbucket=9&skuId=3929211749440
【3】USB下載線
鏈接:https://detail.tmall.com/item.htm?areaId=500100&cat_id=2&id=36635861113&is_b=1&rn=b29713f11d07002439272415bce5c7e1&skuId=3762719825529&spm=a220m.1000858.1000725.31.46e677b4qLTl6B&user_id=1695056989
【4】STM32F103RCT6開發(fā)板
主控CPU采用STM32F103RCT6,這顆芯片包括48 KB SRAM、256 KB Flash、2個(gè)基本定時(shí)器、4個(gè)通用定時(shí)器、2個(gè)高級(jí)定時(shí)器、51個(gè)通用IO口、5個(gè)串口、2個(gè)DMA控制器、3個(gè)SPI、2個(gè)I2C、1個(gè)USB、1個(gè)CAN、3個(gè)12位ADC、1個(gè)12位DAC、1個(gè)SDIO接口,芯片屬于大容量類型,配置較高,整體符合硬件選型設(shè)計(jì)。當(dāng)前選擇的這款開發(fā)板自帶了一個(gè)1.4寸的TFT-LCD彩屏,可以顯示當(dāng)前傳感器數(shù)據(jù)以及一些運(yùn)行狀態(tài)信息。
鏈接:https://detail.tmall.com/item.htm?id=540109077095&skuId=4456080806080&spm=a1z0d.6639537.1997196601.4.69157484Ospeps
【5】 DHT11溫濕度傳感器
DHT11數(shù)字溫濕度傳感器是一款含有已校準(zhǔn)數(shù)字信號(hào)輸出的溫濕度復(fù)合傳感器。它應(yīng)用專用的數(shù)字模塊采集技術(shù)和溫濕度傳感技術(shù),確保產(chǎn)品具有可靠性與卓越的長(zhǎng)期穩(wěn)定性,成本低、相對(duì)濕度和溫度測(cè)量、快響應(yīng)、抗干擾能力強(qiáng)、信號(hào)傳輸距離長(zhǎng)、數(shù)字信號(hào)輸出、精確校準(zhǔn)。傳感器包括一個(gè)電容式感濕元件和一個(gè)NTC測(cè)溫元件,并與一個(gè)高性能8位單片機(jī)相連接??捎糜谂照{(diào)、除濕器、測(cè)試及檢測(cè)設(shè)備、消費(fèi)品、汽車、自動(dòng)控制、數(shù)據(jù)記錄器、氣象站、家電、濕度調(diào)節(jié)器、醫(yī)療、其他相關(guān)濕度檢測(cè)控制。
特點(diǎn)如下:
1、可以檢測(cè)周圍環(huán)境的濕度
2、可以檢測(cè)周圍環(huán)境的溫度
3、濕度測(cè)量范圍:20%-95%(0度-50度范圍)濕度測(cè)量誤差:±5%4、溫度測(cè)量范圍:o度-50度溫度測(cè)量誤差:±2度
4、工作電壓3.3V-5V
5、輸出形式數(shù)字輸出
https://detail.tmall.com/item.htm?id=15598344236&ali_refid=a3_430582_1006:1104520036:N:TAiHo9GD8eTurMzH21/csQ==:bead289475b4a86864858785eb160a52&ali_trackid=1_bead289475b4a86864858785eb160a52&spm=a230r.1.14.1&skuId=4835521242383
【6】BH1750光敏傳感器
鏈接:https://detail.tmall.com/item.htm?abbucket=3&id=543135220776&ns=1&spm=a230r.1.14.16.d7597d40XRn0Ec
【7】 ESP8266 WIFI
鏈接:https://detail.tmall.com/item.htm?spm=a230r.1.14.1.322267d12csSBI&id=609757779633&ns=1&abbucket=9&skuId=4447338308660
■模塊采用串口(LVTTL) 與MCU (或其他串口設(shè)備) 通信,內(nèi)置TCP/IP協(xié)議棧,能夠?qū)崿F(xiàn)串口與WIFI之間的轉(zhuǎn)換
■模塊支持LVTTL串口, 兼容3…3V和5V單片機(jī)系統(tǒng)
■模塊支持串 口轉(zhuǎn)WIFI STA、串口轉(zhuǎn)AP和WIFI STA+WIFI AP的模式,從而快速構(gòu)建串口-WIFI數(shù)據(jù)傳輸方案
■模塊小巧(19mm*29mm), 通過6個(gè)2.54mm間距排針與外部連接
【8】 繼電器
鏈接:https://detail.tmall.com/item.htm?abbucket=0&id=41268748362&ns=1&spm=a21n57.1.0.0.1f98523c5N83UP
【9】土壤濕度傳感器
鏈接: https://detail.tmall.com/item.htm?spm=a230r.1.14.16.f54e4813fvxQrB&id=37365775741&ns=1&abbucket=19&skuId=4136086852947
十、上位機(jī)開發(fā)
10.1 說明
一套完整的物聯(lián)網(wǎng)產(chǎn)品。會(huì)分為設(shè)備端,服務(wù)器,上位機(jī)部分。
這個(gè)章節(jié),介紹采用Qt開發(fā)上位機(jī)的過程。利用EMQX提供的API接口與MQTT客戶端設(shè)備進(jìn)行通信,完成數(shù)據(jù)上傳,命令下發(fā)等功能。
10.2 查看全部的API接口
幫助文檔地址: https://www.emqx.io/docs/zh/v5.0/admin/api.html#%E8%AE%A4%E8%AF%81
EMQX 提供了管理監(jiān)控 REST API,這些 API 遵循 OpenAPI (Swagger) 3.0 規(guī)范。
EMQX 在 REST API 上做了版本控制,EMQX 5.0.0 以后的所有 API 調(diào)用均以 /api/v5 開頭。
EMQX 服務(wù)啟動(dòng)后,可以訪問 http://localhost:18083/api-docs/index.html (opens new window)來查看 API 的文檔。還可以直接在 Swagger UI 上嘗試執(zhí)行一些 API。
比如: 我的EMQX服務(wù)器是在華為云ECS服務(wù)器上搭建,公網(wǎng)IP是: 122.112.225.194
那我訪問API文檔的地址就是下面這樣的格式: 在瀏覽器里打開即可。
http://122.112.225.194:18083/api-docs/index.html
訪問效果如下:
10.3 創(chuàng)建API密匙
【1】登錄EMQX的后臺(tái)管理頁(yè)面: http://122.112.225.194:18083/
【2】找到菜單里的 系統(tǒng)設(shè)置選項(xiàng)–>API密匙。
【3】創(chuàng)建密匙。
【4】填寫密匙名稱
【5】創(chuàng)建成功
【6】得到API Key 和 Secret Key
API Key : f072a6e9758b8cdf
Secret Key : LzwPB71Yf7PTED39C7RGboz9C9ANhv83ULUynTANgog4hG
10.4 測(cè)試API: 獲取節(jié)點(diǎn)信息
上一步已經(jīng)創(chuàng)建好API的訪問密匙,這里就以 獲取節(jié)點(diǎn)信息為例,調(diào)用獲取節(jié)點(diǎn)信息的API接口,獲取節(jié)點(diǎn) 信息。
接口在API文檔里的介紹:
根據(jù)前面的API訪問路徑規(guī)則說明; 那么,獲取節(jié)點(diǎn)信息的API完整訪問路徑為:
http://122.112.225.194:18083/api/v5/nodes
接下來就用python寫一份代碼,測(cè)試一下接口是否可以正常訪問。 python代碼直接放服務(wù)器運(yùn)行(主要是我本地沒有安裝python環(huán)境,云服務(wù)器的環(huán)境是已經(jīng)安裝OK的,測(cè)試方便)。
【1】在云服務(wù)器上創(chuàng)建一個(gè)python文件,方便測(cè)試代碼
【2】創(chuàng)建之后FinaShell
自動(dòng)上傳到服務(wù)器
【3】編輯代碼
在這里雙擊
要編輯的文件,就可以打開文件進(jìn)行編輯。默認(rèn)采用內(nèi)置的編輯器,也可以選擇自己電腦上的外置編輯器。
【4】代碼編輯完成,按下鍵盤快捷鍵Ctrl + S
保存文件內(nèi)容,保存之后文件內(nèi)容會(huì)自動(dòng)同步到服務(wù)器。
保存后提示,自動(dòng)上傳。
寫入的代碼如下:
import urllib.request
import json
import base64
username = 'f072a6e9758b8cdf'
password = 'LzwPB71Yf7PTED39C7RGboz9C9ANhv83ULUynTANgog4hG'
url = 'http://122.112.225.194:18083/api/v5/nodes'
req = urllib.request.Request(url)
req.add_header('Content-Type', 'application/json')
auth_header = "Basic " + base64.b64encode((username + ":" + password).encode()).decode()
req.add_header('Authorization', auth_header)
with urllib.request.urlopen(req) as response:
data = json.loads(response.read().decode())
print(data)
【5】執(zhí)行代碼,返回結(jié)果
通過返回信息來看,節(jié)點(diǎn)信息獲取是沒有問題的。
root@emqx:~/emqx# python3 http_api_test.sh
[{'connections': 0, 'edition': 'Opensource', 'live_connections': 0, 'load1': 0.0, 'load15': 0.0, 'load5': 0.0, 'log_path': '/var/log/emqx', 'max_fds': 1048576, 'memory_total': '3.66G', 'memory_used': '612.59M', 'node': 'emqx@127.0.0.1', 'node_status': 'running', 'otp_release': '25.3.2-2/13.2.2', 'process_available': 2097152, 'process_used': 543, 'role': 'core', 'sys_path': '/usr/lib/emqx', 'uptime': 84000040, 'version': '5.3.1-alpha.1'}]
root@emqx:~/emqx# python3 http_api_test.sh
[{'connections': 0, 'edition': 'Opensource', 'live_connections': 0, 'load1': 0.0, 'load15': 0.0, 'load5': 0.0, 'log_path': '/var/log/emqx', 'max_fds': 1048576, 'memory_total': '3.66G', 'memory_used': '613.23M', 'node': 'emqx@127.0.0.1', 'node_status': 'running', 'otp_release': '25.3.2-2/13.2.2', 'process_available': 2097152, 'process_used': 543, 'role': 'core', 'sys_path': '/usr/lib/emqx', 'uptime': 84008046, 'version': '5.3.1-alpha.1'}]
10.5 在線調(diào)試(獲取主題列表)
在編寫代碼之前,可以先測(cè)試下API接口的效果,可以直接在Swagger UI
界面直接調(diào)試API。
地址: http://122.112.225.194:18083/api-docs/index.html#/
例如:以獲取以訂閱主題列表的API接口為例。
【1】在Swagger UI
界面上找到對(duì)應(yīng)的API接口。
【2】點(diǎn)擊API說明,展開詳情
【3】點(diǎn)擊右邊的試試看
按鈕。
【4】點(diǎn)擊執(zhí)行
【5】然后會(huì)彈出提示框,讓你填入用戶名和密碼。
這個(gè)用戶名和密碼就是前面創(chuàng)建API密匙生成的API Key(用戶名)
和 Secret Key(密碼)
。
API Key : f072a6e9758b8cdf
Secret Key : LzwPB71Yf7PTED39C7RGboz9C9ANhv83ULUynTANgog4hG
【6】根據(jù)提示輸入用戶名和密碼,再點(diǎn)擊登錄。
【7】再次點(diǎn)擊執(zhí)行,就可以看到接口返回的數(shù)據(jù)了。
并且在頁(yè)面上也寫出了,請(qǐng)求的信息。使用curl
命令行給出詳細(xì)的請(qǐng)求過程,參考這個(gè)就可以自己寫代碼了。
【8】API調(diào)用,curl
命令行執(zhí)行代碼如下:
curl -X 'GET'
'http://122.112.225.194:18083/api/v5/topics?node=emqx%40127.0.0.1&page=1&limit=50'
-H 'accept: application/json'
【9】python代碼實(shí)現(xiàn)
import requests
url = 'http://122.112.225.194:18083/api/v5/topics?node=emqx%40127.0.0.1&page=1&limit=50'
headers = {'accept': 'application/json'}
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = response.json()
# 在這里處理返回的數(shù)據(jù)
print(data)
else:
print("請(qǐng)求失敗,狀態(tài)碼:", response.status_code)
10.6 在線調(diào)試(發(fā)布主題)
API里也支持發(fā)布主題,利用HTTP協(xié)議發(fā)布主題消息,如果設(shè)備端訂閱了該主題,就可以收到API接口發(fā)布的消息。
【1】先找到發(fā)布主題的API接口
【2】點(diǎn)擊API名字,展開詳情
【3】點(diǎn)擊右邊的Try it out
按鈕。
【4】參數(shù)填寫說明
因?yàn)檫@個(gè)接口是發(fā)送主題的,需要填參數(shù),填自己需要發(fā)布什么主題,什么消息。
出來的框框里就是發(fā)布信息,根據(jù)自己需要修改。
topic
就是發(fā)布的主題。 payload
就是發(fā)布的消息內(nèi)容。 只要MQTT客戶端訂閱了這個(gè)主題,就可以收到發(fā)布的消息。
這個(gè)主題的名字可以隨便改的。我這里就用默認(rèn)的名字和內(nèi)容測(cè)試。
{
"payload_encoding": "plain",
"topic": "api/example/topic",
"qos": 0,
"payload": "hello emqx api",
"properties": {
"payload_format_indicator": 0,
"message_expiry_interval": 0,
"response_topic": "some_other_topic",
"correlation_data": "string",
"user_properties": {
"foo": "bar"
},
"content_type": "text/plain"
},
"retain": false
}
【5】MQTT客戶端登錄。
打開MQTT客戶端,登錄服務(wù)器,訂閱api/example/topic
主題。
【6】在API調(diào)試頁(yè)面,點(diǎn)擊執(zhí)行
【7】執(zhí)行之后,在MQTT客戶端的就可以收到API下發(fā)的消息了。
【8】API接口調(diào)用,curl
命令行執(zhí)行的代碼如下:
curl -X 'POST'
'http://122.112.225.194:18083/api/v5/publish'
-H 'accept: application/json'
-H 'Content-Type: application/json'
-d '{
"payload_encoding": "plain",
"topic": "api/example/topic",
"qos": 0,
"payload": "hello emqx api",
"properties": {
"payload_format_indicator": 0,
"message_expiry_interval": 0,
"response_topic": "some_other_topic",
"correlation_data": "string",
"user_properties": {
"foo": "bar"
},
"content_type": "text/plain"
},
"retain": false
}'
【9】Python代碼實(shí)現(xiàn)
import requests
import json
url = 'http://122.112.225.194:18083/api/v5/publish'
headers = {
'accept': 'application/json',
'Content-Type': 'application/json'
}
data = {
"payload_encoding": "plain",
"topic": "api/example/topic",
"qos": 0,
"payload": "hello emqx api",
"properties": {
"payload_format_indicator": 0,
"message_expiry_interval": 0,
"response_topic": "some_other_topic",
"correlation_data": "string",
"user_properties": {
"foo": "bar"
},
"content_type": "text/plain"
},
"retain": False
}
response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
print("消息發(fā)布成功")
else:
print("消息發(fā)布失敗,狀態(tài)碼:", response.status_code)
10.7 安裝Qt環(huán)境
Qt的中文官網(wǎng): https://www.qt.io/zh-cn/
QT5.12.6的下載地址:https://download.qt.io/archive/qt/5.12/5.12.6
打開下載鏈接后選擇下面的版本進(jìn)行下載:
qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details
軟件安裝時(shí)斷網(wǎng)安裝,否則會(huì)提示輸入賬戶。
安裝的時(shí)候,第一個(gè)復(fù)選框里勾選一個(gè)mingw 32
編譯器即可,其他的不管默認(rèn)就行,直接點(diǎn)擊下一步繼續(xù)安裝。
說明: 我這里只是介紹PC端的環(huán)境搭建(這個(gè)比較簡(jiǎn)單)。 Android的開發(fā)環(huán)境比較麻煩,可以去我的博客里看詳細(xì)文章。
選擇MinGW 32-bit 編譯器:
10.8 新建Qt工程
【1】新建工程
【2】設(shè)置工程名字
【3】選擇QWiget父類
【4】選擇編譯套件: 如果電腦沒有安裝VS環(huán)境,就選MinGW,這個(gè)比較簡(jiǎn)單沒有其他依賴環(huán)境問題。 具體看自己編譯的程序最終在哪里運(yùn)行,來選擇合適的編譯器。
【5】創(chuàng)建完成
【6】點(diǎn)擊左下角設(shè)置發(fā)布類型。默認(rèn)是Debug,選擇Release,運(yùn)行效率高一些(如果需要調(diào)試就選擇Debug)。
10.9 設(shè)計(jì)代碼
【1】獲取服務(wù)器節(jié)點(diǎn)信息
QString requestUrl;
QNetworkRequest request;
request.setUrl(QUrl("http://100.112.225.194:18083/api/v5/nodes"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QString username = "f072a6e9758b8cdf";
QString password = "LzwPB71Yf7PTED39C7RGboz9C9ANhv83ULUynTANgog4hG";
QString concatenated = username + ":" + password;
QByteArray data = concatenated.toLocal8Bit().toBase64();
QString headerData = "Basic " + data;
request.setRawHeader("Authorization", headerData.toLocal8Bit());
//發(fā)送請(qǐng)求
manager->get(request);
【2】獲得訂閱的主題列表
QString requestUrl;
QNetworkRequest request;
request.setUrl(QUrl("http://100.112.225.194:18083/api/v5/topics"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QString username = "f072a6e9758b8cdf";
QString password = "LzwPB71Yf7PTED39C7RGboz9C9ANhv83ULUynTANgog4hG";
QString concatenated = username + ":" + password;
QByteArray data = concatenated.toLocal8Bit().toBase64();
QString headerData = "Basic " + data;
request.setRawHeader("Authorization", headerData.toLocal8Bit());
//發(fā)送請(qǐng)求
manager->get(request);
【3】發(fā)布主題
void Widget::publish_topic_http_post(QString topic,QString message)
{
QString requestUrl;
QNetworkRequest request;
request.setUrl(QUrl(QString("http://%1:18083/api/v5/publish").arg(emqx_ip)));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
request.setRawHeader("Authorization", "Basic ZjA3MmE2ZTk3NThiOGNkZjpMendQQjcxWWY3UFRFRDM5QzdSR2JvejlDOUFOaHY4M1VMVXluVEFOZ29nNGhH");
QJsonObject payload;
payload["payload_encoding"] = "plain";
payload["topic"] = topic; // "api/example/topic";
payload["qos"] = 0;
payload["payload"] =message; // "hello emqx api";
QJsonObject properties;
properties["payload_format_indicator"] = 0;
properties["message_expiry_interval"] = 0;
properties["response_topic"] = "some_other_topic";
properties["correlation_data"] = "string";
QJsonObject userProperties;
userProperties["foo"] = "bar";
properties["user_properties"] = userProperties;
properties["content_type"] = "text/plain";
payload["properties"] = properties;
payload["retain"] = false;
QJsonDocument jsonDoc(payload);
QByteArray jsonData = jsonDoc.toJson();
//發(fā)送請(qǐng)求
manager->post(request, jsonData);
}
調(diào)用示例:
//發(fā)布主題
publish_topic_http_post("api/cmd/topic","hello mqtt dev");
十一、制作過程
十二、總結(jié)
本智慧農(nóng)業(yè)管理系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)項(xiàng)目基于STM32F103RCT6微控制器為核心,通過集成DHT11溫濕度傳感器、BH1750光照強(qiáng)度傳感器和土壤濕度檢測(cè)傳感器等設(shè)備,構(gòu)建了一套全面的農(nóng)田環(huán)境監(jiān)測(cè)系統(tǒng)。當(dāng)環(huán)境參數(shù)超出預(yù)設(shè)閾值時(shí),系統(tǒng)能夠?qū)崟r(shí)報(bào)警并自動(dòng)或提醒進(jìn)行灌溉、施肥等操作,同時(shí)利用蜂鳴器發(fā)出聲音警報(bào)。
在遠(yuǎn)程控制方面,系統(tǒng)采用NBIoT-BC26模塊實(shí)現(xiàn)了無線通信功能,將采集到的數(shù)據(jù)傳輸至云端MQTT服務(wù)器,并通過EMQX開源框架搭建的服務(wù)器處理數(shù)據(jù)。用戶可通過微信小程序隨時(shí)隨地查看農(nóng)田環(huán)境的各項(xiàng)實(shí)時(shí)數(shù)據(jù),實(shí)現(xiàn)對(duì)農(nóng)作物生長(zhǎng)環(huán)境的遠(yuǎn)程監(jiān)控,并能便捷地執(zhí)行手動(dòng)灌溉、開啟補(bǔ)光燈等遠(yuǎn)程控制操作。
本項(xiàng)目的成功實(shí)施,不僅有效提升了農(nóng)業(yè)生產(chǎn)過程中的智能化水平,降低了人工管理成本,而且為實(shí)現(xiàn)精準(zhǔn)農(nóng)業(yè)和智慧農(nóng)業(yè)提供了有力的技術(shù)支持。未來,隨著物聯(lián)網(wǎng)技術(shù)、云計(jì)算和人工智能技術(shù)的進(jìn)一步發(fā)展,這套智慧農(nóng)業(yè)管理系統(tǒng)將有望在更多領(lǐng)域推廣使用,助力我國(guó)現(xiàn)代農(nóng)業(yè)朝著更高效、智能、可持續(xù)的方向邁進(jìn)。