• 方案介紹
  • 附件下載
  • 相關推薦
申請入駐 產(chǎn)業(yè)圖譜

【零基礎實戰(zhàn)】基于STM32和物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)設計

11小時前
224
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

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

共1個文件

一、前言

1.1 項目介紹

1.1.1 開發(fā)背景

在當前全球水資源日益緊張與環(huán)境污染加劇的背景下,淡水湖養(yǎng)殖業(yè)面臨著前所未有的挑戰(zhàn)。傳統(tǒng)的淡水湖養(yǎng)殖方式往往依賴于自然條件,缺乏有效的水質(zhì)監(jiān)測與調(diào)控手段,這不僅限制了養(yǎng)殖效率,也增加了疾病爆發(fā)的風險,進而影響到水產(chǎn)品的品質(zhì)與產(chǎn)量。隨著物聯(lián)網(wǎng)技術的迅猛發(fā)展及其在農(nóng)業(yè)領域的廣泛應用,基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)應運而生,成為提升養(yǎng)殖智能化水平、優(yōu)化資源管理的關鍵所在。

本項目致力于設計一套集成化的淡水湖養(yǎng)殖管理系統(tǒng),以STM32F103RCT6為主控芯片,結合PH值、渾濁度、TDS值等多種水質(zhì)參數(shù)的實時監(jiān)測,輔以遠程控制與自動化設備,實現(xiàn)了淡水湖養(yǎng)殖環(huán)境的全方位智能監(jiān)管。通過采用先進的傳感器技術,系統(tǒng)能夠準確檢測水質(zhì)狀況,及時反饋至本地LCD顯示屏與手機APP,為養(yǎng)殖人員提供直觀的數(shù)據(jù)支持。特別地,項目引入了遠程操控功能,用戶不僅能在手機APP上遠程啟動換水、投喂、充氧等操作,還能通過Windows電腦APP進行更為細致的管理設定,極大地提升了養(yǎng)殖管理的靈活性與便捷性。

為了確保系統(tǒng)的穩(wěn)定運行與數(shù)據(jù)的安全傳輸,項目選用了ESP8266-WIFI模塊,借助MQTT協(xié)議與華為云IOT物聯(lián)網(wǎng)服務器建立連接,實現(xiàn)了設備與云端的無縫對接。這樣一來,不僅養(yǎng)殖現(xiàn)場的數(shù)據(jù)能夠實時上傳至云端,便于數(shù)據(jù)分析與長期存儲,同時也使得用戶能夠隨時隨地通過手機APP或電腦APP訪問養(yǎng)殖信息,實現(xiàn)真正的遠程監(jiān)控與智能決策。

考慮到淡水湖養(yǎng)殖過程中可能遇到的突發(fā)情況,如水質(zhì)污染等,項目特別設計了基于閾值觸發(fā)的蜂鳴器報警系統(tǒng),一旦檢測到渾濁度超出安全范圍,系統(tǒng)將立即發(fā)出警報,提醒養(yǎng)殖人員及時采取措施,避免潛在的經(jīng)濟損失。整個系統(tǒng)通過外部5V 2A電源供電,保證了穩(wěn)定持久的運行能力。

基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)設計,不僅代表了現(xiàn)代養(yǎng)殖業(yè)向著智慧化、精細化方向發(fā)展的趨勢,也為解決傳統(tǒng)養(yǎng)殖中存在的諸多問題提供了創(chuàng)新解決方案,有望推動淡水湖養(yǎng)殖業(yè)邁向更加可持續(xù)與高效的未來。

image-20240725103450360

image-20240725103726929

image-20240725103907651

1.1.2 項目實現(xiàn)的功能

(1)PH值監(jiān)測與展示

系統(tǒng)配備PH值檢測傳感器,能夠持續(xù)監(jiān)測淡水湖中的酸堿度,確保水質(zhì)維持在適宜魚類生長的最佳范圍內(nèi)。監(jiān)測數(shù)據(jù)不僅實時顯示在本地LCD顯示屏上,供現(xiàn)場管理人員即時查看,同時,通過物聯(lián)網(wǎng)技術,這些數(shù)據(jù)也會同步推送至用戶的手機APP和Windows電腦端,實現(xiàn)遠程監(jiān)控,確保無論身處何地,養(yǎng)殖者都能掌握水質(zhì)的最新動態(tài)。

(2)渾濁度檢測與預警

利用濁度檢測傳感器,系統(tǒng)能夠精確測定水體的渾濁程度,及時反映水體中懸浮物含量的變化。渾濁度數(shù)據(jù)同樣在本地顯示屏和遠程終端上實時更新,一旦檢測到渾濁度超過預設的安全閾值,系統(tǒng)將啟動蜂鳴器報警,提醒管理者迅速采取應對措施,防止水質(zhì)惡化對養(yǎng)殖生物造成不利影響。

(3)TDS值監(jiān)控

TDS(Total Dissolved Solids,總溶解固體)傳感器用于監(jiān)測水中溶解物質(zhì)的總量,幫助養(yǎng)殖者了解水質(zhì)的純凈度。系統(tǒng)將TDS值數(shù)據(jù)實時傳輸至本地和遠程終端,為養(yǎng)殖決策提供重要依據(jù),確保水質(zhì)始終符合養(yǎng)殖需求。

(4)遠程手動換水控制

通過手機APP和電腦端,養(yǎng)殖者可遠程啟動換水電機,實現(xiàn)淡水湖的自動換水。系統(tǒng)設計了兩個電機,分別負責抽水進出,以循環(huán)方式更新水質(zhì)。在本地LCD顯示屏上,用戶可查看下一次換水的倒計時,合理規(guī)劃換水頻率,保持水體的健康狀態(tài)。

(5)周期自動投喂管理

借助手機APP和電腦端的遠程控制功能,系統(tǒng)支持自動投喂周期設定。養(yǎng)殖者可根據(jù)魚群的生長需求,定制定時投喂計劃,系統(tǒng)將自動啟動食物投喂電機,適時投放飼料。本地LCD顯示屏顯示下一次投喂的時間,確保養(yǎng)殖過程的自動化與精準化。

(6)數(shù)據(jù)上云與遠程監(jiān)控

系統(tǒng)通過ESP8266-WIFI模塊與華為云IOT物聯(lián)網(wǎng)服務器相連,所有監(jiān)測數(shù)據(jù)均上傳至云端,支持歷史數(shù)據(jù)查詢與分析,便于養(yǎng)殖者做出科學決策。同時,用戶可通過手機APP和Windows電腦APP實時訪問云端數(shù)據(jù),實現(xiàn)遠程監(jiān)控與管理,即使遠離養(yǎng)殖現(xiàn)場,也能隨時掌握養(yǎng)殖環(huán)境狀況。

(7)周期自動充氧功能

系統(tǒng)具備遠程設定充氧周期的能力,養(yǎng)殖者可通過手機APP和電腦端自定義充氧時間,系統(tǒng)將自動啟動充氧電機,確保水體含氧量充足,促進魚類健康成長。本地LCD顯示屏顯示下一次充氧的倒計時,便于養(yǎng)殖者安排日常管理工作。

(8)異常報警機制

當水質(zhì)參數(shù)超出正常范圍,如渾濁度過高,系統(tǒng)將通過蜂鳴器發(fā)出警報,并在手機APP和電腦端同步推送警告信息,確保養(yǎng)殖者第一時間獲知異常情況,及時采取補救措施,降低潛在風險。

1.1.3 項目硬件模塊組成

(1)主控芯片模塊

采用高性能的STM32F103RCT6微控制器作為系統(tǒng)的核心大腦,負責接收來自各種傳感器的數(shù)據(jù),執(zhí)行控制邏輯,并通過無線模塊與遠程設備進行通信。STM32F103RCT6憑借其強大的處理能力和豐富的外設接口,能夠高效處理復雜的數(shù)據(jù)流和控制任務,確保系統(tǒng)的穩(wěn)定運行。

(2)水質(zhì)監(jiān)測傳感器模塊

包括PH值、渾濁度和TDS值三種傳感器,用于實時監(jiān)測水質(zhì)狀況。這些傳感器通過模擬電壓輸出的方式,將水質(zhì)參數(shù)轉化為電信號,由主控芯片讀取并處理。PH值傳感器監(jiān)測水體酸堿度;渾濁度傳感器檢測水中懸浮物濃度;TDS傳感器則測定水中的溶解固體總量,三者共同構成了水質(zhì)監(jiān)測的基礎。

(3)控制與執(zhí)行模塊

  • 換水系統(tǒng):由兩個5V高電平觸發(fā)的繼電器控制抽水電機組成,實現(xiàn)淡水湖的自動換水。一個電機負責抽水出去,另一個負責抽水進來,形成水體循環(huán),保持水質(zhì)清潔。
  • 食物投喂系統(tǒng):采用ULN2003驅動的28BYJ4步進電機,用于控制食物投放閥門的開關,實現(xiàn)定時定量的自動投喂。
  • 充氧系統(tǒng):同樣是5V高電平觸發(fā)的繼電器控制充氧電機,用于調(diào)節(jié)水體中的氧氣含量,確保養(yǎng)殖生物的健康生長。

(4)連接與通信模塊

  • ESP8266-WIFI模塊:作為系統(tǒng)與外界通信的橋梁,ESP8266負責將主控芯片處理后的數(shù)據(jù)上傳至華為云IOT物聯(lián)網(wǎng)服務器,并接收來自遠程客戶端的控制指令,實現(xiàn)數(shù)據(jù)的雙向傳輸。
  • MQTT協(xié)議:用于系統(tǒng)與華為云服務器之間的數(shù)據(jù)通信,確保數(shù)據(jù)傳輸的安全與高效。

(5)顯示與用戶界面模塊

  • 本地LCD顯示屏:用于現(xiàn)場顯示實時監(jiān)測數(shù)據(jù)和系統(tǒng)狀態(tài),包括PH值、渾濁度、TDS值、下一次換水/投喂/充氧的倒計時等信息。
  • 手機APP與Windows電腦軟件:通過華為云IOT服務器提供的API接口,用戶可在手機APP和電腦軟件上遠程監(jiān)控水質(zhì)參數(shù),接收報警信息,以及進行遠程控制操作。

(6)電源模塊

采用外部5V 2A電源供電,為整個系統(tǒng)提供穩(wěn)定電力,確保各模塊的正常運行。

(7)報警模塊

系統(tǒng)配置了高電平觸發(fā)的有源蜂鳴器,當水質(zhì)參數(shù)超出預設安全范圍時,蜂鳴器將發(fā)出警報聲,確保養(yǎng)殖者能及時采取措施。

1.1.4 ESP8266工作模式配置

在整個設計里,STM32端的ESP8266配置成STA模式+TCP客戶端模式,上電時連接家里的路由器WIF熱點,連接互聯(lián)網(wǎng),以TCP客戶端模式(通過MQTT協(xié)議)去連接騰訊云聯(lián)網(wǎng)服務器,實時上傳當前的設備狀態(tài)等各種參數(shù)信息。用戶在Android手機APP可以遠程查看設備的狀態(tài)信息。

ESP8266模塊具有兩種常用的工作模式,分別是STA模式和AP模式:

(1)STA模式(Station Mode):在STA模式下,ESP8266可以連接到已存在的Wi-Fi網(wǎng)絡作為一個客戶端設備。它可以掃描周圍的Wi-Fi網(wǎng)絡,并且根據(jù)提供的SSID和密碼進行連接,獲取IP地址后可以通過該網(wǎng)絡與其他設備進行通信。在STA模式下,ESP8266可以實現(xiàn)與互聯(lián)網(wǎng)的連接,執(zhí)行各種網(wǎng)絡相關的操作。

(2)AP模式(Access Point Mode):在AP模式下,ESP8266可以作為一個獨立的Wi-Fi接入點(熱點)運行。它會創(chuàng)建一個自己的Wi-Fi網(wǎng)絡,允許其他設備(如手機、電腦等)連接到這個熱點上。在AP模式下,ESP8266可以充當局域網(wǎng)內(nèi)部的服務器,通過建立TCP/IP連接與其他設備進行通信,提供Web頁面訪問、數(shù)據(jù)傳輸?shù)确铡?/p>

通過STA模式,ESP8266可以連接到互聯(lián)網(wǎng)上的其他設備或服務器,實現(xiàn)遠程控制和數(shù)據(jù)交換;而通過AP模式,ESP8266可以作為一個獨立的接入點,讓其他設備通過它進行連接和通信。

1.2 系統(tǒng)設計方案

1.2.1 關鍵技術與創(chuàng)新點

本項目打造了一個高度自動化、智能化的養(yǎng)殖環(huán)境監(jiān)測與控制系統(tǒng)。首要關鍵技術在于物聯(lián)網(wǎng)技術的應用,通過ESP8266-WIFI模塊與華為云IOT物聯(lián)網(wǎng)服務器的無縫連接,實現(xiàn)了淡水湖養(yǎng)殖數(shù)據(jù)的實時采集、遠程傳輸與云端存儲。這一技術不僅確保了水質(zhì)參數(shù)的連續(xù)監(jiān)測,還為養(yǎng)殖者提供了隨時隨地的遠程監(jiān)控與管理能力,極大提升了養(yǎng)殖作業(yè)的靈活性與響應速度。

創(chuàng)新點之一在于系統(tǒng)的集成化設計。將PH值、渾濁度、TDS值等水質(zhì)參數(shù)的監(jiān)測與自動化控制功能融為一體,通過主控芯片STM32F103RCT6的高效數(shù)據(jù)處理,實現(xiàn)了水質(zhì)監(jiān)測、換水、投喂、充氧等關鍵環(huán)節(jié)的自動化管理,顯著減少了人工干預,提高了養(yǎng)殖效率與水質(zhì)管理的精準度。

另一創(chuàng)新點體現(xiàn)在遠程控制與數(shù)據(jù)可視化方面。借助手機APP與Windows電腦軟件,養(yǎng)殖者不僅可以實時查看水質(zhì)參數(shù),還能遠程設定換水、投喂、充氧的周期與時間,甚至在緊急情況下,如水質(zhì)異常時,系統(tǒng)會自動觸發(fā)報警機制,通過蜂鳴器與遠程通知提醒養(yǎng)殖者及時采取行動,確保養(yǎng)殖環(huán)境的安全與穩(wěn)定。

