• 正文
    • 一、前言
    • 二、硬件介紹
    • 三、部署華為云物聯(lián)網(wǎng)平臺(tái)
    • 四、STM32設(shè)備端代碼設(shè)計(jì)
    • 五、上位機(jī)開(kāi)發(fā)
    • 六、總結(jié)
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

基于STM32設(shè)計(jì)的水資源監(jiān)測(cè)系統(tǒng)

06/07 11:25
682
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

一、前言

1.1 項(xiàng)目開(kāi)發(fā)背景

水資源作為人類賴以生存和發(fā)展的基礎(chǔ)性自然資源,其質(zhì)量直接關(guān)系到生態(tài)環(huán)境的可持續(xù)發(fā)展和人民群眾的生命健康。隨著工業(yè)化與城鎮(zhèn)化的快速推進(jìn),水體污染問(wèn)題日益嚴(yán)重,水資源的保護(hù)與科學(xué)管理已成為全球關(guān)注的重要議題。為了實(shí)現(xiàn)對(duì)水環(huán)境的高效監(jiān)測(cè)與管理,亟需構(gòu)建一套集成化、智能化的水資源環(huán)境監(jiān)測(cè)系統(tǒng),實(shí)現(xiàn)水質(zhì)數(shù)據(jù)的實(shí)時(shí)采集、分析、傳輸與展示,為環(huán)境治理提供數(shù)據(jù)支撐與決策依據(jù)。

傳統(tǒng)的水質(zhì)監(jiān)測(cè)方法多以人工采樣與實(shí)驗(yàn)室分析為主,周期長(zhǎng)、效率低,難以及時(shí)反映動(dòng)態(tài)變化的水質(zhì)狀況,無(wú)法滿足當(dāng)前水環(huán)境實(shí)時(shí)監(jiān)控的需求。借助嵌入式技術(shù)物聯(lián)網(wǎng)通信技術(shù)及傳感器技術(shù)的發(fā)展,構(gòu)建基于STM32嵌入式平臺(tái)的智能水環(huán)境監(jiān)測(cè)系統(tǒng)成為一種可行而有效的方案。該系統(tǒng)通過(guò)多種水質(zhì)傳感器實(shí)現(xiàn)對(duì)水溫、pH值、溶解氧、電導(dǎo)率、水位等參數(shù)的連續(xù)自動(dòng)監(jiān)測(cè),并通過(guò)無(wú)線通信方式將數(shù)據(jù)實(shí)時(shí)上傳至物聯(lián)網(wǎng)平臺(tái),實(shí)現(xiàn)遠(yuǎn)程監(jiān)控與報(bào)警。

本項(xiàng)目基于STM32F103C8T6單片機(jī)作為主控核心,結(jié)合DS18B20、pH傳感器、溶解氧傳感器、TDS電導(dǎo)率傳感器、水位傳感器等多種模塊構(gòu)建多參數(shù)水質(zhì)檢測(cè)系統(tǒng),通過(guò)IIC接口實(shí)現(xiàn)本地OLED顯示,結(jié)合Air780E 4G通信模塊實(shí)現(xiàn)遠(yuǎn)程數(shù)據(jù)上傳。項(xiàng)目采用MQTT協(xié)議接入華為云物聯(lián)網(wǎng)平臺(tái),同時(shí)配套開(kāi)發(fā)基于Qt(C++)的Android手機(jī)APP和Windows上位機(jī),用于數(shù)據(jù)可視化展示和歷史數(shù)據(jù)分析,提升系統(tǒng)的可用性與智能化水平。

系統(tǒng)還集成了高電平觸發(fā)蜂鳴器,在監(jiān)測(cè)數(shù)據(jù)出現(xiàn)異常時(shí)可實(shí)現(xiàn)現(xiàn)場(chǎng)聲光報(bào)警,有效提升應(yīng)急響應(yīng)能力。該系統(tǒng)具有部署靈活、運(yùn)行穩(wěn)定、實(shí)時(shí)性強(qiáng)等優(yōu)點(diǎn),廣泛適用于河流、湖泊、水庫(kù)、水產(chǎn)養(yǎng)殖、污水處理等多種場(chǎng)景,對(duì)于推動(dòng)水環(huán)境保護(hù)信息化、智能化具有重要現(xiàn)實(shí)意義和應(yīng)用價(jià)值。

1.2 設(shè)計(jì)實(shí)現(xiàn)的功能

(1)水溫檢測(cè)功能:通過(guò)DS18B20防水溫度傳感器對(duì)水體溫度進(jìn)行實(shí)時(shí)監(jiān)測(cè),并將數(shù)據(jù)傳送至主控芯片處理。

(2)pH值檢測(cè)功能:采用模擬量輸出的pH傳感器對(duì)水體酸堿度進(jìn)行檢測(cè),經(jīng)ADC采集并通過(guò)算法轉(zhuǎn)換為實(shí)際pH值。

(3)溶解氧檢測(cè)功能:采用485接口輸出的溶解氧傳感器,通過(guò)485轉(zhuǎn)串口模塊與STM32通信,實(shí)時(shí)獲取水中溶解氧濃度。

(4)水位檢測(cè)功能:使用電阻式模擬量輸出的水位傳感器,實(shí)現(xiàn)水體液位的實(shí)時(shí)監(jiān)測(cè),并通過(guò)ADC接口采集。

(5)TDS電導(dǎo)率檢測(cè)功能:通過(guò)TDS傳感器采集水體的電導(dǎo)率信息,反映水中溶解固體物的含量。

(6)OLED本地顯示功能:通過(guò)0.96寸IIC接口OLED屏,實(shí)時(shí)顯示采集的水溫、pH值、溶解氧、水位、電導(dǎo)率等關(guān)鍵參數(shù),便于現(xiàn)場(chǎng)查看。

(7)數(shù)據(jù)上云功能:利用Air780E 4G模塊,通過(guò)MQTT協(xié)議將采集的所有水質(zhì)參數(shù)上傳至華為云IoT物聯(lián)網(wǎng)平臺(tái),實(shí)現(xiàn)遠(yuǎn)程數(shù)據(jù)可視化管理。

(8)遠(yuǎn)程APP與上位機(jī)顯示功能:基于Qt(C++)開(kāi)發(fā)Android手機(jī)APP與Windows上位機(jī),接收云端數(shù)據(jù)并以圖表方式進(jìn)行可視化展示,支持實(shí)時(shí)查看與歷史數(shù)據(jù)查詢。

(9)歷史數(shù)據(jù)記錄與折線圖查看功能:Android APP端支持每日歷史數(shù)據(jù)的存儲(chǔ)和查詢功能,用戶可通過(guò)折線圖形式查看各項(xiàng)水質(zhì)指標(biāo)的變化趨勢(shì)。

(10)異常報(bào)警功能:當(dāng)系統(tǒng)監(jiān)測(cè)到水質(zhì)參數(shù)異常(如超出設(shè)定閾值)時(shí),觸發(fā)高電平蜂鳴器進(jìn)行現(xiàn)場(chǎng)聲響報(bào)警,提示相關(guān)人員及時(shí)處理。

1.3 項(xiàng)目硬件模塊組成

(1)STM32F103C8T6主控模塊:作為系統(tǒng)的核心控制單元,負(fù)責(zé)采集傳感器數(shù)據(jù)、數(shù)據(jù)處理、本地顯示和數(shù)據(jù)上傳等任務(wù)。

(2)DS18B20水溫傳感器模塊:用于實(shí)時(shí)采集水體溫度數(shù)據(jù),具有防水封裝,通信方式為單總線接口。

(3)pH值檢測(cè)傳感器模塊:輸出模擬電壓信號(hào),通過(guò)STM32的ADC采樣接口讀取,結(jié)合公式算法換算出實(shí)際pH值。

(4)溶解氧傳感器模塊:采用RS485接口輸出,通過(guò)485轉(zhuǎn)TTL串口模塊連接STM32,實(shí)現(xiàn)對(duì)水體溶解氧濃度的讀取。

(5)水位檢測(cè)模塊:使用電阻式模擬量輸出的水位傳感器,通過(guò)STM32的ADC接口獲取水位高度信息。

(6)TDS電導(dǎo)率傳感器模塊:模擬量輸出,檢測(cè)水中溶解固體的電導(dǎo)率值,通過(guò)ADC采集處理。

(7)OLED顯示模塊:采用0.96寸IIC通信接口,用于實(shí)時(shí)顯示采集到的水溫、pH值、溶解氧、水位、電導(dǎo)率等數(shù)據(jù)。

(8)Air780E 4G通信模塊:負(fù)責(zé)將處理后的水質(zhì)數(shù)據(jù)通過(guò)MQTT協(xié)議上傳至華為云IoT物聯(lián)網(wǎng)平臺(tái),實(shí)現(xiàn)遠(yuǎn)程數(shù)據(jù)通信。

(9)蜂鳴器模塊:采用高電平觸發(fā)方式,在檢測(cè)數(shù)據(jù)異常時(shí)發(fā)出聲響警報(bào),用于本地故障提示。

(10)485轉(zhuǎn)串口通信模塊:用于將溶解氧傳感器的RS485信號(hào)轉(zhuǎn)換為STM32可識(shí)別的TTL串口信號(hào),實(shí)現(xiàn)串口數(shù)據(jù)通信。

1.4 設(shè)計(jì)思路

本項(xiàng)目設(shè)計(jì)一套基于STM32的水資源環(huán)境監(jiān)測(cè)系統(tǒng),實(shí)現(xiàn)多項(xiàng)水質(zhì)參數(shù)的實(shí)時(shí)監(jiān)測(cè)、本地顯示、遠(yuǎn)程上傳和異常報(bào)警等功能。系統(tǒng)整體設(shè)計(jì)思路遵循“模塊化、集成化、智能化”的原則,圍繞數(shù)據(jù)采集、數(shù)據(jù)處理、數(shù)據(jù)傳輸與數(shù)據(jù)展示四個(gè)核心環(huán)節(jié)進(jìn)行系統(tǒng)開(kāi)發(fā)。

