国产成人高清亚洲,日韩无码一区二区,国产精品亚洲综合专区片高清久久久,欧美日韩国产区在线观看,sese在线,亞洲綜合久久精品無碼色欲,日韩亚洲av三级片

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

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

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

一、前言

1.1 項目開發(fā)背景

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1.3 項目硬件模塊組成

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

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

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

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

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

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

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

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

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

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

1.4 設(shè)計思路

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

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

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

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

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

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

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

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

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

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

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

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

【2】上位機開發(fā)

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

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

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

在華為云 IoT 平臺定義以下字段屬性:

字段名稱(標識符) 數(shù)據(jù)類型 單位 描述 示例值
waterTemp float 水溫 22.5
phValue float 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ù)據(jù)上傳時間 2025-06-05T12:30:00
alarmStatus int 異常報警狀態(tài)(0正常,1異常) 0

說明:

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

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

? uploadTime 可以作為歷史數(shù)據(jù)存儲和查詢依據(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)前項目使用的相關(guān)軟件工具、模塊源碼已經(jīng)上傳到網(wǎng)盤:https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink

2.1 STM32F102C8T6

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

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

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

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

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

2.2 Air780e

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

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

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

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

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

2.3 TDS傳感器

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

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

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

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

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

2.4 溶解氧傳感器

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

開通免費單元。

點擊立即創(chuàng)建

正在創(chuàng)建標準版實例,需要等待片刻。

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

下面框起來的就是端口號域名

點擊實例名稱,可以查看當(dāng)前免費單元的配置情況。

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

總結(jié):

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

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

打開Windows電腦的命令行控制臺終端,使用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ù):
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時間=37ms TTL=44
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時間=37ms TTL=44
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時間=37ms TTL=44
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時間=37ms TTL=44

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

C:UsersLenovo>

MQTT協(xié)議接入端口號有兩個,1883是非加密端口,8883是證書加密端口,單片機無法加載證書,所以使用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)填寫產(chǎn)品信息

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

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

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

(4)添加自定義模型

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

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

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

比如:

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

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

字段名稱(標識符) 數(shù)據(jù)類型 單位 描述 示例值
waterTemp float 水溫 22.5
phValue float 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ù)據(jù)上傳時間 2025-06-05T12:30:00
alarmStatus int 異常報警狀態(tài)(0正常,1異常) 0

說明:

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

int

    • 、

float

    • 、

string

boolean

    • 。?

alarmStatus

    • ?可用于報警提示功能,如當(dāng)PH超標、TDS過高等時上傳

1

    • 。?

uploadTime

    ?可以作為歷史數(shù)據(jù)存儲和查詢依據(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 平臺創(chuàng)建產(chǎn)品后,可以在?產(chǎn)品模型 > 服務(wù) > 屬性?中添加上述字段,并配置設(shè)備上傳的 Topic。STM32 端通過 AT 指令控制 4G 模塊(Air780E)連接 MQTT Broker,將這些字段打包為 JSON 并上報即可。

先點擊自定義模型。

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

接著點擊新增屬性。

3.4 添加設(shè)備

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

(1)注冊設(shè)備

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

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

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

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

(5)設(shè)備詳情

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

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

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

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

MQTT是一種消息隊列協(xié)議,使用發(fā)布/訂閱消息模式,提供一對多的消息發(fā)布,解除應(yīng)用程序耦合,相對于其他協(xié)議,開發(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é)議,就可以與華為云平臺完成通信。

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

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

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

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

(3)主題訂閱格式

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

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

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

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

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

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

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

這個操作稱為:屬性上報。

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

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

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

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

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

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

3.6 MQTT三元組

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

接下來介紹,華為云平臺的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 是加密端口更加安全。但是單片機上使用比較困難,所以當(dāng)前的設(shè)備是采用1883端口進連接的。

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

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

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

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

(2)生成MQTT三元組

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

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

下面是打開的頁面:

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

直接得到三元組信息。

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

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

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

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

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

(1)填入登錄信息

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

(2)打開網(wǎng)頁查看

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

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

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

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

MQTT服務(wù)器: ?117.78.5.125
MQTT端口號: ?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)建一個IAM賬戶,因為接下來開發(fā)上位機,需要使用云平臺的API接口,這些接口都需要token進行鑒權(quán)。來說,就是身份的認證。 調(diào)用接口獲取Token時,就需要填寫IAM賬號信息。所以,接下來演示一下過程。

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

**【1】獲取項目憑證 ** 點擊左上角用戶名,選擇下拉菜單里的我的憑證