系統(tǒng)在數(shù)據(jù)處理與分析上也進行了創(chuàng)新。通過MQTT協(xié)議與華為云IOT物聯(lián)網(wǎng)服務器的深度整合,不僅保證了數(shù)據(jù)傳輸?shù)陌踩耘c可靠性,還為養(yǎng)殖者提供了歷史數(shù)據(jù)查詢與分析功能,有助于總結養(yǎng)殖規(guī)律,優(yōu)化管理策略,推動養(yǎng)殖業(yè)向數(shù)據(jù)驅動的方向發(fā)展。

本項目的關鍵技術與創(chuàng)新點集中體現(xiàn)在物聯(lián)網(wǎng)技術的深度應用、系統(tǒng)集成化設計、遠程控制與數(shù)據(jù)可視化、以及數(shù)據(jù)處理與分析等方面,共同構建了一個高效、智能、可靠的淡水湖養(yǎng)殖管理平臺,為現(xiàn)代養(yǎng)殖業(yè)的可持續(xù)發(fā)展注入了新的活力。

1.2.2 功能需求分析

本項目功能聚焦于如何通過技術手段實現(xiàn)養(yǎng)殖環(huán)境的智能化監(jiān)控與自動化管理,以提升養(yǎng)殖效率、保障水質(zhì)安全、簡化操作流程,并為養(yǎng)殖決策提供數(shù)據(jù)支持。首先,系統(tǒng)必須具備實時監(jiān)測水質(zhì)參數(shù)的能力,包括但不限于PH值、渾濁度和TDS值,確保這些關鍵指標處于適宜養(yǎng)殖生物生長的范圍內(nèi)。監(jiān)測數(shù)據(jù)需通過本地LCD顯示屏直觀呈現(xiàn),借助物聯(lián)網(wǎng)技術,實現(xiàn)數(shù)據(jù)的遠程傳輸,確保養(yǎng)殖者無論身在何處,都能通過手機APP或Windows電腦軟件實時掌握水質(zhì)狀況。

系統(tǒng)應支持自動化控制功能,涵蓋定時換水、自動投喂和周期性充氧等關鍵操作。養(yǎng)殖者應能在手機APP或電腦軟件上設定換水、投喂和充氧的周期與時間,系統(tǒng)自動執(zhí)行相應任務,減少人力投入,提高養(yǎng)殖過程的自動化水平。系統(tǒng)還應提供倒計時顯示,便于養(yǎng)殖者提前規(guī)劃相關工作。

數(shù)據(jù)上云與遠程監(jiān)控是不可或缺的需求。通過ESP8266-WIFI模塊與華為云IOT物聯(lián)網(wǎng)服務器的連接,系統(tǒng)需將監(jiān)測數(shù)據(jù)定期上傳至云端,一方面實現(xiàn)數(shù)據(jù)的長期存儲,另一方面,養(yǎng)殖者能通過云平臺提供的API接口,實現(xiàn)遠程數(shù)據(jù)訪問,進行歷史數(shù)據(jù)查詢與分析,為養(yǎng)殖策略的優(yōu)化提供科學依據(jù)。

報警機制也是系統(tǒng)的重要組成部分。當監(jiān)測到水質(zhì)參數(shù)異常,如渾濁度超過安全閾值時,系統(tǒng)應立即觸發(fā)蜂鳴器報警,并通過手機APP與電腦軟件發(fā)送警告通知,確保養(yǎng)殖者能及時響應,采取有效措施,避免水質(zhì)惡化對養(yǎng)殖生物造成傷害。

考慮到淡水湖養(yǎng)殖環(huán)境的特殊性,系統(tǒng)還需具備一定的抗干擾與穩(wěn)定性,確保在復雜環(huán)境下仍能持續(xù)、準確地執(zhí)行各項功能。此外,操作界面應簡潔友好,無論是現(xiàn)場的LCD顯示屏還是遠程的手機APP與電腦軟件,都應易于理解和操作,降低養(yǎng)殖者的使用門檻。

1.2.3 現(xiàn)有技術與市場分析

當前,隨著物聯(lián)網(wǎng)、大數(shù)據(jù)人工智能技術的飛速發(fā)展,智慧農(nóng)業(yè)正逐漸成為現(xiàn)代農(nóng)業(yè)轉型的重要方向,特別是在水產(chǎn)養(yǎng)殖領域,科技的應用正在重塑養(yǎng)殖模式,提升養(yǎng)殖效率與產(chǎn)品質(zhì)量。

從技術角度來看,物聯(lián)網(wǎng)技術在淡水湖養(yǎng)殖中的應用已初具規(guī)模。通過部署各類水質(zhì)傳感器,如PH值、渾濁度和TDS值傳感器,養(yǎng)殖者能夠實時監(jiān)測水質(zhì)變化,及時發(fā)現(xiàn)并解決水質(zhì)問題。同時,結合遠程控制技術,自動化執(zhí)行換水、投喂和充氧等操作,不僅節(jié)省了人力成本,還提高了養(yǎng)殖的精準度和效率。然而,目前市面上的解決方案往往側重于單一功能,如水質(zhì)監(jiān)測或自動化投喂,缺乏一個集成化、智能化的綜合管理系統(tǒng),難以滿足養(yǎng)殖者對水質(zhì)全面監(jiān)控與智能決策的需求。

市場層面,隨著消費者對食品安全和營養(yǎng)價值的重視,高品質(zhì)水產(chǎn)品的需求日益增長,促使養(yǎng)殖業(yè)向精細化、標準化方向發(fā)展。養(yǎng)殖者急需一套能夠提供全方位水質(zhì)監(jiān)控、自動化管理與數(shù)據(jù)分析的解決方案,以提升養(yǎng)殖效率,保障水產(chǎn)品質(zhì)量。此外,政府對環(huán)保和資源節(jié)約的政策導向,也推動著養(yǎng)殖業(yè)尋求低能耗、低污染的養(yǎng)殖模式,物聯(lián)網(wǎng)技術的應用恰能滿足這一需求,通過精準控制減少資源浪費,降低環(huán)境污染。

市場上現(xiàn)有的淡水湖養(yǎng)殖系統(tǒng)在數(shù)據(jù)處理與分析能力、遠程監(jiān)控的便捷性以及系統(tǒng)的穩(wěn)定性和易用性方面仍有待提升。養(yǎng)殖者渴望獲得一個集成度高、操作簡便、數(shù)據(jù)處理能力強的養(yǎng)殖管理系統(tǒng),以實現(xiàn)養(yǎng)殖過程的智能化升級。

基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)正處于技術革新與市場需求雙重驅動的有利時機。通過集成水質(zhì)監(jiān)測、自動化控制、遠程監(jiān)控與數(shù)據(jù)分析等功能,不僅能填補市場空白,滿足養(yǎng)殖者對智能化養(yǎng)殖管理的迫切需求,還能順應現(xiàn)代農(nóng)業(yè)向智慧化轉型的大勢,推動淡水湖養(yǎng)殖業(yè)的高質(zhì)量發(fā)展。

1.2.4 硬件架構設計

本項目的硬件架構設計圍繞基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)展開,實現(xiàn)水質(zhì)參數(shù)的實時監(jiān)測、自動化控制以及遠程管理。系統(tǒng)的核心是由STM32F103RCT6微控制器組成的主控單元,它負責協(xié)調(diào)整個系統(tǒng)的運作,包括數(shù)據(jù)采集、處理和傳輸。STM32F103RCT6作為高性能的32位ARM Cortex-M3微控制器,具備足夠的處理能力和豐富的外設接口,能夠高效處理來自各種傳感器的數(shù)據(jù),并控制執(zhí)行器的動作。

傳感器模塊是硬件架構的重要組成部分,其中包括PH值檢測傳感器、渾濁度檢測傳感器和TDS值檢測傳感器,用于實時監(jiān)測水質(zhì)的各項關鍵指標。這些傳感器通過模擬電壓輸出的方式,將物理或化學信號轉換為電信號,STM32F103RCT6通過ADC模數(shù)轉換器)讀取這些信號,并進行相應的數(shù)據(jù)處理。

執(zhí)行器模塊則負責執(zhí)行自動化控制任務,如換水、投喂和充氧。系統(tǒng)中采用5V高電平觸發(fā)的繼電器來控制抽水電機,實現(xiàn)淡水湖的自動換水;ULN2003驅動的28BYJ4步進電機用于控制食物投喂閥門的開閉,實現(xiàn)定時定量的食物投喂;充氧設備同樣通過繼電器控制,確保水體含氧量的充足。所有執(zhí)行器的操作均由STM32F103RCT6通過數(shù)字I/O口控制,實現(xiàn)精準的自動化管理。

為了實現(xiàn)遠程監(jiān)控和數(shù)據(jù)上云,系統(tǒng)集成了ESP8266-WIFI模塊,該模塊負責將STM32F103RCT6處理后的數(shù)據(jù)通過Wi-Fi網(wǎng)絡上傳至華為云IOT物聯(lián)網(wǎng)服務器,同時接收來自服務器的控制指令。ESP8266-WIFI模塊與STM32F103RCT6之間通過串行通信接口(如UART)進行數(shù)據(jù)交換,確保數(shù)據(jù)的實時傳輸。

本地LCD顯示屏用于現(xiàn)場顯示水質(zhì)參數(shù)和系統(tǒng)狀態(tài),方便現(xiàn)場工作人員實時監(jiān)控。此外,系統(tǒng)還配置了蜂鳴器報警裝置,當水質(zhì)異常時,如渾濁度超過預設閾值,蜂鳴器將發(fā)出警報,提醒工作人員采取相應措施。

最后,系統(tǒng)采用外部5V 2A電源供電,確保整個硬件架構的穩(wěn)定運行。電源模塊不僅為微控制器、傳感器和執(zhí)行器提供必要的電力,還配備了過載保護和穩(wěn)壓功能,以應對淡水湖養(yǎng)殖環(huán)境中的電壓波動

1.2.5 軟件架構設計

本項目的軟件架構設計是整體邏輯核心,實現(xiàn)水質(zhì)參數(shù)的實時監(jiān)測、自動化控制以及遠程管理。軟件架構的核心是基于STM32F103RCT6微控制器的嵌入式軟件,負責數(shù)據(jù)采集、處理、執(zhí)行自動化任務和通信控制。該軟件架構遵循分層設計理念,包括數(shù)據(jù)采集層、數(shù)據(jù)處理層、控制邏輯層和通信層,每一層都有明確的功能和職責,確保系統(tǒng)的穩(wěn)定性和可維護性。

數(shù)據(jù)采集層主要負責與各種傳感器交互,讀取PH值、渾濁度和TDS值等水質(zhì)參數(shù)的原始數(shù)據(jù)。這一層通過STM32F103RCT6的ADC模塊讀取模擬電壓信號,并進行適當?shù)男屎皖A處理,確保數(shù)據(jù)的準確性和一致性。

數(shù)據(jù)處理層則對采集到的原始數(shù)據(jù)進行深入處理和分析,包括數(shù)據(jù)過濾、異常檢測、數(shù)據(jù)轉換和存儲。這一層軟件采用先進的算法,如滑動平均濾波和閾值比較,以剔除噪聲和異常值,確保水質(zhì)參數(shù)的可靠性和有效性。此外,數(shù)據(jù)處理層還負責將處理后的數(shù)據(jù)格式化,以便于傳輸和遠程顯示。

控制邏輯層是軟件架構的關鍵部分,它基于處理后的水質(zhì)數(shù)據(jù),執(zhí)行自動化控制策略,如啟動換水、投喂和充氧等操作。這一層軟件包含了復雜的控制算法,能夠根據(jù)水質(zhì)參數(shù)的實時變化,動態(tài)調(diào)整執(zhí)行器的動作,實現(xiàn)淡水湖養(yǎng)殖環(huán)境的精準管理。

通信層負責與ESP8266-WIFI模塊和遠程服務器的交互,通過MQTT協(xié)議實現(xiàn)數(shù)據(jù)的上傳和接收控制指令。這一層軟件不僅處理數(shù)據(jù)的序列化和反序列化,還負責數(shù)據(jù)包的完整性檢查和重傳機制,確保數(shù)據(jù)傳輸?shù)目煽啃院桶踩浴4送?,通信層還支持與手機APP和電腦軟件的交互,通過RESTful API提供數(shù)據(jù)訪問和控制接口。

為了提供直觀的用戶界面和遠程監(jiān)控功能,本項目還設計了基于Qt框架的手機APP和Windows電腦軟件。這些應用程序通過調(diào)用云平臺提供的API,實現(xiàn)水質(zhì)數(shù)據(jù)的實時查看、遠程控制和歷史數(shù)據(jù)分析,為養(yǎng)殖者提供全面的管理工具和決策支持。

本項目的軟件架構設計通過分層結構和模塊化編程,實現(xiàn)了淡水湖養(yǎng)殖系統(tǒng)的智能化和自動化管理,不僅提升了水質(zhì)監(jiān)測的精度和效率,還簡化了養(yǎng)殖管理流程,為養(yǎng)殖者提供了便捷的遠程監(jiān)控和控制手段。

1.2.6 上位機開發(fā)思路

項目里,上位機是采用Qt開發(fā),Qt是一個基于C++的跨平臺軟件開發(fā)框架。

Qt框架提供了網(wǎng)絡模塊,能夠支持HTTPS協(xié)議的請求和響應??梢岳肣t的網(wǎng)絡模塊來建立與華為云IOT平臺的HTTPS連接,并通過API接口獲取設備的影子數(shù)據(jù)。

(1)從華為云IOT平臺獲取數(shù)據(jù)的流程

  • 認證授權:使用設備的Access Key和Secret Key進行認證授權,獲取訪問令牌。
  • 構建HTTPS請求:利用Qt的網(wǎng)絡模塊構建HTTPS請求,包括API接口的URL、Header信息、請求參數(shù)等。
  • 發(fā)送HTTPS請求:發(fā)送構建好的HTTPS請求給華為云IOT平臺,獲取設備的影子數(shù)據(jù)。
  • 處理響應數(shù)據(jù):解析HTTPS響應,提取設備的影子數(shù)據(jù)并進行處理。

(2)數(shù)據(jù)展示與交互

在獲取到設備的影子數(shù)據(jù)后,可以利用Qt的界面設計模塊,結合自定義的數(shù)據(jù)展示控件,將設備的影子數(shù)據(jù)以直觀的方式呈現(xiàn)給用戶。

1.3 系統(tǒng)功能總結