在數(shù)據(jù)采集部分,系統(tǒng)選用多種水質(zhì)傳感器模塊,分別用于采集水溫、pH值、溶解氧、水位和電導(dǎo)率等核心水質(zhì)指標(biāo)。其中,溫度傳感器DS18B20通過(guò)單總線通信方式獲取數(shù)據(jù);pH值和TDS電導(dǎo)率采用模擬量輸出方式,STM32通過(guò)ADC模塊進(jìn)行電壓采樣并結(jié)合算法轉(zhuǎn)換為實(shí)際值;水位傳感器同樣輸出模擬信號(hào),方便讀取液位變化;溶解氧傳感器則通過(guò)RS485通信輸出,經(jīng)過(guò)485轉(zhuǎn)串口模塊后接入STM32的串口讀取。通過(guò)合理搭配通信協(xié)議和接口資源,實(shí)現(xiàn)了多參數(shù)、多通道的水質(zhì)數(shù)據(jù)采集。

在數(shù)據(jù)處理與顯示方面,STM32F103C8T6主控芯片作為系統(tǒng)核心,負(fù)責(zé)各項(xiàng)傳感器數(shù)據(jù)的采集調(diào)度與數(shù)值處理。處理后的數(shù)據(jù)通過(guò)IIC接口發(fā)送至0.96寸OLED顯示屏,便于現(xiàn)場(chǎng)查看當(dāng)前水質(zhì)狀態(tài)。系統(tǒng)設(shè)計(jì)時(shí)充分考慮資源優(yōu)化,確保多個(gè)模塊協(xié)同工作,避免通信沖突和資源浪費(fèi)。

在數(shù)據(jù)傳輸部分,系統(tǒng)集成了Air780E 4G模塊,實(shí)現(xiàn)遠(yuǎn)程無(wú)線通信。選用輕量級(jí)的MQTT協(xié)議,將處理后的數(shù)據(jù)通過(guò)4G網(wǎng)絡(luò)上傳至華為云物聯(lián)網(wǎng)平臺(tái),確保數(shù)據(jù)上傳的穩(wěn)定性和實(shí)時(shí)性。MQTT協(xié)議具有發(fā)布/訂閱機(jī)制,能夠降低網(wǎng)絡(luò)帶寬消耗,提高通信效率,特別適合物聯(lián)網(wǎng)設(shè)備低功耗、低帶寬應(yīng)用場(chǎng)景。

為實(shí)現(xiàn)遠(yuǎn)程數(shù)據(jù)展示與分析,系統(tǒng)配套開(kāi)發(fā)Android手機(jī)APP與Windows上位機(jī)軟件,采用Qt(C++)設(shè)計(jì),支持從華為云物聯(lián)網(wǎng)平臺(tái)接收數(shù)據(jù)并進(jìn)行可視化展示。APP端還支持歷史數(shù)據(jù)存儲(chǔ)與查看功能,用戶可按日期查詢歷史記錄,并以折線圖形式分析水質(zhì)變化趨勢(shì)。通過(guò)跨平臺(tái)設(shè)計(jì),實(shí)現(xiàn)了移動(dòng)端與PC端的無(wú)縫對(duì)接。

系統(tǒng)具備異常報(bào)警功能,當(dāng)監(jiān)測(cè)到某項(xiàng)參數(shù)超過(guò)預(yù)設(shè)閾值時(shí),STM32將自動(dòng)驅(qū)動(dòng)蜂鳴器報(bào)警,實(shí)現(xiàn)現(xiàn)場(chǎng)預(yù)警,增強(qiáng)系統(tǒng)的安全性和響應(yīng)能力。整體系統(tǒng)硬件采用模塊化結(jié)構(gòu)設(shè)計(jì),便于后期擴(kuò)展與維護(hù),同時(shí)提升了項(xiàng)目的穩(wěn)定性和實(shí)用性。

1.5 系統(tǒng)功能總結(jié)

功能模塊 實(shí)現(xiàn)內(nèi)容 硬件支持 通信方式
水溫檢測(cè) 實(shí)時(shí)監(jiān)測(cè)水體溫度 DS18B20溫度傳感器 單總線
pH值檢測(cè) 檢測(cè)水體酸堿度,轉(zhuǎn)換為實(shí)際pH值顯示 模擬pH傳感器 模擬量 → ADC
溶解氧檢測(cè) 檢測(cè)水中溶解氧濃度 溶解氧傳感器 + 485轉(zhuǎn)串口模塊 RS485 → TTL串口
水位檢測(cè) 實(shí)時(shí)監(jiān)測(cè)水位高度 電阻式水位傳感器 模擬量 → ADC
TDS電導(dǎo)率檢測(cè) 檢測(cè)水體中溶解固體含量的電導(dǎo)率 TDS電導(dǎo)率傳感器 模擬量 → ADC
本地顯示 實(shí)時(shí)顯示各項(xiàng)水質(zhì)數(shù)據(jù)(溫度、pH、溶解氧、水位、電導(dǎo)率) 0.96寸OLED顯示屏(IIC接口) IIC通信
數(shù)據(jù)上傳 將采集數(shù)據(jù)上傳至華為云IoT平臺(tái) Air780E 4G模塊 MQTT協(xié)議(4G網(wǎng)絡(luò))
遠(yuǎn)程數(shù)據(jù)顯示 在Android APP和Windows上位機(jī)端查看實(shí)時(shí)及歷史數(shù)據(jù),支持折線圖顯示 Qt開(kāi)發(fā)APP與上位機(jī) MQTT訂閱(云端同步)
歷史數(shù)據(jù)管理 APP端支持每日數(shù)據(jù)存儲(chǔ)與查詢,圖形化展示水質(zhì)變化 Android手機(jī)APP 本地+云端數(shù)據(jù)同步
異常報(bào)警 當(dāng)數(shù)據(jù)異常超閾值,蜂鳴器報(bào)警提醒 高電平觸發(fā)蜂鳴器 IO控制

1.6 開(kāi)發(fā)工具的選擇

【1】設(shè)備端開(kāi)發(fā)

STM32的編程語(yǔ)言選擇C語(yǔ)言,C語(yǔ)言執(zhí)行效率高,大學(xué)里主學(xué)的C語(yǔ)言,C語(yǔ)言編譯出來(lái)的可執(zhí)行文件最接近于機(jī)器碼,匯編語(yǔ)言執(zhí)行效率最高,但是匯編的移植性比較差,目前在一些操作系統(tǒng)內(nèi)核里還有一些低配的單片機(jī)使用的較多,平常的單片機(jī)編程還是以C語(yǔ)言為主。C語(yǔ)言的執(zhí)行效率僅次于匯編,語(yǔ)法理解、代碼通用性強(qiáng),也支持跨平臺(tái),在嵌入式底層、單片機(jī)編程里用的非常多,當(dāng)前的設(shè)計(jì)就是采用C語(yǔ)言開(kāi)發(fā)。

開(kāi)發(fā)工具選擇Keil,keil是一家世界領(lǐng)先的嵌入式微控制器軟件開(kāi)發(fā)商,在2015年,keil被ARM公司收購(gòu)。因?yàn)楫?dāng)前芯片選擇的是STM32F103系列,STMF103是屬于ARM公司的芯片構(gòu)架、Cortex-M3內(nèi)核系列的芯片,所以使用Kile來(lái)開(kāi)發(fā)STM32是有先天優(yōu)勢(shì)的,而keil在各大高校使用的也非常多,很多教科書(shū)里都是以keil來(lái)教學(xué),開(kāi)發(fā)51單片機(jī)、STM32單片機(jī)等等。目前作為MCU芯片開(kāi)發(fā)的軟件也不只是keil一家獨(dú)大,IAR在MCU微處理器開(kāi)發(fā)領(lǐng)域里也使用的非常多,IAR擴(kuò)展性更強(qiáng),也支持STM32開(kāi)發(fā),也支持其他芯片,比如:CC2530,51單片機(jī)的開(kāi)發(fā)。從軟件的使用上來(lái)講,IAR比keil更加簡(jiǎn)潔,功能相對(duì)少一些。如果之前使用過(guò)keil,而且使用頻率較多,已經(jīng)習(xí)慣再使用IAR是有點(diǎn)不適應(yīng)界面的。

【2】上位機(jī)開(kāi)發(fā)

上位機(jī)的開(kāi)發(fā)選擇Qt框架,編程語(yǔ)言采用C++;Qt是一個(gè)1991年由Qt Company開(kāi)發(fā)的跨平臺(tái)C++圖形用戶界面應(yīng)用程序開(kāi)發(fā)框架。它既可以開(kāi)發(fā)GUI程序,也可用于開(kāi)發(fā)非GUI程序,比如控制臺(tái)工具和服務(wù)器。Qt是面向?qū)ο蟮目蚣?,使用特殊的代碼生成擴(kuò)展(稱為元對(duì)象編譯器(Meta Object Compiler, moc))以及一些宏,Qt很容易擴(kuò)展,并且允許真正地組件編程。Qt能輕松創(chuàng)建具有原生C++性能的連接設(shè)備、用戶界面(UI)和應(yīng)用程序。它功能強(qiáng)大且結(jié)構(gòu)緊湊,擁有直觀的工具和庫(kù)。

1.7 數(shù)據(jù)交互字段

在將本項(xiàng)目采集的數(shù)據(jù)上傳至?華為云 IoT 物聯(lián)網(wǎng)平臺(tái)?時(shí),需要為設(shè)備模型(即產(chǎn)品模型)定義一組字段屬性(屬性服務(wù)),用于描述設(shè)備采集到的各種數(shù)據(jù)。這些屬性應(yīng)能完整表達(dá)你系統(tǒng)的功能。

在華為云 IoT 平臺(tái)定義以下字段屬性:

字段名稱(標(biāo)識(shí)符) 數(shù)據(jù)類型 單位 描述 示例值
waterTemp float 水溫 22.5
phValue float 無(wú) PH值 7.21
dissolvedOxygen float mg/L 溶解氧濃度 6.85
waterLevel float cm 當(dāng)前水位高度 13.2
tdsValue float ppm TDS電導(dǎo)率(溶解性總固體) 580
uploadTime string 時(shí)間戳 數(shù)據(jù)上傳時(shí)間 2025-06-05T12:30:00
alarmStatus int 無(wú) 異常報(bào)警狀態(tài)(0正常,1異常) 0

說(shuō)明:

? 數(shù)據(jù)類型需與華為云平臺(tái)支持的類型一致,如?int、float、stringboolean。

??alarmStatus 可用于報(bào)警提示功能,如當(dāng)PH超標(biāo)、TDS過(guò)高等時(shí)上傳?1。

? uploadTime 可以作為歷史數(shù)據(jù)存儲(chǔ)和查詢依據(jù)。

MQTT 上傳格式(JSON 結(jié)構(gòu)):

{
??"waterTemp":?22.5,
??"phValue":?7.21,
??"dissolvedOxygen":?6.85,
??"waterLevel":?13.2,
??"tdsValue":?580,
??"alarmStatus":?0,
??"uploadTime":?"2025-06-05T12:30:00"
}

二、硬件介紹

當(dāng)前項(xiàng)目使用的相關(guān)軟件工具、模塊源碼已經(jīng)上傳到網(wǎng)盤(pán):https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink

2.1 STM32F102C8T6

STM32F103C8T6 是 STMicroelectronics 公司推出的一款基于 ARM Cortex-M3 內(nèi)核的 32 位高性能低功耗微控制器,屬于 STM32F1 系列中的主流型產(chǎn)品。該芯片具有較高的性價(jià)比和穩(wěn)定的性能,被廣泛應(yīng)用于嵌入式控制系統(tǒng)、物聯(lián)網(wǎng)設(shè)備、傳感器采集、工業(yè)自動(dòng)化等領(lǐng)域。

STM32F103C8T6 運(yùn)行主頻為 72MHz,具有 64KB 的 Flash 程序存儲(chǔ)器和 20KB 的 SRAM,滿足中小型嵌入式項(xiàng)目的代碼和數(shù)據(jù)存儲(chǔ)需求。它集成豐富的外設(shè)接口,包括多達(dá) 37 個(gè)通用 I/O 端口、3 個(gè)通用定時(shí)器、1 個(gè)高級(jí)定時(shí)器、多個(gè)串口(USART)、SPI 接口、I2C 接口以及 12 位 ADC 模塊(多達(dá) 10 個(gè)通道),能夠支持多種模擬和數(shù)字信號(hào)輸入輸出。

芯片封裝為 LQFP-48(48 引腳封裝),方便用戶在 PCB 設(shè)計(jì)和元件焊接過(guò)程中操作。它支持 2.0V~3.6V 的供電電壓,具有較強(qiáng)的抗干擾能力和低功耗特性,適合在復(fù)雜或要求較高的工作環(huán)境中運(yùn)行。

在開(kāi)發(fā)方面,STM32F103C8T6 支持多種開(kāi)發(fā)工具,如 Keil、IAR、STM32CubeIDE 等,開(kāi)發(fā)者既可以使用標(biāo)準(zhǔn)外設(shè)庫(kù)(SPL)或硬件抽象庫(kù)(HAL)開(kāi)發(fā),也可以直接基于寄存器編程方式進(jìn)行底層控制,便于系統(tǒng)的精細(xì)調(diào)試與資源優(yōu)化。芯片支持通過(guò) ISP 方式(串口)下載程序,用戶可以方便地進(jìn)行程序更新和調(diào)試。

STM32F103C8T6 是一款性能穩(wěn)定、資源豐富、接口齊全的通用型微控制器,非常適合應(yīng)用在多傳感器數(shù)據(jù)采集、通信控制和實(shí)時(shí)處理等嵌入式系統(tǒng)設(shè)計(jì)中,如本項(xiàng)目中的水資源環(huán)境監(jiān)測(cè)系統(tǒng)。

2.2 Air780e

Air780E 是移遠(yuǎn)通信(Quectel)推出的一款高性能、低功耗、功能豐富的 4G 全網(wǎng)通通信模塊,適用于物聯(lián)網(wǎng)領(lǐng)域中對(duì)數(shù)據(jù)傳輸速率、可靠性和遠(yuǎn)程接入能力有較高要求的應(yīng)用場(chǎng)景。該模塊支持 LTE CAT1 通信標(biāo)準(zhǔn),可實(shí)現(xiàn)較快的數(shù)據(jù)傳輸速度與穩(wěn)定的網(wǎng)絡(luò)連接能力,廣泛應(yīng)用于智能終端、遠(yuǎn)程監(jiān)控、工業(yè)物聯(lián)、智慧農(nóng)業(yè)等系統(tǒng)中。

Air780E 支持中國(guó)三大運(yùn)營(yíng)商(移動(dòng)、聯(lián)通、電信)的 4G 網(wǎng)絡(luò),具備良好的網(wǎng)絡(luò)兼容性和通信覆蓋能力。模塊內(nèi)部集成了 TCP/IP 協(xié)議棧,并支持常用的通信協(xié)議如 MQTT、HTTP、FTP、UDP、TCP 等,用戶可以通過(guò)串口 AT 指令方式快速配置模塊,實(shí)現(xiàn)云平臺(tái)的數(shù)據(jù)上傳與下發(fā)控制。對(duì)于本項(xiàng)目,Air780E 通過(guò) MQTT 協(xié)議將采集的水質(zhì)數(shù)據(jù)上傳到華為云物聯(lián)網(wǎng)平臺(tái),起到了關(guān)鍵的數(shù)據(jù)傳輸橋梁作用。

硬件接口方面,Air780E 模塊提供標(biāo)準(zhǔn)的 UART 接口,方便與主控芯片(如 STM32)通信,支持常見(jiàn)的波特率配置,并且具有多路 GPIO、SIM 卡接口、天線接口、電源管理等功能。模塊支持主控通過(guò)串口發(fā)送 AT 指令來(lái)進(jìn)行撥號(hào)上網(wǎng)、參數(shù)設(shè)置、數(shù)據(jù)發(fā)送、斷線重連等操作,操作、上手快速,能夠顯著降低開(kāi)發(fā)難度。

在功耗控制方面,Air780E 具備多種省電模式,如飛行模式、睡眠模式和掉電模式,特別適合電池供電類的嵌入式應(yīng)用場(chǎng)景。模塊體積小巧,集成度高,封裝方式適合貼片安裝,可方便集成在各種尺寸受限的設(shè)備中。

Air780E 是一款集高可靠性、易用性和網(wǎng)絡(luò)兼容性于一體的 4G 通信模塊,特別適合用于需要遠(yuǎn)程數(shù)據(jù)傳輸、接入云平臺(tái)的嵌入式系統(tǒng)。在本水資源環(huán)境監(jiān)測(cè)項(xiàng)目中,它有效實(shí)現(xiàn)了傳感器數(shù)據(jù)從本地終端到云端的遠(yuǎn)距離傳輸,是系統(tǒng)遠(yuǎn)程監(jiān)控功能實(shí)現(xiàn)的關(guān)鍵組成部分。

2.3 TDS傳感器

TDS電導(dǎo)率檢測(cè)傳感器是一種用于檢測(cè)水中溶解性總固體(Total Dissolved Solids)含量的傳感器,廣泛應(yīng)用于水質(zhì)檢測(cè)、飲用水處理、水產(chǎn)養(yǎng)殖、農(nóng)業(yè)灌溉等場(chǎng)景。TDS 的單位通常為 ppm(每百萬(wàn)分之一),代表每升水中含有多少毫克的可溶性物質(zhì),如礦物質(zhì)、鹽類、金屬離子等。

該傳感器的工作原理基于電導(dǎo)率的測(cè)量,即通過(guò)檢測(cè)水體對(duì)電流的導(dǎo)通能力,間接判斷水中溶解固體的濃度。水中含有的離子越多,導(dǎo)電能力越強(qiáng),對(duì)應(yīng)的TDS值也越高。傳感器內(nèi)部通常包含兩個(gè)電極,當(dāng)電極浸入水中后,電解質(zhì)會(huì)使電流形成通路,控制模塊通過(guò)測(cè)量電導(dǎo)值并結(jié)合算法,將其轉(zhuǎn)換為實(shí)際的TDS數(shù)值。

TDS傳感器通常輸出為模擬電壓信號(hào),便于與單片機(jī)的ADC模塊(如STM32的ADC)進(jìn)行對(duì)接。傳感器輸出的電壓與TDS值成正比,經(jīng)過(guò)采樣與算法換算后即可獲得相應(yīng)的ppm濃度值。在應(yīng)用中,為了獲得更準(zhǔn)確的測(cè)量結(jié)果,常配合溫度傳感器(如DS18B20)進(jìn)行溫度補(bǔ)償,以消除不同水溫對(duì)電導(dǎo)率造成的影響。

TDS傳感器一般采用防水探頭,外殼材質(zhì)耐腐蝕,適合長(zhǎng)期浸入水中使用??刂颇K則具備電壓調(diào)節(jié)、濾波放大、信號(hào)校準(zhǔn)等功能,提高輸出信號(hào)的穩(wěn)定性和抗干擾能力。

在本水資源環(huán)境監(jiān)測(cè)系統(tǒng)中,TDS電導(dǎo)率傳感器用于實(shí)時(shí)監(jiān)測(cè)水體中溶解物的濃度,反映水質(zhì)純凈程度,為判斷水質(zhì)優(yōu)劣提供關(guān)鍵依據(jù)。通過(guò)STM32的ADC接口讀取其輸出的模擬信號(hào),并結(jié)合補(bǔ)償算法計(jì)算出當(dāng)前水體的TDS值,再通過(guò)OLED本地顯示及4G模塊上傳至物聯(lián)網(wǎng)平臺(tái),為遠(yuǎn)程水質(zhì)管理與預(yù)警提供數(shù)據(jù)支持。

2.4 溶解氧傳感器

溶解氧檢測(cè)傳感器是一種用于測(cè)量水體中溶解氧(Dissolved Oxygen, DO)濃度的傳感器,廣泛應(yīng)用于水質(zhì)監(jiān)測(cè)、水產(chǎn)養(yǎng)殖、環(huán)保工程、污水處理等領(lǐng)域。溶解氧是水中生物呼吸和水體自凈能力的重要指標(biāo),過(guò)高或過(guò)低都會(huì)影響水體生態(tài)系統(tǒng)的穩(wěn)定性。

