• 方案介紹
    • 一、前言
    • 二、硬件介紹
    • 三、部署華為云物聯(lián)網平臺
    • 四、STM32設備端代碼設計
    • 五、上位機開發(fā)
    • 六、總結
  • 附件下載
  • 相關推薦
申請入駐 產業(yè)圖譜

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

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

更多詳細資料請聯(lián)系.docx

共1個文件

一、前言

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)實意義和應用價值。

image-20250605122258379

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)和應用程序。它功能強大且結構緊湊,擁有直觀的工具和庫。

image-20230218001243591

image-20230218001219105

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、floatstring、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

image-20221204193824815

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è)務場景。

img

3.2 開通物聯(lián)網服務

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

image-20241028135834377

開通免費單元。

image-20241028135935457

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

image-20240117134653452

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

image-20241028140048811

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

image-20241028140129102

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

image-20241028140229696

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

image-20241028140331523

image-20241028140428663

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

image-20241028140511105

總結:

端口號:   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)建產品

image-20241028141601305

(2)填寫產品信息

根據自己產品名字填寫,下面的設備類型選擇自定義類型。

image-20240612094809689

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

image-20240612095148945

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

image-20240612095134263

(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ù)據類型需與華為云平臺支持的類型一致,如 intfloat、stringboolean。
  • 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 并上報即可。

先點擊自定義模型。

image-20240612095517900

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

image-20240612095542749

接著點擊新增屬性。

image-20240612095648815

image-20240612095711898

3.4 添加設備

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

(1)注冊設備

image-20240425181935561

(2)根據自己的設備填寫

image-20240612100115167

(3)保存設備信息

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

image-20240612100128061

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

image-20240612100147232

(5)設備詳情

image-20240612100202960

image-20240612100217236

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

img

業(yè)務流程:

img

(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

image-20221207153310037

對于設備而言,一般會訂閱平臺下發(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

image-20221207153637391

根據幫助文檔的介紹, 當前設備發(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

image-20240509193207359

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

image-20240425182610048

(2)生成MQTT三元組

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

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

下面是打開的頁面:

image-20240425183025893

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

直接得到三元組信息。

image-20240509193310020

得到三元組之后,設備端通過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ā)布主題。

image-20240509193457358

(2)打開網頁查看

完成上面的操作之后,打開華為云網頁后臺,可以看到設備已經在線了。

image-20240612100508790

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

image-20240612100529581

到此,云平臺的部署已經完成,設備已經可以正常上傳數(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】獲取項目憑證 ** 點擊左上角用戶名,選擇下拉菜單里的我的憑證

image-20240509193646253

image-20240509193701262

項目憑證:

28add376c01e4a61ac8b621c714bf459

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

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

image-20240509193729078

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

image-20240509193744287

image-20240314153208692

image-20240314153228359

image-20240314153258229

創(chuàng)建成功:

image-20240314153315444

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

image-20240509193828289

用戶信息如下:

主用戶名  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ù)據。

image-20240509194152229

設備影子接口返回的數(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ā)。

image-20240509194214716

鏈接如下:

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/image-20221207160550486

image-20221207160606892

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

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

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

軟件安裝時斷網安裝,否則會提示輸入賬戶。

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

image-20221203151742653

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

image-20241028152725134

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

【1】新建工程

image-20240117144052547

【2】設置項目的名稱。

image-20241112142627805

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

image-20240117144239681

【4】選擇默認繼承的類

image-20240117144302275

【5】選擇編譯器

image-20241028153603487

【6】點擊完成

image-20240117144354252

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

image-20241112142836874

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下運行的程序。

image-20241112142912481

5.4 編譯測試功能

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

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

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

image-20241112142939735

5.5 設計UI界面與工程配置

【1】打開UI文件

image-20241112143019233

打開默認的界面如下:

image-20240425194845233

【2】開始設計界面

根據自己需求設計界面。

5.5 編譯Windows上位機

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

image-20241112153656462

5.6 配置Android環(huán)境

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

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

【1】選擇Android編譯器

選擇編譯器。

image-20240425232651515

切換編譯器。

image-20241112153812833

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

image-20240117144604025

image-20240117144635052

image-20240117144652014

創(chuàng)建完成。

image-20241112153851571

【3】配置Android圖標與名稱

image-20241113114730689

【3】編譯Android上位機

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

然后點擊構建。

image-20241112154026342

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

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

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

image-20241112154142209

  -- 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)測設備的智能化升級提供了可靠的技術參考,具有較高的應用推廣價值和社會意義。

  • 更多詳細資料請聯(lián)系.docx
    下載
意法半導體

意法半導體

意法半導體(ST)集團于1987年6月成立,是由意大利的SGS微電子公司和法國Thomson半導體公司合并而成。1998年5月,SGS-THOMSON Microelectronics將公司名稱改為意法半導體有限公司。意法半導體是世界最大的半導體公司之一,公司銷售收入在半導體工業(yè)五大高速增長市場之間分布均衡(五大市場占2007年銷售收入的百分比):通信(35%),消費(17%),計算機(16%),汽車(16%),工業(yè)(16%)。 據最新的工業(yè)統(tǒng)計數(shù)據,意法半導體是全球第五大半導體廠商,在很多市場居世界領先水平。例如,意法半導體是世界第一大專用模擬芯片和電源轉換芯片制造商,世界第一大工業(yè)半導體和機頂盒芯片供應商,而且在分立器件、手機相機模塊和車用集成電路領域居世界前列.

意法半導體(ST)集團于1987年6月成立,是由意大利的SGS微電子公司和法國Thomson半導體公司合并而成。1998年5月,SGS-THOMSON Microelectronics將公司名稱改為意法半導體有限公司。意法半導體是世界最大的半導體公司之一,公司銷售收入在半導體工業(yè)五大高速增長市場之間分布均衡(五大市場占2007年銷售收入的百分比):通信(35%),消費(17%),計算機(16%),汽車(16%),工業(yè)(16%)。 據最新的工業(yè)統(tǒng)計數(shù)據,意法半導體是全球第五大半導體廠商,在很多市場居世界領先水平。例如,意法半導體是世界第一大專用模擬芯片和電源轉換芯片制造商,世界第一大工業(yè)半導體和機頂盒芯片供應商,而且在分立器件、手機相機模塊和車用集成電路領域居世界前列.收起

查看更多

相關推薦