功能點 描述 顯示位置 操作方式
PH值檢測 檢測淡水湖中PH值情況 本地LCD顯示屏、手機APP 自動檢測,遠程查看
渾濁度檢測 檢測淡水湖中水質(zhì)渾濁度 本地LCD顯示屏、手機APP 自動檢測,遠程查看
TDS值檢測 檢測淡水湖中TDS值情況 本地LCD顯示屏、手機APP 自動檢測,遠程查看
手動換水 遠程啟動換水電機進行換水 本地LCD顯示屏(顯示換水倒計時)、手機APP 手機APP遠程啟動
周期自動投喂 遠程啟動食物投喂電機進行自動投喂 本地LCD顯示屏(顯示投喂倒計時)、手機APP 手機APP遠程啟動
數(shù)據(jù)上云 將檢測數(shù)據(jù)上傳至華為云IOT物聯(lián)網(wǎng)服務器 華為云IOT服務器 自動上傳
遠程控制 支持手機APP、Windows電腦遠程控制 手機APP、Windows電腦APP 遠程操作
周期自動充氧 遠程設置時間進行自動充氧 本地LCD顯示屏(顯示充氧倒計時)、手機APP、Windows電腦APP 手機APP、Windows電腦APP遠程設置
蜂鳴器報警 當渾濁度高于設定值時報警 本地蜂鳴器 自動報警

此表格總結了基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)的各項功能,包括其描述、顯示位置以及操作方式。這些功能通過STM32F103RCT6主控芯片、各類傳感器、繼電器、步進電機、ESP8266-WIFI模塊等硬件實現(xiàn),并通過手機APP和Windows電腦APP進行遠程控制和監(jiān)測。

1.4 關鍵技術選型與說明

1.4.1 STM32F103RCT6最小系統(tǒng)板介紹

在基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)中,STM32F103RCT6最小系統(tǒng)板作為整個系統(tǒng)的大腦,它負責處理來自各種傳感器的數(shù)據(jù),執(zhí)行自動化控制邏輯,并管理與外部設備和遠程服務器的通信。STM32F103RCT6最小系統(tǒng)板是一個高度集成的開發(fā)平臺,專為嵌入式應用設計,它基于ARM Cortex-M3內(nèi)核,提供高性能的32位微處理器,具備高速的處理能力和低功耗特性,非常適合要求實時響應和高精度數(shù)據(jù)處理的場景。

該系統(tǒng)板集成了主控芯片STM32F103RCT6,擁有豐富的外設資源,包括多個通用輸入輸出(GPIO引腳,可以連接各種傳感器和執(zhí)行器,如水質(zhì)檢測傳感器、電機控制電路等。此外,它還配備了精確的時鐘源,如外部晶振,以及電源管理電路,確保系統(tǒng)穩(wěn)定運行。系統(tǒng)板上還設計有調(diào)試接口,如SWD接口,便于程序的燒錄和調(diào)試,以及LED指示燈和按鍵,用于狀態(tài)顯示和用戶交互。

在本項目中,STM32F103RCT6最小系統(tǒng)板不僅負責接收和處理來自PH值、渾濁度和TDS值傳感器的數(shù)據(jù),還控制著換水、投喂和充氧等自動化操作,通過集成的通信模塊如ESP8266-WIFI,實現(xiàn)與華為云IOT物聯(lián)網(wǎng)服務器的連接,支持數(shù)據(jù)上云和遠程控制功能。此外,系統(tǒng)板上的資源還被用于驅動本地LCD顯示屏,顯示實時水質(zhì)參數(shù)和系統(tǒng)狀態(tài),以及控制蜂鳴器報警系統(tǒng),當水質(zhì)異常時及時發(fā)出警報。

STM32F103RCT6最小系統(tǒng)板憑借其強大的處理能力、豐富的外設接口和高度集成的設計,成為了構建基于物聯(lián)網(wǎng)的淡水湖養(yǎng)殖系統(tǒng)的關鍵組件,確保了水質(zhì)監(jiān)測的準確性、自動化控制的可靠性以及遠程管理的便利性,為實現(xiàn)淡水湖養(yǎng)殖的智能化和高效化奠定了堅實的硬件基礎。

1.4.2 ESP8266與MQTT協(xié)議應用

在基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)中,ESP8266與MQTT協(xié)議的應用是實現(xiàn)遠程數(shù)據(jù)傳輸和設備管理的核心技術。ESP8266是一款低成本、低功耗的Wi-Fi模塊,特別適用于物聯(lián)網(wǎng)應用,因其集成了TCP/IP協(xié)議棧和內(nèi)置的微控制器,能夠直接與各種傳感器和執(zhí)行器通信,無需額外的微處理器,極大地簡化了物聯(lián)網(wǎng)設備的設計和開發(fā)。

MQTT(Message Queuing Telemetry Transport)協(xié)議是一種輕量級的發(fā)布/訂閱消息協(xié)議,專為低帶寬、高延遲或不可靠的網(wǎng)絡設計。它基于TCP/IP協(xié)議,通過最小化數(shù)據(jù)包大小和帶寬使用,使得設備能夠在資源受限的環(huán)境中高效地交換信息。MQTT協(xié)議的發(fā)布/訂閱模型允許設備(如淡水湖養(yǎng)殖系統(tǒng)中的傳感器和執(zhí)行器)作為訂閱者接收特定主題的消息,同時作為發(fā)布者發(fā)送數(shù)據(jù),這種機制非常適合分布式物聯(lián)網(wǎng)系統(tǒng)中設備間的通信。

在本項目中,ESP8266 Wi-Fi模塊作為淡水湖養(yǎng)殖系統(tǒng)與華為云IOT物聯(lián)網(wǎng)服務器之間的通信橋梁,負責將水質(zhì)監(jiān)測數(shù)據(jù)(如PH值、渾濁度、TDS值等)通過MQTT協(xié)議上傳至云服務器,同時接收來自云服務器的控制指令,如換水、投喂和充氧的調(diào)度。通過MQTT協(xié)議,養(yǎng)殖系統(tǒng)可以將大量傳感器數(shù)據(jù)壓縮成小包傳輸,減少網(wǎng)絡擁堵,同時確保數(shù)據(jù)傳輸?shù)目煽啃院桶踩浴?/p>

STM32F103RCT6主控芯片收集水質(zhì)傳感器的數(shù)據(jù)后,通過串行通信接口(如UART)將數(shù)據(jù)發(fā)送給ESP8266模塊。ESP8266模塊利用MQTT協(xié)議將這些數(shù)據(jù)打包并發(fā)送到華為云服務器的指定主題,服務器則通過預先設置的規(guī)則引擎處理這些數(shù)據(jù),將其存儲、分析或轉發(fā)給授權的用戶(如通過手機APP或電腦軟件)。此外,用戶可以通過同樣的MQTT主題發(fā)送控制命令,ESP8266模塊接收到這些命令后,再將它們轉發(fā)給STM32F103RCT6,從而實現(xiàn)遠程控制功能,如啟動換水電機、調(diào)整投喂周期或設定充氧時間。

ESP8266與MQTT協(xié)議在淡水湖養(yǎng)殖系統(tǒng)中的應用,不僅實現(xiàn)了水質(zhì)參數(shù)的實時監(jiān)測與遠程管理,還構建了一個高效、穩(wěn)定的數(shù)據(jù)傳輸通道,確保了養(yǎng)殖環(huán)境的智能化和自動化,為養(yǎng)殖者提供了便捷的遠程監(jiān)控和控制手段,推動了淡水湖養(yǎng)殖業(yè)向智慧農(nóng)業(yè)的轉型。

1.4.3 Qt(C++)手機APP開發(fā)框架

在基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)中,Qt(C++)框架被用于開發(fā)手機應用程序,為養(yǎng)殖者提供一個直觀且功能全面的遠程監(jiān)控與控制平臺。Qt是一個跨平臺的開發(fā)框架,以其豐富的GUI工具、強大的網(wǎng)絡功能以及廣泛的設備支持而聞名。Qt不僅支持C++編程,還提供了一套完整的工具鏈,包括Qt Creator集成開發(fā)環(huán)境(IDE)、Qt Widgets和Qt Quick/QML用于UI設計,以及一系列庫和模塊,如Qt Networking和Qt Sensors,適用于構建復雜的物聯(lián)網(wǎng)應用。

Qt(C++)手機APP開發(fā)框架在本項目中的應用,使得開發(fā)者能夠構建出既美觀又功能強大的Android應用程序,而無需深入了解底層的Android SDK。通過Qt Quick和QML,開發(fā)者可以快速設計出響應式的用戶界面,這些界面能夠適應不同尺寸的屏幕,提供一致的用戶體驗。QML是一種聲明式語言,它簡化了UI的構建過程,允許開發(fā)者使用簡單的語法描述界面布局、動畫和交互邏輯,同時還可以與C++代碼無縫集成,實現(xiàn)復雜業(yè)務邏輯的編寫。

在淡水湖養(yǎng)殖系統(tǒng)中,Qt開發(fā)的手機APP充當了養(yǎng)殖者與物聯(lián)網(wǎng)設備之間的交互界面。它不僅實時顯示水質(zhì)參數(shù),如PH值、渾濁度和TDS值,還允許用戶遠程控制關鍵的養(yǎng)殖操作,比如啟動換水、設置投喂周期和充氧時間。

Qt的網(wǎng)絡模塊在實現(xiàn)數(shù)據(jù)傳輸方面發(fā)揮了重要作用,它支持多種通信協(xié)議,包括HTTP、HTTPS和MQTT,這使得APP能夠與華為云IOT物聯(lián)網(wǎng)服務器建立穩(wěn)定連接,實現(xiàn)數(shù)據(jù)的雙向通信。通過調(diào)用華為云提供的API接口,Qt開發(fā)的APP能夠從云服務器下載最新的水質(zhì)數(shù)據(jù),同時上傳控制指令,確保養(yǎng)殖系統(tǒng)的遠程監(jiān)控和管理。

Qt(C++)框架在淡水湖養(yǎng)殖系統(tǒng)的手機APP開發(fā)中,提供了強大的開發(fā)工具和豐富的功能庫,使得開發(fā)者能夠高效地構建出功能全面、界面友好的移動應用程序,極大地提升了養(yǎng)殖者的操作便利性和養(yǎng)殖系統(tǒng)的智能化水平。

1.4.4 通信協(xié)議與云平臺對接方案

在本項目中,系統(tǒng)采用了MQTT(Message Queuing Telemetry Transport)協(xié)議作為主要的通信機制,這是一種輕量級的發(fā)布/訂閱模式的消息傳輸協(xié)議,專為低帶寬和高延遲的網(wǎng)絡環(huán)境設計,非常適合物聯(lián)網(wǎng)場景下的數(shù)據(jù)傳輸。MQTT協(xié)議的特點在于其低開銷、低網(wǎng)絡流量和良好的穩(wěn)定性,能夠有效減少設備端與云平臺之間的通信延遲,并保證數(shù)據(jù)傳輸?shù)目煽啃浴?/p>

為了實現(xiàn)淡水湖養(yǎng)殖系統(tǒng)與華為云IOT平臺的對接,在系統(tǒng)中集成了MQTT客戶端,該客戶端運行在基于STM32的微控制器上,負責收集各種傳感器數(shù)據(jù),如水質(zhì)參數(shù)檢測模塊采集的PH值、渾濁度和TDS值等,并通過無線模塊將這些數(shù)據(jù)封裝成MQTT消息,發(fā)送至華為云IOT物聯(lián)網(wǎng)平臺。同時,MQTT客戶端也接收來自云平臺的控制指令,如啟動換水、設置投喂周期和充氧時間等操作,從而實現(xiàn)對養(yǎng)殖系統(tǒng)的遠程控制。

在云平臺側,利用華為云IOT提供的SDK和API接口,構建了一個數(shù)據(jù)處理和分析的后端服務。當?shù)B(yǎng)殖系統(tǒng)上傳的數(shù)據(jù)到達華為云IOT平臺后,后端服務會自動接收并解析這些數(shù)據(jù),將其存儲到數(shù)據(jù)庫中,以便于后續(xù)的數(shù)據(jù)分析和可視化展示。同時,后端服務還負責處理來自手機APP的請求,將用戶的控制指令轉換為MQTT消息,通過華為云IOT平臺重新下發(fā)給淡水湖養(yǎng)殖系統(tǒng)的MQTT客戶端,實現(xiàn)了云平臺、手機APP與養(yǎng)殖系統(tǒng)三者之間的數(shù)據(jù)閉環(huán)。

本項目的通信協(xié)議與云平臺對接方案,充分利用了MQTT協(xié)議的特性,結合華為云IOT平臺的強大功能,構建了一個穩(wěn)定、安全且高效的淡水湖養(yǎng)殖系統(tǒng)遠程監(jiān)控與控制系統(tǒng),極大地提升了養(yǎng)殖效率和管理水平。

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

1.5.1 設備端開發(fā)

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

開發(fā)工具選擇Keil,keil是一家世界領先的嵌入式微控制器軟件開發(fā)商,在2015年,keil被ARM公司收購。因為當前芯片選擇的是STM32F103系列,STMF103是屬于ARM公司的芯片構架、Cortex-M3內(nèi)核系列的芯片,所以使用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,而且使用頻率較多,已經(jīng)習慣再使用IAR是有點不適應界面的。

1.5.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.6 參考文獻