常見(jiàn)的溶解氧傳感器類型主要包括電化學(xué)式(極譜型、蓋爾文型)和光學(xué)式。電化學(xué)式傳感器工作原理基于氧分子通過(guò)膜擴(kuò)散進(jìn)入電極系統(tǒng)發(fā)生還原反應(yīng),產(chǎn)生電流信號(hào),該信號(hào)與溶解氧濃度成正比。光學(xué)式則通過(guò)熒光猝滅原理測(cè)量氧氣濃度,具有更高的穩(wěn)定性和更長(zhǎng)的使用壽命,但成本相對(duì)較高。

在本系統(tǒng)中使用的溶解氧傳感器為 RS-485 接口輸出型,具有抗干擾能力強(qiáng)、傳輸距離遠(yuǎn)、通信穩(wěn)定等優(yōu)點(diǎn)。通過(guò)與485轉(zhuǎn)串口模塊配合,STM32單片機(jī)可以通過(guò)串口協(xié)議(如Modbus-RTU)與傳感器進(jìn)行通信,實(shí)時(shí)讀取水中溶解氧的數(shù)值。該傳感器通常支持標(biāo)準(zhǔn)指令查詢,返回的數(shù)據(jù)格式規(guī)范,便于主控程序解析。

傳感器通常采用防水封裝,能夠長(zhǎng)期浸入水中運(yùn)行,且部分型號(hào)支持自動(dòng)溫度補(bǔ)償,進(jìn)一步提高測(cè)量的準(zhǔn)確性。部分高端型號(hào)還具備校準(zhǔn)功能,用戶可以根據(jù)實(shí)際水質(zhì)環(huán)境定期校準(zhǔn)以保持精度。

在本水資源環(huán)境監(jiān)測(cè)系統(tǒng)中,溶解氧傳感器的作用是監(jiān)控水體中氧含量水平,從而判斷是否存在水質(zhì)惡化、生物缺氧等異常情況。通過(guò) STM32 讀取溶解氧值后,不僅可在 OLED 顯示屏上實(shí)時(shí)查看,還可以通過(guò) 4G 模塊上傳至云平臺(tái),便于遠(yuǎn)程監(jiān)測(cè)和歷史數(shù)據(jù)分析,為水質(zhì)保護(hù)和應(yīng)急響應(yīng)提供依據(jù)。

三、部署華為云物聯(lián)網(wǎng)平臺(tái)

華為云官網(wǎng): https://www.huaweicloud.com/

打開(kāi)官網(wǎng),搜索物聯(lián)網(wǎng),就能快速找到?設(shè)備接入IoTDA。

3.1 物聯(lián)網(wǎng)平臺(tái)介紹

華為云物聯(lián)網(wǎng)平臺(tái)(IoT 設(shè)備接入云服務(wù))提供海量設(shè)備的接入和管理能力,將物理設(shè)備聯(lián)接到云,支撐設(shè)備數(shù)據(jù)采集上云和云端下發(fā)命令給設(shè)備進(jìn)行遠(yuǎn)程控制,配合華為云其他產(chǎn)品,幫助我們快速構(gòu)筑物聯(lián)網(wǎng)解決方案。

使用物聯(lián)網(wǎng)平臺(tái)構(gòu)建一個(gè)完整的物聯(lián)網(wǎng)解決方案主要包括3部分:物聯(lián)網(wǎng)平臺(tái)、業(yè)務(wù)應(yīng)用和設(shè)備。

物聯(lián)網(wǎng)平臺(tái)作為連接業(yè)務(wù)應(yīng)用和設(shè)備的中間層,屏蔽了各種復(fù)雜的設(shè)備接口,實(shí)現(xiàn)設(shè)備的快速接入;同時(shí)提供強(qiáng)大的開(kāi)放能力,支撐行業(yè)用戶構(gòu)建各種物聯(lián)網(wǎng)解決方案。

設(shè)備可以通過(guò)固網(wǎng)、2G/3G/4G/5G、NB-IoT、Wifi等多種網(wǎng)絡(luò)接入物聯(lián)網(wǎng)平臺(tái),并使用LWM2M/CoAP、MQTT、HTTPS協(xié)議將業(yè)務(wù)數(shù)據(jù)上報(bào)到平臺(tái),平臺(tái)也可以將控制命令下發(fā)給設(shè)備。

業(yè)務(wù)應(yīng)用通過(guò)調(diào)用物聯(lián)網(wǎng)平臺(tái)提供的API,實(shí)現(xiàn)設(shè)備數(shù)據(jù)采集、命令下發(fā)、設(shè)備管理等業(yè)務(wù)場(chǎng)景。

3.2 開(kāi)通物聯(lián)網(wǎng)服務(wù)

地址: https://www.huaweicloud.com/product/iothub.html

開(kāi)通免費(fèi)單元。

點(diǎn)擊立即創(chuàng)建。

正在創(chuàng)建標(biāo)準(zhǔn)版實(shí)例,需要等待片刻。

創(chuàng)建完成之后,點(diǎn)擊詳情。 可以看到標(biāo)準(zhǔn)版實(shí)例的設(shè)備接入端口和地址。

下面框起來(lái)的就是端口號(hào)域名

點(diǎn)擊實(shí)例名稱,可以查看當(dāng)前免費(fèi)單元的配置情況。

開(kāi)通之后,點(diǎn)擊接入信息,也能查看接入信息。 我們當(dāng)前設(shè)備準(zhǔn)備采用MQTT協(xié)議接入華為云平臺(tái),這里可以看到MQTT協(xié)議的地址和端口號(hào)等信息。

總結(jié):

端口號(hào): ? MQTT (1883)| MQTTS (8883) ? ?
接入地址: dab1a1f2c6.st1.iotda-device.cn-north-4.myhuaweicloud.com

根據(jù)域名地址得到IP地址信息:

打開(kāi)Windows電腦的命令行控制臺(tái)終端,使用ping?命令。ping一下即可。

Microsoft Windows [版本 10.0.19045.5011]
(c) Microsoft Corporation。保留所有權(quán)利。

C:UsersLenovo>ping dab1a1f2c6.st1.iotda-device.cn-north-4.myhuaweicloud.com

正在 Ping dab1a1f2c6.st1.iotda-device.cn-north-4.myhuaweicloud.com [117.78.5.125] 具有 32 字節(jié)的數(shù)據(jù):
來(lái)自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=37ms TTL=44
來(lái)自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=37ms TTL=44
來(lái)自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=37ms TTL=44
來(lái)自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=37ms TTL=44

117.78.5.125 的 Ping 統(tǒng)計(jì)信息:
? ? 數(shù)據(jù)包: 已發(fā)送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計(jì)時(shí)間(以毫秒為單位):
? ? 最短 = 37ms,最長(zhǎng) = 37ms,平均 = 37ms

C:UsersLenovo>

MQTT協(xié)議接入端口號(hào)有兩個(gè),1883是非加密端口,8883是證書(shū)加密端口,單片機(jī)無(wú)法加載證書(shū),所以使用1883端口合適

3.3 創(chuàng)建產(chǎn)品

鏈接:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-dev/all-product?instanceId=03c5c68c-e588-458c-90c3-9e4c640be7af

(1)創(chuàng)建產(chǎn)品

(2)填寫(xiě)產(chǎn)品信息

根據(jù)自己產(chǎn)品名字填寫(xiě),下面的設(shè)備類型選擇自定義類型。

(3)產(chǎn)品創(chuàng)建成功

創(chuàng)建完成之后點(diǎn)擊查看詳情。

(4)添加自定義模型

產(chǎn)品創(chuàng)建完成之后,點(diǎn)擊進(jìn)入產(chǎn)品詳情頁(yè)面,翻到最下面可以看到模型定義。

模型來(lái)說(shuō): 就是存放設(shè)備上傳到云平臺(tái)的數(shù)據(jù)。

你可以根據(jù)自己的產(chǎn)品進(jìn)行創(chuàng)建。

比如:

在將本項(xiàng)目采集的數(shù)據(jù)上傳至?華為云 IoT 物聯(lián)網(wǎng)平臺(tái)?時(shí),需要為設(shè)備模型(即產(chǎn)品模型)定義一組字段屬性(屬性服務(wù)),用于描述設(shè)備采集到的各種數(shù)據(jù)。這些屬性應(yīng)能完整表達(dá)你系統(tǒng)的功能。

根據(jù)項(xiàng)目功能,在華為云 IoT 平臺(tái)定義以下字段屬性:

字段名稱(標(biāo)識(shí)符) 數(shù)據(jù)類型 單位 描述 示例值
waterTemp float 水溫 22.5
phValue float 無(wú) PH值 7.21
dissolvedOxygen float mg/L 溶解氧濃度 6.85
waterLevel float cm 當(dāng)前水位高度 13.2
tdsValue float ppm TDS電導(dǎo)率(溶解性總固體) 580
uploadTime string 時(shí)間戳 數(shù)據(jù)上傳時(shí)間 2025-06-05T12:30:00
alarmStatus int 無(wú) 異常報(bào)警狀態(tài)(0正常,1異常) 0

說(shuō)明:

    • ? 數(shù)據(jù)類型需與華為云平臺(tái)支持的類型一致,如

int

    • 、

float

    • 、

string

    • 、

boolean

    • 。?

alarmStatus

    • ?可用于報(bào)警提示功能,如當(dāng)PH超標(biāo)、TDS過(guò)高等時(shí)上傳

1

    • 。?

uploadTime

    ?可以作為歷史數(shù)據(jù)存儲(chǔ)和查詢依據(jù)。

MQTT 上傳格式(JSON 結(jié)構(gòu)):

{
??"waterTemp":?22.5,
??"phValue":?7.21,
??"dissolvedOxygen":?6.85,
??"waterLevel":?13.2,
??"tdsValue":?580,
??"alarmStatus":?0,
??"uploadTime":?"2025-06-05T12:30:00"
}

在華為云 IoT 平臺(tái)創(chuàng)建產(chǎn)品后,可以在?產(chǎn)品模型 > 服務(wù) > 屬性?中添加上述字段,并配置設(shè)備上傳的 Topic。STM32 端通過(guò) AT 指令控制 4G 模塊(Air780E)連接 MQTT Broker,將這些字段打包為 JSON 并上報(bào)即可。

先點(diǎn)擊自定義模型。