項目憑證:

28add376c01e4a61ac8b621c714bf459

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

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

點擊左上角創(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è)備影子是一個用于存儲和檢索設(shè)備當(dāng)前狀態(tài)信息的JSON文檔。
每個設(shè)備有且只有一個設(shè)備影子,由設(shè)備ID唯一標識
設(shè)備影子僅保存最近一次設(shè)備的上報數(shù)據(jù)和預(yù)期數(shù)據(jù)
無論該設(shè)備是否在線,都可以通過該影子獲取和設(shè)置設(shè)備的屬性

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

我們設(shè)計的軟件里,如果想要獲取設(shè)備的最新狀態(tài)信息,就采用設(shè)備影子接口。

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

在線調(diào)試接口,可以請求影子接口,了解請求,與返回的數(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)試成功之后,可以得到訪問影子數(shù)據(jù)的真實鏈接,接下來的代碼開發(fā)中,就采用Qt寫代碼訪問此鏈接,獲取影子數(shù)據(jù),完成上位機開發(fā)。

鏈接如下:

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

3.10 訪問接口的代碼實現(xiàn)

(1)配置 Qt 項目

在 Qt 項目的?.pro?文件中,加入對?libcurl?的支持:

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

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

SOURCES += main.cpp

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

main.cpp?文件中實現(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; ?// 用于存儲響應(yīng)數(shù)據(jù)

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

? ? ? ??// 設(shè)置HTTP請求頭
? ? ? ??struct?curl_slist?*headers =?NULL;
? ? ? ? headers =?curl_slist_append(headers,?"Authorization: Bearer <Your_Access_Token>");?// 這里需要替換為你的實際 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請求
? ? ? ? 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 (一個用于解析 JSON 數(shù)據(jù)的輕量級 C 庫) 來解析返回的 JSON 數(shù)據(jù)。

(1)配置 Qt 項目

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

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

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

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

LIBS += -lcurl ?# 鏈接 libcurl 庫

(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) {
? ? ? ? ? ??// 解析每個 shadow 項目
? ? ? ? ? ? cJSON *serviceId =?cJSON_GetObjectItemCaseSensitive(shadowItem,?"service_id");
? ? ? ? ? ??if?(cJSON_IsString(serviceId) && (serviceId->valuestring !=?NULL)) {
? ? ? ? ? ? ? ??qDebug() <<?"Service ID:"?<< serviceId->valuestring;
? ? ? ? ? ? }

? ? ? ? ? ??// 解析 "reported" 對象
? ? ? ? ? ? cJSON *reported =?cJSON_GetObjectItemCaseSensitive(shadowItem,?"reported");
? ? ? ? ? ??if?(cJSON_IsObject(reported)) {
? ? ? ? ? ? ? ??// 解析 "properties" 對象
? ? ? ? ? ? ? ? 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 對象
? ??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è)計

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


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

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

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

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

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


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();

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

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

? ? ? ? ? ??// 判斷報警狀態(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();
? ? ? ? ? ? }
? ? ? ? }

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

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

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

// 報警判斷邏輯示例
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ù)需要擴展報警條件
? ??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)時鐘配置及systick定時器配置,具體由你實現(xiàn)
void?SystemClock_Config(void)
{
? ??// 省略具體時鐘初始化代碼
}

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

五、上位機開發(fā)

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

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

5.1 Qt開發(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

打開下載鏈接后選擇下面的版本進行下載:

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

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

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

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

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

【1】新建工程

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

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

【4】選擇默認繼承的類

【5】選擇編譯器

【6】點擊完成

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

5.3 切換編譯器

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

目前新建工程的時候選擇了2種編譯器。 一種是mingw32這個編譯Windows下運行的程序。 一種是Android編譯器,可以生成Android手機APP。

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

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

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

下面我這里就選擇的?mingw32這個編譯器,編譯Windows下運行的程序。

5.4 編譯測試功能

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

點擊左下角的綠色三角形按鈕。

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

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

【1】打開UI文件

打開默認的界面如下:

【2】開始設(shè)計界面

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

5.5 編譯Windows上位機

點擊軟件左下角的綠色三角形按鈕進行編譯運行。

5.6 配置Android環(huán)境

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

然后才可以進行下面的步驟。

【1】選擇Android編譯器

選擇編譯器。

切換編譯器。

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

創(chuàng)建完成。

【3】配置Android圖標與名稱

【3】編譯Android上位機

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

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

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

生成的apk的目錄在哪里呢? 編譯完成之后,在控制臺會輸出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é)

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

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

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

相關(guān)推薦