1. 宦娟,吳帆,曹偉建等.基于窄帶物聯(lián)網(wǎng)的養(yǎng)殖塘水質(zhì)監(jiān)測系統(tǒng)研制[J].農(nóng)業(yè)工程學報,2019,35(08):252-261. 
2. Sajal Saha, Rakibul Hasan Rajib et al. “IoT Based Automated Fish Farm Aquaculture Monitoring System.” 2018 International Conference on Innovations in Science, Engineering and Technology (ICISET) (2018). 201-206. 
3. K. Preetham, B. Mallikarjun et al. “Aquaculture monitoring and control system: An IoT based approach.” (2019). 1167-1170. 
4. Nikitha Rosaline and Dr. S. Sathyalakshimi. “IoT Based Aquaculture Monitoring and Control System.” Journal of Physics: Conference Series (2019). 
5. Rodolfo W. L. Coutinho and A. Boukerche. “Towards a Novel Architectural Design for IoT-Based Smart Marine Aquaculture.” IEEE Internet of Things Magazine (2022). 174-179. 
6. 彭琛,陳偉平,曾昱.物聯(lián)網(wǎng)技術在智能水產(chǎn)養(yǎng)殖系統(tǒng)中的應用[J].湖南文理學院學報(自然科學版),2021,33(04):37-41+87. 
7. 楊金明,余情,朱紅飛等.基于物聯(lián)網(wǎng)技術的水產(chǎn)養(yǎng)殖智能管理系統(tǒng)設計[J].湖北農(nóng)業(yè)科學,2016,55(16):4276-4279. 
8. 冼鋰東,龍祖連.基于物聯(lián)網(wǎng)技術智慧水產(chǎn)養(yǎng)殖系統(tǒng)的研究設計[J].物聯(lián)網(wǎng)技術,2022,12(02):65-68. 
9. 徐曉姍.基于物聯(lián)網(wǎng)和3G技術的智能水產(chǎn)養(yǎng)殖環(huán)境監(jiān)測系統(tǒng)的設計與應用[J].網(wǎng)絡安全技術與應用,2014,No.165(09):235-236. 
10. 劉星橋,駱波,朱成云.基于物聯(lián)網(wǎng)和GIS的水產(chǎn)養(yǎng)殖測控系統(tǒng)平臺設計[J].漁業(yè)現(xiàn)代化,2016,43(06):16-20. 
11. 李新成,林德峰,王勝濤等.基于物聯(lián)網(wǎng)的水產(chǎn)養(yǎng)殖池塘智能管控系統(tǒng)設計[J].水產(chǎn)學雜志,2020,33(01):81-86. 
12. 楊軼霞.基于物聯(lián)網(wǎng)技術的智能水產(chǎn)養(yǎng)殖監(jiān)控系統(tǒng)應用[J].電子技術,2021,50(05):178-179. 
13. B. Paul, Shubham Agnihotri et al. “Sustainable Smart Aquaponics Farming Using IoT and Data Analytics.” Journal of Information Technology Research (2022). 1-27. 
14. 林永鋮,林超洋,梁志鋒等.基于物聯(lián)網(wǎng)技術的淡水養(yǎng)殖監(jiān)控系統(tǒng)[J].電氣技術,2015,No.192(10):59-62. 
15. 基于物聯(lián)網(wǎng)的智慧水產(chǎn)系統(tǒng)開發(fā) [2021-08-05]
16. 吳小峰.基于物聯(lián)網(wǎng)技術的智能水產(chǎn)養(yǎng)殖管理系統(tǒng)設計[J].襄陽職業(yè)技術學院學報,2015,14(06):15-18. 
17. R. Ismail, K. Shafinah et al. “A Proposed Model of Fishpond Water Quality Measurement and Monitoring System based on Internet of Things (IoT).” IOP Conference Series: Earth and Environment (2020). 
18. 王韻琪,尤文杰,李呈祥等.基于物聯(lián)網(wǎng)的水產(chǎn)智能養(yǎng)殖環(huán)境監(jiān)控系統(tǒng)設計[J].科技風,2022,No.510(34):66-68. 
19. 潘春霖.基于物聯(lián)網(wǎng)技術的智能漁業(yè)監(jiān)控系統(tǒng)設計[J].天津農(nóng)業(yè)科學,2017,23(12):26-30. 
20. 湯朝婧.基于物聯(lián)網(wǎng)技術的水產(chǎn)養(yǎng)殖系統(tǒng)設計[J].物聯(lián)網(wǎng)技術,2024,14(02):82-85+89. 
21. 基于物聯(lián)網(wǎng)的水產(chǎn)養(yǎng)殖環(huán)境智能監(jiān)控系統(tǒng) [2014-02-20]
22. 胡瓊.基于物聯(lián)網(wǎng)的智慧水產(chǎn)養(yǎng)殖系統(tǒng)模型設計[J].無線互聯(lián)科技,2019,16(02):33-34. 
23. 李卓然.基于嵌入式Linux的水產(chǎn)養(yǎng)殖物聯(lián)網(wǎng)監(jiān)測系統(tǒng)設計[J].農(nóng)機化研究,2019,41(11):229-233. 
24. 王英杰. 基于物聯(lián)網(wǎng)的水產(chǎn)養(yǎng)殖測控系統(tǒng)的設計與實現(xiàn)[D].江蘇大學,2017. 
25. 黃勁斐.物聯(lián)網(wǎng)水產(chǎn)監(jiān)測系統(tǒng)的設計[J].科技視界,2020,No.318(24):24-25. 
26. 楊寧生,袁永明,孫英澤.物聯(lián)網(wǎng)技術在我國水產(chǎn)養(yǎng)殖上的應用發(fā)展對策[J].中國工程科學,2016,18(03):57-61. 
27. 陳浩成,袁永明,馬曉飛等.基于物聯(lián)網(wǎng)的水產(chǎn)養(yǎng)殖水質(zhì)監(jiān)控集成技術[J].現(xiàn)代農(nóng)業(yè)科技,2013,No.608(18):324-326. 
28. M. Lafont, Samuel Dupont et al. “Back to the future: IoT to improve aquaculture : Real-time monitoring and algorithmic prediction of water parameters for aquaculture needs.” Global Internet of Things Summit (2019). 1-6. 
29. U. Acar, Frank Kane et al. “Designing An IoT Cloud Solution for Aquaculture.” Global Internet of Things Summit (2019). 1-6. 
30. 顧麗敏.基于物聯(lián)網(wǎng)的數(shù)字化漁業(yè)養(yǎng)殖監(jiān)測系統(tǒng)設計[J].信息系統(tǒng)工程,2021,No.325(01):74-75. 

1.7 系統(tǒng)框架圖

image-20240703160524708

二、硬件選

2.1 STM32系統(tǒng)板與LCD顯示屏

鏈接:https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-22005753285.30.5737310cXpmN0y&id=620032209322&rn=37a37f544a247f36db4df3cb971b28a7&abbucket=13&skuId=4380279868463

主控CPU采用STM32F103RCT6,這顆芯片包括48 KB SRAM、256 KB Flash、2個基本定時器、4個通用定時器、2個高級定時器、51個通用IO口、5個串口、2個DMA控制器、3個SPI、2個I2C、1個USB、1個CAN、3個12位ADC、1個12位DAC、1個SDIO接口,芯片屬于大容量類型,配置較高,整體符合硬件選型設計。當前選擇的這款開發(fā)板自帶了一個1.4寸的TFT-LCD彩屏,可以顯示當前傳感器數(shù)據(jù)以及一些運行狀態(tài)信息。

image-20240703152928438

1.44寸LCD顯示屏的鏈接:https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-22005753285.30.5737310cXpmN0y&id=620032209322&rn=37a37f544a247f36db4df3cb971b28a7&abbucket=13&skuId=4380340448771

image-20240703153020377

2.2 PCB板

鏈接:https://detail.tmall.com/item.htm?abbucket=9&id=525489414251&ns=1&skuId=3929211749440&spm=a230r.1.14.34.16b221829wBwAI

image-20240404223242975

2.3 蜂鳴器模塊

鏈接:https://detail.tmall.com/item.htm?ali_refid=a3_430582_1006:1104520036:N:X/YIdD%20/nzZWyWHIKhozj3ahdFvQYGOd:09a834d50903c653d8893f1f618eb321&ali_trackid=1_09a834d50903c653d8893f1f618eb321&id=21124132861&spm=a230r.1.14.1&skuId=4319138558993

image-20230226222801899

2.4 電源擴展接口(x2)

買2個擴展板,方便擴展5v電源 和 3.3V電源。

鏈接:https://item.taobao.com/item.htm?id=647681090119&skuId=4672158745999&spm=a1z0d.6639537/tb.1997196601.4.754374841n18eN

image-20240410095312092

2.5 ESP8266-WIFI(ESP-01S)

鏈接:https://detail.tmall.com/item.htm?spm=a21n57.1.item.39.42bb523cSULOQH&priceTId=213e38c717199909300956449ecfca&utparam=%7B%22aplus_abtest%22:%228edbe31ddaa06b3212d4f9a079965932%22%7D&id=757493104729&ns=1&abbucket=13&skuId=5396864971038

image-20240703151855558

2.6 母對母杜邦線(X2)

作用: 連接模塊與單片機。

鏈接:https://detail.tmall.com/item.htm?ali_refid=a3_430582_1006:1104520036:N:MsF9mE9KLTC2IibWJh%20K1A==:adaa6d3d7abe6f1f07b87a36416ee4fb&ali_trackid=1_adaa6d3d7abe6f1f07b87a36416ee4fb&id=14466195609&skuId=3108214440215&spm=a230r.1.14.1

image-20231120103302046

2.7 繼電器(x3)

鏈接:https://detail.tmall.com/item.htm?id=15909056050&ali_refid=a3_430582_1006:1104520036:N:sGzbt9RI84M4qtD4oBlF3Q==:94221238ccf10c5aeb7c31df1a993981&ali_trackid=1_94221238ccf10c5aeb7c31df1a993981&spm=a230r.1.14.1&skuId=3931798090624

image-20240703150747255

2.8 穩(wěn)壓模塊

鏈接:https://item.taobao.com/item.htm?spm=a21n57.1.0.0.2921523cQeodt2&id=16606969730&ns=1&abbucket=7#detail

image-20230919222637274

img

2.9 5V2A電源插頭

鏈接:https://item.taobao.com/item.htm?spm=a1z0d.7625083.1998302264.6.5c5f4e69WfgpgO&id=616513772095

image-20240703151402638

2.10 5V 28BYJ4 步進電機

鏈接: https://detail.tmall.com/item.htm?id=41303683115&ali_refid=a3_430582_1006:1109983619:N:2nt6mzKrI7Z4Z+4S7irb6TVt9Q0NFo+R:c6bbda7f39718df42ff324c85021cf7e&ali_trackid=1_c6bbda7f39718df42ff324c85021cf7e&spm=a230r.1.14.1

image-20240703151131014

步進電機28BYJ-48名稱含義:

28:表示步進電機的有效最大外徑為28毫米
B: 表示步進電機“步”字漢語拼音首字母
Y: 表示永磁式“永”字漢語拼音首字母
J: 表示減速型“減”字漢語拼音首字母
BYJ: 組合即為永磁式減速步進電機
48:表示四相八拍
5V:表示額定電壓為5V,且為直流電壓

步進角:5.625度,就是1個脈沖信號轉5.625度,64個信號轉360度。
減速比:1/64,電機殼里邊的電機轉64圈,電機殼外邊的部分轉1圈。
四相:ABCD四相(電機定子上有8個齒,相對的2個齒是1相),
八拍:(A-AB-B-BC-C-CD-D-DA-A)。
一拍就是一個脈沖信號,完成一個循環(huán)用8個脈沖信號。
當通電狀態(tài)的改變完成一個循環(huán)時,轉子轉過一個齒距。轉8個齒距就是一圈,8×8=64
64拍,64個脈沖信號轉一圈360度。
  

image-20240316183312091

image-20240316183322434

2.11 增氧泵

鏈接:https://item.taobao.com/item.htm?id=613985790640&ali_refid=a3_430582_1006:1226360064:N:2BeiTZ6q9YYxgXM%2BVERvrA%2FFUJg%2FXa1Y:1cfd93a70ad4f25752bf8ced2f95c95f&ali_trackid=1_1cfd93a70ad4f25752bf8ced2f95c95f&spm=a230r.1.14.1#detail

image-20221107101816441

2.12 TDS檢測傳感器

鏈接:https://item.taobao.com/item.htm?spm=a21n57.1.item.99.42bb523cSULOQH&priceTId=213e385317199920382462481e622d&utparam=%7B%22aplus_abtest%22:%22839189b7b1235738d42966f0795b6672%22%7D&id=649460401747&ns=1&abbucket=13&skuId=5588303190398

TDS (Total Dissolved Solids)、中文名總溶解固體、又稱溶解性固體、又稱溶解性固體總量、表明1升水腫容有多少毫克溶解性固體、一般來說、TDS值越高、表示水中含有溶解物越多、水就越不潔凈、雖然在特定情況下TDS并不能有效反映水質(zhì)的情況、但作為一種可快速檢測的參數(shù)、TDS目前還可以作為有效的在水質(zhì)情況反映參數(shù)來作為參考。常用的TDS檢測設備為TDS筆、雖然價格低廉、簡單易用、但不能把數(shù)據(jù)傳給控制系統(tǒng)、做長時間的在線監(jiān)測、并做水質(zhì)狀況分析、使用專門的儀器、雖然能傳數(shù)據(jù)、精度也高、但價格很貴、為此這款TDS傳感器模塊、即插即用、使用簡單方便、測量用的激勵源采用交流信號、可有效防止探頭極化、延長探頭壽命的同時、也增加了輸出信號的穩(wěn)定性、TDS探頭為防水探頭、可長期侵入水中測量、該產(chǎn)品可以應用于生活用水、水培等領域的水質(zhì)檢測、有了這個傳感器、可輕松DIY–套TDS檢測儀了、輕松檢測水的潔凈程度。
image-20240703153852779

2.13 渾濁度檢測傳感器

鏈接:https://item.taobao.com/item.htm?spm=a21n57.1.item.2.426f523cArKJnA&priceTId=213e394a17199924273215703ee6b5&utparam=%7B%22aplus_abtest%22:%22dc113eb55c74290e427c17dd33dfe431%22%7D&id=634709383404&ns=1&abbucket=13&skuId=4534228449927

image-20240703154209747

2.14 抽水馬達(X2)

進水和出水控制

鏈接地址:https://detail.tmall.com/item.htm?abbucket=6&id=599450427587&ns=1&skuId=4531922407703&spm=a21n57.1.0.0.438e523cDKEtmS

image-20240703154503821

2.15 USB母頭(接電機使用的)

鏈接:https://item.taobao.com/item.htm?spm=a1z09.2.0.0.4ff12e8dBjY7rQ&id=660481026591&_u=31pq7ueodfb1&skuId=4760127756241

image-20240703154826039

2.16 PH值檢測傳感器

鏈接:https://item.taobao.com/item.htm?id=634709383404&ali_refid=a3_430582_1006:1102529383:N:JlEYFEO17l7srXd1PIPepQ==:156a9250417b127e9fef702f7e0ad206&ali_trackid=1_156a9250417b127e9fef702f7e0ad206&spm=a21n57.1.item.49&skuId=5411506393849

image-20240703155406217

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

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

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

image-20221204193824815

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

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

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

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

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

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

img

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

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

image-20221204194233414

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

image-20240117134653452

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

image-20240117134729401

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

image-20240117134810379

可以看到標準版實例的設備接入端口和地址。

image-20240117134919643

在上面也能看到 免費單元的限制。

image-20240117135018568

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

image-20240227105650173

總結:

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

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

C:Users11266>ping 3cee0d1a66.st1.iotda-device.cn-north-4.myhuaweicloud.com

正在 Ping 3cee0d1a66.st1.iotda-device.cn-north-4.myhuaweicloud.com [117.78.5.125] 具有 32 字節(jié)的數(shù)據(jù):
來自 117.78.5.125 的回復: 字節(jié)=32 時間=42ms TTL=94
來自 117.78.5.125 的回復: 字節(jié)=32 時間=42ms TTL=94
來自 117.78.5.125 的回復: 字節(jié)=32 時間=42ms TTL=94
來自 117.78.5.125 的回復: 字節(jié)=32 時間=43ms TTL=94

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