再創(chuàng)建一個(gè)服務(wù)ID。

接著點(diǎn)擊新增屬性。

3.4 添加設(shè)備

產(chǎn)品是屬于上層的抽象模型,接下來(lái)在產(chǎn)品模型下添加實(shí)際的設(shè)備。添加的設(shè)備最終需要與真實(shí)的設(shè)備關(guān)聯(lián)在一起,完成數(shù)據(jù)交互。

(1)注冊(cè)設(shè)備

(2)根據(jù)自己的設(shè)備填寫(xiě)

(3)保存設(shè)備信息

創(chuàng)建完畢之后,點(diǎn)擊保存并關(guān)閉,得到創(chuàng)建的設(shè)備密匙信息。該信息在后續(xù)生成MQTT三元組的時(shí)候需要使用。

(4)設(shè)備創(chuàng)建完成

(5)設(shè)備詳情

3.5 MQTT協(xié)議主題訂閱與發(fā)布

(1)MQTT協(xié)議介紹

當(dāng)前的設(shè)備是采用MQTT協(xié)議與華為云平臺(tái)進(jìn)行通信。

MQTT是一個(gè)物聯(lián)網(wǎng)傳輸協(xié)議,它被設(shè)計(jì)用于輕量級(jí)的發(fā)布/訂閱式消息傳輸,旨在為低帶寬和不穩(wěn)定的網(wǎng)絡(luò)環(huán)境中的物聯(lián)網(wǎng)設(shè)備提供可靠的網(wǎng)絡(luò)服務(wù)。MQTT是專門(mén)針對(duì)物聯(lián)網(wǎng)開(kāi)發(fā)的輕量級(jí)傳輸協(xié)議。MQTT協(xié)議針對(duì)低帶寬網(wǎng)絡(luò),低計(jì)算能力的設(shè)備,做了特殊的優(yōu)化,使得其能適應(yīng)各種物聯(lián)網(wǎng)應(yīng)用場(chǎng)景。目前MQTT擁有各種平臺(tái)和設(shè)備上的客戶端,已經(jīng)形成了初步的生態(tài)系統(tǒng)。

MQTT是一種消息隊(duì)列協(xié)議,使用發(fā)布/訂閱消息模式,提供一對(duì)多的消息發(fā)布,解除應(yīng)用程序耦合,相對(duì)于其他協(xié)議,開(kāi)發(fā)更;MQTT協(xié)議是工作在TCP/IP協(xié)議上;由TCP/IP協(xié)議提供穩(wěn)定的網(wǎng)絡(luò)連接;所以,只要具備TCP協(xié)議棧的網(wǎng)絡(luò)設(shè)備都可以使用MQTT協(xié)議。 本次設(shè)備采用的ESP8266就具備TCP協(xié)議棧,能夠建立TCP連接,所以,配合STM32代碼里封裝的MQTT協(xié)議,就可以與華為云平臺(tái)完成通信。

華為云的MQTT協(xié)議接入幫助文檔在這里: https://support.huaweicloud.com/devg-iothub/iot_02_2200.html

業(yè)務(wù)流程:

(2)華為云平臺(tái)MQTT協(xié)議使用限制

描述 限制
支持的MQTT協(xié)議版本 3.1.1
與標(biāo)準(zhǔn)MQTT協(xié)議的區(qū)別 支持Qos 0和Qos 1支持Topic自定義不支持QoS2不支持will、retain msg
MQTTS支持的安全等級(jí) 采用TCP通道基礎(chǔ) + TLS協(xié)議(最高TLSv1.3版本)
單帳號(hào)每秒最大MQTT連接請(qǐng)求數(shù) 無(wú)限制
單個(gè)設(shè)備每分鐘支持的最大MQTT連接數(shù) 1
單個(gè)MQTT連接每秒的吞吐量,即帶寬,包含直連設(shè)備和網(wǎng)關(guān) 3KB/s
MQTT單個(gè)發(fā)布消息最大長(zhǎng)度,超過(guò)此大小的發(fā)布請(qǐng)求將被直接拒絕 1MB
MQTT連接心跳時(shí)間建議值 心跳時(shí)間限定為30至1200秒,推薦設(shè)置為120秒
產(chǎn)品是否支持自定義Topic 支持
消息發(fā)布與訂閱 設(shè)備只能對(duì)自己的Topic進(jìn)行消息發(fā)布與訂閱
每個(gè)訂閱請(qǐng)求的最大訂閱數(shù) 無(wú)限制

(3)主題訂閱格式

幫助文檔地址:https://support.huaweicloud.com/devg-iothub/iot_02_2200.html

對(duì)于設(shè)備而言,一般會(huì)訂閱平臺(tái)下發(fā)消息給設(shè)備 這個(gè)主題。

設(shè)備想接收平臺(tái)下發(fā)的消息,就需要訂閱平臺(tái)下發(fā)消息給設(shè)備 的主題,訂閱后,平臺(tái)下發(fā)消息給設(shè)備,設(shè)備就會(huì)收到消息。

如果設(shè)備想要知道平臺(tái)下發(fā)的消息,需要訂閱上面圖片里標(biāo)注的主題。

以當(dāng)前設(shè)備為例,最終訂閱主題的格式如下:
$oc/devices/{device_id}/sys/messages/down
? ??
最終的格式:
$oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down

(4)主題發(fā)布格式

對(duì)于設(shè)備來(lái)說(shuō),主題發(fā)布表示向云平臺(tái)上傳數(shù)據(jù),將最新的傳感器數(shù)據(jù),設(shè)備狀態(tài)上傳到云平臺(tái)。

這個(gè)操作稱為:屬性上報(bào)。

幫助文檔地址:https://support.huaweicloud.com/usermanual-iothub/iot_06_v5_3010.html

根據(jù)幫助文檔的介紹, 當(dāng)前設(shè)備發(fā)布主題,上報(bào)屬性的格式總結(jié)如下:

發(fā)布的主題格式:
$oc/devices/{device_id}/sys/properties/report
?
最終的格式:
$oc/devices/663cb18871d845632a0912e7_dev1/sys/properties/report
發(fā)布主題時(shí),需要上傳數(shù)據(jù),這個(gè)數(shù)據(jù)格式是JSON格式。

上傳的JSON數(shù)據(jù)格式如下:

{
??"services": [
? ? {
? ? ??"service_id": <填服務(wù)ID>,
? ? ??"properties": {
? ? ? ??"<填屬性名稱1>": <填屬性值>,
? ? ? ??"<填屬性名稱2>": <填屬性值>,
? ? ? ? ..........
? ? ? }
? ? }
? ]
}
根據(jù)JSON格式,一次可以上傳多個(gè)屬性字段。 這個(gè)JSON格式里的,服務(wù)ID,屬性字段名稱,屬性值類型,在前面創(chuàng)建產(chǎn)品的時(shí)候就已經(jīng)介紹了,不記得可以翻到前面去查看。

根據(jù)這個(gè)格式,組合一次上傳的屬性數(shù)據(jù):
{"services": [{"service_id":?"stm32","properties":{"你的字段名字1":30,"你的字段名字2":10,"你的字段名字3":1,"你的字段名字4":0}}]}

3.6 MQTT三元組

MQTT協(xié)議登錄需要填用戶ID,設(shè)備ID,設(shè)備密碼等信息,就像我們平時(shí)登錄QQ,微信一樣要輸入賬號(hào)密碼才能登錄。MQTT協(xié)議登錄的這3個(gè)參數(shù),一般稱為MQTT三元組。

接下來(lái)介紹,華為云平臺(tái)的MQTT三元組參數(shù)如何得到。

(1)MQTT服務(wù)器地址

要登錄MQTT服務(wù)器,首先記得先知道服務(wù)器的地址是多少,端口是多少。

幫助文檔地址:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-portal/home

MQTT協(xié)議的端口支持1883和8883,它們的區(qū)別是:8883 是加密端口更加安全。但是單片機(jī)上使用比較困難,所以當(dāng)前的設(shè)備是采用1883端口進(jìn)連接的。

根據(jù)上面的域名和端口號(hào),得到下面的IP地址和端口號(hào)信息:?如果設(shè)備支持填寫(xiě)域名可以直接填域名,不支持就直接填寫(xiě)IP地址。 (IP地址就是域名解析得到的)

華為云的MQTT服務(wù)器地址:117.78.5.125
華為云的MQTT端口號(hào):1883

如何得到IP地址?如何域名轉(zhuǎn)IP? 打開(kāi)Windows的命令行輸入以下命令。

ping ?ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com

(2)生成MQTT三元組

華為云提供了一個(gè)在線工具,用來(lái)生成MQTT鑒權(quán)三元組: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/

打開(kāi)這個(gè)工具,填入設(shè)備的信息(也就是剛才創(chuàng)建完設(shè)備之后保存的信息),點(diǎn)擊生成,就可以得到MQTT的登錄信息了。

下面是打開(kāi)的頁(yè)面:

填入設(shè)備的信息:?(上面兩行就是設(shè)備創(chuàng)建完成之后保存得到的)

直接得到三元組信息。

得到三元組之后,設(shè)備端通過(guò)MQTT協(xié)議登錄鑒權(quán)的時(shí)候,填入?yún)?shù)即可。

ClientId ?663cb18871d845632a0912e7_dev1_0_0_2024050911
Username ?663cb18871d845632a0912e7_dev1
Password ?71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac237

3.7 模擬設(shè)備登錄測(cè)試

經(jīng)過(guò)上面的步驟介紹,已經(jīng)創(chuàng)建了產(chǎn)品,設(shè)備,數(shù)據(jù)模型,得到MQTT登錄信息。 接下來(lái)就用MQTT客戶端軟件模擬真實(shí)的設(shè)備來(lái)登錄平臺(tái)。測(cè)試與服務(wù)器通信是否正常。

MQTT軟件下載地址【免費(fèi)】:?https://download.csdn.net/download/xiaolong1126626497/89928772

(1)填入登錄信息

打開(kāi)MQTT客戶端軟件,對(duì)號(hào)填入相關(guān)信息(就是上面的文本介紹)。然后,點(diǎn)擊登錄,訂閱主題,發(fā)布主題。

(2)打開(kāi)網(wǎng)頁(yè)查看

