一、前言
1.1 項目開發(fā)背景
水資源作為人類賴以生存和發(fā)展的基礎性自然資源,其質量直接關系到生態(tài)環(huán)境的可持續(xù)發(fā)展和人民群眾的生命健康。隨著工業(yè)化與城鎮(zhèn)化的快速推進,水體污染問題日益嚴重,水資源的保護與科學管理已成為全球關注的重要議題。為了實現(xiàn)對水環(huán)境的高效監(jiān)測與管理,亟需構建一套集成化、智能化的水資源環(huán)境監(jiān)測系統(tǒng),實現(xiàn)水質數(shù)據的實時采集、分析、傳輸與展示,為環(huán)境治理提供數(shù)據支撐與決策依據。
傳統(tǒng)的水質監(jiān)測方法多以人工采樣與實驗室分析為主,周期長、效率低,難以及時反映動態(tài)變化的水質狀況,無法滿足當前水環(huán)境實時監(jiān)控的需求。借助嵌入式技術、物聯(lián)網通信技術及傳感器技術的發(fā)展,構建基于STM32嵌入式平臺的智能水環(huán)境監(jiān)測系統(tǒng)成為一種可行而有效的方案。該系統(tǒng)通過多種水質傳感器實現(xiàn)對水溫、pH值、溶解氧、電導率、水位等參數(shù)的連續(xù)自動監(jiān)測,并通過無線通信方式將數(shù)據實時上傳至物聯(lián)網平臺,實現(xiàn)遠程監(jiān)控與報警。
本項目基于STM32F103C8T6單片機作為主控核心,結合DS18B20、pH傳感器、溶解氧傳感器、TDS電導率傳感器、水位傳感器等多種模塊構建多參數(shù)水質檢測系統(tǒng),通過IIC接口實現(xiàn)本地OLED顯示,結合Air780E 4G通信模塊實現(xiàn)遠程數(shù)據上傳。項目采用MQTT協(xié)議接入華為云物聯(lián)網平臺,同時配套開發(fā)基于Qt(C++)的Android手機APP和Windows上位機,用于數(shù)據可視化展示和歷史數(shù)據分析,提升系統(tǒng)的可用性與智能化水平。
系統(tǒng)還集成了高電平觸發(fā)蜂鳴器,在監(jiān)測數(shù)據出現(xiàn)異常時可實現(xiàn)現(xiàn)場聲光報警,有效提升應急響應能力。該系統(tǒng)具有部署靈活、運行穩(wěn)定、實時性強等優(yōu)點,廣泛適用于河流、湖泊、水庫、水產養(yǎng)殖、污水處理等多種場景,對于推動水環(huán)境保護信息化、智能化具有重要現(xiàn)實意義和應用價值。
1.2 設計實現(xiàn)的功能
(1)水溫檢測功能:通過DS18B20防水溫度傳感器對水體溫度進行實時監(jiān)測,并將數(shù)據傳送至主控芯片處理。
(2)pH值檢測功能:采用模擬量輸出的pH傳感器對水體酸堿度進行檢測,經ADC采集并通過算法轉換為實際pH值。
(3)溶解氧檢測功能:采用485接口輸出的溶解氧傳感器,通過485轉串口模塊與STM32通信,實時獲取水中溶解氧濃度。
(4)水位檢測功能:使用電阻式模擬量輸出的水位傳感器,實現(xiàn)水體液位的實時監(jiān)測,并通過ADC接口采集。
(5)TDS電導率檢測功能:通過TDS傳感器采集水體的電導率信息,反映水中溶解固體物的含量。
(6)OLED本地顯示功能:通過0.96寸IIC接口OLED屏,實時顯示采集的水溫、pH值、溶解氧、水位、電導率等關鍵參數(shù),便于現(xiàn)場查看。
(7)數(shù)據上云功能:利用Air780E 4G模塊,通過MQTT協(xié)議將采集的所有水質參數(shù)上傳至華為云IoT物聯(lián)網平臺,實現(xiàn)遠程數(shù)據可視化管理。
(8)遠程APP與上位機顯示功能:基于Qt(C++)開發(fā)Android手機APP與Windows上位機,接收云端數(shù)據并以圖表方式進行可視化展示,支持實時查看與歷史數(shù)據查詢。
(9)歷史數(shù)據記錄與折線圖查看功能:Android APP端支持每日歷史數(shù)據的存儲和查詢功能,用戶可通過折線圖形式查看各項水質指標的變化趨勢。
(10)異常報警功能:當系統(tǒng)監(jiān)測到水質參數(shù)異常(如超出設定閾值)時,觸發(fā)高電平蜂鳴器進行現(xiàn)場聲響報警,提示相關人員及時處理。
1.3 項目硬件模塊組成
(1)STM32F103C8T6主控模塊:作為系統(tǒng)的核心控制單元,負責采集傳感器數(shù)據、數(shù)據處理、本地顯示和數(shù)據上傳等任務。
(2)DS18B20水溫傳感器模塊:用于實時采集水體溫度數(shù)據,具有防水封裝,通信方式為單總線接口。
(3)pH值檢測傳感器模塊:輸出模擬電壓信號,通過STM32的ADC采樣接口讀取,結合公式算法換算出實際pH值。
(4)溶解氧傳感器模塊:采用RS485接口輸出,通過485轉TTL串口模塊連接STM32,實現(xiàn)對水體溶解氧濃度的讀取。
(5)水位檢測模塊:使用電阻式模擬量輸出的水位傳感器,通過STM32的ADC接口獲取水位高度信息。
(6)TDS電導率傳感器模塊:模擬量輸出,檢測水中溶解固體的電導率值,通過ADC采集處理。
(7)OLED顯示模塊:采用0.96寸IIC通信接口,用于實時顯示采集到的水溫、pH值、溶解氧、水位、電導率等數(shù)據。
(8)Air780E 4G通信模塊:負責將處理后的水質數(shù)據通過MQTT協(xié)議上傳至華為云IoT物聯(lián)網平臺,實現(xiàn)遠程數(shù)據通信。
(9)蜂鳴器模塊:采用高電平觸發(fā)方式,在檢測數(shù)據異常時發(fā)出聲響警報,用于本地故障提示。
(10)485轉串口通信模塊:用于將溶解氧傳感器的RS485信號轉換為STM32可識別的TTL串口信號,實現(xiàn)串口數(shù)據通信。
1.4 設計思路
本項目設計一套基于STM32的水資源環(huán)境監(jiān)測系統(tǒng),實現(xiàn)多項水質參數(shù)的實時監(jiān)測、本地顯示、遠程上傳和異常報警等功能。系統(tǒng)整體設計思路遵循“模塊化、集成化、智能化”的原則,圍繞數(shù)據采集、數(shù)據處理、數(shù)據傳輸與數(shù)據展示四個核心環(huán)節(jié)進行系統(tǒng)開發(fā)。
在數(shù)據采集部分,系統(tǒng)選用多種水質傳感器模塊,分別用于采集水溫、pH值、溶解氧、水位和電導率等核心水質指標。其中,溫度傳感器DS18B20通過單總線通信方式獲取數(shù)據;pH值和TDS電導率采用模擬量輸出方式,STM32通過ADC模塊進行電壓采樣并結合算法轉換為實際值;水位傳感器同樣輸出模擬信號,方便讀取液位變化;溶解氧傳感器則通過RS485通信輸出,經過485轉串口模塊后接入STM32的串口讀取。通過合理搭配通信協(xié)議和接口資源,實現(xiàn)了多參數(shù)、多通道的水質數(shù)據采集。
在數(shù)據處理與顯示方面,STM32F103C8T6主控芯片作為系統(tǒng)核心,負責各項傳感器數(shù)據的采集調度與數(shù)值處理。處理后的數(shù)據通過IIC接口發(fā)送至0.96寸OLED顯示屏,便于現(xiàn)場查看當前水質狀態(tài)。系統(tǒng)設計時充分考慮資源優(yōu)化,確保多個模塊協(xié)同工作,避免通信沖突和資源浪費。
在數(shù)據傳輸部分,系統(tǒng)集成了Air780E 4G模塊,實現(xiàn)遠程無線通信。選用輕量級的MQTT協(xié)議,將處理后的數(shù)據通過4G網絡上傳至華為云物聯(lián)網平臺,確保數(shù)據上傳的穩(wěn)定性和實時性。MQTT協(xié)議具有發(fā)布/訂閱機制,能夠降低網絡帶寬消耗,提高通信效率,特別適合物聯(lián)網設備的低功耗、低帶寬應用場景。
為實現(xiàn)遠程數(shù)據展示與分析,系統(tǒng)配套開發(fā)Android手機APP與Windows上位機軟件,采用Qt(C++)設計,支持從華為云物聯(lián)網平臺接收數(shù)據并進行可視化展示。APP端還支持歷史數(shù)據存儲與查看功能,用戶可按日期查詢歷史記錄,并以折線圖形式分析水質變化趨勢。通過跨平臺設計,實現(xiàn)了移動端與PC端的無縫對接。
系統(tǒng)具備異常報警功能,當監(jiān)測到某項參數(shù)超過預設閾值時,STM32將自動驅動蜂鳴器報警,實現(xiàn)現(xiàn)場預警,增強系統(tǒng)的安全性和響應能力。整體系統(tǒng)硬件采用模塊化結構設計,便于后期擴展與維護,同時提升了項目的穩(wěn)定性和實用性。
1.5 系統(tǒng)功能總結
功能模塊 | 實現(xiàn)內容 | 硬件支持 | 通信方式 |
---|---|---|---|
水溫檢測 | 實時監(jiān)測水體溫度 | DS18B20溫度傳感器 | 單總線 |
pH值檢測 | 檢測水體酸堿度,轉換為實際pH值顯示 | 模擬pH傳感器 | 模擬量 → ADC |
溶解氧檢測 | 檢測水中溶解氧濃度 | 溶解氧傳感器 + 485轉串口模塊 | RS485 → TTL串口 |
水位檢測 | 實時監(jiān)測水位高度 | 電阻式水位傳感器 | 模擬量 → ADC |
TDS電導率檢測 | 檢測水體中溶解固體含量的電導率 | TDS電導率傳感器 | 模擬量 → ADC |
本地顯示 | 實時顯示各項水質數(shù)據(溫度、pH、溶解氧、水位、電導率) | 0.96寸OLED顯示屏(IIC接口) | IIC通信 |
數(shù)據上傳 | 將采集數(shù)據上傳至華為云IoT平臺 | Air780E 4G模塊 | MQTT協(xié)議(4G網絡) |
遠程數(shù)據顯示 | 在Android APP和Windows上位機端查看實時及歷史數(shù)據,支持折線圖顯示 | Qt開發(fā)APP與上位機 | MQTT訂閱(云端同步) |
歷史數(shù)據管理 | APP端支持每日數(shù)據存儲與查詢,圖形化展示水質變化 | Android手機APP | 本地+云端數(shù)據同步 |
異常報警 | 當數(shù)據異常超閾值,蜂鳴器報警提醒 | 高電平觸發(fā)蜂鳴器 | IO控制 |
1.6 開發(fā)工具的選擇
【1】設備端開發(fā)
STM32的編程語言選擇C語言,C語言執(zhí)行效率高,大學里主學的C語言,C語言編譯出來的可執(zhí)行文件最接近于機器碼,匯編語言執(zhí)行效率最高,但是匯編的移植性比較差,目前在一些操作系統(tǒng)內核里還有一些低配的單片機使用的較多,平常的單片機編程還是以C語言為主。C語言的執(zhí)行效率僅次于匯編,語法理解、代碼通用性強,也支持跨平臺,在嵌入式底層、單片機編程里用的非常多,當前的設計就是采用C語言開發(fā)。
開發(fā)工具選擇Keil,keil是一家世界領先的嵌入式微控制器軟件開發(fā)商,在2015年,keil被ARM公司收購。因為當前芯片選擇的是STM32F103系列,STMF103是屬于ARM公司的芯片構架、Cortex-M3內核系列的芯片,所以使用Kile來開發(fā)STM32是有先天優(yōu)勢的,而keil在各大高校使用的也非常多,很多教科書里都是以keil來教學,開發(fā)51單片機、STM32單片機等等。目前作為MCU芯片開發(fā)的軟件也不只是keil一家獨大,IAR在MCU微處理器開發(fā)領域里也使用的非常多,IAR擴展性更強,也支持STM32開發(fā),也支持其他芯片,比如:CC2530,51單片機的開發(fā)。從軟件的使用上來講,IAR比keil更加簡潔,功能相對少一些。如果之前使用過keil,而且使用頻率較多,已經習慣再使用IAR是有點不適應界面的。
【2】上位機開發(fā)
上位機的開發(fā)選擇Qt框架,編程語言采用C++;Qt是一個1991年由Qt Company開發(fā)的跨平臺C++圖形用戶界面應用程序開發(fā)框架。它既可以開發(fā)GUI程序,也可用于開發(fā)非GUI程序,比如控制臺工具和服務器。Qt是面向對象的框架,使用特殊的代碼生成擴展(稱為元對象編譯器(Meta Object Compiler, moc))以及一些宏,Qt很容易擴展,并且允許真正地組件編程。Qt能輕松創(chuàng)建具有原生C++性能的連接設備、用戶界面(UI)和應用程序。它功能強大且結構緊湊,擁有直觀的工具和庫。
1.7 數(shù)據交互字段
在將本項目采集的數(shù)據上傳至 華為云 IoT 物聯(lián)網平臺 時,需要為設備模型(即產品模型)定義一組字段屬性(屬性服務),用于描述設備采集到的各種數(shù)據。這些屬性應能完整表達你系統(tǒng)的功能。
在華為云 IoT 平臺定義以下字段屬性:
字段名稱(標識符) | 數(shù)據類型 | 單位 | 描述 | 示例值 |
---|---|---|---|---|
waterTemp |
float | ℃ | 水溫 | 22.5 |
phValue |
float | 無 | PH值 | 7.21 |
dissolvedOxygen |
float | mg/L | 溶解氧濃度 | 6.85 |
waterLevel |
float | cm | 當前水位高度 | 13.2 |
tdsValue |
float | ppm | TDS電導率(溶解性總固體) | 580 |
uploadTime |
string | 時間戳 | 數(shù)據上傳時間 | 2025-06-05T12:30:00 |
alarmStatus |
int | 無 | 異常報警狀態(tài)(0正常,1異常) | 0 |
說明:
- 數(shù)據類型需與華為云平臺支持的類型一致,如
int
、float
、string
、boolean
。 alarmStatus
可用于報警提示功能,如當PH超標、TDS過高等時上傳1
。uploadTime
可以作為歷史數(shù)據存儲和查詢依據。
MQTT 上傳格式(JSON 結構):
{
"waterTemp": 22.5,
"phValue": 7.21,
"dissolvedOxygen": 6.85,
"waterLevel": 13.2,
"tdsValue": 580,
"alarmStatus": 0,
"uploadTime": "2025-06-05T12:30:00"
}
二、硬件介紹
當前項目使用的相關軟件工具、模塊源碼已經上傳到網盤:https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink
2.1 STM32F102C8T6
STM32F103C8T6 是 STMicroelectronics 公司推出的一款基于 ARM Cortex-M3 內核的 32 位高性能低功耗微控制器,屬于 STM32F1 系列中的主流型產品。該芯片具有較高的性價比和穩(wěn)定的性能,被廣泛應用于嵌入式控制系統(tǒng)、物聯(lián)網設備、傳感器采集、工業(yè)自動化等領域。
STM32F103C8T6 運行主頻為 72MHz,具有 64KB 的 Flash 程序存儲器和 20KB 的 SRAM,滿足中小型嵌入式項目的代碼和數(shù)據存儲需求。它集成豐富的外設接口,包括多達 37 個通用 I/O 端口、3 個通用定時器、1 個高級定時器、多個串口(USART)、SPI 接口、I2C 接口以及 12 位 ADC 模塊(多達 10 個通道),能夠支持多種模擬和數(shù)字信號輸入輸出。
該芯片封裝為 LQFP-48(48 引腳封裝),方便用戶在 PCB 設計和元件焊接過程中操作。它支持 2.0V~3.6V 的供電電壓,具有較強的抗干擾能力和低功耗特性,適合在復雜或要求較高的工作環(huán)境中運行。
在開發(fā)方面,STM32F103C8T6 支持多種開發(fā)工具,如 Keil、IAR、STM32CubeIDE 等,開發(fā)者既可以使用標準外設庫(SPL)或硬件抽象庫(HAL)開發(fā),也可以直接基于寄存器編程方式進行底層控制,便于系統(tǒng)的精細調試與資源優(yōu)化。芯片支持通過 ISP 方式(串口)下載程序,用戶可以方便地進行程序更新和調試。
STM32F103C8T6 是一款性能穩(wěn)定、資源豐富、接口齊全的通用型微控制器,非常適合應用在多傳感器數(shù)據采集、通信控制和實時處理等嵌入式系統(tǒng)設計中,如本項目中的水資源環(huán)境監(jiān)測系統(tǒng)。
2.2 Air780e
Air780E 是移遠通信(Quectel)推出的一款高性能、低功耗、功能豐富的 4G 全網通通信模塊,適用于物聯(lián)網領域中對數(shù)據傳輸速率、可靠性和遠程接入能力有較高要求的應用場景。該模塊支持 LTE CAT1 通信標準,可實現(xiàn)較快的數(shù)據傳輸速度與穩(wěn)定的網絡連接能力,廣泛應用于智能終端、遠程監(jiān)控、工業(yè)物聯(lián)、智慧農業(yè)等系統(tǒng)中。
Air780E 支持中國三大運營商(移動、聯(lián)通、電信)的 4G 網絡,具備良好的網絡兼容性和通信覆蓋能力。模塊內部集成了 TCP/IP 協(xié)議棧,并支持常用的通信協(xié)議如 MQTT、HTTP、FTP、UDP、TCP 等,用戶可以通過串口 AT 指令方式快速配置模塊,實現(xiàn)云平臺的數(shù)據上傳與下發(fā)控制。對于本項目,Air780E 通過 MQTT 協(xié)議將采集的水質數(shù)據上傳到華為云物聯(lián)網平臺,起到了關鍵的數(shù)據傳輸橋梁作用。
硬件接口方面,Air780E 模塊提供標準的 UART 接口,方便與主控芯片(如 STM32)通信,支持常見的波特率配置,并且具有多路 GPIO、SIM 卡接口、天線接口、電源管理等功能。模塊支持主控通過串口發(fā)送 AT 指令來進行撥號上網、參數(shù)設置、數(shù)據發(fā)送、斷線重連等操作,操作、上手快速,能夠顯著降低開發(fā)難度。
在功耗控制方面,Air780E 具備多種省電模式,如飛行模式、睡眠模式和掉電模式,特別適合電池供電類的嵌入式應用場景。模塊體積小巧,集成度高,封裝方式適合貼片安裝,可方便集成在各種尺寸受限的設備中。
Air780E 是一款集高可靠性、易用性和網絡兼容性于一體的 4G 通信模塊,特別適合用于需要遠程數(shù)據傳輸、接入云平臺的嵌入式系統(tǒng)。在本水資源環(huán)境監(jiān)測項目中,它有效實現(xiàn)了傳感器數(shù)據從本地終端到云端的遠距離傳輸,是系統(tǒng)遠程監(jiān)控功能實現(xiàn)的關鍵組成部分。
2.3 TDS傳感器
TDS電導率檢測傳感器是一種用于檢測水中溶解性總固體(Total Dissolved Solids)含量的傳感器,廣泛應用于水質檢測、飲用水處理、水產養(yǎng)殖、農業(yè)灌溉等場景。TDS 的單位通常為 ppm(每百萬分之一),代表每升水中含有多少毫克的可溶性物質,如礦物質、鹽類、金屬離子等。
該傳感器的工作原理基于電導率的測量,即通過檢測水體對電流的導通能力,間接判斷水中溶解固體的濃度。水中含有的離子越多,導電能力越強,對應的TDS值也越高。傳感器內部通常包含兩個電極,當電極浸入水中后,電解質會使電流形成通路,控制模塊通過測量電導值并結合算法,將其轉換為實際的TDS數(shù)值。
TDS傳感器通常輸出為模擬電壓信號,便于與單片機的ADC模塊(如STM32的ADC)進行對接。傳感器輸出的電壓與TDS值成正比,經過采樣與算法換算后即可獲得相應的ppm濃度值。在應用中,為了獲得更準確的測量結果,常配合溫度傳感器(如DS18B20)進行溫度補償,以消除不同水溫對電導率造成的影響。
TDS傳感器一般采用防水探頭,外殼材質耐腐蝕,適合長期浸入水中使用。控制模塊則具備電壓調節(jié)、濾波放大、信號校準等功能,提高輸出信號的穩(wěn)定性和抗干擾能力。
在本水資源環(huán)境監(jiān)測系統(tǒng)中,TDS電導率傳感器用于實時監(jiān)測水體中溶解物的濃度,反映水質純凈程度,為判斷水質優(yōu)劣提供關鍵依據。通過STM32的ADC接口讀取其輸出的模擬信號,并結合補償算法計算出當前水體的TDS值,再通過OLED本地顯示及4G模塊上傳至物聯(lián)網平臺,為遠程水質管理與預警提供數(shù)據支持。
2.4 溶解氧傳感器
溶解氧檢測傳感器是一種用于測量水體中溶解氧(Dissolved Oxygen, DO)濃度的傳感器,廣泛應用于水質監(jiān)測、水產養(yǎng)殖、環(huán)保工程、污水處理等領域。溶解氧是水中生物呼吸和水體自凈能力的重要指標,過高或過低都會影響水體生態(tài)系統(tǒng)的穩(wěn)定性。
常見的溶解氧傳感器類型主要包括電化學式(極譜型、蓋爾文型)和光學式。電化學式傳感器工作原理基于氧分子通過膜擴散進入電極系統(tǒng)發(fā)生還原反應,產生電流信號,該信號與溶解氧濃度成正比。光學式則通過熒光猝滅原理測量氧氣濃度,具有更高的穩(wěn)定性和更長的使用壽命,但成本相對較高。
在本系統(tǒng)中使用的溶解氧傳感器為 RS-485 接口輸出型,具有抗干擾能力強、傳輸距離遠、通信穩(wěn)定等優(yōu)點。通過與485轉串口模塊配合,STM32單片機可以通過串口協(xié)議(如Modbus-RTU)與傳感器進行通信,實時讀取水中溶解氧的數(shù)值。該傳感器通常支持標準指令查詢,返回的數(shù)據格式規(guī)范,便于主控程序解析。
傳感器通常采用防水封裝,能夠長期浸入水中運行,且部分型號支持自動溫度補償,進一步提高測量的準確性。部分高端型號還具備校準功能,用戶可以根據實際水質環(huán)境定期校準以保持精度。
在本水資源環(huán)境監(jiān)測系統(tǒng)中,溶解氧傳感器的作用是監(jiān)控水體中氧含量水平,從而判斷是否存在水質惡化、生物缺氧等異常情況。通過 STM32 讀取溶解氧值后,不僅可在 OLED 顯示屏上實時查看,還可以通過 4G 模塊上傳至云平臺,便于遠程監(jiān)測和歷史數(shù)據分析,為水質保護和應急響應提供依據。
三、部署華為云物聯(lián)網平臺
華為云官網: https://www.huaweicloud.com/
打開官網,搜索物聯(lián)網,就能快速找到 設備接入IoTDA
。
3.1 物聯(lián)網平臺介紹
華為云物聯(lián)網平臺(IoT 設備接入云服務)提供海量設備的接入和管理能力,將物理設備聯(lián)接到云,支撐設備數(shù)據采集上云和云端下發(fā)命令給設備進行遠程控制,配合華為云其他產品,幫助我們快速構筑物聯(lián)網解決方案。
使用物聯(lián)網平臺構建一個完整的物聯(lián)網解決方案主要包括3部分:物聯(lián)網平臺、業(yè)務應用和設備。
物聯(lián)網平臺作為連接業(yè)務應用和設備的中間層,屏蔽了各種復雜的設備接口,實現(xiàn)設備的快速接入;同時提供強大的開放能力,支撐行業(yè)用戶構建各種物聯(lián)網解決方案。
設備可以通過固網、2G/3G/4G/5G、NB-IoT、Wifi等多種網絡接入物聯(lián)網平臺,并使用LWM2M/CoAP、MQTT、HTTPS協(xié)議將業(yè)務數(shù)據上報到平臺,平臺也可以將控制命令下發(fā)給設備。
業(yè)務應用通過調用物聯(lián)網平臺提供的API,實現(xiàn)設備數(shù)據采集、命令下發(fā)、設備管理等業(yè)務場景。
3.2 開通物聯(lián)網服務
地址: https://www.huaweicloud.com/product/iothub.html
開通免費單元。
點擊立即創(chuàng)建
。
正在創(chuàng)建標準版實例,需要等待片刻。
創(chuàng)建完成之后,點擊詳情。 可以看到標準版實例的設備接入端口和地址。
下面框起來的就是端口號
和域名
點擊實例名稱,可以查看當前免費單元
的配置情況。
開通之后,點擊接入信息
,也能查看接入信息。 我們當前設備準備采用MQTT協(xié)議接入華為云平臺,這里可以看到MQTT協(xié)議的地址和端口號等信息。
總結:
端口號: MQTT (1883)| MQTTS (8883)
接入地址: dab1a1f2c6.st1.iotda-device.cn-north-4.myhuaweicloud.com
根據域名地址得到IP地址信息:
打開Windows電腦的命令行控制臺終端,使用ping
命令。ping
一下即可。
Microsoft Windows [版本 10.0.19045.5011]
(c) Microsoft Corporation。保留所有權利。
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ù)據:
來自 117.78.5.125 的回復: 字節(jié)=32 時間=37ms TTL=44
來自 117.78.5.125 的回復: 字節(jié)=32 時間=37ms TTL=44
來自 117.78.5.125 的回復: 字節(jié)=32 時間=37ms TTL=44
來自 117.78.5.125 的回復: 字節(jié)=32 時間=37ms TTL=44
117.78.5.125 的 Ping 統(tǒng)計信息:
數(shù)據包: 已發(fā)送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒為單位):
最短 = 37ms,最長 = 37ms,平均 = 37ms
C:UsersLenovo>
MQTT協(xié)議接入端口號有兩個,1883是非加密端口,8883是證書加密端口,單片機無法加載證書,所以使用1883端口合適
。
3.3 創(chuàng)建產品
鏈接:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-dev/all-product?instanceId=03c5c68c-e588-458c-90c3-9e4c640be7af
(1)創(chuàng)建產品
(2)填寫產品信息
根據自己產品名字填寫,下面的設備類型選擇自定義類型。
(3)產品創(chuàng)建成功
創(chuàng)建完成之后點擊查看詳情。
(4)添加自定義模型
產品創(chuàng)建完成之后,點擊進入產品詳情頁面,翻到最下面可以看到模型定義。
模型來說: 就是存放設備上傳到云平臺的數(shù)據。
你可以根據自己的產品進行創(chuàng)建。
比如:
在將本項目采集的數(shù)據上傳至 華為云 IoT 物聯(lián)網平臺 時,需要為設備模型(即產品模型)定義一組字段屬性(屬性服務),用于描述設備采集到的各種數(shù)據。這些屬性應能完整表達你系統(tǒng)的功能。
根據項目功能,在華為云 IoT 平臺定義以下字段屬性:
字段名稱(標識符) | 數(shù)據類型 | 單位 | 描述 | 示例值 |
---|---|---|---|---|
waterTemp |
float | ℃ | 水溫 | 22.5 |
phValue |
float | 無 | PH值 | 7.21 |
dissolvedOxygen |
float | mg/L | 溶解氧濃度 | 6.85 |
waterLevel |
float | cm | 當前水位高度 | 13.2 |
tdsValue |
float | ppm | TDS電導率(溶解性總固體) | 580 |
uploadTime |
string | 時間戳 | 數(shù)據上傳時間 | 2025-06-05T12:30:00 |
alarmStatus |
int | 無 | 異常報警狀態(tài)(0正常,1異常) | 0 |
說明:
- 數(shù)據類型需與華為云平臺支持的類型一致,如
int
、float
、string
、boolean
。 alarmStatus
可用于報警提示功能,如當PH超標、TDS過高等時上傳1
。uploadTime
可以作為歷史數(shù)據存儲和查詢依據。
MQTT 上傳格式(JSON 結構):
{
"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)建產品后,可以在 產品模型 > 服務 > 屬性 中添加上述字段,并配置設備上傳的 Topic。STM32 端通過 AT 指令控制 4G 模塊(Air780E)連接 MQTT Broker,將這些字段打包為 JSON 并上報即可。
先點擊自定義模型。
再創(chuàng)建一個服務ID。
接著點擊新增屬性。
3.4 添加設備
產品是屬于上層的抽象模型,接下來在產品模型下添加實際的設備。添加的設備最終需要與真實的設備關聯(lián)在一起,完成數(shù)據交互。
(1)注冊設備
(2)根據自己的設備填寫
(3)保存設備信息
創(chuàng)建完畢之后,點擊保存并關閉,得到創(chuàng)建的設備密匙信息。該信息在后續(xù)生成MQTT三元組的時候需要使用。
(4)設備創(chuàng)建完成
(5)設備詳情
3.5 MQTT協(xié)議主題訂閱與發(fā)布
(1)MQTT協(xié)議介紹
當前的設備是采用MQTT協(xié)議與華為云平臺進行通信。
MQTT是一個物聯(lián)網傳輸協(xié)議,它被設計用于輕量級的發(fā)布/訂閱式消息傳輸,旨在為低帶寬和不穩(wěn)定的網絡環(huán)境中的物聯(lián)網設備提供可靠的網絡服務。MQTT是專門針對物聯(lián)網開發(fā)的輕量級傳輸協(xié)議。MQTT協(xié)議針對低帶寬網絡,低計算能力的設備,做了特殊的優(yōu)化,使得其能適應各種物聯(lián)網應用場景。目前MQTT擁有各種平臺和設備上的客戶端,已經形成了初步的生態(tài)系統(tǒng)。
MQTT是一種消息隊列協(xié)議,使用發(fā)布/訂閱消息模式,提供一對多的消息發(fā)布,解除應用程序耦合,相對于其他協(xié)議,開發(fā)更;MQTT協(xié)議是工作在TCP/IP協(xié)議上;由TCP/IP協(xié)議提供穩(wěn)定的網絡連接;所以,只要具備TCP協(xié)議棧的網絡設備都可以使用MQTT協(xié)議。 本次設備采用的ESP8266就具備TCP協(xié)議棧,能夠建立TCP連接,所以,配合STM32代碼里封裝的MQTT協(xié)議,就可以與華為云平臺完成通信。
華為云的MQTT協(xié)議接入幫助文檔在這里: https://support.huaweicloud.com/devg-iothub/iot_02_2200.html
業(yè)務流程:
(2)華為云平臺MQTT協(xié)議使用限制
描述 | 限制 |
---|---|
支持的MQTT協(xié)議版本 | 3.1.1 |
與標準MQTT協(xié)議的區(qū)別 | 支持Qos 0和Qos 1支持Topic自定義不支持QoS2不支持will、retain msg |
MQTTS支持的安全等級 | 采用TCP通道基礎 + TLS協(xié)議(最高TLSv1.3版本) |
單帳號每秒最大MQTT連接請求數(shù) | 無限制 |
單個設備每分鐘支持的最大MQTT連接數(shù) | 1 |
單個MQTT連接每秒的吞吐量,即帶寬,包含直連設備和網關 | 3KB/s |
MQTT單個發(fā)布消息最大長度,超過此大小的發(fā)布請求將被直接拒絕 | 1MB |
MQTT連接心跳時間建議值 | 心跳時間限定為30至1200秒,推薦設置為120秒 |
產品是否支持自定義Topic | 支持 |
消息發(fā)布與訂閱 | 設備只能對自己的Topic進行消息發(fā)布與訂閱 |
每個訂閱請求的最大訂閱數(shù) | 無限制 |
(3)主題訂閱格式
幫助文檔地址:https://support.huaweicloud.com/devg-iothub/iot_02_2200.html
對于設備而言,一般會訂閱平臺下發(fā)消息給設備 這個主題。
設備想接收平臺下發(fā)的消息,就需要訂閱平臺下發(fā)消息給設備 的主題,訂閱后,平臺下發(fā)消息給設備,設備就會收到消息。
如果設備想要知道平臺下發(fā)的消息,需要訂閱上面圖片里標注的主題。
以當前設備為例,最終訂閱主題的格式如下:
$oc/devices/{device_id}/sys/messages/down
最終的格式:
$oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down
(4)主題發(fā)布格式
對于設備來說,主題發(fā)布表示向云平臺上傳數(shù)據,將最新的傳感器數(shù)據,設備狀態(tài)上傳到云平臺。
這個操作稱為:屬性上報。
幫助文檔地址:https://support.huaweicloud.com/usermanual-iothub/iot_06_v5_3010.html
根據幫助文檔的介紹, 當前設備發(fā)布主題,上報屬性的格式總結如下:
發(fā)布的主題格式:
$oc/devices/{device_id}/sys/properties/report
最終的格式:
$oc/devices/663cb18871d845632a0912e7_dev1/sys/properties/report
發(fā)布主題時,需要上傳數(shù)據,這個數(shù)據格式是JSON格式。
上傳的JSON數(shù)據格式如下:
{
"services": [
{
"service_id": <填服務ID>,
"properties": {
"<填屬性名稱1>": <填屬性值>,
"<填屬性名稱2>": <填屬性值>,
..........
}
}
]
}
根據JSON格式,一次可以上傳多個屬性字段。 這個JSON格式里的,服務ID,屬性字段名稱,屬性值類型,在前面創(chuàng)建產品的時候就已經介紹了,不記得可以翻到前面去查看。
根據這個格式,組合一次上傳的屬性數(shù)據:
{"services": [{"service_id": "stm32","properties":{"你的字段名字1":30,"你的字段名字2":10,"你的字段名字3":1,"你的字段名字4":0}}]}
3.6 MQTT三元組
MQTT協(xié)議登錄需要填用戶ID,設備ID,設備密碼等信息,就像我們平時登錄QQ,微信一樣要輸入賬號密碼才能登錄。MQTT協(xié)議登錄的這3個參數(shù),一般稱為MQTT三元組。
接下來介紹,華為云平臺的MQTT三元組參數(shù)如何得到。
(1)MQTT服務器地址
要登錄MQTT服務器,首先記得先知道服務器的地址是多少,端口是多少。
幫助文檔地址:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-portal/home
MQTT協(xié)議的端口支持1883和8883,它們的區(qū)別是:8883 是加密端口更加安全。但是單片機上使用比較困難,所以當前的設備是采用1883端口進連接的。
根據上面的域名和端口號,得到下面的IP地址和端口號信息: 如果設備支持填寫域名可以直接填域名,不支持就直接填寫IP地址。 (IP地址就是域名解析得到的)
華為云的MQTT服務器地址:117.78.5.125
華為云的MQTT端口號:1883
如何得到IP地址?如何域名轉IP? 打開Windows的命令行輸入以下命令。
ping ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com
(2)生成MQTT三元組
華為云提供了一個在線工具,用來生成MQTT鑒權三元組: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/
打開這個工具,填入設備的信息(也就是剛才創(chuàng)建完設備之后保存的信息),點擊生成,就可以得到MQTT的登錄信息了。
下面是打開的頁面:
填入設備的信息: (上面兩行就是設備創(chuàng)建完成之后保存得到的)
直接得到三元組信息。
得到三元組之后,設備端通過MQTT協(xié)議登錄鑒權的時候,填入參數(shù)即可。
ClientId 663cb18871d845632a0912e7_dev1_0_0_2024050911
Username 663cb18871d845632a0912e7_dev1
Password 71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac237
3.7 模擬設備登錄測試
經過上面的步驟介紹,已經創(chuàng)建了產品,設備,數(shù)據模型,得到MQTT登錄信息。 接下來就用MQTT客戶端軟件模擬真實的設備來登錄平臺。測試與服務器通信是否正常。
MQTT軟件下載地址【免費】: https://download.csdn.net/download/xiaolong1126626497/89928772
(1)填入登錄信息
打開MQTT客戶端軟件,對號填入相關信息(就是上面的文本介紹)。然后,點擊登錄,訂閱主題,發(fā)布主題。
(2)打開網頁查看
完成上面的操作之后,打開華為云網頁后臺,可以看到設備已經在線了。
點擊詳情頁面,可以看到上傳的數(shù)據:
到此,云平臺的部署已經完成,設備已經可以正常上傳數(shù)據了。
(3)MQTT登錄測試參數(shù)總結
MQTT服務器: 117.78.5.125
MQTT端口號: 183
//物聯(lián)網服務器的設備信息
#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ù)據:
{"services": [{"service_id": "stm32","properties":{"你的字段名字1":30,"你的字段名字2":10,"你的字段名字3":1,"你的字段名字4":0}}]}
3.8 創(chuàng)建IAM賬戶
創(chuàng)建一個IAM賬戶,因為接下來開發(fā)上位機,需要使用云平臺的API接口,這些接口都需要token進行鑒權。來說,就是身份的認證。 調用接口獲取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ù)據
幫助文檔:https://support.huaweicloud.com/api-iothub/iot_06_v5_0079.html
設備影子介紹:
設備影子是一個用于存儲和檢索設備當前狀態(tài)信息的JSON文檔。
每個設備有且只有一個設備影子,由設備ID唯一標識
設備影子僅保存最近一次設備的上報數(shù)據和預期數(shù)據
無論該設備是否在線,都可以通過該影子獲取和設置設備的屬性
來說:設備影子就是保存,設備最新上傳的一次數(shù)據。
我們設計的軟件里,如果想要獲取設備的最新狀態(tài)信息,就采用設備影子接口。
如果對接口不熟悉,可以先進行在線調試:https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?product=IoTDA&api=ShowDeviceShadow
在線調試接口,可以請求影子接口,了解請求,與返回的數(shù)據格式。
調試完成看右下角的響應體,就是返回的影子數(shù)據。
設備影子接口返回的數(shù)據如下:
{
"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
}
]
}
調試成功之后,可以得到訪問影子數(shù)據的真實鏈接,接下來的代碼開發(fā)中,就采用Qt寫代碼訪問此鏈接,獲取影子數(shù)據,完成上位機開發(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 # 根據你的系統(tǒng)設置 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>
// 回調函數(shù),處理libcurl下載數(shù)據
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; // 用于存儲響應數(shù)據
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
// 設置訪問URL
const QString url = "https://ad635970a1.st1.iotda-app.cn-north-4.myhuaweicloud.com:443/v5/iot/28add376c01e4a61ac8b621c714bf459/devices/663cb18871d845632a0912e7_dev1/shadow";
// 設置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ù)據解析代碼
在 Qt 中使用 CJSON (一個用于解析 JSON 數(shù)據的輕量級 C 庫) 來解析返回的 JSON 數(shù)據。
(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ù)據的完整代碼
在 main.cpp
中,以下代碼展示了如何解析你提供的 JSON 數(shù)據。
#include <QCoreApplication>
#include <curl/curl.h>
#include <QDebug>
#include <QString>
#include <QByteArray>
#include "cJSON.h"
// 回調函數(shù),處理libcurl下載數(shù)據
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ù)據
void parseJson(const QByteArray &data) {
// 將 QByteArray 轉換為 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ù)據
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
}
]
})";
// 調用解析函數(shù)
parseJson(jsonData);
return a.exec();
}
四、STM32設備端代碼設計
下面給出的 STM32F103C8T6 主控的 main.c
代碼框架,各子模塊(PH傳感器采集、DS18B20水溫讀取、485串口溶解氧讀取、水位傳感器ADC采集、TDS傳感器ADC采集、OLED顯示、4G模塊MQTT通信、蜂鳴器報警)均有對應的驅動和接口函數(shù)。
源碼下載:
https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzU5Mjg3NTMxOQ==&action=getalbum&album_id=3230261637572755458#wechat_redirect
設計思路(整體代碼)
STM32主程序設計采用基于寄存器的編程方式,代碼結構清晰,模塊化管理。系統(tǒng)啟動后,初始化所有硬件外設和通信接口(ADC、UART、I2C、GPIO等),然后進入主循環(huán)。
主循環(huán)中依次進行各傳感器數(shù)據采集,通過ADC讀取模擬傳感器電壓,串口通信讀取溶解氧傳感器數(shù)據,數(shù)字接口讀取DS18B20溫度數(shù)據。采集到的原始數(shù)據經過校準和算法轉換,得到實際物理值。
隨后將所有傳感器數(shù)據更新到OLED屏幕,實現(xiàn)本地實時顯示。同時,系統(tǒng)根據預設閾值判斷是否產生報警,控制蜂鳴器提示。周期性地將完整數(shù)據打包成JSON格式,通過UART驅動的4G模塊發(fā)送MQTT消息上傳到華為云物聯(lián)網平臺。
系統(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ù)據結構體
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ù)據
g_waterData.waterTemp = DS18B20_ReadTemperature();
g_waterData.phValue = PH_GetValue(); // 模擬量轉換并校準
g_waterData.dissolvedOxygen = DO_ReadValue(); // 485串口讀取
g_waterData.waterLevel = WaterLevel_ReadADC();// ADC讀取
g_waterData.tdsValue = TDS_ReadValue(); // ADC讀取并算法轉換
// 判斷報警狀態(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ù)據
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;
// 根據需要擴展報警條件
return 0;
}
// 初始化所有外設
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ù)據,接下來利用Qt開發(fā)一款Android手機APP 和 Windows上位機。
使用華為云平臺提供的API接口獲取設備上傳的數(shù)據,進行可視化顯示,以及遠程控制設備。
5.1 Qt開發(fā)環(huán)境安裝
Qt的中文官網: https://www.qt.io/zh-cn/
QT5.12.6的下載地址:https://download.qt.io/archive/qt/5.12/5.12.6
打開下載鏈接后選擇下面的版本進行下載:
如果下載不了,可以在網盤里找到安裝包下載: https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink
軟件安裝時斷網安裝,否則會提示輸入賬戶。
安裝的時候,第一個復選框里的編譯器可以全選,直接點擊下一步繼續(xù)安裝。
選擇編譯器: (一定要看清楚了)
前面2講解了需要用的API接口,接下來就使用Qt設計上位機,設計界面,完成整體上位機的邏輯設計。
【1】新建工程
【2】設置項目的名稱。
【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)境沒有問題了。 接下來就可以放心的設計界面了。
5.5 設計UI界面與工程配置
【1】打開UI文件
打開默認的界面如下:
【2】開始設計界面
根據自己需求設計界面。
5.5 編譯Windows上位機
點擊軟件左下角的綠色三角形按鈕進行編譯運行。
5.6 配置Android環(huán)境
如果想編譯Android手機APP,必須要先自己配置好自己的Android環(huán)境。(搭建環(huán)境的過程可以自行百度搜索學習)
然后才可以進行下面的步驟。
【1】選擇Android編譯器
選擇編譯器。
切換編譯器。
【2】創(chuàng)建Android配置文件
創(chuàng)建完成。
【3】配置Android圖標與名稱
【3】編譯Android上位機
Qt本身是跨平臺的,直接選擇Android的編譯器,就可以將程序編譯到Android平臺。
然后點擊構建。
成功之后,在目錄下可以看到生成的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
六、總結
本項目基于STM32F103C8T6主控芯片,設計實現(xiàn)了一個集水溫、PH值、溶解氧、水位和TDS電導率多參數(shù)檢測于一體的水資源環(huán)境監(jiān)測系統(tǒng)。系統(tǒng)通過高精度傳感器采集關鍵水質指標,利用OLED顯示屏實現(xiàn)本地數(shù)據實時展示,保證現(xiàn)場監(jiān)測的直觀性與便捷性。結合Air780E 4G模塊和MQTT協(xié)議,系統(tǒng)將采集的數(shù)據穩(wěn)定可靠地上傳至華為云物聯(lián)網平臺,支持遠程監(jiān)控與歷史數(shù)據查詢,極大提升了數(shù)據管理的智能化和自動化水平。
此外,系統(tǒng)設計中充分考慮了異常報警功能,能夠及時發(fā)現(xiàn)并反饋水質異常,保障環(huán)境安全。Android手機APP和Windows上位機軟件的雙平臺設計,實現(xiàn)了多終端的遠程數(shù)據訪問與管理,滿足不同用戶的使用需求。整體方案采用寄存器級STM32編程,提升了系統(tǒng)的穩(wěn)定性和響應速度,兼顧硬件性能與軟件效率。
本項目的完成不僅驗證了基于STM32的多參數(shù)水質監(jiān)測系統(tǒng)的可行性和實用性,也為后續(xù)環(huán)境監(jiān)測設備的智能化升級提供了可靠的技術參考,具有較高的應用推廣價值和社會意義。