C:Users11266>

MQTT協(xié)議接入端口號有兩個,1883是非加密端口,8883是證書加密端口,單片機無法加載證書,所以使用1883端口比較合適。 接下來的ESP8266就采用1883端口連接華為云物聯(lián)網(wǎng)平臺。

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

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

image-20240117135239062

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

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

image-20240227105804075

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

image-20240227105823745

image-20240227105859521

(4)添加自定義模型

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

image-20240227105848014

模型簡單來說: 就是存放設備上傳到云平臺的數(shù)據(jù)。比如:水溫、換水電機、充氧電機、水質(zhì)狀態(tài)、充氧時間間隔等等,我們都可以單獨創(chuàng)建一個模型保存。

當前設備需要與云平臺交互的屬性如下: 接下來就按照下面的屬性創(chuàng)建 華為云平臺的模型。

上傳到華為云IOT平臺的屬性:
PH值檢測     PH                    整型
渾濁度檢測   water_quality	   	   整型
溫度檢測     DS18B20  			   浮點數(shù)
換水電機     water_motor           BOOL類型
充氧電機     oxygen_motor		   BOOL類型
定時充氧     oxygen_motor_time 	   整型
水溫閥值     DS18B20_MAX           整型
 換水電機-出水 clean_motor		   BOOL類型
照明燈       lighting_led		   BOOL類型
水位檢測     water_monitor         整型

先點擊自定義模型。

image-20240227113654148

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

image-20240227113714639

接著點擊新增屬性。

image-20240227113742106

PH值檢測 PH 整型

image-20240227113933977

渾濁度檢測 water_quality 整型

image-20240227113956953

溫度檢測 DS18B20 浮點數(shù)

image-20240227114039106

換水電機 water_motor BOOL類型

image-20240227114110606

充氧電機 oxygen_motor BOOL類型

image-20240227114134840

定時充氧 oxygen_motor_time 整型

image-20240227114156004

水溫閥值 DS18B20_MAX 整型

image-20240227114216941

** 換水電機-出水 clean_motor BOOL類型**

image-20240227114237002

照明燈 lighting_led BOOL類型

image-20240227114300974

水位檢測 water_monitor 整型

image-20240227114325253

3.4 添加設備

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

(1)注冊設備

image-20240227114807036

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

image-20240227114840454

image-20240227114853167

(3)保存設備信息

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

image-20240227114924925

當前設備的信息如下:

{
    "device_id": "65dd4fc72ccc1a583879a7e1_dev1",
    "secret": "12345678"
}

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

image-20240227114959283

點擊詳情:

image-20240227115011698

這就是設備頁面:

image-20240227115031219

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

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

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

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

MQTT是一種消息隊列協(xié)議,使用發(fā)布/訂閱消息模式,提供一對多的消息發(fā)布,解除應用程序耦合,相對于其他協(xié)議,開發(fā)更簡單;MQTT協(xié)議是工作在TCP/IP協(xié)議上;由TCP/IP協(xié)議提供穩(wěn)定的網(wǎng)絡連接;所以,只要具備TCP協(xié)議棧的網(wǎng)絡設備都可以使用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連接每秒的吞吐量,即帶寬,包含直連設備和網(wǎng)關 3KB/s
MQTT單個發(fā)布消息最大長度,超過此大小的發(fā)布請求將被直接拒絕 1MB
MQTT連接心跳時間建議值 心跳時間限定為30至1200秒,推薦設置為120秒
產(chǎn)品是否支持自定義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/65dd4fc72ccc1a583879a7e1_dev1/sys/messages/down

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

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

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

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

image-20221207153637391

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

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

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

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

根據(jù)這個格式,組合一次上傳的屬性數(shù)據(jù):
{"services": [{"service_id": "stm32","properties":{"PH":20,"water_quality":60,"DS18B20":14.1,"oxygen_motor_time":10,"DS18B20_MAX":15,"water_monitor":10,"clean_motor":1,"lighting_led":1,"water_motor":1,"oxygen_motor":1}}]}

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-20240227132259196

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

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

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

(2)生成MQTT三元組

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

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

下面是打開的頁面:

image-20221207154917230

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

直接得到三元組信息。

image-20240227132356796

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

ClientId  65dd4fc72ccc1a583879a7e1_dev1_0_0_2024022705
Username  65dd4fc72ccc1a583879a7e1_dev1
Password  91c783515515d883c533df05ef0e15ed526e583cfb141de54e9ba1545fba0513

3.7 模擬設備登錄測試

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

當前模擬設備登錄,調(diào)試設備的MQTT客戶端軟件可以在這里下載:

https://download.csdn.net/download/xiaolong1126626497/18784012

image-20240227134814527

(1)填入登錄信息

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

image-20240227132853862

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

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

image-20240227132925075

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

image-20240227132948843

image-20240227133007154

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

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

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


ClientId  65dd4fc72ccc1a583879a7e1_dev1_0_0_2024022705
Username  65dd4fc72ccc1a583879a7e1_dev1
Password  91c783515515d883c533df05ef0e15ed526e583cfb141de54e9ba1545fba0513



訂閱主題:  $oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/messages/down
發(fā)布主題:  $oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/report
發(fā)布的數(shù)據(jù):
{"services": [{"service_id": "stm32","properties":{"PH":20,"water_quality":60,"DS18B20":14.1,"oxygen_motor_time":10,"DS18B20_MAX":15,"water_monitor":10,"clean_motor":1,"lighting_led":1,"water_motor":1,"oxygen_motor":1}}]}

四、上位機開發(fā)

為了方便查看設備上傳的數(shù)據(jù),對設備進行遠程控制,接下來利用Qt開發(fā)一款Android和windows系統(tǒng)的上位機。

使用華為云平臺提供的API接口獲取設備上傳的數(shù)據(jù),也可以給設備下發(fā)指令,控制設備。

4.1 Qt開發(fā)環(huán)境安裝

Qt的中文官網(wǎng): https://www.qt.io/zh-cn/image-20221207160550486

image-20221207160606892

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

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

qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details

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

安裝的時候,第一個復選框里勾選一個mingw 32編譯器即可,其他的不管默認就行,直接點擊下一步繼續(xù)安裝。

image-20221203151742653

說明: 我這里只是介紹PC端的環(huán)境搭建(這個比較簡單)。 Android的開發(fā)環(huán)境比較麻煩,如果想學習Android開發(fā),想編譯Android程序的APP,可以去我的博客里看詳細文章。

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

選擇MinGW 32-bit 編譯器:

image-20221203151750344

4.2 創(chuàng)建IAM賬戶

創(chuàng)建一個IAM賬戶,因為接下來開發(fā)上位機,需要使用云平臺的API接口,這些接口都需要token進行鑒權。簡單來說,就是身份的認證。 調(diào)用接口獲取Token時,就需要填寫IAM賬號信息。所以,接下來演示一下過程。

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

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

image-20240227133127079

項目憑證:

756f8211ec6847c3a5ee4061b37d4ddb

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

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

image-20240227133234497

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

image-20240227133258130

image-20221207161209880

image-20221207161308917

image-20221207161327200

創(chuàng)建成功:

image-20221212174412097

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

image-20240227133348426

用戶信息如下:

主用戶名  hid_x13ruy5yb1ruano
IAM用戶  ds_abc
密碼     DS12345678

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

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

設備影子介紹:

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

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

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

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

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

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

image-20240227133525999

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

{
 "device_id": "65dd4fc72ccc1a583879a7e1_dev1",
 "shadow": [
  {
   "service_id": "stm32",
   "desired": {
    "properties": null,
    "event_time": null
   },
   "reported": {
    "properties": {
     "PH": 20,
     "water_quality": 60,
     "DS18B20": 14.1,
     "oxygen_motor_time": 10,
     "DS18B20_MAX": 15,
     "water_monitor": 10,
     "clean_motor": 1,
     "lighting_led": 1,
     "water_motor": 1,
     "oxygen_motor": 1
    },
    "event_time": "20240227T052838Z"
   },
   "version": 0
  }
 ]
}

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

image-20240227133555629

4.4 修改設備屬性

地址: https://support.huaweicloud.com/api-iothub/iot_06_v5_0034.html

接口說明

設備的產(chǎn)品模型中定義了物聯(lián)網(wǎng)平臺可向設備下發(fā)的屬性,應用服務器可調(diào)用此接口向指定設備下發(fā)屬性。平臺負責將屬性以同步方式發(fā)送給設備,并將設備執(zhí)行屬性結果同步返回。

修改設備屬性的接口,可以讓服務器給設備下發(fā)指令,如果需要控制設備。

在線調(diào)試地址:

https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?product=IoTDA&api=UpdateProperties

修改設備屬性是屬于同步命令,需要設備在線才可以進行調(diào)試,先使用MQTT客戶端登錄服務器,模擬設備上線。

然后進行調(diào)試,測試數(shù)據(jù)遠程下發(fā)給設備。

【1】利用MQTT客戶端先登錄設備 (這是同步命令,必須在線才能調(diào)試)

image-20240227133904041

【2】點擊調(diào)試

image-20240227133840260

填入的測試數(shù)據(jù):

{"services":{"oxygen_motor":1}}

【4】可以看到,MQTT客戶端軟件上已經(jīng)收到了服務器下發(fā)的消息

image-20240227133925707

由于是同步命令,服務器必須要收到設備的響應才能順利完成一個流程(當然,設備不回應也沒影響),設備響應了服務器才能確定數(shù)據(jù)下發(fā)成功。

MQTT設備端如何響應呢?

設備響應格式說明:https://support.huaweicloud.com/api-iothub/iot_06_v5_3008.html

image-20221203163532648

4.5 新建上位機工程

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

【1】新建工程

image-20240117144052547

【2】設置項目的名稱。

image-20240227134234510

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

image-20240117144239681

【4】選擇默認繼承的類

image-20240117144302275

【5】選擇編譯器

image-20240117144334967

【6】點擊完成

image-20240117144354252

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

image-20240227134340352

4.6 設計UI界面與工程配置

【1】打開UI文件

image-20240227134935394

打開默認的界面如下:

image-20240227134946603

【2】開始設計界面

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

image-20240725103359034

【3】配置pro工程文件

image-20240227135917795

其中,加了注釋的代碼,表示Android環(huán)境才需要,而當前是配置的Windows下的開發(fā)環(huán)境,在Windows下編譯,就將其注釋掉,暫時不使用。

【4】配置軟件圖標

在工程文件下方,增加當前軟件的圖標配置,圖標需要是ICO格式,將圖標放在工程同級路徑下,在工程配置文件里指定好圖標名稱。

image-20240227140031762

4.7 設計代碼

【1】獲取token

調(diào)用華為云的API都需要填token參數(shù),先看幫助文章,了解如何獲取token。

幫助文檔:https://support.huaweicloud.com/api-iam/iam_30_0001.html

image-20221207175635181

4.8 編譯Windows上位機

image-20240227160019104

編譯之后的效果:

image-20240725103439814

4.9 配置Android環(huán)境

如果想編譯Android手機APP,可以參考此章節(jié)配置。 但是: 生成Android手機APP必須要先自己配置Android環(huán)境,這個配置相對比較復雜。

配置Android環(huán)境可以參考教程: https://blog.csdn.net/xiaolong1126626497/article/details/117254453

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

image-20240227160310547

image-20240117144604025

image-20240117144635052

image-20240117144652014

創(chuàng)建完成。

image-20240227160237253

【2】配置Android圖標與名稱

image-20240725103033249

【3】編譯Android上位機

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

image-20240227160504476

image-20240227160609926

然后點擊構建。

image-20240227160633028

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

生成的apk的目錄在哪里呢?

從這里可以查看。

image-20240227160708578

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

D:linux-share-dirQTbuild-Smarts_Fishbowl_HuaWeiYunIot-Android_for_arm64_v8a_Clang_Qt_5_12_6_for_Android_ARM64_v8a-Releaseandroid-buildbuildoutputsapkdebug

image-20240227160736929

4.10 交互命令

上位機給設備下發(fā)的命令:

len:140,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=17f9bd7d-d81a-493c-94fa-5d7fc4d637a3{"services":{"lighting_led":1}}
len:139,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=bc1d53f6-dd28-48f6-a39c-fea3f1c7c45c{"services":{"clean_motor":0}}
len:140,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=2fb1619b-9d48-4bc2-9d07-054895275005{"services":{"oxygen_motor":1}}
len:139,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=9b2b0c35-12ea-4c6a-a43d-496d229b1783{"services":{"water_motor":1}}
len:145,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=f27f9be3-4e78-483b-82ae-d145ba78ce60{"services":{"oxygen_motor_time":1}}
len:136,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=09f0831e-6e9b-4220-a3d0-25912c67b48e{"services":{"temp_max":1}}
len:149,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=696f8046-fcf7-4307-b9a5-9604d31c8b94{"services":{"rtc_time":20240227162845}}

五、STM32設備端代碼設計

了解STM32F103的芯片配置:

image-20221209173742636

5.1 硬件連線

1. ESP8266 WIFI接線
ATK-ESP8266串口WIFI模塊與STM32的串口2相連接。
PA2(TX)--RXD 模塊接收腳
PA3(RX)--TXD 模塊發(fā)送腳
GND---GND 地
VCC---VCC 3.3V

2. TFT 1.44 寸彩屏接線
GND   電源地
VCC   3.3v電源
SCL   接PC8(SCL)
SDA   接PC9(SDA)
RST   接PC10
DC    接PB7
CS    接PB8
BL	  接PB11
 
3. DS18B20溫度傳感器
VCC--3.3v
GND---GND
OUT---PB3 

4. SG90舵機-模擬魚缸換水-出水
VCC--->5V
OUT--->PA7
GND--->GND

5. 水質(zhì)傳感器(ADC通道1)
VCC--->5V
GND--->GND
OUT--->PA1

6. SG90舵機-模擬魚缸換水-進水
OUT----PB5
GND---GND 地
VCC---5v


7. 魚缸水溫加熱--繼電器控制
GND----GND
VCC---3.3V
OUT---PB4

8. 增氧泵--繼電器控制
GND----GND
VCC---5V
OUT---PC11


9. PH值檢測
VCC--->3.3V
GND--->GND
OUT--->PA4


10. 照明燈開關
VCC--->3.3V
GND--->GND
OUT--->PA6