完成上面的操作之后,打開(kāi)華為云網(wǎng)頁(yè)后臺(tái),可以看到設(shè)備已經(jīng)在線了。

點(diǎn)擊詳情頁(yè)面,可以看到上傳的數(shù)據(jù):

到此,云平臺(tái)的部署已經(jīng)完成,設(shè)備已經(jīng)可以正常上傳數(shù)據(jù)了。

(3)MQTT登錄測(cè)試參數(shù)總結(jié)

MQTT服務(wù)器: ?117.78.5.125
MQTT端口號(hào): ?183

//物聯(lián)網(wǎng)服務(wù)器的設(shè)備信息
#define?MQTT_ClientID?"663cb18871d845632a0912e7_dev1_0_0_2024050911"
#define?MQTT_UserName?"663cb18871d845632a0912e7_dev1"
#define?MQTT_PassWord?"71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac237"

//訂閱與發(fā)布的主題
#define?SET_TOPIC ?"$oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down"??//訂閱
#define?POST_TOPIC?"$oc/devices/663cb18871d845632a0912e7_dev1/sys/properties/report"??//發(fā)布


發(fā)布的數(shù)據(jù):
{"services": [{"service_id":?"stm32","properties":{"你的字段名字1":30,"你的字段名字2":10,"你的字段名字3":1,"你的字段名字4":0}}]}

3.8 創(chuàng)建IAM賬戶

創(chuàng)建一個(gè)IAM賬戶,因?yàn)榻酉聛?lái)開(kāi)發(fā)上位機(jī),需要使用云平臺(tái)的API接口,這些接口都需要token進(jìn)行鑒權(quán)。來(lái)說(shuō),就是身份的認(rèn)證。 調(diào)用接口獲取Token時(shí),就需要填寫(xiě)IAM賬號(hào)信息。所以,接下來(lái)演示一下過(guò)程。

地址: https://console.huaweicloud.com/iam/?region=cn-north-4#/iam/users

**【1】獲取項(xiàng)目憑證 ** 點(diǎn)擊左上角用戶名,選擇下拉菜單里的我的憑證

項(xiàng)目憑證:

28add376c01e4a61ac8b621c714bf459

【2】創(chuàng)建IAM用戶

鼠標(biāo)放在左上角頭像上,在下拉菜單里選擇統(tǒng)一身份認(rèn)證。

點(diǎn)擊左上角創(chuàng)建用戶。

創(chuàng)建成功:

【3】創(chuàng)建完成

用戶信息如下:

主用戶名 ?l19504562721
IAM用戶 ?ds_abc
密碼 ? ? DS12345678

3.9 獲取影子數(shù)據(jù)

幫助文檔:https://support.huaweicloud.com/api-iothub/iot_06_v5_0079.html

設(shè)備影子介紹:

設(shè)備影子是一個(gè)用于存儲(chǔ)和檢索設(shè)備當(dāng)前狀態(tài)信息的JSON文檔。
每個(gè)設(shè)備有且只有一個(gè)設(shè)備影子,由設(shè)備ID唯一標(biāo)識(shí)
設(shè)備影子僅保存最近一次設(shè)備的上報(bào)數(shù)據(jù)和預(yù)期數(shù)據(jù)
無(wú)論該設(shè)備是否在線,都可以通過(guò)該影子獲取和設(shè)置設(shè)備的屬性

來(lái)說(shuō):設(shè)備影子就是保存,設(shè)備最新上傳的一次數(shù)據(jù)。

我們?cè)O(shè)計(jì)的軟件里,如果想要獲取設(shè)備的最新?tīng)顟B(tài)信息,就采用設(shè)備影子接口。

如果對(duì)接口不熟悉,可以先進(jìn)行在線調(diào)試:https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?product=IoTDA&api=ShowDeviceShadow

在線調(diào)試接口,可以請(qǐng)求影子接口,了解請(qǐng)求,與返回的數(shù)據(jù)格式。

調(diào)試完成看右下角的響應(yīng)體,就是返回的影子數(shù)據(jù)。

設(shè)備影子接口返回的數(shù)據(jù)如下:

{
?"device_id":?"663cb18871d845632a0912e7_dev1",
?"shadow": [
? {
? ?"service_id":?"stm32",
? ?"desired": {
? ??"properties": null,
? ??"event_time": null
? ?},
? ?"reported": {
? ??"properties": {
? ? ?"DHT11_T":?18,
? ? ?"DHT11_H":?90,
? ? ?"BH1750":?38,
? ? ?"MQ135":?70
? ? },
? ??"event_time":?"20240509T113448Z"
? ?},
? ?"version":?3
? }
?]
}

調(diào)試成功之后,可以得到訪問(wèn)影子數(shù)據(jù)的真實(shí)鏈接,接下來(lái)的代碼開(kāi)發(fā)中,就采用Qt寫(xiě)代碼訪問(wèn)此鏈接,獲取影子數(shù)據(jù),完成上位機(jī)開(kāi)發(fā)。

鏈接如下:

https://ad635970a1.st1.iotda-app.cn-north-4.myhuaweicloud.com:443/v5/iot/28add376c01e4a61ac8b621c714bf459/devices/663cb18871d845632a0912e7_dev1/shadow

3.10 訪問(wèn)接口的代碼實(shí)現(xiàn)

(1)配置 Qt 項(xiàng)目

在 Qt 項(xiàng)目的?.pro?文件中,加入對(duì)?libcurl?的支持:

QT += core
CONFIG += console
CONFIG -= app_bundle

INCLUDEPATH += /usr/include/curl ?# 根據(jù)你的系統(tǒng)設(shè)置 libcurl 的路徑
LIBS += -lcurl ?# 鏈接 libcurl 庫(kù)

SOURCES += main.cpp

(2)代碼實(shí)現(xiàn)

main.cpp?文件中實(shí)現(xiàn)代碼如下:

#include?<QCoreApplication>
#include?<curl/curl.h>
#include?<QDebug>
#include?<QString>
#include?<QByteArray>

// 回調(diào)函數(shù),處理libcurl下載數(shù)據(jù)
size_t?WriteCallback(void?*contents,?size_t?size,?size_t?nmemb,?void?*userp)?{
? ??size_t?totalSize = size * nmemb;
? ? QByteArray *response =?static_cast<QByteArray *>(userp);
? ? response->append(static_cast<char?*>(contents), totalSize);
? ??return?totalSize;
}

int?main(int?argc,?char?*argv[])?{
? ??QCoreApplication?a(argc, argv);

? ??// 初始化libcurl
? ? CURL *curl;
? ? CURLcode res;
? ? QByteArray responseData; ?// 用于存儲(chǔ)響應(yīng)數(shù)據(jù)

? ??curl_global_init(CURL_GLOBAL_DEFAULT);
? ? curl =?curl_easy_init();
? ??if?(curl) {
? ? ? ??// 設(shè)置訪問(wèn)URL
? ? ? ??const?QString url =?"https://ad635970a1.st1.iotda-app.cn-north-4.myhuaweicloud.com:443/v5/iot/28add376c01e4a61ac8b621c714bf459/devices/663cb18871d845632a0912e7_dev1/shadow";

? ? ? ??// 設(shè)置HTTP請(qǐng)求頭
? ? ? ??struct?curl_slist?*headers =?NULL;
? ? ? ? headers =?curl_slist_append(headers,?"Authorization: Bearer <Your_Access_Token>");?// 這里需要替換為你的實(shí)際 token

? ? ? ??curl_easy_setopt(curl, CURLOPT_URL, url.toStdString().c_str());
? ? ? ??curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
? ? ? ??curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
? ? ? ??curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);

? ? ? ??// 發(fā)起GET請(qǐng)求
? ? ? ? res =?curl_easy_perform(curl);

? ? ? ??if?(res != CURLE_OK) {
? ? ? ? ? ??qDebug() <<?"Curl request failed:"?<<?curl_easy_strerror(res);
? ? ? ? }?else?{
? ? ? ? ? ??qDebug() <<?"Response data:"?<< responseData;
? ? ? ? }

? ? ? ??// 清理
? ? ? ??curl_easy_cleanup(curl);
? ? ? ??curl_slist_free_all(headers);
? ? }

? ??curl_global_cleanup();

? ??return?a.exec();
}

3.11 數(shù)據(jù)解析代碼

在 Qt 中使用 CJSON (一個(gè)用于解析 JSON 數(shù)據(jù)的輕量級(jí) C 庫(kù)) 來(lái)解析返回的 JSON 數(shù)據(jù)。

(1)配置 Qt 項(xiàng)目

在 Qt 項(xiàng)目的?.pro?文件中,確保包括了 CJSON 的頭文件,并鏈接 CJSON 的源代碼。

QT += core
CONFIG += console
CONFIG -= app_bundle

SOURCES += main.cpp 
? ? ? ? ? ?cJSON.c ?# 將 cJSON.c 文件添加到你的項(xiàng)目中

INCLUDEPATH += path/to/cjson/ ?# 添加 CJSON 頭文件的路徑

LIBS += -lcurl ?# 鏈接 libcurl 庫(kù)

(2)解析 JSON 數(shù)據(jù)的完整代碼

在?main.cpp?中,以下代碼展示了如何解析你提供的 JSON 數(shù)據(jù)。

#include?<QCoreApplication>
#include?<curl/curl.h>
#include?<QDebug>
#include?<QString>
#include?<QByteArray>
#include?"cJSON.h"

// 回調(diào)函數(shù),處理libcurl下載數(shù)據(jù)
size_t?WriteCallback(void?*contents,?size_t?size,?size_t?nmemb,?void?*userp)?{
? ??size_t?totalSize = size * nmemb;
? ? QByteArray *response =?static_cast<QByteArray *>(userp);
? ? response->append(static_cast<char?*>(contents), totalSize);
? ??return?totalSize;
}