11. 水位檢測
VCC--->3.3V
GND--->GND
OUT--->PA5



13. 板載LED燈接線(這個不用接,這是開發(fā)板本身的)
LED1---PA8
LED2---PD2

14. 板載按鍵接線(這個不用接,這是開發(fā)板本身的)
K0---PA0 
K1---PC5 
K2---PA15

5.2 取模軟件使用

本地設備的LCD顯示屏上會顯示各種傳感器數(shù)據(jù),需要用到中文、數(shù)字、字母。

image-20240117214107546

這是軟件的設置頁面:

image-20240227192913049

5.3 通信協(xié)議

STM32設備端與華為云服務器通信的協(xié)議:

//如果WIFI已經(jīng)連接到網(wǎng)絡
if(esp8266_connect)
{
    //組合JSON報文數(shù)據(jù)
    sprintf(data_buff,"{"services": [{"service_id": "stm32","properties":{"PH":%d,"water_quality":%d,"DS18B20":%.1f,"oxygen_motor_time":%d,"DS18B20_MAX":%d,"water_monitor":%d,"clean_motor":%d,"lighting_led":%d,"water_motor":%d,"oxygen_motor":%d}}]}",
            PH,percentage,DS18B20,oxygen_motor_time,DS18B20_MAX,water_monitor,clean_motor,lighting_led,water_motor,oxygen_motor);

    //上傳數(shù)據(jù)
    MQTT_PublishData(POST_TOPIC,data_buff,0);
    printf("更新一次數(shù)據(jù).rn"); 
}

手機APP向STM32下發(fā)的數(shù)據(jù)協(xié)議:

len:140,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=17f9bd7d-d81a-493c-94fa-5d7fc4d637a3{"services":{"lighting_led":1}}
len:139,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=bc1d53f6-dd28-48f6-a39c-fea3f1c7c45c{"services":{"clean_motor":0}}
len:140,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=2fb1619b-9d48-4bc2-9d07-054895275005{"services":{"oxygen_motor":1}}
len:139,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=9b2b0c35-12ea-4c6a-a43d-496d229b1783{"services":{"water_motor":1}}
len:145,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=f27f9be3-4e78-483b-82ae-d145ba78ce60{"services":{"oxygen_motor_time":1}}
len:136,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=09f0831e-6e9b-4220-a3d0-25912c67b48e{"services":{"temp_max":1}}
len:149,Data:l$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/request_id=696f8046-fcf7-4307-b9a5-9604d31c8b94{"services":{"rtc_time":20240227162845}}

5.4 按鍵的功能說明

開發(fā)板自帶了4個按鍵,其中第2是個RST 是復位鍵、另外3個按鍵是可編程的獨立按鍵。

image-20240120161134807

按鍵1 功能: 顯示翻頁。

按鍵2 功能: 啟動-SG90電機。

按鍵3: 功能: 開啟或關閉照明燈。

詳細代碼如下:

key=KEY_Scan();
if(key)printf("key=%drn",key);

//按下按鍵1進行翻頁
if(key==1)
{
    Lcd_Clear(0); //清屏為黑色

    page++;
    if(page>=2)page=0;
    if(page==0)
    {
        page_1();
    }
    else 
    {
        page_2();
    }          
}

//按下按鍵2控制照明燈打開
else if(key==2)
{
    lighting_led=!lighting_led;
}
//按下按鍵3控制  控制
else if(key==3)
{
    //清洗3次
    open_clean_motor();
    close_clean_motor();
    delay_ms(1000);
    open_clean_motor();
    close_clean_motor();
    delay_ms(1000);
    open_clean_motor();
    close_clean_motor();
}

5.5 自動模式控制邏輯

在while(1)循環(huán)里,每1秒鐘的周期整體執(zhí)行一次。讀取傳感器的數(shù)據(jù),處理,上傳到華為云IOT平臺。

如果檢測到水質(zhì)超過閥值,會啟用換水功能自動換水。

如果檢測到溫度低于設置閥值,會啟用加熱功能自動加熱升溫。

如果檢測到充氧時間到達,會啟用充氧功能自動充氧。

在LCD顯示屏上會實時當前檢測到所有數(shù)據(jù)。

具體代碼如下:

//輪詢時間到達
if(time_cnt>20)
{
    time_cnt=0;
    LED1=!LED1;

    //--------------------------------采集數(shù)據(jù)--------------------------------

    //讀取水溫度
    DS18B20_int=DS18B20_Get_Temp();
    //轉換溫度為浮點數(shù)
    sprintf(mqtt_message,"%d.%d",DS18B20_int>>4,DS18B20_int&0xF);   
    DS18B20=atof(mqtt_message);


    //讀取水質(zhì)
    //水質(zhì):   純凈水300多   自來水800多   直接純牛奶2000
    water_quality=GetAvgAdcCHxDATA(1);
    percentage = water_quality / 3000.0 * 100.0;

    //讀取PH值
    PH=GetAvgAdcCHxDATA(4);
    if(PH>=4000)PH=5;

    //讀取水位
    //水越深值越大,最大值1640  
    water_monitor=GetAvgAdcCHxDATA(5);
    water_monitor= water_monitor / 1640.0 * 100.0;

    //--------------------------------下次充氧時間倒計時計算--------------------------------
    if(oxygen_food_sec<=0)
    {
        //默認充氧5秒
        oxygen_motor=1;
        DelayMs(5000);
        oxygen_motor=0;

        //時間歸位
        oxygen_food_sec=oxygen_motor_time*60;
    }

    //水質(zhì)太差 就啟動換水
    if(percentage>80)
    {
        //正轉  換水電機
        open_water_motor();
    }
    else
    {
        //--反轉  換水電機
        close_water_motor();
    }                  


    //顯示頁面1
    if(page==0)
    {
        //實時時間與日期
        Gui_DrawFont_GBK16(16*1,16*6+2,WHITE,0,(u8*)date_buff);
        Gui_DrawFont_GBK16(16*1+8,16*7+2,WHITE,0,(u8*)time_buff);

        //顯示溫度
        sprintf(mqtt_message,"%4.1fC",DS18B20);              
        Gui_DrawFont_GBK16(72,16*0+2,WHITE,0,(u8*)mqtt_message);
        // printf("%srn",mqtt_message);

        //顯示水質(zhì)
        sprintf(mqtt_message,"%4d%%",percentage);              
        Gui_DrawFont_GBK16(72,16*1+2,WHITE,0,(u8*)mqtt_message);


        //PH值
        sprintf(mqtt_message,"%4d",PH);              
        Gui_DrawFont_GBK16(72,16*2+2,WHITE,0,(u8*)mqtt_message);

        //充氧間隔
        sprintf(mqtt_message,"%4dm",oxygen_motor_time);              
        Gui_DrawFont_GBK16(72,16*3+2,WHITE,0,(u8*)mqtt_message);

        //恒溫溫度
        sprintf(mqtt_message,"%4dC",DS18B20_MAX); 
        Gui_DrawFont_GBK16(72,16*4+2,WHITE,0,(u8*)mqtt_message);  

        //水位距離
        sprintf(mqtt_message,"%4d%%",water_monitor);              
        Gui_DrawFont_GBK16(72,16*5+2,WHITE,0,(u8*)mqtt_message);     
    }

    else if(page==1)
    {
        //實時時間與日期
        Gui_DrawFont_GBK16(16*0,16*2+2,WHITE,0,(u8*)date_buff);
        Gui_DrawFont_GBK16(16*0+8,16*3+2,WHITE,0,(u8*)time_buff);


        char *p=format_time(oxygen_food_sec);
        Gui_DrawFont_GBK16(0,16*5+2,WHITE,0,(u8*)p);  
    }



    //恒溫判斷. 如果小于溫度閥值
    if(DS18B20<DS18B20_MAX)
    {
        temp_heat=1; //開啟加熱
    }
    else
    {
        temp_heat=0; //停止加熱
    }


    //如果WIFI已經(jīng)連接到網(wǎng)絡
    if(esp8266_connect)
    {
        //組合JSON報文數(shù)據(jù)
        sprintf(data_buff,"{"services": [{"service_id": "stm32","properties":{"PH":%d,"water_quality":%d,"DS18B20":%.1f,"oxygen_motor_time":%d,"DS18B20_MAX":%d,"water_monitor":%d,"clean_motor":%d,"lighting_led":%d,"water_motor":%d,"oxygen_motor":%d}}]}",
                PH,percentage,DS18B20,oxygen_motor_time,DS18B20_MAX,water_monitor,clean_motor,lighting_led,water_motor,oxygen_motor);

        //上傳數(shù)據(jù)
        MQTT_PublishData(POST_TOPIC,data_buff,0);
        printf("更新一次數(shù)據(jù).rn"); 
    }
}

5.6 手機APP遠程控制

如果STM32收到APP遠程下發(fā)的控制指令之后,會進行判斷處理。

具體代碼如下:

// 接收WIFI返回的數(shù)據(jù)
if(USART2_RX_FLAG)
{
    USART2_RX_BUFFER[USART2_RX_CNT]='?';

    printf("WIFI收到數(shù)據(jù):rn");
    //向串口打印服務器返回的數(shù)據(jù)
    for(i=0;i<USART2_RX_CNT;i++)
    {
        printf("%c",USART2_RX_BUFFER[i]);
    }

    #if 0

    $oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=8401c98b-268e-4382-82fd-b69d78275020{"services":{"motor_food":1}}
    $oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=22e6e1ff-3e5c-4a25-bbbf-fd4e8f314a68{"services":{"led_sw":1}}
    $oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=a15b8f8d-06cf-4597-8cd9-f92e3e0a7b4f{"services":{"motor_oxygen":1}}
    $oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=c5b708d8-7c58-43c8-9943-64e25fe6f4df{"services":{"motor_water":1}}
    $oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=852659ce-183c-42bf-b896-f9c1e960f405{"services":{"time_food":1}}
    $oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=e401d20d-8c10-453d-b1cf-ba7c97a66f7d{"services":{"oxygen_food":1}}
    $oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=dd10158b-3da0-45a2-be68-27ddb14a797c{"services":{"temp_max":15}}

    #endif

    if(USART2_RX_CNT>5)
    {
        //開  照明燈
        if(strstr((char*)&USART2_RX_BUFFER[5],""lighting_led":1"))
        {
            lighting_led=1;
        }
        //關  照明燈
        else if(strstr((char*)&USART2_RX_BUFFER[5],""lighting_led":0"))
        {
            lighting_led=0;

        }
        //開  換水電機
        else if(strstr((char*)&USART2_RX_BUFFER[5],""water_motor":1"))
        {
            //--反轉  換水電機
            close_water_motor();
        }
        //關  換水電機
        else if(strstr((char*)&USART2_RX_BUFFER[5],""water_motor":0"))
        {
            //正轉  換水電機
            open_water_motor();
        }
        //開  充氧電機
        else if(strstr((char*)&USART2_RX_BUFFER[5],""oxygen_motor":1"))
        {
            oxygen_motor=1;
        }
        //關  充氧電機
        else if(strstr((char*)&USART2_RX_BUFFER[5],""oxygen_motor":0"))
        {
            oxygen_motor=0;
        }
        //開   換水電機
        else if(strstr((char*)&USART2_RX_BUFFER[5],""clean_motor":1"))
        {
            //--反轉  換水電機-出水
            close_clean_motor();
        }
        //關   換水電機-出水
        else if(strstr((char*)&USART2_RX_BUFFER[5],""clean_motor":0"))
        {
            //正轉   換水電機-出水
            open_clean_motor();
        }
        //充氧時間間隔
        else if(strstr((char*)&USART2_RX_BUFFER[5],""oxygen_motor_time":"))
        {
            char *p=strstr((char*)&USART2_RX_BUFFER[5],""oxygen_motor_time":");
            oxygen_motor_time=atoi(p+20);

            oxygen_food_sec = oxygen_motor_time*60; //轉為秒單位
            printf("oxygen_motor_time=%drn",oxygen_motor_time);
        }
        //加熱溫度上限閥值
        else if(strstr((char*)&USART2_RX_BUFFER[5],""temp_max":"))
        {
            char *p=strstr((char*)&USART2_RX_BUFFER[5],""temp_max":");
            DS18B20_MAX=atoi(p+11);
            printf("DS18B20_MAX=%drn",DS18B20_MAX);
        }
        else if(strstr((char*)&USART2_RX_BUFFER[5],""rtc_time":"))
        {
            char *p=strstr((char*)&USART2_RX_BUFFER[5],""rtc_time":");
            p+=11; //向后偏移,指向正確的時間
            char *time=p;
            int tm_sec;  //秒
            int tm_min;  //分
            int tm_hour; //時
            int tm_mday; //日
            int tm_mon;  //月
            int tm_year; //年
            tm_year=(time[0]-48)*1000+(time[1]-48)*100+(time[2]-48)*10+(time[3]-48)*1;
            tm_mon=(time[4]-48)*10+(time[5]-48)*1;
            tm_mday=(time[6]-48)*10+(time[7]-48)*1;
            tm_hour=(time[8]-48)*10+(time[9]-48)*1;
            tm_min=(time[10]-48)*10+(time[11]-48)*1;
            tm_sec=(time[12]-48)*10+(time[13]-48)*1;
            SetRtcTime(tm_year,tm_mon,tm_mday,tm_hour,tm_min,tm_sec);
            printf("RTC時間設置成功:%d-%d-%d %d:%d:%drn",tm_year,tm_mon,tm_mday,tm_hour,tm_min,tm_sec);
        }

        //下發(fā)指令請求回應給服務器
        if(strstr((char*)&USART2_RX_BUFFER[5],"properties/set/request_id"))
        {
            char *p=NULL;
            p=strstr((char*)&USART2_RX_BUFFER[5],"request_id");
            if(p)
            {        
                //解析數(shù)據(jù)
                //$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/get/request_id=5f359b5c-542f-460e-9f51-85e82150ff4a{"service_id":"gps"} 
                strncpy(request_id,p,47);      
            }

            //上報數(shù)據(jù)
            sprintf(mqtt_message,"{"result_code": 0,"result_desc": "success"}");

            sprintf(data_buff,"$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/response/%s",
                    request_id);

            MQTT_PublishData(data_buff,mqtt_message,0);

            printf("發(fā)布主題:%srn",data_buff);
            printf("發(fā)布數(shù)據(jù):%srn",mqtt_message);
        }      
    }
    USART2_RX_CNT=0;
    USART2_RX_FLAG=0;
}

5.7 KEIL工程

image-20240227232840620

六、使用STM32代碼的流程以及注意事項

6.1 第一步

照著設計文檔,買回來硬件模塊。 然后照著第五章節(jié)的第1小節(jié)(5.1章節(jié))的硬件連線說明,將模塊與STM32開發(fā)板之間連接好線。

注意:LCD顯示屏,直接插上去就行了,買的開發(fā)板上本身就有排母,照著接,看準開發(fā)板板子上的 絲印說明。

image-20240227232916603

6.2 第二步

將Android手機APP安裝到自己的Android手機上,打開手機APP,點擊更新Token按鈕,點擊更新數(shù)據(jù),然后就可以了。 (這時候無法點擊控制按鈕,點擊會報錯,因為設備沒有在線,無法進行遠程控制設備,這是正常的)

6.3 第三步

使用手機開一個熱點。
(1)名字設置為: abc
(2)密碼設置為:12345678

注意事項:
WIFI頻段設置為:2.4GHZ

千萬注意:熱點的名字,密碼,頻段一點要設置正確。 否則,到時候,ESP8266-WIFI連接不上。 ESP8266 只能連接2.4GHZ的WIFI。

6.4 第四步

打STM32的keil工程,編譯代碼、然后,使用USB線將開發(fā)板的左邊的USB口(串口1)與電腦的USB連接,打開程序下載軟件下載程序。

具體下載過程看下面圖:

image-20240120161043543

打開程序下載軟件:

image-20240120160735942

6.5 第五步

下載成功之后,本地的LCD顯示屏會顯示硬件的初始化過程。 比如:ESP8266的初始化過程,以及WIFI熱點的連接過程。

如何提示ESP8266-錯誤,那么就認真檢查WIFI接線。

如果顯示W(wǎng)IFI連接失敗,請認真檢查 第三步。

如果一切正常,就進入了程序主界面。

這時候,打開手機APP,也能看到設備的最新數(shù)據(jù),點擊控制按鈕,也能控制設備了。

到此,恭喜你,整個項目已經(jīng)完成開發(fā)。

七、制作過程

串口調(diào)試助手:

image-20240228011023906

WIFI模式:STA+TCP客戶端
Connect_WIFI熱點名稱:abc
Connect_WIFI熱點密碼:12345678
TCP服務器端口號:1883
TCP服務器IP地址:117.78.5.125
ESP8266成功連接上熱點...
準備連接MQTT服務器...
0x20 0x2 0 0 服務器連接成功.

image-20240227233136333

image-20240227233200794

八、STM32完整代碼

下面是main.c文件的完整代碼。

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include <string.h>
#include "timer.h"
#include "esp8266.h"
#include "oled.h"
#include "adc.h"
#include <string.h>
#include <stdlib.h>
#include "font.h"
#include "mqtt.h"
#include "ds18b20.h"
#include "rtc.h"
#include "hardware.h"


//物聯(lián)網(wǎng)服務器的設備信息
#define MQTT_ClientID "65dd4fc72ccc1a583879a7e1_dev1_0_0_2024022705"
#define MQTT_UserName "65dd4fc72ccc1a583879a7e1_dev1"
#define MQTT_PassWord "91c783515515d883c533df05ef0e15ed526e583cfb141de54e9ba1545fba0513"

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

//設置連接的路由器信息
#define CONNECT_WIFI  "abc"   //將要連接的路由器名稱 --不要出現(xiàn)中文、空格等特殊字符
#define CONNECT_PASS "12345678"       //將要連接的路由器密碼

#define CONNECT_SERVER_IP "117.78.5.125"   //服務器IP地址
#define CONNECT_SERVER_PORT 1883            //服務器端口號


//JTAG模式設置,用于設置JTAG的模式
//mode:jtag,swd模式設置;00,全使能;01,使能SWD;10,全關閉;	   
#define JTAG_SWD_DISABLE   0X02
#define SWD_ENABLE         0X01
#define JTAG_SWD_ENABLE    0X00		  
void JTAG_Set(u8 mode)
{
	u32 temp;
	temp=mode;
	temp<<=25;
	RCC->APB2ENR|=1<<0;     //開啟輔助時鐘	   
	AFIO->MAPR&=0XF8FFFFFF; //清除MAPR的[26:24]
	AFIO->MAPR|=temp;       //設置jtag模式
}


char request_id[100];
char mqtt_message[100];

//WIFI發(fā)送數(shù)據(jù)存儲區(qū)域
char data_buff[300];

char time_buff[50];
char date_buff[50];

double DS18B20;//    環(huán)境溫度
int DS18B20_int;//    環(huán)境溫度

int DS18B20_MAX=15;   //加熱溫度上限閥值:  DS18B20_MAX;

int oxygen_motor_time=5; //充氧時間間隔:  oxygen_motor_time
int oxygen_food_sec=300; // 充氧時間間隔 秒

int water_quality=0;    //渾濁度檢測  水質(zhì)狀態(tài): 渾濁度檢測;
int led_sw=0; //氛圍燈開關
int ledNumber=1; //LED燈的編號
int percentage=0; //水質(zhì)

int water_monitor; //水位檢測

u32 SecCnt=0;

int PH;  //PH值檢測


/*
函數(shù)功能: 定時器1的更新中斷服務函數(shù)  模擬RTC
*/
void TIM1_UP_IRQHandler(void)
{
    //1秒鐘進來一次
    if(TIM1->SR&1<<0)
    {
        //記錄時間
        SecCnt++;
        
        
        GetRtcTime(SecCnt); //轉換標準時間

        sprintf(time_buff,"%02d:%02d:%02d",rtc_time.tm_hour,rtc_time.tm_min,rtc_time.tm_sec);
        sprintf(date_buff,"%02d-%02d-%02d",rtc_time.tm_year,rtc_time.tm_mon,rtc_time.tm_mday);
        
          //倒計時
        if(oxygen_food_sec>0)oxygen_food_sec--;  
        
    }
    TIM1->SR=0;
}



/*
這個函數(shù)接受一個整數(shù)參數(shù)(秒數(shù)),并返回一個指向固定長度字符串的指針。
使用 sprintf 函數(shù)將小時、分鐘和秒格式化為 HH:MM:SS 的字符串,并將其存儲在 result 數(shù)組中,最后將其作為返回值返回。

在主函數(shù)中,程序要求用戶輸入秒數(shù),調(diào)用 format_time 函數(shù)將其轉換為格式化后的時分秒字符串,并將其打印輸出。

注意,這個程序假設用戶輸入的秒數(shù)不超過一天(86400秒)。如果需要處理更長的時間單位,需要修改 format_time 函數(shù)的實現(xiàn)。

*/
char* format_time(int seconds) 
{
    static char result[9];  // 存儲結果的字符串,固定長度為8(HH:MM:SS?)

    int minutes = seconds / 60;
    seconds = seconds % 60;

    int hours = minutes / 60;
    minutes = minutes % 60;

    sprintf(result, "%02d:%02d:%02d", hours, minutes, seconds);
    
   // printf("seconds:%drn",seconds);
    return result;
}



/*
實時水溫水質(zhì)濁度投喂間隔充氧間隔恒溫溫度下次投喂時間下次充氧時間水位距離
*/
//頁面1
void page_1()
{
   //實時水溫
   LCD_ShowChineseFont(0,0+2,16,HZ_FONT_16[0],RED,0);
   LCD_ShowChineseFont(16*1,0+2,16,HZ_FONT_16[1],RED,0);
   LCD_ShowChineseFont(16*2,0+2,16,HZ_FONT_16[2],RED,0);
   LCD_ShowChineseFont(16*3,0+2,16,HZ_FONT_16[3],RED,0);
     
   //水質(zhì)濁度
   LCD_ShowChineseFont(0,16*1+2,16,HZ_FONT_16[4],RED,0);
   LCD_ShowChineseFont(16*1,16*1+2,16,HZ_FONT_16[5],RED,0);
   LCD_ShowChineseFont(16*2,16*1+2,16,HZ_FONT_16[6],RED,0);
   LCD_ShowChineseFont(16*3,16*1+2,16,HZ_FONT_16[7],RED,0);
   
   //PH值
   Gui_DrawFont_GBK16(0,16*2+2,RED,0,(u8*)"PH");
    
   //充氧間隔
   LCD_ShowChineseFont(0,16*3+2,16,HZ_FONT_16[12],RED,0);
   LCD_ShowChineseFont(16*1,16*3+2,16,HZ_FONT_16[13],RED,0);
   LCD_ShowChineseFont(16*2,16*3+2,16,HZ_FONT_16[14],RED,0);
   LCD_ShowChineseFont(16*3,16*3+2,16,HZ_FONT_16[15],RED,0);

   //恒溫溫度
   LCD_ShowChineseFont(0,16*4+2,16,HZ_FONT_16[16],RED,0);
   LCD_ShowChineseFont(16*1,16*4+2,16,HZ_FONT_16[17],RED,0);
   LCD_ShowChineseFont(16*2,16*4+2,16,HZ_FONT_16[18],RED,0);
   LCD_ShowChineseFont(16*3,16*4+2,16,HZ_FONT_16[19],RED,0);
   
   //魚缸水位
   LCD_ShowChineseFont(0,16*5+2,16,HZ_FONT_16[22],RED,0);
   LCD_ShowChineseFont(16*1,16*5+2,16,HZ_FONT_16[23],RED,0);
   LCD_ShowChineseFont(16*2,16*5+2,16,HZ_FONT_16[32],RED,0);
   LCD_ShowChineseFont(16*3,16*5+2,16,HZ_FONT_16[33],RED,0);
   
}



//頁面2
void page_2()
{
   
  //當前實時時間
   LCD_ShowChineseFont(0,16*1+2,16,HZ_FONT_16[20],RED,0);
   LCD_ShowChineseFont(16*1,16*1+2,16,HZ_FONT_16[21],RED,0);
   LCD_ShowChineseFont(16*2,16*1+2,16,HZ_FONT_16[22],RED,0);
   LCD_ShowChineseFont(16*3,16*1+2,16,HZ_FONT_16[23],RED,0);
   LCD_ShowChineseFont(16*4,16*1+2,16,HZ_FONT_16[24],RED,0);
   LCD_ShowChineseFont(16*5,16*1+2,16,HZ_FONT_16[25],RED,0);
    
   //下次充氧時間
   LCD_ShowChineseFont(0,16*4+2,16,HZ_FONT_16[26],RED,0);
   LCD_ShowChineseFont(16*1,16*4+2,16,HZ_FONT_16[27],RED,0);
   LCD_ShowChineseFont(16*2,16*4+2,16,HZ_FONT_16[28],RED,0);
   LCD_ShowChineseFont(16*3,16*4+2,16,HZ_FONT_16[29],RED,0);
   LCD_ShowChineseFont(16*4,16*4+2,16,HZ_FONT_16[30],RED,0);
   LCD_ShowChineseFont(16*5,16*4+2,16,HZ_FONT_16[31],RED,0);
 
}