// 解析 JSON 數(shù)據(jù)
void?parseJson(const?QByteArray &data)?{
? ??// 將 QByteArray 轉(zhuǎn)換為 char*
? ??const?char* jsonData = data.constData();

? ??// 解析 JSON
? ? cJSON *root =?cJSON_Parse(jsonData);
? ??if?(root ==?NULL) {
? ? ? ??qDebug() <<?"Error parsing JSON.";
? ? ? ??return;
? ? }

? ??// 解析 "device_id"
? ? cJSON *deviceId =?cJSON_GetObjectItemCaseSensitive(root,?"device_id");
? ??if?(cJSON_IsString(deviceId) && (deviceId->valuestring !=?NULL)) {
? ? ? ??qDebug() <<?"Device ID:"?<< deviceId->valuestring;
? ? }

? ??// 解析 "shadow" 數(shù)組
? ? cJSON *shadow =?cJSON_GetObjectItemCaseSensitive(root,?"shadow");
? ??if?(cJSON_IsArray(shadow)) {
? ? ? ? cJSON *shadowItem =?NULL;
? ? ? ??cJSON_ArrayForEach(shadowItem, shadow) {
? ? ? ? ? ??// 解析每個(gè) shadow 項(xiàng)目
? ? ? ? ? ? cJSON *serviceId =?cJSON_GetObjectItemCaseSensitive(shadowItem,?"service_id");
? ? ? ? ? ??if?(cJSON_IsString(serviceId) && (serviceId->valuestring !=?NULL)) {
? ? ? ? ? ? ? ??qDebug() <<?"Service ID:"?<< serviceId->valuestring;
? ? ? ? ? ? }

? ? ? ? ? ??// 解析 "reported" 對(duì)象
? ? ? ? ? ? cJSON *reported =?cJSON_GetObjectItemCaseSensitive(shadowItem,?"reported");
? ? ? ? ? ??if?(cJSON_IsObject(reported)) {
? ? ? ? ? ? ? ??// 解析 "properties" 對(duì)象
? ? ? ? ? ? ? ? cJSON *properties =?cJSON_GetObjectItemCaseSensitive(reported,?"properties");
? ? ? ? ? ? ? ??if?(cJSON_IsObject(properties)) {
? ? ? ? ? ? ? ? ? ? cJSON *data1 =?cJSON_GetObjectItemCaseSensitive(properties,?"data1");
? ? ? ? ? ? ? ? ? ??if?(cJSON_IsNumber(data1)) {
? ? ? ? ? ? ? ? ? ? ? ??qDebug() <<?"data1:"?<< data1->valueint;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? cJSON *data2 =?cJSON_GetObjectItemCaseSensitive(properties,?"data2");
? ? ? ? ? ? ? ? ? ??if?(cJSON_IsNumber(data2)) {
? ? ? ? ? ? ? ? ? ? ? ??qDebug() <<?"data2:"?<< data2->valueint;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? cJSON *data3 =?cJSON_GetObjectItemCaseSensitive(properties,?"data3");
? ? ? ? ? ? ? ? ? ??if?(cJSON_IsNumber(data3)) {
? ? ? ? ? ? ? ? ? ? ? ??qDebug() <<?"data3:"?<< data3->valueint;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? cJSON *data4 =?cJSON_GetObjectItemCaseSensitive(properties,?"data4");
? ? ? ? ? ? ? ? ? ??if?(cJSON_IsNumber(data4)) {
? ? ? ? ? ? ? ? ? ? ? ??qDebug() <<?"data4:"?<< data4->valueint;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ??// 解析 "event_time"
? ? ? ? ? ? ? ? cJSON *eventTime =?cJSON_GetObjectItemCaseSensitive(reported,?"event_time");
? ? ? ? ? ? ? ??if?(cJSON_IsString(eventTime) && (eventTime->valuestring !=?NULL)) {
? ? ? ? ? ? ? ? ? ??qDebug() <<?"Event Time:"?<< eventTime->valuestring;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }

? ? ? ? ? ??// 解析 version
? ? ? ? ? ? cJSON *version =?cJSON_GetObjectItemCaseSensitive(shadowItem,?"version");
? ? ? ? ? ??if?(cJSON_IsNumber(version)) {
? ? ? ? ? ? ? ??qDebug() <<?"Version:"?<< version->valueint;
? ? ? ? ? ? }
? ? ? ? }
? ? }

? ??// 釋放 JSON 對(duì)象
? ??cJSON_Delete(root);
}

int?main(int?argc,?char?*argv[])?{
? ??QCoreApplication?a(argc, argv);

? ??// 模擬獲取到的 JSON 數(shù)據(jù)
? ? QByteArray jsonData =?R"(
? ? {
? ? ? ? "device_id": "663cb18871d845632a0912e7_dev1",
? ? ? ? "shadow": [
? ? ? ? ? ? {
? ? ? ? ? ? ? ? "service_id": "stm32",
? ? ? ? ? ? ? ? "desired": {
? ? ? ? ? ? ? ? ? ? "properties": null,
? ? ? ? ? ? ? ? ? ? "event_time": null
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? "reported": {
? ? ? ? ? ? ? ? ? ? "properties": {
? ? ? ? ? ? ? ? ? ? ? ? "data1": 18,
? ? ? ? ? ? ? ? ? ? ? ? "data2": 90,
? ? ? ? ? ? ? ? ? ? ? ? "data3": 38,
? ? ? ? ? ? ? ? ? ? ? ? "data4": 70
? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? "event_time": "20240509T113448Z"
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? "version": 3
? ? ? ? ? ? }
? ? ? ? ]
? ? })";

? ??// 調(diào)用解析函數(shù)
? ??parseJson(jsonData);

? ??return?a.exec();
}

四、STM32設(shè)備端代碼設(shè)計(jì)

下面給出的?STM32F103C8T6?主控的?main.c?代碼框架,各子模塊(PH傳感器采集、DS18B20水溫讀取、485串口溶解氧讀取、水位傳感器ADC采集、TDS傳感器ADC采集、OLED顯示、4G模塊MQTT通信、蜂鳴器報(bào)警)均有對(duì)應(yīng)的驅(qū)動(dòng)和接口函數(shù)。


設(shè)計(jì)思路(整體代碼)

STM32主程序設(shè)計(jì)采用基于寄存器的編程方式,代碼結(jié)構(gòu)清晰,模塊化管理。系統(tǒng)啟動(dòng)后,初始化所有硬件外設(shè)和通信接口(ADC、UART、I2C、GPIO等),然后進(jìn)入主循環(huán)。

主循環(huán)中依次進(jìn)行各傳感器數(shù)據(jù)采集,通過(guò)ADC讀取模擬傳感器電壓,串口通信讀取溶解氧傳感器數(shù)據(jù),數(shù)字接口讀取DS18B20溫度數(shù)據(jù)。采集到的原始數(shù)據(jù)經(jīng)過(guò)校準(zhǔn)和算法轉(zhuǎn)換,得到實(shí)際物理值。

隨后將所有傳感器數(shù)據(jù)更新到OLED屏幕,實(shí)現(xiàn)本地實(shí)時(shí)顯示。同時(shí),系統(tǒng)根據(jù)預(yù)設(shè)閾值判斷是否產(chǎn)生報(bào)警,控制蜂鳴器提示。周期性地將完整數(shù)據(jù)打包成JSON格式,通過(guò)UART驅(qū)動(dòng)的4G模塊發(fā)送MQTT消息上傳到華為云物聯(lián)網(wǎng)平臺(tái)。

系統(tǒng)通過(guò)定時(shí)器或延時(shí)函數(shù)控制采樣和上傳頻率,確保實(shí)時(shí)性和穩(wěn)定性。異常處理包括傳感器故障檢測(cè)和通信錯(cuò)誤重試機(jī)制,保障系統(tǒng)可靠運(yùn)行。


main.c 示例代碼

#include?"stm32f10x.h"
#include?"adc.h"
#include?"usart.h"
#include?"i2c.h"
#include?"oled.h"
#include?"ds18b20.h"
#include?"ph_sensor.h"
#include?"do_sensor.h"
#include?"tds_sensor.h"
#include?"water_level_sensor.h"
#include?"buzzer.h"
#include?"mqtt_4g.h"
#include?"json_utils.h"??// 自定義JSON封裝函數(shù)

// 采樣與上傳周期 (單位: ms)
#define?SAMPLE_INTERVAL 5000
#define?UPLOAD_INTERVAL 60000

// 傳感器數(shù)據(jù)結(jié)構(gòu)體
typedef?struct?{
? ??float?waterTemp;
? ??float?phValue;
? ??float?dissolvedOxygen;
? ??float?waterLevel;
? ??float?tdsValue;
? ??uint8_t?alarmStatus;
} WaterData_t;

static?WaterData_t g_waterData;

void?SystemClock_Config(void);
void?Periph_Init(void);
void?Delay_ms(uint32_t?ms);
uint8_t?Check_Alarm(const?WaterData_t *data);

int?main(void)
{
? ? SystemClock_Config();
? ? Periph_Init();

? ??uint32_t?lastSampleTime =?0;
? ??uint32_t?lastUploadTime =?0;

? ??while(1)
? ? {
? ? ? ??uint32_t?currentTime = GetSysTick_ms();

? ? ? ??// 定時(shí)采樣
? ? ? ??if(currentTime - lastSampleTime >= SAMPLE_INTERVAL)
? ? ? ? {
? ? ? ? ? ? lastSampleTime = currentTime;

? ? ? ? ? ??// 讀取各傳感器數(shù)據(jù)
? ? ? ? ? ? g_waterData.waterTemp = DS18B20_ReadTemperature();
? ? ? ? ? ? g_waterData.phValue = PH_GetValue(); ? ? ? ? ?// 模擬量轉(zhuǎn)換并校準(zhǔn)
? ? ? ? ? ? g_waterData.dissolvedOxygen = DO_ReadValue();?// 485串口讀取
? ? ? ? ? ? g_waterData.waterLevel = WaterLevel_ReadADC();// ADC讀取
? ? ? ? ? ? g_waterData.tdsValue = TDS_ReadValue(); ? ? ??// ADC讀取并算法轉(zhuǎn)換

? ? ? ? ? ??// 判斷報(bào)警狀態(tài)
? ? ? ? ? ? g_waterData.alarmStatus = Check_Alarm(&g_waterData);

? ? ? ? ? ??// OLED顯示更新
? ? ? ? ? ? OLED_Clear();
? ? ? ? ? ? OLED_ShowString(0,?0,?"Water Temp:");
? ? ? ? ? ? OLED_ShowFloat(80,?0, g_waterData.waterTemp,?1);
? ? ? ? ? ? OLED_ShowString(0,?2,?"PH Value:");
? ? ? ? ? ? OLED_ShowFloat(80,?2, g_waterData.phValue,?2);
? ? ? ? ? ? OLED_ShowString(0,?4,?"DO mg/L:");
? ? ? ? ? ? OLED_ShowFloat(80,?4, g_waterData.dissolvedOxygen,?2);
? ? ? ? ? ? OLED_ShowString(0,?6,?"Water Level:");
? ? ? ? ? ? OLED_ShowFloat(80,?6, g_waterData.waterLevel,?1);
? ? ? ? ? ? OLED_ShowString(0,?8,?"TDS ppm:");
? ? ? ? ? ? OLED_ShowFloat(80,?8, g_waterData.tdsValue,?0);

? ? ? ? ? ??if(g_waterData.alarmStatus)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Buzzer_On();
? ? ? ? ? ? }
? ? ? ? ? ??else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Buzzer_Off();
? ? ? ? ? ? }
? ? ? ? }

? ? ? ??// 定時(shí)上傳
? ? ? ??if(currentTime - lastUploadTime >= UPLOAD_INTERVAL)
? ? ? ? {
? ? ? ? ? ? lastUploadTime = currentTime;

? ? ? ? ? ??// 組裝JSON數(shù)據(jù)
? ? ? ? ? ??char?jsonData[256];
? ? ? ? ? ? Json_CreateWaterDataJson(&g_waterData, jsonData,?sizeof(jsonData));

? ? ? ? ? ??// 通過(guò)4G模塊上傳
? ? ? ? ? ? MQTT_4G_Publish(jsonData);
? ? ? ? }
? ? }
}

// 報(bào)警判斷邏輯示例
uint8_t?Check_Alarm(const?WaterData_t *data)
{
? ??if(data->phValue <?6.5f?|| data->phValue >?8.5f)
? ? ? ??return?1;
? ??if(data->dissolvedOxygen <?4.0f)
? ? ? ??return?1;
? ??if(data->tdsValue >?1000)
? ? ? ??return?1;
? ??// 根據(jù)需要擴(kuò)展報(bào)警條件
? ??return?0;
}

// 初始化所有外設(shè)
void?Periph_Init(void)
{
? ? ADC_Init_Config();
? ? USART1_Init(115200);?// 4G模塊串口
? ? USART2_Init(9600); ??// 485串口(溶解氧)
? ? I2C_Init();
? ? OLED_Init();
? ? DS18B20_Init();
? ? PH_Sensor_Init();
? ? DO_Sensor_Init();
? ? TDS_Sensor_Init();
? ? WaterLevel_Sensor_Init();
? ? Buzzer_Init();
? ? MQTT_4G_Init();
}

// 系統(tǒng)時(shí)鐘配置及systick定時(shí)器配置,具體由你實(shí)現(xiàn)
void?SystemClock_Config(void)
{
? ??// 省略具體時(shí)鐘初始化代碼
}

// 獲取系統(tǒng)運(yùn)行時(shí)間(毫秒)
uint32_t?GetSysTick_ms(void)
{
? ??// systick中斷已配置,每1ms遞增一個(gè)計(jì)數(shù)
? ??extern?volatile?uint32_t?sysTickCounter;
? ??return?sysTickCounter;
}

五、上位機(jī)開(kāi)發(fā)

為了方便查看設(shè)備上傳的數(shù)據(jù),接下來(lái)利用Qt開(kāi)發(fā)一款A(yù)ndroid手機(jī)APP 和 Windows上位機(jī)。

使用華為云平臺(tái)提供的API接口獲取設(shè)備上傳的數(shù)據(jù),進(jìn)行可視化顯示,以及遠(yuǎn)程控制設(shè)備。

5.1 Qt開(kāi)發(fā)環(huán)境安裝

Qt的中文官網(wǎng): https://www.qt.io/zh-cn/![image-20221207160550486](https://led-obs.obs.cn-north-1.myhuaweicloud.com/Blog/img/image-20221207160550486.png)

QT5.12.6的下載地址:https://download.qt.io/archive/qt/5.12/5.12.6

打開(kāi)下載鏈接后選擇下面的版本進(jìn)行下載:

如果下載不了,可以在網(wǎng)盤(pán)里找到安裝包下載:?https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink

軟件安裝時(shí)斷網(wǎng)安裝,否則會(huì)提示輸入賬戶。

安裝的時(shí)候,第一個(gè)復(fù)選框里的編譯器可以全選,直接點(diǎn)擊下一步繼續(xù)安裝。

選擇編譯器: (一定要看清楚了)

前面2講解了需要用的API接口,接下來(lái)就使用Qt設(shè)計(jì)上位機(jī),設(shè)計(jì)界面,完成整體上位機(jī)的邏輯設(shè)計(jì)。

【1】新建工程

【2】設(shè)置項(xiàng)目的名稱。

【3】選擇編譯系統(tǒng)

【4】選擇默認(rèn)繼承的類

【5】選擇編譯器

【6】點(diǎn)擊完成

【7】工程創(chuàng)建完成

5.3 切換編譯器

在左下角是可以切換編譯器的。 可以選擇用什么樣的編譯器編譯程序。

目前新建工程的時(shí)候選擇了2種編譯器。 一種是mingw32這個(gè)編譯Windows下運(yùn)行的程序。 一種是Android編譯器,可以生成Android手機(jī)APP。

不過(guò)要注意:Android的編譯器需要配置一些環(huán)境才可以正常使用,這個(gè)大家可以看下面的教程配置一下就行了。

Android環(huán)境搭建的博客鏈接:?https://blog.csdn.net/xiaolong1126626497/article/details/117254453

windows的編譯器就沒(méi)有這么麻煩,安裝好Qt就可以編譯使用。

下面我這里就選擇的?mingw32這個(gè)編譯器,編譯Windows下運(yùn)行的程序。

5.4 編譯測(cè)試功能

創(chuàng)建完畢之后,編譯測(cè)試一下功能是否OK。

點(diǎn)擊左下角的綠色三角形按鈕。

正常運(yùn)行就可以看到彈出一個(gè)白色的框框。這就表示工程環(huán)境沒(méi)有問(wèn)題了。 接下來(lái)就可以放心的設(shè)計(jì)界面了。

5.5 設(shè)計(jì)UI界面與工程配置

【1】打開(kāi)UI文件

打開(kāi)默認(rèn)的界面如下:

【2】開(kāi)始設(shè)計(jì)界面

根據(jù)自己需求設(shè)計(jì)界面。

5.5 編譯Windows上位機(jī)

點(diǎn)擊軟件左下角的綠色三角形按鈕進(jìn)行編譯運(yùn)行。

5.6 配置Android環(huán)境

如果想編譯Android手機(jī)APP,必須要先自己配置好自己的Android環(huán)境。(搭建環(huán)境的過(guò)程可以自行百度搜索學(xué)習(xí))

然后才可以進(jìn)行下面的步驟。

【1】選擇Android編譯器

選擇編譯器。

切換編譯器。

【2】創(chuàng)建Android配置文件

創(chuàng)建完成。

【3】配置Android圖標(biāo)與名稱

【3】編譯Android上位機(jī)

Qt本身是跨平臺(tái)的,直接選擇Android的編譯器,就可以將程序編譯到Android平臺(tái)。

然后點(diǎn)擊構(gòu)建。

成功之后,在目錄下可以看到生成的apk文件,也就是Android手機(jī)的安裝包,電腦端使用QQ發(fā)送給手機(jī)QQ,手機(jī)登錄QQ接收,就能直接安裝。

生成的apk的目錄在哪里呢? 編譯完成之后,在控制臺(tái)會(huì)輸出APK文件的路徑。

知道目錄在哪里之后,在Windows的文件資源管理器里,找到路徑,具體看下圖,找到生成的apk文件。

? -- File: D:/QtProject/build-265_AgritechIoTManager-Android_for_arm64_v8a_Clang_Qt_5_12_6_for_Android_ARM64_v8a-Release/android-build//build/outputs/apk/debug/android-build-debug.apk

六、總結(jié)

本項(xiàng)目基于STM32F103C8T6主控芯片,設(shè)計(jì)實(shí)現(xiàn)了一個(gè)集水溫、PH值、溶解氧、水位和TDS電導(dǎo)率多參數(shù)檢測(cè)于一體的水資源環(huán)境監(jiān)測(cè)系統(tǒng)。系統(tǒng)通過(guò)高精度傳感器采集關(guān)鍵水質(zhì)指標(biāo),利用OLED顯示屏實(shí)現(xiàn)本地?cái)?shù)據(jù)實(shí)時(shí)展示,保證現(xiàn)場(chǎng)監(jiān)測(cè)的直觀性與便捷性。結(jié)合Air780E 4G模塊和MQTT協(xié)議,系統(tǒng)將采集的數(shù)據(jù)穩(wěn)定可靠地上傳至華為云物聯(lián)網(wǎng)平臺(tái),支持遠(yuǎn)程監(jiān)控與歷史數(shù)據(jù)查詢,極大提升了數(shù)據(jù)管理的智能化和自動(dòng)化水平。

此外,系統(tǒng)設(shè)計(jì)中充分考慮了異常報(bào)警功能,能夠及時(shí)發(fā)現(xiàn)并反饋水質(zhì)異常,保障環(huán)境安全。Android手機(jī)APP和Windows上位機(jī)軟件的雙平臺(tái)設(shè)計(jì),實(shí)現(xiàn)了多終端的遠(yuǎn)程數(shù)據(jù)訪問(wèn)與管理,滿足不同用戶的使用需求。整體方案采用寄存器級(jí)STM32編程,提升了系統(tǒng)的穩(wěn)定性和響應(yīng)速度,兼顧硬件性能與軟件效率。

本項(xiàng)目的完成不僅驗(yàn)證了基于STM32的多參數(shù)水質(zhì)監(jiān)測(cè)系統(tǒng)的可行性和實(shí)用性,也為后續(xù)環(huán)境監(jiān)測(cè)設(shè)備的智能化升級(jí)提供了可靠的技術(shù)參考,具有較高的應(yīng)用推廣價(jià)值和社會(huì)意義。

相關(guān)推薦