int main()
{
    u8 key;
    u8 i;
    u32 time_cnt=0;
    u32 timer_hour_cnt=0; //記錄定時的時間
    u8 page=0;  //翻頁
    
    u8 run_state=0;
    u8 esp8266_connect=0; //連接狀態(tài)  1表示連接  0表示未連接
    
    
    //釋放PA15
    JTAG_Set(JTAG_SWD_DISABLE); 
    
    
    //板載LED初始化
    LED_Init();
    //板載按鍵初始化
    KEY_Init();
    //串口1初始化,用于打印
    USART1_Init(115200);
    
    
    //串口2初始化: 
    USART2_Init(115200);//串口-WIFI
    TIMER2_Init(72,20000); //超時時間20ms
    
    //LCD顯示屏初始化
    Lcd_Init(); //LCD初始化
    Lcd_Clear(0); //清屏為黑色
    LCD_LED_SET;//通過IO控制背光亮(通過這個引腳控制顯示屏開關)
    
    //ADC初始化  水質(zhì)狀態(tài)、PH值檢測、水位
    AdcInit(); 
    
    //其他硬件初始化
    hardware_init();
    
    //DS18B20--溫度傳感器初始化
    DS18B20_Init(); 
    
	
    #if 1
    
    //----------------------------------------------初始化ESP8266-WIFI模塊----------------------------------
    //清屏為黑色
    Lcd_Clear(0); 
    Gui_DrawFont_GBK16(0,16*0+2,WHITE,0,(u8*)"WIFI Init...");
    for(i=0;i<10;i++)
    {
        if(ESP8266_Init()==0)
        {
            Gui_DrawFont_GBK16(0,16*0+2,WHITE,0,(u8*)"WIFI OK...");
            run_state=1;
            break;
        }
        else
        {
            Gui_DrawFont_GBK16(0,16*0+2,WHITE,0,(u8*)"WIFI ERROR...");
            run_state=0;
            printf("ESP8266硬件檢測錯誤.n");  
        }
    }
  
    
   //如果初始化成功。就去連接指定的熱點。
   if(run_state)
   {
       Gui_DrawFont_GBK16(0,16*1+2,WHITE,0,(u8*)"Connect WIFI...");
       
       printf("ESP8266硬件正常。準備連接WIFI熱點(必須2.4GHZ)....rn");
       printf("準備連接熱點名稱:%s  密碼:%srn",CONNECT_WIFI,CONNECT_PASS);
 
       
       Gui_DrawFont_GBK16(0,16*2+2,WHITE,0,(u8*)CONNECT_WIFI);
       Gui_DrawFont_GBK16(0,16*3+2,WHITE,0,(u8*)CONNECT_PASS);
       
       
 AA:        
       //開始連接熱點
       run_state=ESP8266_STA_TCP_Client_Mode(CONNECT_WIFI,CONNECT_PASS,CONNECT_SERVER_IP,CONNECT_SERVER_PORT,1);
       
       //如果為真, 就表示連接錯誤
       if(run_state)
       {
           printf("熱點連接失敗:正在重試...rn");
           printf("注意: ESP8266只支持2.4GHZ頻段的WiFi. 供電要穩(wěn)定.rn");
           Gui_DrawFont_GBK16(0,16*4+2,WHITE,0,(u8*)"Connect Error..");
           goto AA;
       }

       Gui_DrawFont_GBK16(0,16*4+2,WHITE,0,(u8*)"Connect Success");
       
       printf("ESP8266成功連接上熱點...rn");
         
       printf("準備連接MQTT服務器...rn");
       
       //清屏為黑色
       Lcd_Clear(0); 
       Gui_DrawFont_GBK16(0,16*1+2,WHITE,0,(u8*)"                ");
       Gui_DrawFont_GBK16(0,16*0+2,WHITE,0,(u8*)"Connect IOT MQTT");
       
    
        //2. MQTT協(xié)議初始化	
        MQTT_Init(); 

         
        //3. 連接服務器  
        for(i=0;i<5;i++)
        {
            if(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord)==0)
            {
                esp8266_connect=1;
                run_state=1;
                break;
            }
            run_state=0;
            Gui_DrawFont_GBK16(0,16*1+2,WHITE,0,(u8*)"                ");
            Gui_DrawFont_GBK16(0,16*1+2,WHITE,0,(u8*)"Connect Error");
            printf("服務器連接失敗,正在重試...rn");
            delay_ms(500);
        }
        
        
        //如果服務器已連接
        if(esp8266_connect)
        {
            esp8266_connect=0;
            
            Gui_DrawFont_GBK16(0,16*1+2,WHITE,0,(u8*)"                ");
            Gui_DrawFont_GBK16(0,16*1+2,WHITE,0,(u8*)"Connect Success");
        
            
            printf("服務器連接成功.rn");
            
            printf("準備訂閱主題...rn");
            //3. 訂閱主題
            if(MQTT_SubscribeTopic(SET_TOPIC,0,1))
            {
               printf("主題訂閱失敗.rn");
               Gui_DrawFont_GBK16(0,16*2+2,WHITE,0,(u8*)"                ");
               Gui_DrawFont_GBK16(0,16*2+2,WHITE,0,(u8*)"TOPIC Sub ERROR"); 
               goto AA;
            }
            else
            {
               Gui_DrawFont_GBK16(0,16*2+2,WHITE,0,(u8*)"                ");
               Gui_DrawFont_GBK16(0,16*2+2,WHITE,0,(u8*)"TOPIC Sub OK.");
               printf("主題訂閱成功.rn");
               
               //表示W(wǎng)IFI連接成功                
               esp8266_connect=1;
                
            } 
        }
        else
        {
            printf("服務器連接失敗.請保證WIFI能夠連接互聯(lián)網(wǎng).rn");
            
            Gui_DrawFont_GBK16(0,16*1+2,WHITE,0,(u8*)"                ");
            Gui_DrawFont_GBK16(0,16*1+2,WHITE,0,(u8*)"Connect ERROR");
            Gui_DrawFont_GBK16(0,16*2+2,WHITE,0,(u8*)"NET ERROR");
            
            //視覺停留
            delay_ms(1000);delay_ms(1000);delay_ms(1000);delay_ms(1000);delay_ms(1000);
        }     
   }
  #endif
   
   
   SetRtcTime(2023,03,22,22,22,10); //設置時間	  
   
    //定時器初始化。1秒中斷一次,為了方便計時
   TIMER1_Init(7200,15000); //1000000us   1000000us

   
   //清屏為黑色
   Lcd_Clear(0);  
   
   
   //復位 正轉   換水電機-出水
   open_clean_motor(); 
   //復位 正轉  換水電機
   open_water_motor();
   
   //默認顯示頁面1
   page_1();
   
   while(1)
   {
        //---------------------------------按鍵檢測---------------------------------
        key=KEY_Scan();
        if(key)printf("key=%drn",key);
          
        //按下按鍵1進行翻頁
        if(key==1)
        {
            Lcd_Clear(0); //清屏為黑色
            
            page++;
            if(page>=2)page=0;
            if(page==0)
            {
                  page_1();
            }
            else 
            {
                  page_2();
            }          
        }
        
        //按下按鍵2控制照明燈打開
        else if(key==2)
        {
            lighting_led=!lighting_led;
        }
        //按下按鍵3控制  控制魚缸清洗
        else if(key==3)
        {
            //清洗3次
            open_clean_motor();
            close_clean_motor();
            delay_ms(1000);
            open_clean_motor();
            close_clean_motor();
            delay_ms(1000);
            open_clean_motor();
            close_clean_motor();
        }
         
        
        //輪詢時間到達
        if(time_cnt>20)
        {
            time_cnt=0;
            LED1=!LED1;
            
            //--------------------------------采集數(shù)據(jù)--------------------------------
            
            //讀取水溫度
            DS18B20_int=DS18B20_Get_Temp();
            //轉換溫度為浮點數(shù)
            sprintf(mqtt_message,"%d.%d",DS18B20_int>>4,DS18B20_int&0xF);   
            DS18B20=atof(mqtt_message);
            
            
            //讀取水質(zhì)
            //水質(zhì):   純凈水300多   自來水800多   直接純牛奶2000
            water_quality=GetAvgAdcCHxDATA(1);
            percentage = water_quality / 3000.0 * 100.0;
            
             //讀取PH值
            PH=GetAvgAdcCHxDATA(4);
            if(PH>=4000)PH=5;
            
             //讀取水位
            //水越深值越大,最大值1640  
            water_monitor=GetAvgAdcCHxDATA(5);
            water_monitor= water_monitor / 1640.0 * 100.0;
            
            //--------------------------------下次充氧時間倒計時計算--------------------------------
            if(oxygen_food_sec<=0)
            {
                //默認充氧5秒
                oxygen_motor=1;
                DelayMs(5000);
                oxygen_motor=0;
                
                //時間歸位
                oxygen_food_sec=oxygen_motor_time*60;
            }
               
            //水質(zhì)太差 就啟動換水
            if(percentage>80)
            {
                //正轉  換水電機
                open_water_motor();
            }
            else
            {
                //--反轉  換水電機
                close_water_motor();
            }                  
             
            
            //顯示頁面1
            if(page==0)
            {
                //實時時間與日期
                Gui_DrawFont_GBK16(16*1,16*6+2,WHITE,0,(u8*)date_buff);
                Gui_DrawFont_GBK16(16*1+8,16*7+2,WHITE,0,(u8*)time_buff);
                 
                //顯示溫度
                sprintf(mqtt_message,"%4.1fC",DS18B20);              
                Gui_DrawFont_GBK16(72,16*0+2,WHITE,0,(u8*)mqtt_message);
                // printf("%srn",mqtt_message);

                //顯示水質(zhì)
                sprintf(mqtt_message,"%4d%%",percentage);              
                Gui_DrawFont_GBK16(72,16*1+2,WHITE,0,(u8*)mqtt_message);

                
                //PH值
                sprintf(mqtt_message,"%4d",PH);              
                Gui_DrawFont_GBK16(72,16*2+2,WHITE,0,(u8*)mqtt_message);
                
                //充氧間隔
                sprintf(mqtt_message,"%4dm",oxygen_motor_time);              
                Gui_DrawFont_GBK16(72,16*3+2,WHITE,0,(u8*)mqtt_message);
                
                //恒溫溫度
                sprintf(mqtt_message,"%4dC",DS18B20_MAX); 
                Gui_DrawFont_GBK16(72,16*4+2,WHITE,0,(u8*)mqtt_message);  

                //水位距離
                sprintf(mqtt_message,"%4d%%",water_monitor);              
                Gui_DrawFont_GBK16(72,16*5+2,WHITE,0,(u8*)mqtt_message);     
            }
            
            else if(page==1)
            {
                //實時時間與日期
                Gui_DrawFont_GBK16(16*0,16*2+2,WHITE,0,(u8*)date_buff);
                Gui_DrawFont_GBK16(16*0+8,16*3+2,WHITE,0,(u8*)time_buff);
                 
               
                char *p=format_time(oxygen_food_sec);
                Gui_DrawFont_GBK16(0,16*5+2,WHITE,0,(u8*)p);  
            }
            
            
            
            //恒溫判斷. 如果小于溫度閥值
            if(DS18B20<DS18B20_MAX)
            {
                temp_heat=1; //開啟加熱
            }
            else
            {
                temp_heat=0; //停止加熱
            }
        
 
            //如果WIFI已經(jīng)連接到網(wǎng)絡
            if(esp8266_connect)
            {
                //組合JSON報文數(shù)據(jù)
                sprintf(data_buff,"{"services": [{"service_id": "stm32","properties":{"PH":%d,"water_quality":%d,"DS18B20":%.1f,"oxygen_motor_time":%d,"DS18B20_MAX":%d,"water_monitor":%d,"clean_motor":%d,"lighting_led":%d,"water_motor":%d,"oxygen_motor":%d}}]}",
                PH,percentage,DS18B20,oxygen_motor_time,DS18B20_MAX,water_monitor,clean_motor,lighting_led,water_motor,oxygen_motor);
                
                //上傳數(shù)據(jù)
                MQTT_PublishData(POST_TOPIC,data_buff,0);
                printf("更新一次數(shù)據(jù).rn"); 
            }
        }
        

        // 接收WIFI返回的數(shù)據(jù)
        if(USART2_RX_FLAG)
        {
            USART2_RX_BUFFER[USART2_RX_CNT]='?';
            
            printf("WIFI收到數(shù)據(jù):rn");
            //向串口打印服務器返回的數(shù)據(jù)
            for(i=0;i<USART2_RX_CNT;i++)
            {
                printf("%c",USART2_RX_BUFFER[i]);
            }
            
#if 0

$oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=8401c98b-268e-4382-82fd-b69d78275020{"services":{"motor_food":1}}
$oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=22e6e1ff-3e5c-4a25-bbbf-fd4e8f314a68{"services":{"led_sw":1}}
$oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=a15b8f8d-06cf-4597-8cd9-f92e3e0a7b4f{"services":{"motor_oxygen":1}}
$oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=c5b708d8-7c58-43c8-9943-64e25fe6f4df{"services":{"motor_water":1}}
$oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=852659ce-183c-42bf-b896-f9c1e960f405{"services":{"time_food":1}}
$oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=e401d20d-8c10-453d-b1cf-ba7c97a66f7d{"services":{"oxygen_food":1}}
$oc/devices/640ee9ee40773741f9fb55cb_dev1/sys/properties/set/request_id=dd10158b-3da0-45a2-be68-27ddb14a797c{"services":{"temp_max":15}}

#endif
            
            if(USART2_RX_CNT>5)
            {
                //開  照明燈
                if(strstr((char*)&USART2_RX_BUFFER[5],""lighting_led":1"))
                {
                    lighting_led=1;
                }
                //關  照明燈
                else if(strstr((char*)&USART2_RX_BUFFER[5],""lighting_led":0"))
                {
                     lighting_led=0;
                    
                }
                //開  換水電機
                else if(strstr((char*)&USART2_RX_BUFFER[5],""water_motor":1"))
                {
                   //--反轉  換水電機
                    close_water_motor();
                }
                //關  換水電機
                else if(strstr((char*)&USART2_RX_BUFFER[5],""water_motor":0"))
                {
                   //正轉  換水電機
                    open_water_motor();
                }
                //開  充氧電機
                else if(strstr((char*)&USART2_RX_BUFFER[5],""oxygen_motor":1"))
                {
                   oxygen_motor=1;
                }
                //關  充氧電機
                else if(strstr((char*)&USART2_RX_BUFFER[5],""oxygen_motor":0"))
                {
                   oxygen_motor=0;
                }
                //開   換水電機-出水
                else if(strstr((char*)&USART2_RX_BUFFER[5],""clean_motor":1"))
                {
                   //--反轉  換水電機-出水
                    close_clean_motor();
                }
                //關   換水電機-出水
                else if(strstr((char*)&USART2_RX_BUFFER[5],""clean_motor":0"))
                {
                   //正轉   換水電機-出水
                    open_clean_motor();
                }
                //充氧時間間隔
                else if(strstr((char*)&USART2_RX_BUFFER[5],""oxygen_motor_time":"))
                {
                   char *p=strstr((char*)&USART2_RX_BUFFER[5],""oxygen_motor_time":");
                   oxygen_motor_time=atoi(p+20);
                    
                   oxygen_food_sec = oxygen_motor_time*60; //轉為秒單位
                   printf("oxygen_motor_time=%drn",oxygen_motor_time);
                }
                //加熱溫度上限閥值
                else if(strstr((char*)&USART2_RX_BUFFER[5],""temp_max":"))
                {
                   char *p=strstr((char*)&USART2_RX_BUFFER[5],""temp_max":");
                   DS18B20_MAX=atoi(p+11);
                   printf("DS18B20_MAX=%drn",DS18B20_MAX);
                }
                else if(strstr((char*)&USART2_RX_BUFFER[5],""rtc_time":"))
                {
                    char *p=strstr((char*)&USART2_RX_BUFFER[5],""rtc_time":");
                    p+=11; //向后偏移,指向正確的時間
                    char *time=p;
                    int tm_sec;  //秒
                    int tm_min;  //分
                    int tm_hour; //時
                    int tm_mday; //日
                    int tm_mon;  //月
                    int tm_year; //年
                    tm_year=(time[0]-48)*1000+(time[1]-48)*100+(time[2]-48)*10+(time[3]-48)*1;
                    tm_mon=(time[4]-48)*10+(time[5]-48)*1;
                    tm_mday=(time[6]-48)*10+(time[7]-48)*1;
                    tm_hour=(time[8]-48)*10+(time[9]-48)*1;
                    tm_min=(time[10]-48)*10+(time[11]-48)*1;
                    tm_sec=(time[12]-48)*10+(time[13]-48)*1;
                    SetRtcTime(tm_year,tm_mon,tm_mday,tm_hour,tm_min,tm_sec);
                    printf("RTC時間設置成功:%d-%d-%d %d:%d:%drn",tm_year,tm_mon,tm_mday,tm_hour,tm_min,tm_sec);
                }
                
                //下發(fā)指令請求回應給服務器
                if(strstr((char*)&USART2_RX_BUFFER[5],"properties/set/request_id"))
                {
                    char *p=NULL;
                    p=strstr((char*)&USART2_RX_BUFFER[5],"request_id");
                    if(p)
                    {        
                        //解析數(shù)據(jù)
                        //$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/get/request_id=5f359b5c-542f-460e-9f51-85e82150ff4a{"service_id":"gps"} 
                        strncpy(request_id,p,47);      
                    }
                    
                    //上報數(shù)據(jù)
                    sprintf(mqtt_message,"{"result_code": 0,"result_desc": "success"}");
                    
                    sprintf(data_buff,"$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/set/response/%s",
                    request_id);
                    
                    MQTT_PublishData(data_buff,mqtt_message,0);
                    
                    printf("發(fā)布主題:%srn",data_buff);
                    printf("發(fā)布數(shù)據(jù):%srn",mqtt_message);
                }      
            }
            USART2_RX_CNT=0;
            USART2_RX_FLAG=0;
        }
        
        DelayMs(10);
        time_cnt++;
        timer_hour_cnt++;
	 }
}
  • 更多詳細資料請聯(lián)系.docx
    下載
意法半導體

意法半導體

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

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

查看更多

相關推薦