一、前言
1.1 項(xiàng)目介紹
當(dāng)前項(xiàng)目使用的相關(guān)軟件工具、傳感器源代碼工程已經(jīng)上傳到網(wǎng)盤(pán)(實(shí)時(shí)更新項(xiàng)目?jī)?nèi)容):
[https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink]
1.1.1 開(kāi)發(fā)背景
在當(dāng)前全球水資源日益緊張與環(huán)境污染加劇的背景下,淡水湖養(yǎng)殖業(yè)面臨著前所未有的挑戰(zhàn)。傳統(tǒng)的淡水湖養(yǎng)殖方式往往依賴(lài)于自然條件,缺乏有效的水質(zhì)監(jiān)測(cè)與調(diào)控手段,這不僅限制了養(yǎng)殖效率,也增加了疾病爆發(fā)的風(fēng)險(xiǎn),進(jìn)而影響到水產(chǎn)品的品質(zhì)與產(chǎn)量。隨著物聯(lián)網(wǎng)技術(shù)的迅猛發(fā)展及其在農(nóng)業(yè)領(lǐng)域的廣泛應(yīng)用,基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)應(yīng)運(yùn)而生,成為提升養(yǎng)殖智能化水平、優(yōu)化資源管理的關(guān)鍵所在。
本項(xiàng)目致力于設(shè)計(jì)一套集成化的淡水湖養(yǎng)殖管理系統(tǒng),以STM32F103RCT6為主控芯片,結(jié)合PH值、渾濁度、TDS值等多種水質(zhì)參數(shù)的實(shí)時(shí)監(jiān)測(cè),輔以遠(yuǎn)程控制與自動(dòng)化設(shè)備,實(shí)現(xiàn)了淡水湖養(yǎng)殖環(huán)境的全方位智能監(jiān)管。通過(guò)采用先進(jìn)的傳感器技術(shù),系統(tǒng)能夠準(zhǔn)確檢測(cè)水質(zhì)狀況,及時(shí)反饋至本地LCD顯示屏與手機(jī)APP,為養(yǎng)殖人員提供直觀(guān)的數(shù)據(jù)支持。特別地,項(xiàng)目引入了遠(yuǎn)程操控功能,用戶(hù)不僅能在手機(jī)APP上遠(yuǎn)程啟動(dòng)換水、投喂、充氧等操作,還能通過(guò)Windows電腦APP進(jìn)行更為細(xì)致的管理設(shè)定,極大地提升了養(yǎng)殖管理的靈活性與便捷性。
為了確保系統(tǒng)的穩(wěn)定運(yùn)行與數(shù)據(jù)的安全傳輸,項(xiàng)目選用了ESP8266-WIFI模塊,借助MQTT協(xié)議與華為云IOT物聯(lián)網(wǎng)服務(wù)器建立連接,實(shí)現(xiàn)了設(shè)備與云端的無(wú)縫對(duì)接。這樣一來(lái),不僅養(yǎng)殖現(xiàn)場(chǎng)的數(shù)據(jù)能夠?qū)崟r(shí)上傳至云端,便于數(shù)據(jù)分析與長(zhǎng)期存儲(chǔ),同時(shí)也使得用戶(hù)能夠隨時(shí)隨地通過(guò)手機(jī)APP或電腦APP訪(fǎng)問(wèn)養(yǎng)殖信息,實(shí)現(xiàn)真正的遠(yuǎn)程監(jiān)控與智能決策。
考慮到淡水湖養(yǎng)殖過(guò)程中可能遇到的突發(fā)情況,如水質(zhì)污染等,項(xiàng)目特別設(shè)計(jì)了基于閾值觸發(fā)的蜂鳴器報(bào)警系統(tǒng),一旦檢測(cè)到渾濁度超出安全范圍,系統(tǒng)將立即發(fā)出警報(bào),提醒養(yǎng)殖人員及時(shí)采取措施,避免潛在的經(jīng)濟(jì)損失。整個(gè)系統(tǒng)通過(guò)外部5V 2A電源供電,保證了穩(wěn)定持久的運(yùn)行能力。
基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)設(shè)計(jì),不僅代表了現(xiàn)代養(yǎng)殖業(yè)向著智慧化、精細(xì)化方向發(fā)展的趨勢(shì),也為解決傳統(tǒng)養(yǎng)殖中存在的諸多問(wèn)題提供了創(chuàng)新解決方案,有望推動(dòng)淡水湖養(yǎng)殖業(yè)邁向更加可持續(xù)與高效的未來(lái)。
1.1.2 項(xiàng)目實(shí)現(xiàn)的功能
(1)PH值監(jiān)測(cè)與展示
系統(tǒng)配備PH值檢測(cè)傳感器,能夠持續(xù)監(jiān)測(cè)淡水湖中的酸堿度,確保水質(zhì)維持在適宜魚(yú)類(lèi)生長(zhǎng)的最佳范圍內(nèi)。監(jiān)測(cè)數(shù)據(jù)不僅實(shí)時(shí)顯示在本地LCD顯示屏上,供現(xiàn)場(chǎng)管理人員即時(shí)查看,同時(shí),通過(guò)物聯(lián)網(wǎng)技術(shù),這些數(shù)據(jù)也會(huì)同步推送至用戶(hù)的手機(jī)APP和Windows電腦端,實(shí)現(xiàn)遠(yuǎn)程監(jiān)控,確保無(wú)論身處何地,養(yǎng)殖者都能掌握水質(zhì)的最新動(dòng)態(tài)。
(2)渾濁度檢測(cè)與預(yù)警
利用濁度檢測(cè)傳感器,系統(tǒng)能夠精確測(cè)定水體的渾濁程度,及時(shí)反映水體中懸浮物含量的變化。渾濁度數(shù)據(jù)同樣在本地顯示屏和遠(yuǎn)程終端上實(shí)時(shí)更新,一旦檢測(cè)到渾濁度超過(guò)預(yù)設(shè)的安全閾值,系統(tǒng)將啟動(dòng)蜂鳴器報(bào)警,提醒管理者迅速采取應(yīng)對(duì)措施,防止水質(zhì)惡化對(duì)養(yǎng)殖生物造成不利影響。
(3)TDS值監(jiān)控
TDS(Total Dissolved Solids,總?cè)芙夤腆w)傳感器用于監(jiān)測(cè)水中溶解物質(zhì)的總量,幫助養(yǎng)殖者了解水質(zhì)的純凈度。系統(tǒng)將TDS值數(shù)據(jù)實(shí)時(shí)傳輸至本地和遠(yuǎn)程終端,為養(yǎng)殖決策提供重要依據(jù),確保水質(zhì)始終符合養(yǎng)殖需求。
(4)遠(yuǎn)程手動(dòng)換水控制
通過(guò)手機(jī)APP和電腦端,養(yǎng)殖者可遠(yuǎn)程啟動(dòng)換水電機(jī),實(shí)現(xiàn)淡水湖的自動(dòng)換水。系統(tǒng)設(shè)計(jì)了兩個(gè)電機(jī),分別負(fù)責(zé)抽水進(jìn)出,以循環(huán)方式更新水質(zhì)。在本地LCD顯示屏上,用戶(hù)可查看下一次換水的倒計(jì)時(shí),合理規(guī)劃換水頻率,保持水體的健康狀態(tài)。
(5)周期自動(dòng)投喂管理
借助手機(jī)APP和電腦端的遠(yuǎn)程控制功能,系統(tǒng)支持自動(dòng)投喂周期設(shè)定。養(yǎng)殖者可根據(jù)魚(yú)群的生長(zhǎng)需求,定制定時(shí)投喂計(jì)劃,系統(tǒng)將自動(dòng)啟動(dòng)食物投喂電機(jī),適時(shí)投放飼料。本地LCD顯示屏顯示下一次投喂的時(shí)間,確保養(yǎng)殖過(guò)程的自動(dòng)化與精準(zhǔn)化。
(6)數(shù)據(jù)上云與遠(yuǎn)程監(jiān)控
系統(tǒng)通過(guò)ESP8266-WIFI模塊與華為云IOT物聯(lián)網(wǎng)服務(wù)器相連,所有監(jiān)測(cè)數(shù)據(jù)均上傳至云端,支持歷史數(shù)據(jù)查詢(xún)與分析,便于養(yǎng)殖者做出科學(xué)決策。同時(shí),用戶(hù)可通過(guò)手機(jī)APP和Windows電腦APP實(shí)時(shí)訪(fǎng)問(wèn)云端數(shù)據(jù),實(shí)現(xiàn)遠(yuǎn)程監(jiān)控與管理,即使遠(yuǎn)離養(yǎng)殖現(xiàn)場(chǎng),也能隨時(shí)掌握養(yǎng)殖環(huán)境狀況。
(7)周期自動(dòng)充氧功能
系統(tǒng)具備遠(yuǎn)程設(shè)定充氧周期的能力,養(yǎng)殖者可通過(guò)手機(jī)APP和電腦端自定義充氧時(shí)間,系統(tǒng)將自動(dòng)啟動(dòng)充氧電機(jī),確保水體含氧量充足,促進(jìn)魚(yú)類(lèi)健康成長(zhǎng)。本地LCD顯示屏顯示下一次充氧的倒計(jì)時(shí),便于養(yǎng)殖者安排日常管理工作。
(8)異常報(bào)警機(jī)制
當(dāng)水質(zhì)參數(shù)超出正常范圍,如渾濁度過(guò)高,系統(tǒng)將通過(guò)蜂鳴器發(fā)出警報(bào),并在手機(jī)APP和電腦端同步推送警告信息,確保養(yǎng)殖者第一時(shí)間獲知異常情況,及時(shí)采取補(bǔ)救措施,降低潛在風(fēng)險(xiǎn)。
1.1.3 項(xiàng)目硬件模塊組成
(1)主控芯片模塊
采用高性能的STM32F103RCT6微控制器作為系統(tǒng)的核心大腦,負(fù)責(zé)接收來(lái)自各種傳感器的數(shù)據(jù),執(zhí)行控制邏輯,并通過(guò)無(wú)線(xiàn)模塊與遠(yuǎn)程設(shè)備進(jìn)行通信。STM32F103RCT6憑借其強(qiáng)大的處理能力和豐富的外設(shè)接口,能夠高效處理復(fù)雜的數(shù)據(jù)流和控制任務(wù),確保系統(tǒng)的穩(wěn)定運(yùn)行。
(2)水質(zhì)監(jiān)測(cè)傳感器模塊
包括PH值、渾濁度和TDS值三種傳感器,用于實(shí)時(shí)監(jiān)測(cè)水質(zhì)狀況。這些傳感器通過(guò)模擬電壓輸出的方式,將水質(zhì)參數(shù)轉(zhuǎn)化為電信號(hào),由主控芯片讀取并處理。PH值傳感器監(jiān)測(cè)水體酸堿度;渾濁度傳感器檢測(cè)水中懸浮物濃度;TDS傳感器則測(cè)定水中的溶解固體總量,三者共同構(gòu)成了水質(zhì)監(jiān)測(cè)的基礎(chǔ)。
(3)控制與執(zhí)行模塊
- 換水系統(tǒng) :由兩個(gè)5V高電平觸發(fā)的繼電器控制抽水電機(jī)組成,實(shí)現(xiàn)淡水湖的自動(dòng)換水。一個(gè)電機(jī)負(fù)責(zé)抽水出去,另一個(gè)負(fù)責(zé)抽水進(jìn)來(lái),形成水體循環(huán),保持水質(zhì)清潔。
- 食物投喂系統(tǒng) :采用ULN2003驅(qū)動(dòng)的28BYJ4步進(jìn)電機(jī),用于控制食物投放閥門(mén)的開(kāi)關(guān),實(shí)現(xiàn)定時(shí)定量的自動(dòng)投喂。
- 充氧系統(tǒng) :同樣是5V高電平觸發(fā)的繼電器控制充氧電機(jī),用于調(diào)節(jié)水體中的氧氣含量,確保養(yǎng)殖生物的健康生長(zhǎng)。
(4)連接與通信模塊
- ESP8266-WIFI模塊 :作為系統(tǒng)與外界通信的橋梁,ESP8266負(fù)責(zé)將主控芯片處理后的數(shù)據(jù)上傳至華為云IOT物聯(lián)網(wǎng)服務(wù)器,并接收來(lái)自遠(yuǎn)程客戶(hù)端的控制指令,實(shí)現(xiàn)數(shù)據(jù)的雙向傳輸。
- MQTT協(xié)議 :用于系統(tǒng)與華為云服務(wù)器之間的數(shù)據(jù)通信,確保數(shù)據(jù)傳輸?shù)陌踩c高效。
(5)顯示與用戶(hù)界面模塊
- 本地LCD顯示屏 :用于現(xiàn)場(chǎng)顯示實(shí)時(shí)監(jiān)測(cè)數(shù)據(jù)和系統(tǒng)狀態(tài),包括PH值、渾濁度、TDS值、下一次換水/投喂/充氧的倒計(jì)時(shí)等信息。
- 手機(jī)APP與Windows電腦軟件 :通過(guò)華為云IOT服務(wù)器提供的API接口,用戶(hù)可在手機(jī)APP和電腦軟件上遠(yuǎn)程監(jiān)控水質(zhì)參數(shù),接收?qǐng)?bào)警信息,以及進(jìn)行遠(yuǎn)程控制操作。
(6)電源模塊
采用外部5V 2A電源供電,為整個(gè)系統(tǒng)提供穩(wěn)定電力,確保各模塊的正常運(yùn)行。
(7)報(bào)警模塊
系統(tǒng)配置了高電平觸發(fā)的有源蜂鳴器,當(dāng)水質(zhì)參數(shù)超出預(yù)設(shè)安全范圍時(shí),蜂鳴器將發(fā)出警報(bào)聲,確保養(yǎng)殖者能及時(shí)采取措施。
1.1.4 ESP8266工作模式配置
在整個(gè)設(shè)計(jì)里,STM32端的ESP8266配置成STA模式+TCP客戶(hù)端模式,上電時(shí)連接家里的路由器WIF熱點(diǎn),連接互聯(lián)網(wǎng),以TCP客戶(hù)端模式(通過(guò)MQTT協(xié)議)去連接騰訊云聯(lián)網(wǎng)服務(wù)器,實(shí)時(shí)上傳當(dāng)前的設(shè)備狀態(tài)等各種參數(shù)信息。用戶(hù)在Android手機(jī)APP可以遠(yuǎn)程查看設(shè)備的狀態(tài)信息。
ESP8266模塊具有兩種常用的工作模式,分別是STA模式和AP模式:
(1)STA模式(Station Mode):在STA模式下,ESP8266可以連接到已存在的Wi-Fi網(wǎng)絡(luò)作為一個(gè)客戶(hù)端設(shè)備。它可以?huà)呙柚車(chē)腤i-Fi網(wǎng)絡(luò),并且根據(jù)提供的SSID和密碼進(jìn)行連接,獲取IP地址后可以通過(guò)該網(wǎng)絡(luò)與其他設(shè)備進(jìn)行通信。在STA模式下,ESP8266可以實(shí)現(xiàn)與互聯(lián)網(wǎng)的連接,執(zhí)行各種網(wǎng)絡(luò)相關(guān)的操作。
(2)AP模式(Access Point Mode):在AP模式下,ESP8266可以作為一個(gè)獨(dú)立的Wi-Fi接入點(diǎn)(熱點(diǎn))運(yùn)行。它會(huì)創(chuàng)建一個(gè)自己的Wi-Fi網(wǎng)絡(luò),允許其他設(shè)備(如手機(jī)、電腦等)連接到這個(gè)熱點(diǎn)上。在AP模式下,ESP8266可以充當(dāng)局域網(wǎng)內(nèi)部的服務(wù)器,通過(guò)建立TCP/IP連接與其他設(shè)備進(jìn)行通信,提供Web頁(yè)面訪(fǎng)問(wèn)、數(shù)據(jù)傳輸?shù)确?wù)。
通過(guò)STA模式,ESP8266可以連接到互聯(lián)網(wǎng)上的其他設(shè)備或服務(wù)器,實(shí)現(xiàn)遠(yuǎn)程控制和數(shù)據(jù)交換;而通過(guò)AP模式,ESP8266可以作為一個(gè)獨(dú)立的接入點(diǎn),讓其他設(shè)備通過(guò)它進(jìn)行連接和通信。
1.2 系統(tǒng)設(shè)計(jì)方案
1.2.1 關(guān)鍵技術(shù)與創(chuàng)新點(diǎn)
本項(xiàng)目打造了一個(gè)高度自動(dòng)化、智能化的養(yǎng)殖環(huán)境監(jiān)測(cè)與控制系統(tǒng)。首要關(guān)鍵技術(shù)在于物聯(lián)網(wǎng)技術(shù)的應(yīng)用,通過(guò)ESP8266-WIFI模塊與華為云IOT物聯(lián)網(wǎng)服務(wù)器的無(wú)縫連接,實(shí)現(xiàn)了淡水湖養(yǎng)殖數(shù)據(jù)的實(shí)時(shí)采集、遠(yuǎn)程傳輸與云端存儲(chǔ)。這一技術(shù)不僅確保了水質(zhì)參數(shù)的連續(xù)監(jiān)測(cè),還為養(yǎng)殖者提供了隨時(shí)隨地的遠(yuǎn)程監(jiān)控與管理能力,極大提升了養(yǎng)殖作業(yè)的靈活性與響應(yīng)速度。
創(chuàng)新點(diǎn)之一在于系統(tǒng)的集成化設(shè)計(jì)。將PH值、渾濁度、TDS值等水質(zhì)參數(shù)的監(jiān)測(cè)與自動(dòng)化控制功能融為一體,通過(guò)主控芯片STM32F103RCT6的高效數(shù)據(jù)處理,實(shí)現(xiàn)了水質(zhì)監(jiān)測(cè)、換水、投喂、充氧等關(guān)鍵環(huán)節(jié)的自動(dòng)化管理,顯著減少了人工干預(yù),提高了養(yǎng)殖效率與水質(zhì)管理的精準(zhǔn)度。
另一創(chuàng)新點(diǎn)體現(xiàn)在遠(yuǎn)程控制與數(shù)據(jù)可視化方面。借助手機(jī)APP與Windows電腦軟件,養(yǎng)殖者不僅可以實(shí)時(shí)查看水質(zhì)參數(shù),還能遠(yuǎn)程設(shè)定換水、投喂、充氧的周期與時(shí)間,甚至在緊急情況下,如水質(zhì)異常時(shí),系統(tǒng)會(huì)自動(dòng)觸發(fā)報(bào)警機(jī)制,通過(guò)蜂鳴器與遠(yuǎn)程通知提醒養(yǎng)殖者及時(shí)采取行動(dòng),確保養(yǎng)殖環(huán)境的安全與穩(wěn)定。
系統(tǒng)在數(shù)據(jù)處理與分析上也進(jìn)行了創(chuàng)新。通過(guò)MQTT協(xié)議與華為云IOT物聯(lián)網(wǎng)服務(wù)器的深度整合,不僅保證了數(shù)據(jù)傳輸?shù)陌踩耘c可靠性,還為養(yǎng)殖者提供了歷史數(shù)據(jù)查詢(xún)與分析功能,有助于總結(jié)養(yǎng)殖規(guī)律,優(yōu)化管理策略,推動(dòng)養(yǎng)殖業(yè)向數(shù)據(jù)驅(qū)動(dòng)的方向發(fā)展。
本項(xiàng)目的關(guān)鍵技術(shù)與創(chuàng)新點(diǎn)集中體現(xiàn)在物聯(lián)網(wǎng)技術(shù)的深度應(yīng)用、系統(tǒng)集成化設(shè)計(jì)、遠(yuǎn)程控制與數(shù)據(jù)可視化、以及數(shù)據(jù)處理與分析等方面,共同構(gòu)建了一個(gè)高效、智能、可靠的淡水湖養(yǎng)殖管理平臺(tái),為現(xiàn)代養(yǎng)殖業(yè)的可持續(xù)發(fā)展注入了新的活力。
1.2.2 功能需求分析
本項(xiàng)目功能聚焦于如何通過(guò)技術(shù)手段實(shí)現(xiàn)養(yǎng)殖環(huán)境的智能化監(jiān)控與自動(dòng)化管理,以提升養(yǎng)殖效率、保障水質(zhì)安全、簡(jiǎn)化操作流程,并為養(yǎng)殖決策提供數(shù)據(jù)支持。首先,系統(tǒng)必須具備實(shí)時(shí)監(jiān)測(cè)水質(zhì)參數(shù)的能力,包括但不限于PH值、渾濁度和TDS值,確保這些關(guān)鍵指標(biāo)處于適宜養(yǎng)殖生物生長(zhǎng)的范圍內(nèi)。監(jiān)測(cè)數(shù)據(jù)需通過(guò)本地LCD顯示屏直觀(guān)呈現(xiàn),借助物聯(lián)網(wǎng)技術(shù),實(shí)現(xiàn)數(shù)據(jù)的遠(yuǎn)程傳輸,確保養(yǎng)殖者無(wú)論身在何處,都能通過(guò)手機(jī)APP或Windows電腦軟件實(shí)時(shí)掌握水質(zhì)狀況。
系統(tǒng)應(yīng)支持自動(dòng)化控制功能,涵蓋定時(shí)換水、自動(dòng)投喂和周期性充氧等關(guān)鍵操作。養(yǎng)殖者應(yīng)能在手機(jī)APP或電腦軟件上設(shè)定換水、投喂和充氧的周期與時(shí)間,系統(tǒng)自動(dòng)執(zhí)行相應(yīng)任務(wù),減少人力投入,提高養(yǎng)殖過(guò)程的自動(dòng)化水平。系統(tǒng)還應(yīng)提供倒計(jì)時(shí)顯示,便于養(yǎng)殖者提前規(guī)劃相關(guān)工作。
數(shù)據(jù)上云與遠(yuǎn)程監(jiān)控是不可或缺的需求。通過(guò)ESP8266-WIFI模塊與華為云IOT物聯(lián)網(wǎng)服務(wù)器的連接,系統(tǒng)需將監(jiān)測(cè)數(shù)據(jù)定期上傳至云端,一方面實(shí)現(xiàn)數(shù)據(jù)的長(zhǎng)期存儲(chǔ),另一方面,養(yǎng)殖者能通過(guò)云平臺(tái)提供的API接口,實(shí)現(xiàn)遠(yuǎn)程數(shù)據(jù)訪(fǎng)問(wèn),進(jìn)行歷史數(shù)據(jù)查詢(xún)與分析,為養(yǎng)殖策略的優(yōu)化提供科學(xué)依據(jù)。
報(bào)警機(jī)制也是系統(tǒng)的重要組成部分。當(dāng)監(jiān)測(cè)到水質(zhì)參數(shù)異常,如渾濁度超過(guò)安全閾值時(shí),系統(tǒng)應(yīng)立即觸發(fā)蜂鳴器報(bào)警,并通過(guò)手機(jī)APP與電腦軟件發(fā)送警告通知,確保養(yǎng)殖者能及時(shí)響應(yīng),采取有效措施,避免水質(zhì)惡化對(duì)養(yǎng)殖生物造成傷害。
考慮到淡水湖養(yǎng)殖環(huán)境的特殊性,系統(tǒng)還需具備一定的抗干擾與穩(wěn)定性,確保在復(fù)雜環(huán)境下仍能持續(xù)、準(zhǔn)確地執(zhí)行各項(xiàng)功能。此外,操作界面應(yīng)簡(jiǎn)潔友好,無(wú)論是現(xiàn)場(chǎng)的LCD顯示屏還是遠(yuǎn)程的手機(jī)APP與電腦軟件,都應(yīng)易于理解和操作,降低養(yǎng)殖者的使用門(mén)檻。
1.2.3 現(xiàn)有技術(shù)與市場(chǎng)分析
當(dāng)前,隨著物聯(lián)網(wǎng)、大數(shù)據(jù)和人工智能技術(shù)的飛速發(fā)展,智慧農(nóng)業(yè)正逐漸成為現(xiàn)代農(nóng)業(yè)轉(zhuǎn)型的重要方向,特別是在水產(chǎn)養(yǎng)殖領(lǐng)域,科技的應(yīng)用正在重塑養(yǎng)殖模式,提升養(yǎng)殖效率與產(chǎn)品質(zhì)量。
從技術(shù)角度來(lái)看,物聯(lián)網(wǎng)技術(shù)在淡水湖養(yǎng)殖中的應(yīng)用已初具規(guī)模。通過(guò)部署各類(lèi)水質(zhì)傳感器,如PH值、渾濁度和TDS值傳感器,養(yǎng)殖者能夠?qū)崟r(shí)監(jiān)測(cè)水質(zhì)變化,及時(shí)發(fā)現(xiàn)并解決水質(zhì)問(wèn)題。同時(shí),結(jié)合遠(yuǎn)程控制技術(shù),自動(dòng)化執(zhí)行換水、投喂和充氧等操作,不僅節(jié)省了人力成本,還提高了養(yǎng)殖的精準(zhǔn)度和效率。然而,目前市面上的解決方案往往側(cè)重于單一功能,如水質(zhì)監(jiān)測(cè)或自動(dòng)化投喂,缺乏一個(gè)集成化、智能化的綜合管理系統(tǒng),難以滿(mǎn)足養(yǎng)殖者對(duì)水質(zhì)全面監(jiān)控與智能決策的需求。
市場(chǎng)層面,隨著消費(fèi)者對(duì)食品安全和營(yíng)養(yǎng)價(jià)值的重視,高品質(zhì)水產(chǎn)品的需求日益增長(zhǎng),促使養(yǎng)殖業(yè)向精細(xì)化、標(biāo)準(zhǔn)化方向發(fā)展。養(yǎng)殖者急需一套能夠提供全方位水質(zhì)監(jiān)控、自動(dòng)化管理與數(shù)據(jù)分析的解決方案,以提升養(yǎng)殖效率,保障水產(chǎn)品質(zhì)量。此外,政府對(duì)環(huán)保和資源節(jié)約的政策導(dǎo)向,也推動(dòng)著養(yǎng)殖業(yè)尋求低能耗、低污染的養(yǎng)殖模式,物聯(lián)網(wǎng)技術(shù)的應(yīng)用恰能滿(mǎn)足這一需求,通過(guò)精準(zhǔn)控制減少資源浪費(fèi),降低環(huán)境污染。
市場(chǎng)上現(xiàn)有的淡水湖養(yǎng)殖系統(tǒng)在數(shù)據(jù)處理與分析能力、遠(yuǎn)程監(jiān)控的便捷性以及系統(tǒng)的穩(wěn)定性和易用性方面仍有待提升。養(yǎng)殖者渴望獲得一個(gè)集成度高、操作簡(jiǎn)便、數(shù)據(jù)處理能力強(qiáng)的養(yǎng)殖管理系統(tǒng),以實(shí)現(xiàn)養(yǎng)殖過(guò)程的智能化升級(jí)。
基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)正處于技術(shù)革新與市場(chǎng)需求雙重驅(qū)動(dòng)的有利時(shí)機(jī)。通過(guò)集成水質(zhì)監(jiān)測(cè)、自動(dòng)化控制、遠(yuǎn)程監(jiān)控與數(shù)據(jù)分析等功能,不僅能填補(bǔ)市場(chǎng)空白,滿(mǎn)足養(yǎng)殖者對(duì)智能化養(yǎng)殖管理的迫切需求,還能順應(yīng)現(xiàn)代農(nóng)業(yè)向智慧化轉(zhuǎn)型的大勢(shì),推動(dòng)淡水湖養(yǎng)殖業(yè)的高質(zhì)量發(fā)展。
1.2.4 硬件架構(gòu)設(shè)計(jì)
本項(xiàng)目的硬件架構(gòu)設(shè)計(jì)圍繞基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)展開(kāi),實(shí)現(xiàn)水質(zhì)參數(shù)的實(shí)時(shí)監(jiān)測(cè)、自動(dòng)化控制以及遠(yuǎn)程管理。系統(tǒng)的核心是由STM32F103RCT6微控制器組成的主控單元,它負(fù)責(zé)協(xié)調(diào)整個(gè)系統(tǒng)的運(yùn)作,包括數(shù)據(jù)采集、處理和傳輸。STM32F103RCT6作為高性能的32位ARM Cortex-M3微控制器,具備足夠的處理能力和豐富的外設(shè)接口,能夠高效處理來(lái)自各種傳感器的數(shù)據(jù),并控制執(zhí)行器的動(dòng)作。
傳感器模塊是硬件架構(gòu)的重要組成部分,其中包括PH值檢測(cè)傳感器、渾濁度檢測(cè)傳感器和TDS值檢測(cè)傳感器,用于實(shí)時(shí)監(jiān)測(cè)水質(zhì)的各項(xiàng)關(guān)鍵指標(biāo)。這些傳感器通過(guò)模擬電壓輸出的方式,將物理或化學(xué)信號(hào)轉(zhuǎn)換為電信號(hào),STM32F103RCT6通過(guò)ADC(模數(shù)轉(zhuǎn)換器)讀取這些信號(hào),并進(jìn)行相應(yīng)的數(shù)據(jù)處理。
執(zhí)行器模塊則負(fù)責(zé)執(zhí)行自動(dòng)化控制任務(wù),如換水、投喂和充氧。系統(tǒng)中采用5V高電平觸發(fā)的繼電器來(lái)控制抽水電機(jī),實(shí)現(xiàn)淡水湖的自動(dòng)換水;ULN2003驅(qū)動(dòng)的28BYJ4步進(jìn)電機(jī)用于控制食物投喂閥門(mén)的開(kāi)閉,實(shí)現(xiàn)定時(shí)定量的食物投喂;充氧設(shè)備同樣通過(guò)繼電器控制,確保水體含氧量的充足。所有執(zhí)行器的操作均由STM32F103RCT6通過(guò)數(shù)字I/O口控制,實(shí)現(xiàn)精準(zhǔn)的自動(dòng)化管理。
為了實(shí)現(xiàn)遠(yuǎn)程監(jiān)控和數(shù)據(jù)上云,系統(tǒng)集成了ESP8266-WIFI模塊,該模塊負(fù)責(zé)將STM32F103RCT6處理后的數(shù)據(jù)通過(guò)Wi-Fi網(wǎng)絡(luò)上傳至華為云IOT物聯(lián)網(wǎng)服務(wù)器,同時(shí)接收來(lái)自服務(wù)器的控制指令。ESP8266-WIFI模塊與STM32F103RCT6之間通過(guò)串行通信接口(如UART)進(jìn)行數(shù)據(jù)交換,確保數(shù)據(jù)的實(shí)時(shí)傳輸。
本地LCD顯示屏用于現(xiàn)場(chǎng)顯示水質(zhì)參數(shù)和系統(tǒng)狀態(tài),方便現(xiàn)場(chǎng)工作人員實(shí)時(shí)監(jiān)控。此外,系統(tǒng)還配置了蜂鳴器報(bào)警裝置,當(dāng)水質(zhì)異常時(shí),如渾濁度超過(guò)預(yù)設(shè)閾值,蜂鳴器將發(fā)出警報(bào),提醒工作人員采取相應(yīng)措施。
最后,系統(tǒng)采用外部5V 2A電源供電,確保整個(gè)硬件架構(gòu)的穩(wěn)定運(yùn)行。電源模塊不僅為微控制器、傳感器和執(zhí)行器提供必要的電力,還配備了過(guò)載保護(hù)和穩(wěn)壓功能,以應(yīng)對(duì)淡水湖養(yǎng)殖環(huán)境中的電壓波動(dòng)。
1.2.5 軟件架構(gòu)設(shè)計(jì)
本項(xiàng)目的軟件架構(gòu)設(shè)計(jì)是整體邏輯核心,實(shí)現(xiàn)水質(zhì)參數(shù)的實(shí)時(shí)監(jiān)測(cè)、自動(dòng)化控制以及遠(yuǎn)程管理。軟件架構(gòu)的核心是基于STM32F103RCT6微控制器的嵌入式軟件,負(fù)責(zé)數(shù)據(jù)采集、處理、執(zhí)行自動(dòng)化任務(wù)和通信控制。該軟件架構(gòu)遵循分層設(shè)計(jì)理念,包括數(shù)據(jù)采集層、數(shù)據(jù)處理層、控制邏輯層和通信層,每一層都有明確的功能和職責(zé),確保系統(tǒng)的穩(wěn)定性和可維護(hù)性。
數(shù)據(jù)采集層主要負(fù)責(zé)與各種傳感器交互,讀取PH值、渾濁度和TDS值等水質(zhì)參數(shù)的原始數(shù)據(jù)。這一層通過(guò)STM32F103RCT6的ADC模塊讀取模擬電壓信號(hào),并進(jìn)行適當(dāng)?shù)男?zhǔn)和預(yù)處理,確保數(shù)據(jù)的準(zhǔn)確性和一致性。
數(shù)據(jù)處理層則對(duì)采集到的原始數(shù)據(jù)進(jìn)行深入處理和分析,包括數(shù)據(jù)過(guò)濾、異常檢測(cè)、數(shù)據(jù)轉(zhuǎn)換和存儲(chǔ)。這一層軟件采用先進(jìn)的算法,如滑動(dòng)平均濾波和閾值比較,以剔除噪聲和異常值,確保水質(zhì)參數(shù)的可靠性和有效性。此外,數(shù)據(jù)處理層還負(fù)責(zé)將處理后的數(shù)據(jù)格式化,以便于傳輸和遠(yuǎn)程顯示。
控制邏輯層是軟件架構(gòu)的關(guān)鍵部分,它基于處理后的水質(zhì)數(shù)據(jù),執(zhí)行自動(dòng)化控制策略,如啟動(dòng)換水、投喂和充氧等操作。這一層軟件包含了復(fù)雜的控制算法,能夠根據(jù)水質(zhì)參數(shù)的實(shí)時(shí)變化,動(dòng)態(tài)調(diào)整執(zhí)行器的動(dòng)作,實(shí)現(xiàn)淡水湖養(yǎng)殖環(huán)境的精準(zhǔn)管理。
通信層負(fù)責(zé)與ESP8266-WIFI模塊和遠(yuǎn)程服務(wù)器的交互,通過(guò)MQTT協(xié)議實(shí)現(xiàn)數(shù)據(jù)的上傳和接收控制指令。這一層軟件不僅處理數(shù)據(jù)的序列化和反序列化,還負(fù)責(zé)數(shù)據(jù)包的完整性檢查和重傳機(jī)制,確保數(shù)據(jù)傳輸?shù)目煽啃院桶踩?。此外,通信層還支持與手機(jī)APP和電腦軟件的交互,通過(guò)RESTful API提供數(shù)據(jù)訪(fǎng)問(wèn)和控制接口。
為了提供直觀(guān)的用戶(hù)界面和遠(yuǎn)程監(jiān)控功能,本項(xiàng)目還設(shè)計(jì)了基于Qt框架的手機(jī)APP和Windows電腦軟件。這些應(yīng)用程序通過(guò)調(diào)用云平臺(tái)提供的API,實(shí)現(xiàn)水質(zhì)數(shù)據(jù)的實(shí)時(shí)查看、遠(yuǎn)程控制和歷史數(shù)據(jù)分析,為養(yǎng)殖者提供全面的管理工具和決策支持。
本項(xiàng)目的軟件架構(gòu)設(shè)計(jì)通過(guò)分層結(jié)構(gòu)和模塊化編程,實(shí)現(xiàn)了淡水湖養(yǎng)殖系統(tǒng)的智能化和自動(dòng)化管理,不僅提升了水質(zhì)監(jiān)測(cè)的精度和效率,還簡(jiǎn)化了養(yǎng)殖管理流程,為養(yǎng)殖者提供了便捷的遠(yuǎn)程監(jiān)控和控制手段。
1.2.6 上位機(jī)開(kāi)發(fā)思路
項(xiàng)目里,上位機(jī)是采用Qt開(kāi)發(fā),Qt是一個(gè)基于C++的跨平臺(tái)軟件開(kāi)發(fā)框架。
Qt框架提供了網(wǎng)絡(luò)模塊,能夠支持HTTPS協(xié)議的請(qǐng)求和響應(yīng)。可以利用Qt的網(wǎng)絡(luò)模塊來(lái)建立與華為云IOT平臺(tái)的HTTPS連接,并通過(guò)API接口獲取設(shè)備的影子數(shù)據(jù)。
(1)從華為云IOT平臺(tái)獲取數(shù)據(jù)的流程
- 認(rèn)證授權(quán) :使用設(shè)備的Access Key和Secret Key進(jìn)行認(rèn)證授權(quán),獲取訪(fǎng)問(wèn)令牌。
- 構(gòu)建HTTPS請(qǐng)求 :利用Qt的網(wǎng)絡(luò)模塊構(gòu)建HTTPS請(qǐng)求,包括API接口的URL、Header信息、請(qǐng)求參數(shù)等。
- 發(fā)送HTTPS請(qǐng)求 :發(fā)送構(gòu)建好的HTTPS請(qǐng)求給華為云IOT平臺(tái),獲取設(shè)備的影子數(shù)據(jù)。
- 處理響應(yīng)數(shù)據(jù) :解析HTTPS響應(yīng),提取設(shè)備的影子數(shù)據(jù)并進(jìn)行處理。
(2)數(shù)據(jù)展示與交互
在獲取到設(shè)備的影子數(shù)據(jù)后,可以利用Qt的界面設(shè)計(jì)模塊,結(jié)合自定義的數(shù)據(jù)展示控件,將設(shè)備的影子數(shù)據(jù)以直觀(guān)的方式呈現(xiàn)給用戶(hù)。
1.3 系統(tǒng)功能總結(jié)
功能點(diǎn) | 描述 | 顯示位置 | 操作方式 |
---|---|---|---|
PH值檢測(cè) | 檢測(cè)淡水湖中PH值情況 | 本地LCD顯示屏、手機(jī)APP | 自動(dòng)檢測(cè),遠(yuǎn)程查看 |
渾濁度檢測(cè) | 檢測(cè)淡水湖中水質(zhì)渾濁度 | 本地LCD顯示屏、手機(jī)APP | 自動(dòng)檢測(cè),遠(yuǎn)程查看 |
TDS值檢測(cè) | 檢測(cè)淡水湖中TDS值情況 | 本地LCD顯示屏、手機(jī)APP | 自動(dòng)檢測(cè),遠(yuǎn)程查看 |
手動(dòng)換水 | 遠(yuǎn)程啟動(dòng)換水電機(jī)進(jìn)行換水 | 本地LCD顯示屏(顯示換水倒計(jì)時(shí))、手機(jī)APP | 手機(jī)APP遠(yuǎn)程啟動(dòng) |
周期自動(dòng)投喂 | 遠(yuǎn)程啟動(dòng)食物投喂電機(jī)進(jìn)行自動(dòng)投喂 | 本地LCD顯示屏(顯示投喂倒計(jì)時(shí))、手機(jī)APP | 手機(jī)APP遠(yuǎn)程啟動(dòng) |
數(shù)據(jù)上云 | 將檢測(cè)數(shù)據(jù)上傳至華為云IOT物聯(lián)網(wǎng)服務(wù)器 | 華為云IOT服務(wù)器 | 自動(dòng)上傳 |
遠(yuǎn)程控制 | 支持手機(jī)APP、Windows電腦遠(yuǎn)程控制 | 手機(jī)APP、Windows電腦APP | 遠(yuǎn)程操作 |
周期自動(dòng)充氧 | 遠(yuǎn)程設(shè)置時(shí)間進(jìn)行自動(dòng)充氧 | 本地LCD顯示屏(顯示充氧倒計(jì)時(shí))、手機(jī)APP、Windows電腦APP | 手機(jī)APP、Windows電腦APP遠(yuǎn)程設(shè)置 |
蜂鳴器報(bào)警 | 當(dāng)渾濁度高于設(shè)定值時(shí)報(bào)警 | 本地蜂鳴器 | 自動(dòng)報(bào)警 |
此表格總結(jié)了基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)的各項(xiàng)功能,包括其描述、顯示位置以及操作方式。這些功能通過(guò)STM32F103RCT6主控芯片、各類(lèi)傳感器、繼電器、步進(jìn)電機(jī)、ESP8266-WIFI模塊等硬件實(shí)現(xiàn),并通過(guò)手機(jī)APP和Windows電腦APP進(jìn)行遠(yuǎn)程控制和監(jiān)測(cè)。
1.4 關(guān)鍵技術(shù)選型與說(shuō)明
1.4.1 STM32F103RCT6最小系統(tǒng)板介紹
在基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)中,STM32F103RCT6最小系統(tǒng)板作為整個(gè)系統(tǒng)的大腦,它負(fù)責(zé)處理來(lái)自各種傳感器的數(shù)據(jù),執(zhí)行自動(dòng)化控制邏輯,并管理與外部設(shè)備和遠(yuǎn)程服務(wù)器的通信。STM32F103RCT6最小系統(tǒng)板是一個(gè)高度集成的開(kāi)發(fā)平臺(tái),專(zhuān)為嵌入式應(yīng)用設(shè)計(jì),它基于ARM Cortex-M3內(nèi)核,提供高性能的32位微處理器,具備高速的處理能力和低功耗特性,非常適合要求實(shí)時(shí)響應(yīng)和高精度數(shù)據(jù)處理的場(chǎng)景。
該系統(tǒng)板集成了主控芯片STM32F103RCT6,擁有豐富的外設(shè)資源,包括多個(gè)通用輸入輸出(GPIO)引腳,可以連接各種傳感器和執(zhí)行器,如水質(zhì)檢測(cè)傳感器、電機(jī)控制電路等。此外,它還配備了精確的時(shí)鐘源,如外部晶振,以及電源管理電路,確保系統(tǒng)穩(wěn)定運(yùn)行。系統(tǒng)板上還設(shè)計(jì)有調(diào)試接口,如SWD接口,便于程序的燒錄和調(diào)試,以及LED指示燈和按鍵,用于狀態(tài)顯示和用戶(hù)交互。
在本項(xiàng)目中,STM32F103RCT6最小系統(tǒng)板不僅負(fù)責(zé)接收和處理來(lái)自PH值、渾濁度和TDS值傳感器的數(shù)據(jù),還控制著換水、投喂和充氧等自動(dòng)化操作,通過(guò)集成的通信模塊如ESP8266-WIFI,實(shí)現(xiàn)與華為云IOT物聯(lián)網(wǎng)服務(wù)器的連接,支持?jǐn)?shù)據(jù)上云和遠(yuǎn)程控制功能。此外,系統(tǒng)板上的資源還被用于驅(qū)動(dòng)本地LCD顯示屏,顯示實(shí)時(shí)水質(zhì)參數(shù)和系統(tǒng)狀態(tài),以及控制蜂鳴器報(bào)警系統(tǒng),當(dāng)水質(zhì)異常時(shí)及時(shí)發(fā)出警報(bào)。
STM32F103RCT6最小系統(tǒng)板憑借其強(qiáng)大的處理能力、豐富的外設(shè)接口和高度集成的設(shè)計(jì),成為了構(gòu)建基于物聯(lián)網(wǎng)的淡水湖養(yǎng)殖系統(tǒng)的關(guān)鍵組件,確保了水質(zhì)監(jiān)測(cè)的準(zhǔn)確性、自動(dòng)化控制的可靠性以及遠(yuǎn)程管理的便利性,為實(shí)現(xiàn)淡水湖養(yǎng)殖的智能化和高效化奠定了堅(jiān)實(shí)的硬件基礎(chǔ)。
1.4.2 ESP8266與MQTT協(xié)議應(yīng)用
在基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)中,ESP8266與MQTT協(xié)議的應(yīng)用是實(shí)現(xiàn)遠(yuǎn)程數(shù)據(jù)傳輸和設(shè)備管理的核心技術(shù)。ESP8266是一款低成本、低功耗的Wi-Fi模塊,特別適用于物聯(lián)網(wǎng)應(yīng)用,因其集成了TCP/IP協(xié)議棧和內(nèi)置的微控制器,能夠直接與各種傳感器和執(zhí)行器通信,無(wú)需額外的微處理器,極大地簡(jiǎn)化了物聯(lián)網(wǎng)設(shè)備的設(shè)計(jì)和開(kāi)發(fā)。
MQTT(Message Queuing Telemetry Transport)協(xié)議是一種輕量級(jí)的發(fā)布/訂閱消息協(xié)議,專(zhuān)為低帶寬、高延遲或不可靠的網(wǎng)絡(luò)設(shè)計(jì)。它基于TCP/IP協(xié)議,通過(guò)最小化數(shù)據(jù)包大小和帶寬使用,使得設(shè)備能夠在資源受限的環(huán)境中高效地交換信息。MQTT協(xié)議的發(fā)布/訂閱模型允許設(shè)備(如淡水湖養(yǎng)殖系統(tǒng)中的傳感器和執(zhí)行器)作為訂閱者接收特定主題的消息,同時(shí)作為發(fā)布者發(fā)送數(shù)據(jù),這種機(jī)制非常適合分布式物聯(lián)網(wǎng)系統(tǒng)中設(shè)備間的通信。
在本項(xiàng)目中,ESP8266 Wi-Fi模塊作為淡水湖養(yǎng)殖系統(tǒng)與華為云IOT物聯(lián)網(wǎng)服務(wù)器之間的通信橋梁,負(fù)責(zé)將水質(zhì)監(jiān)測(cè)數(shù)據(jù)(如PH值、渾濁度、TDS值等)通過(guò)MQTT協(xié)議上傳至云服務(wù)器,同時(shí)接收來(lái)自云服務(wù)器的控制指令,如換水、投喂和充氧的調(diào)度。通過(guò)MQTT協(xié)議,養(yǎng)殖系統(tǒng)可以將大量傳感器數(shù)據(jù)壓縮成小包傳輸,減少網(wǎng)絡(luò)擁堵,同時(shí)確保數(shù)據(jù)傳輸?shù)目煽啃院桶踩浴?/p>
STM32F103RCT6主控芯片收集水質(zhì)傳感器的數(shù)據(jù)后,通過(guò)串行通信接口(如UART)將數(shù)據(jù)發(fā)送給ESP8266模塊。ESP8266模塊利用MQTT協(xié)議將這些數(shù)據(jù)打包并發(fā)送到華為云服務(wù)器的指定主題,服務(wù)器則通過(guò)預(yù)先設(shè)置的規(guī)則引擎處理這些數(shù)據(jù),將其存儲(chǔ)、分析或轉(zhuǎn)發(fā)給授權(quán)的用戶(hù)(如通過(guò)手機(jī)APP或電腦軟件)。此外,用戶(hù)可以通過(guò)同樣的MQTT主題發(fā)送控制命令,ESP8266模塊接收到這些命令后,再將它們轉(zhuǎn)發(fā)給STM32F103RCT6,從而實(shí)現(xiàn)遠(yuǎn)程控制功能,如啟動(dòng)換水電機(jī)、調(diào)整投喂周期或設(shè)定充氧時(shí)間。
ESP8266與MQTT協(xié)議在淡水湖養(yǎng)殖系統(tǒng)中的應(yīng)用,不僅實(shí)現(xiàn)了水質(zhì)參數(shù)的實(shí)時(shí)監(jiān)測(cè)與遠(yuǎn)程管理,還構(gòu)建了一個(gè)高效、穩(wěn)定的數(shù)據(jù)傳輸通道,確保了養(yǎng)殖環(huán)境的智能化和自動(dòng)化,為養(yǎng)殖者提供了便捷的遠(yuǎn)程監(jiān)控和控制手段,推動(dòng)了淡水湖養(yǎng)殖業(yè)向智慧農(nóng)業(yè)的轉(zhuǎn)型。
1.4.3 Qt(C++)手機(jī)APP開(kāi)發(fā)框架
在基于物聯(lián)網(wǎng)的人工淡水湖養(yǎng)殖系統(tǒng)中,Qt(C++)框架被用于開(kāi)發(fā)手機(jī)應(yīng)用程序,為養(yǎng)殖者提供一個(gè)直觀(guān)且功能全面的遠(yuǎn)程監(jiān)控與控制平臺(tái)。Qt是一個(gè)跨平臺(tái)的開(kāi)發(fā)框架,以其豐富的GUI工具、強(qiáng)大的網(wǎng)絡(luò)功能以及廣泛的設(shè)備支持而聞名。Qt不僅支持C++編程,還提供了一套完整的工具鏈,包括Qt Creator集成開(kāi)發(fā)環(huán)境(IDE)、Qt Widgets和Qt Quick/QML用于UI設(shè)計(jì),以及一系列庫(kù)和模塊,如Qt Networking和Qt Sensors,適用于構(gòu)建復(fù)雜的物聯(lián)網(wǎng)應(yīng)用。
Qt(C++)手機(jī)APP開(kāi)發(fā)框架在本項(xiàng)目中的應(yīng)用,使得開(kāi)發(fā)者能夠構(gòu)建出既美觀(guān)又功能強(qiáng)大的Android應(yīng)用程序,而無(wú)需深入了解底層的Android SDK。通過(guò)Qt Quick和QML,開(kāi)發(fā)者可以快速設(shè)計(jì)出響應(yīng)式的用戶(hù)界面,這些界面能夠適應(yīng)不同尺寸的屏幕,提供一致的用戶(hù)體驗(yàn)。QML是一種聲明式語(yǔ)言,它簡(jiǎn)化了UI的構(gòu)建過(guò)程,允許開(kāi)發(fā)者使用簡(jiǎn)單的語(yǔ)法描述界面布局、動(dòng)畫(huà)和交互邏輯,同時(shí)還可以與C++代碼無(wú)縫集成,實(shí)現(xiàn)復(fù)雜業(yè)務(wù)邏輯的編寫(xiě)。
在淡水湖養(yǎng)殖系統(tǒng)中,Qt開(kāi)發(fā)的手機(jī)APP充當(dāng)了養(yǎng)殖者與物聯(lián)網(wǎng)設(shè)備之間的交互界面。它不僅實(shí)時(shí)顯示水質(zhì)參數(shù),如PH值、渾濁度和TDS值,還允許用戶(hù)遠(yuǎn)程控制關(guān)鍵的養(yǎng)殖操作,比如啟動(dòng)換水、設(shè)置投喂周期和充氧時(shí)間。
Qt的網(wǎng)絡(luò)模塊在實(shí)現(xiàn)數(shù)據(jù)傳輸方面發(fā)揮了重要作用,它支持多種通信協(xié)議,包括HTTP、HTTPS和MQTT,這使得APP能夠與華為云IOT物聯(lián)網(wǎng)服務(wù)器建立穩(wěn)定連接,實(shí)現(xiàn)數(shù)據(jù)的雙向通信。通過(guò)調(diào)用華為云提供的API接口,Qt開(kāi)發(fā)的APP能夠從云服務(wù)器下載最新的水質(zhì)數(shù)據(jù),同時(shí)上傳控制指令,確保養(yǎng)殖系統(tǒng)的遠(yuǎn)程監(jiān)控和管理。
Qt(C++)框架在淡水湖養(yǎng)殖系統(tǒng)的手機(jī)APP開(kāi)發(fā)中,提供了強(qiáng)大的開(kāi)發(fā)工具和豐富的功能庫(kù),使得開(kāi)發(fā)者能夠高效地構(gòu)建出功能全面、界面友好的移動(dòng)應(yīng)用程序,極大地提升了養(yǎng)殖者的操作便利性和養(yǎng)殖系統(tǒng)的智能化水平。
1.4.4 通信協(xié)議與云平臺(tái)對(duì)接方案
在本項(xiàng)目中,系統(tǒng)采用了MQTT(Message Queuing Telemetry Transport)協(xié)議作為主要的通信機(jī)制,這是一種輕量級(jí)的發(fā)布/訂閱模式的消息傳輸協(xié)議,專(zhuān)為低帶寬和高延遲的網(wǎng)絡(luò)環(huán)境設(shè)計(jì),非常適合物聯(lián)網(wǎng)場(chǎng)景下的數(shù)據(jù)傳輸。MQTT協(xié)議的特點(diǎn)在于其低開(kāi)銷(xiāo)、低網(wǎng)絡(luò)流量和良好的穩(wěn)定性,能夠有效減少設(shè)備端與云平臺(tái)之間的通信延遲,并保證數(shù)據(jù)傳輸?shù)目煽啃浴?/p>
為了實(shí)現(xiàn)淡水湖養(yǎng)殖系統(tǒng)與華為云IOT平臺(tái)的對(duì)接,在系統(tǒng)中集成了MQTT客戶(hù)端,該客戶(hù)端運(yùn)行在基于STM32的微控制器上,負(fù)責(zé)收集各種傳感器數(shù)據(jù),如水質(zhì)參數(shù)檢測(cè)模塊采集的PH值、渾濁度和TDS值等,并通過(guò)無(wú)線(xiàn)模塊將這些數(shù)據(jù)封裝成MQTT消息,發(fā)送至華為云IOT物聯(lián)網(wǎng)平臺(tái)。同時(shí),MQTT客戶(hù)端也接收來(lái)自云平臺(tái)的控制指令,如啟動(dòng)換水、設(shè)置投喂周期和充氧時(shí)間等操作,從而實(shí)現(xiàn)對(duì)養(yǎng)殖系統(tǒng)的遠(yuǎn)程控制。
在云平臺(tái)側(cè),利用華為云IOT提供的SDK和API接口,構(gòu)建了一個(gè)數(shù)據(jù)處理和分析的后端服務(wù)。當(dāng)?shù)B(yǎng)殖系統(tǒng)上傳的數(shù)據(jù)到達(dá)華為云IOT平臺(tái)后,后端服務(wù)會(huì)自動(dòng)接收并解析這些數(shù)據(jù),將其存儲(chǔ)到數(shù)據(jù)庫(kù)中,以便于后續(xù)的數(shù)據(jù)分析和可視化展示。同時(shí),后端服務(wù)還負(fù)責(zé)處理來(lái)自手機(jī)APP的請(qǐng)求,將用戶(hù)的控制指令轉(zhuǎn)換為MQTT消息,通過(guò)華為云IOT平臺(tái)重新下發(fā)給淡水湖養(yǎng)殖系統(tǒng)的MQTT客戶(hù)端,實(shí)現(xiàn)了云平臺(tái)、手機(jī)APP與養(yǎng)殖系統(tǒng)三者之間的數(shù)據(jù)閉環(huán)。
本項(xiàng)目的通信協(xié)議與云平臺(tái)對(duì)接方案,充分利用了MQTT協(xié)議的特性,結(jié)合華為云IOT平臺(tái)的強(qiáng)大功能,構(gòu)建了一個(gè)穩(wěn)定、安全且高效的淡水湖養(yǎng)殖系統(tǒng)遠(yuǎn)程監(jiān)控與控制系統(tǒng),極大地提升了養(yǎng)殖效率和管理水平。
1.5 開(kāi)發(fā)工具的選擇
1.5.1 設(shè)備端開(kāi)發(fā)
STM32的編程語(yǔ)言選擇C語(yǔ)言,C語(yǔ)言執(zhí)行效率高,大學(xué)里主學(xué)的C語(yǔ)言,C語(yǔ)言編譯出來(lái)的可執(zhí)行文件最接近于機(jī)器碼,匯編語(yǔ)言執(zhí)行效率最高,但是匯編的移植性比較差,目前在一些操作系統(tǒng)內(nèi)核里還有一些低配的單片機(jī)使用的較多,平常的單片機(jī)編程還是以C語(yǔ)言為主。C語(yǔ)言的執(zhí)行效率僅次于匯編,語(yǔ)法理解簡(jiǎn)單、代碼通用性強(qiáng),也支持跨平臺(tái),在嵌入式底層、單片機(jī)編程里用的非常多,當(dāng)前的設(shè)計(jì)就是采用C語(yǔ)言開(kāi)發(fā)。
開(kāi)發(fā)工具選擇Keil,keil是一家世界領(lǐng)先的嵌入式微控制器軟件開(kāi)發(fā)商,在2015年,keil被ARM公司收購(gòu)。因?yàn)楫?dāng)前芯片選擇的是STM32F103系列,STMF103是屬于ARM公司的芯片構(gòu)架、Cortex-M3內(nèi)核系列的芯片,所以使用Kile來(lái)開(kāi)發(fā)STM32是有先天優(yōu)勢(shì)的,而keil在各大高校使用的也非常多,很多教科書(shū)里都是以keil來(lái)教學(xué),開(kāi)發(fā)51單片機(jī)、STM32單片機(jī)等等。目前作為MCU芯片開(kāi)發(fā)的軟件也不只是keil一家獨(dú)大,IAR在MCU微處理器開(kāi)發(fā)領(lǐng)域里也使用的非常多,IAR擴(kuò)展性更強(qiáng),也支持STM32開(kāi)發(fā),也支持其他芯片,比如:CC2530,51單片機(jī)的開(kāi)發(fā)。從軟件的使用上來(lái)講,IAR比keil更加簡(jiǎn)潔,功能相對(duì)少一些。如果之前使用過(guò)keil,而且使用頻率較多,已經(jīng)習(xí)慣再使用IAR是有點(diǎn)不適應(yīng)界面的。
1.5.2 上位機(jī)開(kāi)發(fā)
上位機(jī)的開(kāi)發(fā)選擇Qt框架,編程語(yǔ)言采用C++;Qt是一個(gè)1991年由Qt Company開(kāi)發(fā)的跨平臺(tái)C++圖形用戶(hù)界面應(yīng)用程序開(kāi)發(fā)框架。它既可以開(kāi)發(fā)GUI程序,也可用于開(kāi)發(fā)非GUI程序,比如控制臺(tái)工具和服務(wù)器。Qt是面向?qū)ο蟮目蚣?,使用特殊的代碼生成擴(kuò)展(稱(chēng)為元對(duì)象編譯器(Meta Object Compiler, moc))以及一些宏,Qt很容易擴(kuò)展,并且允許真正地組件編程。Qt能輕松創(chuàng)建具有原生C++性能的連接設(shè)備、用戶(hù)界面(UI)和應(yīng)用程序。它功能強(qiáng)大且結(jié)構(gòu)緊湊,擁有直觀(guān)的工具和庫(kù)。
1.6 參考文獻(xiàn)
1. 宦娟,吳帆,曹偉建等.基于窄帶物聯(lián)網(wǎng)的養(yǎng)殖塘水質(zhì)監(jiān)測(cè)系統(tǒng)研制[J].農(nóng)業(yè)工程學(xué)報(bào),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)技術(shù)在智能水產(chǎn)養(yǎng)殖系統(tǒng)中的應(yīng)用[J].湖南文理學(xué)院學(xué)報(bào)(自然科學(xué)版),2021,33(04):37-41+87.
7. 楊金明,余情,朱紅飛等.基于物聯(lián)網(wǎng)技術(shù)的水產(chǎn)養(yǎng)殖智能管理系統(tǒng)設(shè)計(jì)[J].湖北農(nóng)業(yè)科學(xué),2016,55(16):4276-4279.
8. 冼鋰東,龍祖連.基于物聯(lián)網(wǎng)技術(shù)智慧水產(chǎn)養(yǎng)殖系統(tǒng)的研究設(shè)計(jì)[J].物聯(lián)網(wǎng)技術(shù),2022,12(02):65-68.
9. 徐曉?shī)?基于物聯(lián)網(wǎng)和3G技術(shù)的智能水產(chǎn)養(yǎng)殖環(huán)境監(jiān)測(cè)系統(tǒng)的設(shè)計(jì)與應(yīng)用[J].網(wǎng)絡(luò)安全技術(shù)與應(yīng)用,2014,No.165(09):235-236.
10. 劉星橋,駱波,朱成云.基于物聯(lián)網(wǎng)和GIS的水產(chǎn)養(yǎng)殖測(cè)控系統(tǒng)平臺(tái)設(shè)計(jì)[J].漁業(yè)現(xiàn)代化,2016,43(06):16-20.
11. 李新成,林德峰,王勝濤等.基于物聯(lián)網(wǎng)的水產(chǎn)養(yǎng)殖池塘智能管控系統(tǒng)設(shè)計(jì)[J].水產(chǎn)學(xué)雜志,2020,33(01):81-86.
12. 楊軼霞.基于物聯(lián)網(wǎng)技術(shù)的智能水產(chǎn)養(yǎng)殖監(jiān)控系統(tǒng)應(yīng)用[J].電子技術(shù),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)技術(shù)的淡水養(yǎng)殖監(jiān)控系統(tǒng)[J].電氣技術(shù),2015,No.192(10):59-62.
15. 基于物聯(lián)網(wǎng)的智慧水產(chǎn)系統(tǒng)開(kāi)發(fā) [2021-08-05]
16. 吳小峰.基于物聯(lián)網(wǎng)技術(shù)的智能水產(chǎn)養(yǎng)殖管理系統(tǒng)設(shè)計(jì)[J].襄陽(yáng)職業(yè)技術(shù)學(xué)院學(xué)報(bào),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)設(shè)計(jì)[J].科技風(fēng),2022,No.510(34):66-68.
19. 潘春霖.基于物聯(lián)網(wǎng)技術(shù)的智能漁業(yè)監(jiān)控系統(tǒng)設(shè)計(jì)[J].天津農(nóng)業(yè)科學(xué),2017,23(12):26-30.
20. 湯朝婧.基于物聯(lián)網(wǎng)技術(shù)的水產(chǎn)養(yǎng)殖系統(tǒng)設(shè)計(jì)[J].物聯(lián)網(wǎng)技術(shù),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)模型設(shè)計(jì)[J].無(wú)線(xiàn)互聯(lián)科技,2019,16(02):33-34.
23. 李卓然.基于嵌入式Linux的水產(chǎn)養(yǎng)殖物聯(lián)網(wǎng)監(jiān)測(cè)系統(tǒng)設(shè)計(jì)[J].農(nóng)機(jī)化研究,2019,41(11):229-233.
24. 王英杰. 基于物聯(lián)網(wǎng)的水產(chǎn)養(yǎng)殖測(cè)控系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[D].江蘇大學(xué),2017.
25. 黃勁斐.物聯(lián)網(wǎng)水產(chǎn)監(jiān)測(cè)系統(tǒng)的設(shè)計(jì)[J].科技視界,2020,No.318(24):24-25.
26. 楊寧生,袁永明,孫英澤.物聯(lián)網(wǎng)技術(shù)在我國(guó)水產(chǎn)養(yǎng)殖上的應(yīng)用發(fā)展對(duì)策[J].中國(guó)工程科學(xué),2016,18(03):57-61.
27. 陳浩成,袁永明,馬曉飛等.基于物聯(lián)網(wǎng)的水產(chǎn)養(yǎng)殖水質(zhì)監(jiān)控集成技術(shù)[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)測(cè)系統(tǒng)設(shè)計(jì)[J].信息系統(tǒng)工程,2021,No.325(01):74-75.
1.7 系統(tǒng)框架圖
二、硬件選
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個(gè)基本定時(shí)器、4個(gè)通用定時(shí)器、2個(gè)高級(jí)定時(shí)器、51個(gè)通用IO口、5個(gè)串口、2個(gè)DMA控制器、3個(gè)SPI、2個(gè)I2C、1個(gè)USB、1個(gè)CAN、3個(gè)12位ADC、1個(gè)12位DAC、1個(gè)SDIO接口,芯片屬于大容量類(lèi)型,配置較高,整體符合硬件選型設(shè)計(jì)。當(dāng)前選擇的這款開(kāi)發(fā)板自帶了一個(gè)1.4寸的TFT-LCD彩屏,可以顯示當(dāng)前傳感器數(shù)據(jù)以及一些運(yùn)行狀態(tài)信息。
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
2.2 PCB板
鏈接:https://detail.tmall.com/item.htm?abbucket=9&id=525489414251&ns=1&skuId=3929211749440&spm=a230r.1.14.34.16b221829wBwAI
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
2.4 電源擴(kuò)展接口(x2)
買(mǎi)2個(gè)擴(kuò)展板,方便擴(kuò)展5v電源 和 3.3V電源。
解決電源不夠接的問(wèn)題。
鏈接:https://item.taobao.com/item.htm?id=824064501327&pisk=fEFjn0YWOnxjbDWVdFQrdBU9b9h1Cl1F1FgT-Pd2WjhA1VEUVAdNnjks1unzgmzqM1gTYuMTbcz2o8qUJIPVnfRsifcOYM5FTE4msfI4zsVvm03sR1utXmQXpe7fYM5FTtL-1isU0CGLT03i2q3tDAQWwV3j6V3x6ai-52v9DlETyagskddtWx3Jw20j6hHtXzp--2itkmH92agi2chWRTgRh0zfrrhv3gSV8PiW6BTnlxp35dRkZrgxh5hKVYkzNqMjvY7FJFFY4PF4iYXJFf4zdlwTvgJqDJgQVvyfAIZQmVUsWo1HR0Fb57M0UeRLPAibeSHWWCUzy-HLCosXnme4Vv0-eF1nzko8oSe5S3UYYmGxyY5dRzHTUSD3ggdj9J4qgREd4KoYdVIzZBoBA1v6PvAsPD75Pdvgel6pmGJur-Hxr4YFPa9eIx3oPD75PdviH40laa_WLdf..&skuId=5538517420771&spm=pc_detail.29232929%2Fevo365560b447259.guessitem.d0
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
2.6 母對(duì)母杜邦線(xiàn)(X2)
作用: 連接模塊與單片機(jī)。
鏈接: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
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
2.8 穩(wěn)壓模塊
鏈接:https://item.taobao.com/item.htm?spm=a21n57.1.0.0.2921523cQeodt2&id=16606969730&ns=1&abbucket=7#detail
2.9 5V2A電源插頭
鏈接:https://item.taobao.com/item.htm?spm=a1z0d.7625083.1998302264.6.5c5f4e69WfgpgO&id=616513772095
2.10 5V 28BYJ4 步進(jìn)電機(jī)
鏈接: 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
步進(jìn)電機(jī)28BYJ-48名稱(chēng)含義:
28:表示步進(jìn)電機(jī)的有效最大外徑為28毫米
B: 表示步進(jìn)電機(jī)“步”字漢語(yǔ)拼音首字母
Y: 表示永磁式“永”字漢語(yǔ)拼音首字母
J: 表示減速型“減”字漢語(yǔ)拼音首字母
BYJ: 組合即為永磁式減速步進(jìn)電機(jī)
48:表示四相八拍
5V:表示額定電壓為5V,且為直流電壓
步進(jìn)角:5.625度,就是1個(gè)脈沖信號(hào)轉(zhuǎn)5.625度,64個(gè)信號(hào)轉(zhuǎn)360度。
減速比:1/64,電機(jī)殼里邊的電機(jī)轉(zhuǎn)64圈,電機(jī)殼外邊的部分轉(zhuǎn)1圈。
四相:ABCD四相(電機(jī)定子上有8個(gè)齒,相對(duì)的2個(gè)齒是1相),
八拍:(A-AB-B-BC-C-CD-D-DA-A)。
一拍就是一個(gè)脈沖信號(hào),完成一個(gè)循環(huán)用8個(gè)脈沖信號(hào)。
當(dāng)通電狀態(tài)的改變完成一個(gè)循環(huán)時(shí),轉(zhuǎn)子轉(zhuǎn)過(guò)一個(gè)齒距。轉(zhuǎn)8個(gè)齒距就是一圈,8×8=64
64拍,64個(gè)脈沖信號(hào)轉(zhuǎn)一圈360度。
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
2.12 TDS檢測(cè)傳感器
鏈接: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)、中文名總?cè)芙夤腆w、又稱(chēng)溶解性固體、又稱(chēng)溶解性固體總量、表明1升水腫容有多少毫克溶解性固體、一般來(lái)說(shuō)、TDS值越高、表示水中含有溶解物越多、水就越不潔凈、雖然在特定情況下TDS并不能有效反映水質(zhì)的情況、但作為一種可快速檢測(cè)的參數(shù)、TDS目前還可以作為有效的在水質(zhì)情況反映參數(shù)來(lái)作為參考。常用的TDS檢測(cè)設(shè)備為T(mén)DS筆、雖然價(jià)格低廉、簡(jiǎn)單易用、但不能把數(shù)據(jù)傳給控制系統(tǒng)、做長(zhǎng)時(shí)間的在線(xiàn)監(jiān)測(cè)、并做水質(zhì)狀況分析、使用專(zhuān)門(mén)的儀器、雖然能傳數(shù)據(jù)、精度也高、但價(jià)格很貴、為此這款TDS傳感器模塊、即插即用、使用簡(jiǎn)單方便、測(cè)量用的激勵(lì)源采用交流信號(hào)、可有效防止探頭極化、延長(zhǎng)探頭壽命的同時(shí)、也增加了輸出信號(hào)的穩(wěn)定性、TDS探頭為防水探頭、可長(zhǎng)期侵入水中測(cè)量、該產(chǎn)品可以應(yīng)用于生活用水、水培等領(lǐng)域的水質(zhì)檢測(cè)、有了這個(gè)傳感器、可輕松DIY--套TDS檢測(cè)儀了、輕松檢測(cè)水的潔凈程度。
2.13 渾濁度檢測(cè)傳感器
鏈接: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
2.14 抽水馬達(dá)(X2)
進(jìn)水和出水控制
鏈接地址:https://detail.tmall.com/item.htm?abbucket=6&id=599450427587&ns=1&skuId=4531922407703&spm=a21n57.1.0.0.438e523cDKEtmS
2.15 USB母頭(接電機(jī)使用的)
買(mǎi)3個(gè)。
鏈接:https://item.taobao.com/item.htm?spm=a1z09.2.0.0.4ff12e8dBjY7rQ&id=660481026591&_u=31pq7ueodfb1&skuId=4760127756241
2.16 PH值檢測(cè)傳感器
鏈接: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
三、部署華為云物聯(lián)網(wǎng)平臺(tái)
華為云官網(wǎng): https://www.huaweicloud.com/
打開(kāi)官網(wǎng),搜索物聯(lián)網(wǎng),就能快速找到 設(shè)備接入IoTDA
。
3.1 物聯(lián)網(wǎng)平臺(tái)介紹
華為云物聯(lián)網(wǎng)平臺(tái)(IoT 設(shè)備接入云服務(wù))提供海量設(shè)備的接入和管理能力,將物理設(shè)備聯(lián)接到云,支撐設(shè)備數(shù)據(jù)采集上云和云端下發(fā)命令給設(shè)備進(jìn)行遠(yuǎn)程控制,配合華為云其他產(chǎn)品,幫助我們快速構(gòu)筑物聯(lián)網(wǎng)解決方案。
使用物聯(lián)網(wǎng)平臺(tái)構(gòu)建一個(gè)完整的物聯(lián)網(wǎng)解決方案主要包括3部分:物聯(lián)網(wǎng)平臺(tái)、業(yè)務(wù)應(yīng)用和設(shè)備。
物聯(lián)網(wǎng)平臺(tái)作為連接業(yè)務(wù)應(yīng)用和設(shè)備的中間層,屏蔽了各種復(fù)雜的設(shè)備接口,實(shí)現(xiàn)設(shè)備的快速接入;同時(shí)提供強(qiáng)大的開(kāi)放能力,支撐行業(yè)用戶(hù)構(gòu)建各種物聯(lián)網(wǎng)解決方案。
設(shè)備可以通過(guò)固網(wǎng)、2G/3G/4G/5G、NB-IoT、Wifi等多種網(wǎng)絡(luò)接入物聯(lián)網(wǎng)平臺(tái),并使用LWM2M/CoAP、MQTT、HTTPS協(xié)議將業(yè)務(wù)數(shù)據(jù)上報(bào)到平臺(tái),平臺(tái)也可以將控制命令下發(fā)給設(shè)備。
業(yè)務(wù)應(yīng)用通過(guò)調(diào)用物聯(lián)網(wǎng)平臺(tái)提供的API,實(shí)現(xiàn)設(shè)備數(shù)據(jù)采集、命令下發(fā)、設(shè)備管理等業(yè)務(wù)場(chǎng)景。
3.2 開(kāi)通物聯(lián)網(wǎng)服務(wù)
地址: https://www.huaweicloud.com/product/iothub.html
點(diǎn)擊立即創(chuàng)建
。
正在創(chuàng)建標(biāo)準(zhǔn)版實(shí)例,需要等待片刻。
創(chuàng)建完成之后,點(diǎn)擊詳情。
可以看到標(biāo)準(zhǔn)版實(shí)例的設(shè)備接入端口和地址。
在上面也能看到 免費(fèi)單元的限制。
開(kāi)通之后,點(diǎn)擊總覽
,也能查看接入信息。 我們當(dāng)前設(shè)備準(zhǔn)備采用MQTT協(xié)議接入華為云平臺(tái),這里可以看到MQTT協(xié)議的地址和端口號(hào)等信息。
總結(jié):
端口號(hào): MQTT (1883)| MQTTS (8883)
接入地址: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ù):
來(lái)自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=42ms TTL=94
來(lái)自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=42ms TTL=94
來(lái)自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=42ms TTL=94
來(lái)自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=43ms TTL=94
117.78.5.125 的 Ping 統(tǒng)計(jì)信息:
數(shù)據(jù)包: 已發(fā)送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計(jì)時(shí)間(以毫秒為單位):
最短 = 42ms,最長(zhǎng) = 43ms,平均 = 42ms
C:Users11266 >
MQTT協(xié)議接入端口號(hào)有兩個(gè),1883是非加密端口,8883是證書(shū)加密端口,單片機(jī)無(wú)法加載證書(shū),所以使用1883端口比較合適。 接下來(lái)的ESP8266就采用1883端口連接華為云物聯(lián)網(wǎng)平臺(tái)。
3.3 創(chuàng)建產(chǎn)品
(1)創(chuàng)建產(chǎn)品
(2)填寫(xiě)產(chǎn)品信息
根據(jù)自己產(chǎn)品名字填寫(xiě),下面的設(shè)備類(lèi)型選擇自定義類(lèi)型。
(3)產(chǎn)品創(chuàng)建成功
(4)添加自定義模型
產(chǎn)品創(chuàng)建完成之后,點(diǎn)擊進(jìn)入產(chǎn)品詳情頁(yè)面,翻到最下面可以看到模型定義。
模型簡(jiǎn)單來(lái)說(shuō): 就是存放設(shè)備上傳到云平臺(tái)的數(shù)據(jù)。比如:水溫、換水電機(jī)、充氧電機(jī)、水質(zhì)狀態(tài)、充氧時(shí)間間隔等等,我們都可以單獨(dú)創(chuàng)建一個(gè)模型保存。
當(dāng)前設(shè)備需要與云平臺(tái)交互的屬性如下: 接下來(lái)就按照下面的屬性創(chuàng)建 華為云平臺(tái)的模型。
上傳到華為云IOT平臺(tái)的屬性:
PH值檢測(cè) PH 整型
渾濁度檢測(cè) water_quality 整型
溫度檢測(cè) DS18B20 浮點(diǎn)數(shù)
換水電機(jī) water_motor BOOL類(lèi)型
充氧電機(jī) oxygen_motor BOOL類(lèi)型
定時(shí)充氧 oxygen_motor_time 整型
水溫閥值 DS18B20_MAX 整型
換水電機(jī)-出水 clean_motor BOOL類(lèi)型
照明燈 lighting_led BOOL類(lèi)型
水位檢測(cè) water_monitor 整型
先點(diǎn)擊自定義模型。
再創(chuàng)建一個(gè)服務(wù)ID。
接著點(diǎn)擊新增屬性。
PH值檢測(cè) PH 整型
渾濁度檢測(cè) water_quality 整型
溫度檢測(cè) DS18B20 浮點(diǎn)數(shù)
換水電機(jī) water_motor BOOL類(lèi)型
充氧電機(jī) oxygen_motor BOOL類(lèi)型
定時(shí)充氧 oxygen_motor_time 整型
水溫閥值 DS18B20_MAX 整型
** 換水電機(jī)-出水 clean_motor BOOL類(lèi)型**
照明燈 lighting_led BOOL類(lèi)型
水位檢測(cè) water_monitor 整型
3.4 添加設(shè)備
產(chǎn)品是屬于上層的抽象模型,接下來(lái)在產(chǎn)品模型下添加實(shí)際的設(shè)備。添加的設(shè)備最終需要與真實(shí)的設(shè)備關(guān)聯(lián)在一起,完成數(shù)據(jù)交互。
(1)注冊(cè)設(shè)備
(2)根據(jù)自己的設(shè)備填寫(xiě)
(3)保存設(shè)備信息
創(chuàng)建完畢之后,點(diǎn)擊保存并關(guān)閉,得到創(chuàng)建的設(shè)備密匙信息。該信息在后續(xù)生成MQTT三元組的時(shí)候需要使用。
當(dāng)前設(shè)備的信息如下:
{
"device_id": "65dd4fc72ccc1a583879a7e1_dev1",
"secret": "12345678"
}
(4) 設(shè)備創(chuàng)建完成
點(diǎn)擊詳情:
這就是設(shè)備頁(yè)面:
3.5 MQTT協(xié)議主題訂閱與發(fā)布
(1)MQTT協(xié)議介紹
當(dāng)前的設(shè)備是采用MQTT協(xié)議與華為云平臺(tái)進(jìn)行通信。
MQTT是一個(gè)物聯(lián)網(wǎng)傳輸協(xié)議,它被設(shè)計(jì)用于輕量級(jí)的發(fā)布/訂閱式消息傳輸,旨在為低帶寬和不穩(wěn)定的網(wǎng)絡(luò)環(huán)境中的物聯(lián)網(wǎng)設(shè)備提供可靠的網(wǎng)絡(luò)服務(wù)。MQTT是專(zhuān)門(mén)針對(duì)物聯(lián)網(wǎng)開(kāi)發(fā)的輕量級(jí)傳輸協(xié)議。MQTT協(xié)議針對(duì)低帶寬網(wǎng)絡(luò),低計(jì)算能力的設(shè)備,做了特殊的優(yōu)化,使得其能適應(yīng)各種物聯(lián)網(wǎng)應(yīng)用場(chǎng)景。目前MQTT擁有各種平臺(tái)和設(shè)備上的客戶(hù)端,已經(jīng)形成了初步的生態(tài)系統(tǒng)。
MQTT是一種消息隊(duì)列協(xié)議,使用發(fā)布/訂閱消息模式,提供一對(duì)多的消息發(fā)布,解除應(yīng)用程序耦合,相對(duì)于其他協(xié)議,開(kāi)發(fā)更簡(jiǎn)單;MQTT協(xié)議是工作在TCP/IP協(xié)議上;由TCP/IP協(xié)議提供穩(wěn)定的網(wǎng)絡(luò)連接;所以,只要具備TCP協(xié)議棧的網(wǎng)絡(luò)設(shè)備都可以使用MQTT協(xié)議。 本次設(shè)備采用的ESP8266就具備TCP協(xié)議棧,能夠建立TCP連接,所以,配合STM32代碼里封裝的MQTT協(xié)議,就可以與華為云平臺(tái)完成通信。
華為云的MQTT協(xié)議接入幫助文檔在這里: https://support.huaweicloud.com/devg-iothub/iot_02_2200.html
業(yè)務(wù)流程:
(2)華為云平臺(tái)MQTT協(xié)議使用限制
描述 | 限制 |
---|---|
支持的MQTT協(xié)議版本 | 3.1.1 |
與標(biāo)準(zhǔn)MQTT協(xié)議的區(qū)別 | 支持Qos 0和Qos 1支持Topic自定義不支持QoS2不支持will、retain msg |
MQTTS支持的安全等級(jí) | 采用TCP通道基礎(chǔ) + TLS協(xié)議(最高TLSv1.3版本) |
單帳號(hào)每秒最大MQTT連接請(qǐng)求數(shù) | 無(wú)限制 |
單個(gè)設(shè)備每分鐘支持的最大MQTT連接數(shù) | 1 |
單個(gè)MQTT連接每秒的吞吐量,即帶寬,包含直連設(shè)備和網(wǎng)關(guān) | 3KB/s |
MQTT單個(gè)發(fā)布消息最大長(zhǎng)度,超過(guò)此大小的發(fā)布請(qǐng)求將被直接拒絕 | 1MB |
MQTT連接心跳時(shí)間建議值 | 心跳時(shí)間限定為30至1200秒,推薦設(shè)置為120秒 |
產(chǎn)品是否支持自定義Topic | 支持 |
消息發(fā)布與訂閱 | 設(shè)備只能對(duì)自己的Topic進(jìn)行消息發(fā)布與訂閱 |
每個(gè)訂閱請(qǐng)求的最大訂閱數(shù) | 無(wú)限制 |
(3)主題訂閱格式
幫助文檔地址:https://support.huaweicloud.com/devg-iothub/iot_02_2200.html
對(duì)于設(shè)備而言,一般會(huì)訂閱平臺(tái)下發(fā)消息給設(shè)備 這個(gè)主題。
設(shè)備想接收平臺(tái)下發(fā)的消息,就需要訂閱平臺(tái)下發(fā)消息給設(shè)備 的主題,訂閱后,平臺(tái)下發(fā)消息給設(shè)備,設(shè)備就會(huì)收到消息。
如果設(shè)備想要知道平臺(tái)下發(fā)的消息,需要訂閱上面圖片里標(biāo)注的主題。
以當(dāng)前設(shè)備為例,最終訂閱主題的格式如下:
$oc/devices/{device_id}/sys/messages/down
最終的格式:
$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/messages/down
(4)主題發(fā)布格式
對(duì)于設(shè)備來(lái)說(shuō),主題發(fā)布表示向云平臺(tái)上傳數(shù)據(jù),將最新的傳感器數(shù)據(jù),設(shè)備狀態(tài)上傳到云平臺(tái)。
這個(gè)操作稱(chēng)為:屬性上報(bào)。
幫助文檔地址:https://support.huaweicloud.com/usermanual-iothub/iot_06_v5_3010.html
根據(jù)幫助文檔的介紹, 當(dāng)前設(shè)備發(fā)布主題,上報(bào)屬性的格式總結(jié)如下:
發(fā)布的主題格式:
$oc/devices/{device_id}/sys/properties/report
最終的格式:
$oc/devices/65dd4fc72ccc1a583879a7e1_dev1/sys/properties/report
發(fā)布主題時(shí),需要上傳數(shù)據(jù),這個(gè)數(shù)據(jù)格式是JSON格式。
上傳的JSON數(shù)據(jù)格式如下:
{
"services": [
{
"service_id": < 填服務(wù)ID >,
"properties": {
"< 填屬性名稱(chēng)1 >": < 填屬性值 >,
"< 填屬性名稱(chēng)2 >": < 填屬性值 >,
..........
}
}
]
}
根據(jù)JSON格式,一次可以上傳多個(gè)屬性字段。 這個(gè)JSON格式里的,服務(wù)ID,屬性字段名稱(chēng),屬性值類(lèi)型,在前面創(chuàng)建產(chǎn)品的時(shí)候就已經(jīng)介紹了,不記得可以翻到前面去查看。
根據(jù)這個(gè)格式,組合一次上傳的屬性數(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é)議登錄需要填用戶(hù)ID,設(shè)備ID,設(shè)備密碼等信息,就像我們平時(shí)登錄QQ,微信一樣要輸入賬號(hào)密碼才能登錄。MQTT協(xié)議登錄的這3個(gè)參數(shù),一般稱(chēng)為MQTT三元組。
接下來(lái)介紹,華為云平臺(tái)的MQTT三元組參數(shù)如何得到。
(1)MQTT服務(wù)器地址
要登錄MQTT服務(wù)器,首先記得先知道服務(wù)器的地址是多少,端口是多少。
幫助文檔地址:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-portal/home
MQTT協(xié)議的端口支持1883和8883,它們的區(qū)別是:8883 是加密端口更加安全。但是單片機(jī)上使用比較困難,所以當(dāng)前的設(shè)備是采用1883端口進(jìn)連接的。
根據(jù)上面的域名和端口號(hào),得到下面的IP地址和端口號(hào)信息: 如果設(shè)備支持填寫(xiě)域名可以直接填域名,不支持就直接填寫(xiě)IP地址。 (IP地址就是域名解析得到的)
華為云的MQTT服務(wù)器地址:117.78.5.125
華為云的MQTT端口號(hào):1883
(2)生成MQTT三元組
華為云提供了一個(gè)在線(xiàn)工具,用來(lái)生成MQTT鑒權(quán)三元組: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/
打開(kāi)這個(gè)工具,填入設(shè)備的信息(也就是剛才創(chuàng)建完設(shè)備之后保存的信息),點(diǎn)擊生成,就可以得到MQTT的登錄信息了。
下面是打開(kāi)的頁(yè)面:
填入設(shè)備的信息: (上面兩行就是設(shè)備創(chuàng)建完成之后保存得到的)
直接得到三元組信息。
得到三元組之后,設(shè)備端通過(guò)MQTT協(xié)議登錄鑒權(quán)的時(shí)候,填入?yún)?shù)即可。
ClientId 65dd4fc72ccc1a583879a7e1_dev1_0_0_2024022705
Username 65dd4fc72ccc1a583879a7e1_dev1
Password 91c783515515d883c533df05ef0e15ed526e583cfb141de54e9ba1545fba0513
3.7 模擬設(shè)備登錄測(cè)試
經(jīng)過(guò)上面的步驟介紹,已經(jīng)創(chuàng)建了產(chǎn)品,設(shè)備,數(shù)據(jù)模型,得到MQTT登錄信息。 接下來(lái)就用MQTT客戶(hù)端軟件模擬真實(shí)的設(shè)備來(lái)登錄平臺(tái)。測(cè)試與服務(wù)器通信是否正常。
當(dāng)前模擬設(shè)備登錄,調(diào)試設(shè)備的MQTT客戶(hù)端軟件可以在這里下載:
https://download.csdn.net/download/xiaolong1126626497/18784012
(1)填入登錄信息
打開(kāi)MQTT客戶(hù)端軟件,對(duì)號(hào)填入相關(guān)信息(就是上面的文本介紹)。然后,點(diǎn)擊登錄,訂閱主題,發(fā)布主題。
(2)打開(kāi)網(wǎng)頁(yè)查看
完成上面的操作之后,打開(kāi)華為云網(wǎng)頁(yè)后臺(tái),可以看到設(shè)備已經(jīng)在線(xiàn)了。
點(diǎn)擊詳情頁(yè)面,可以看到上傳的數(shù)據(jù):
到此,云平臺(tái)的部署已經(jīng)完成,設(shè)備已經(jīng)可以正常上傳數(shù)據(jù)了。
(3)MQTT登錄測(cè)試參數(shù)總結(jié)
華為云的MQTT服務(wù)器地址:117.78.5.125
華為云的MQTT端口號(hào):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}}]}
四、上位機(jī)開(kāi)發(fā)
為了方便查看設(shè)備上傳的數(shù)據(jù),對(duì)設(shè)備進(jìn)行遠(yuǎn)程控制,接下來(lái)利用Qt開(kāi)發(fā)一款A(yù)ndroid和windows系統(tǒng)的上位機(jī)。
使用華為云平臺(tái)提供的API接口獲取設(shè)備上傳的數(shù)據(jù),也可以給設(shè)備下發(fā)指令,控制設(shè)備。
4.1 Qt開(kāi)發(fā)環(huán)境安裝
Qt的中文官網(wǎng): https://www.qt.io/zh-cn/
QT5.12.6的下載地址:https://download.qt.io/archive/qt/5.12/5.12.6
打開(kāi)下載鏈接后選擇下面的版本進(jìn)行下載:
qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details
軟件安裝時(shí)斷網(wǎng)安裝,否則會(huì)提示輸入賬戶(hù)。
安裝的時(shí)候,第一個(gè)復(fù)選框里勾選一個(gè)mingw 32
編譯器即可,其他的不管默認(rèn)就行,直接點(diǎn)擊下一步繼續(xù)安裝。
說(shuō)明: 我這里只是介紹PC端的環(huán)境搭建(這個(gè)比較簡(jiǎn)單)。 Android的開(kāi)發(fā)環(huán)境比較麻煩,如果想學(xué)習(xí)Android開(kāi)發(fā),想編譯Android程序的APP,可以去我的博客里看詳細(xì)文章。
Android環(huán)境搭建的博客鏈接: https://blog.csdn.net/xiaolong1126626497/article/details/117254453
選擇MinGW 32-bit 編譯器:
4.2 創(chuàng)建IAM賬戶(hù)
創(chuàng)建一個(gè)IAM賬戶(hù),因?yàn)榻酉聛?lái)開(kāi)發(fā)上位機(jī),需要使用云平臺(tái)的API接口,這些接口都需要token進(jìn)行鑒權(quán)。簡(jiǎn)單來(lái)說(shuō),就是身份的認(rèn)證。 調(diào)用接口獲取Token時(shí),就需要填寫(xiě)IAM賬號(hào)信息。所以,接下來(lái)演示一下過(guò)程。
地址: https://console.huaweicloud.com/iam/?region=cn-north-4#/iam/users
**【1】獲取項(xiàng)目憑證 ** 點(diǎn)擊左上角用戶(hù)名,選擇下拉菜單里的我的憑證
項(xiàng)目憑證:
756f8211ec6847c3a5ee4061b37d4ddb
【2】創(chuàng)建IAM用戶(hù)
鼠標(biāo)放在左上角頭像上,在下拉菜單里選擇統(tǒng)一身份認(rèn)證
。
點(diǎn)擊左上角創(chuàng)建用戶(hù)
。
創(chuàng)建成功:
【3】創(chuàng)建完成
用戶(hù)信息如下:
主用戶(hù)名 hid_x13ruy5yb1ruano
IAM用戶(hù) ds_abc
密碼 DS12345678
4.3 獲取影子數(shù)據(jù)
幫助文檔:https://support.huaweicloud.com/api-iothub/iot_06_v5_0079.html
設(shè)備影子介紹:
設(shè)備影子是一個(gè)用于存儲(chǔ)和檢索設(shè)備當(dāng)前狀態(tài)信息的JSON文檔。
每個(gè)設(shè)備有且只有一個(gè)設(shè)備影子,由設(shè)備ID唯一標(biāo)識(shí)
設(shè)備影子僅保存最近一次設(shè)備的上報(bào)數(shù)據(jù)和預(yù)期數(shù)據(jù)
無(wú)論該設(shè)備是否在線(xiàn),都可以通過(guò)該影子獲取和設(shè)置設(shè)備的屬性
簡(jiǎn)單來(lái)說(shuō):設(shè)備影子就是保存,設(shè)備最新上傳的一次數(shù)據(jù)。
我們?cè)O(shè)計(jì)的軟件里,如果想要獲取設(shè)備的最新?tīng)顟B(tài)信息,就采用設(shè)備影子接口。
如果對(duì)接口不熟悉,可以先進(jìn)行在線(xiàn)調(diào)試:https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?product=IoTDA&api=ShowDeviceShadow
在線(xiàn)調(diào)試接口,可以請(qǐng)求影子接口,了解請(qǐng)求,與返回的數(shù)據(jù)格式。
調(diào)試完成看右下角的響應(yīng)體,就是返回的影子數(shù)據(jù)。
設(shè)備影子接口返回的數(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)試成功之后,可以得到訪(fǎng)問(wèn)影子數(shù)據(jù)的真實(shí)鏈接,接下來(lái)的代碼開(kāi)發(fā)中,就采用Qt寫(xiě)代碼訪(fǎng)問(wèn)此鏈接,獲取影子數(shù)據(jù),完成上位機(jī)開(kāi)發(fā)。
4.4 修改設(shè)備屬性
地址: https://support.huaweicloud.com/api-iothub/iot_06_v5_0034.html
接口說(shuō)明
設(shè)備的產(chǎn)品模型中定義了物聯(lián)網(wǎng)平臺(tái)可向設(shè)備下發(fā)的屬性,應(yīng)用服務(wù)器可調(diào)用此接口向指定設(shè)備下發(fā)屬性。平臺(tái)負(fù)責(zé)將屬性以同步方式發(fā)送給設(shè)備,并將設(shè)備執(zhí)行屬性結(jié)果同步返回。
修改設(shè)備屬性的接口,可以讓服務(wù)器給設(shè)備下發(fā)指令,如果需要控制設(shè)備。
在線(xiàn)調(diào)試地址:
https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?product=IoTDA&api=UpdateProperties
修改設(shè)備屬性是屬于同步命令,需要設(shè)備在線(xiàn)才可以進(jìn)行調(diào)試,先使用MQTT客戶(hù)端登錄服務(wù)器,模擬設(shè)備上線(xiàn)。
然后進(jìn)行調(diào)試,測(cè)試數(shù)據(jù)遠(yuǎn)程下發(fā)給設(shè)備。
【1】利用MQTT客戶(hù)端先登錄設(shè)備 (這是同步命令,必須在線(xiàn)才能調(diào)試)
【2】點(diǎn)擊調(diào)試
填入的測(cè)試數(shù)據(jù):
{"services":{"oxygen_motor":1}}
【4】可以看到,MQTT客戶(hù)端軟件上已經(jīng)收到了服務(wù)器下發(fā)的消息
由于是同步命令,服務(wù)器必須要收到設(shè)備的響應(yīng)才能順利完成一個(gè)流程( 當(dāng)然,設(shè)備不回應(yīng)也沒(méi)影響 ),設(shè)備響應(yīng)了服務(wù)器才能確定數(shù)據(jù)下發(fā)成功。
MQTT設(shè)備端如何響應(yīng)呢?
設(shè)備響應(yīng)格式說(shuō)明:https://support.huaweicloud.com/api-iothub/iot_06_v5_3008.html
4.5 新建上位機(jī)工程
前面2講解了需要用的API接口,接下來(lái)就使用Qt設(shè)計(jì)上位機(jī),設(shè)計(jì)界面,完成整體上位機(jī)的邏輯設(shè)計(jì)。
【1】新建工程
【2】設(shè)置項(xiàng)目的名稱(chēng)。
【3】選擇編譯系統(tǒng)
【4】選擇默認(rèn)繼承的類(lèi)
【5】選擇編譯器
【6】點(diǎn)擊完成
【7】工程創(chuàng)建完成
4.6 設(shè)計(jì)UI界面與工程配置
【1】打開(kāi)UI文件
打開(kāi)默認(rèn)的界面如下:
【2】開(kāi)始設(shè)計(jì)界面
根據(jù)自己需求設(shè)計(jì)界面。
【3】配置pro工程文件
其中,加了注釋的代碼,表示Android環(huán)境才需要,而當(dāng)前是配置的Windows下的開(kāi)發(fā)環(huán)境,在Windows下編譯,就將其注釋掉,暫時(shí)不使用。
【4】配置軟件圖標(biāo)
在工程文件下方,增加當(dāng)前軟件的圖標(biāo)配置,圖標(biāo)需要是ICO
格式,將圖標(biāo)放在工程同級(jí)路徑下,在工程配置文件里指定好圖標(biāo)名稱(chēng)。
4.7 設(shè)計(jì)代碼
【1】獲取token
調(diào)用華為云的API都需要填token參數(shù),先看幫助文章,了解如何獲取token。
幫助文檔:https://support.huaweicloud.com/api-iam/iam_30_0001.html
根據(jù)幫助文檔,寫(xiě)完成下面代碼編寫(xiě):
/*
功能: 獲取token
*/
void Widget::GetToken()
{
//表示獲取token
function_select=3;
QString requestUrl;
QNetworkRequest request;
//設(shè)置請(qǐng)求地址
QUrl url;
//獲取token請(qǐng)求地址
requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens")
.arg(SERVER_ID);
//自己創(chuàng)建的TCP服務(wù)器,測(cè)試用
//requestUrl="http://10.0.0.6:8080";
//設(shè)置數(shù)據(jù)提交格式
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));
//構(gòu)造請(qǐng)求
url.setUrl(requestUrl);
request.setUrl(url);
QString text =QString("{"auth":{"identity":{"methods":["password"],"password":"
"{"user":{"domain": {"
""name":"%1"},"name": "%2","password": "%3"}}},"
""scope":{"project":{"name":"%4"}}}}")
.arg(MAIN_USER)
.arg(IAM_USER)
.arg(IAM_PASSWORD)
.arg(SERVER_ID);
//發(fā)送請(qǐng)求
manager- >post(request, text.toUtf8());
}
【2】時(shí)間校準(zhǔn)
前面已經(jīng)介紹了如何發(fā)送數(shù)據(jù)給設(shè)備,也就是修改屬性的接口: https://support.huaweicloud.com/api-iothub/iot_06_v5_0035.html
根據(jù)文檔介紹, 完成代碼編寫(xiě):
void Widget::on_pushButton_rtc_clicked()
{
QDateTime time = QDateTime::currentDateTime();//獲取系統(tǒng)現(xiàn)在的時(shí)間
QString str="按照系統(tǒng)時(shí)間校準(zhǔn):n";
str+= time.toString("yyyy-MM-dd hh:mm:ss ddd"); //設(shè)置顯示格式
QMessageBox::about(this,"校準(zhǔn)設(shè)備RTC時(shí)間",str);
//獲取本地時(shí)間校準(zhǔn)物聯(lián)網(wǎng)開(kāi)發(fā)板RTC時(shí)間
str=time.toString("yyyyMMddhhmmss"); //設(shè)置顯示格式
//修改屬性
function_select=13;
QString requestUrl;
QNetworkRequest request;
//設(shè)置請(qǐng)求地址
QUrl url;
//修改屬性的地址
requestUrl=QString("https://16cc7801b6.st1.iotda-app.cn-north-4.myhuaweicloud.com:443/v5/iot/%1/devices/%2/properties")
.arg(PROJECT_ID).arg(device_id);
//設(shè)置數(shù)據(jù)提交格式
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
//設(shè)置token
request.setRawHeader("X-Auth-Token",Token);
//構(gòu)造請(qǐng)求
url.setUrl(requestUrl);
request.setUrl(url);
//打包請(qǐng)求參數(shù)賦值
QString post_param=QString("{"services":{"rtc_set":"%1"}}").arg(str);
//發(fā)送請(qǐng)求
manager- >put(request, post_param.toUtf8());
}
【3】獲取影子數(shù)據(jù)
前面4.3小節(jié)介紹了影子數(shù)據(jù)獲取接口。下面是對(duì)應(yīng)編寫(xiě)的代碼:
//查詢(xún)?cè)O(shè)備屬性
void Widget::Get_device_properties()
{
//label_time
QDateTime current_date_time =QDateTime::currentDateTime();
QString current_date =current_date_time.toString("yyyy/MM/dd hh:mm:ss");
ui- >label_time- >setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
ui- >label_time- >setText(current_date);
function_select=0;
QString requestUrl;
QNetworkRequest request;
//設(shè)置請(qǐng)求地址
QUrl url;
//獲取token請(qǐng)求地址
requestUrl = QString("https://%1:443/v5/iot/%2/devices/%3/shadow")
.arg(IP_ADDR)
.arg(PROJECT_ID)
.arg(device_id);
//設(shè)置數(shù)據(jù)提交格式
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
//設(shè)置token
request.setRawHeader("X-Auth-Token",Token);
//構(gòu)造請(qǐng)求
url.setUrl(requestUrl);
request.setUrl(url);
//發(fā)送請(qǐng)求
manager- >get(request);
}
【4】解析數(shù)據(jù)更新界面
//解析反饋結(jié)果
void Widget::replyFinished(QNetworkReply *reply)
{
QString displayInfo;
int statusCode = reply- >attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
//讀取所有數(shù)據(jù)
QByteArray replyData = reply- >readAll();
qDebug()< "狀態(tài)碼:"<
【5】下面命令給設(shè)備端
/// 像設(shè)備端發(fā)送命令
/// brief Widget::MQTT_Cmd_Send
/// param cmd
///
void Widget::MQTT_Cmd_Send(QString cmd)
{
//修改屬性
function_select=13;
QString requestUrl;
QNetworkRequest request;
//設(shè)置請(qǐng)求地址
QUrl url;
//修改屬性的地址
requestUrl=QString("https://%1:443/v5/iot/%2/devices/%3/properties")
.arg(IP_ADDR).arg(PROJECT_ID).arg(device_id);
//設(shè)置數(shù)據(jù)提交格式
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
//設(shè)置token
request.setRawHeader("X-Auth-Token",Token);
//構(gòu)造請(qǐng)求
url.setUrl(requestUrl);
request.setUrl(url);
//打包請(qǐng)求參數(shù)賦值
QString post_param=QString("{"services":{%1}}").arg(cmd);
//發(fā)送請(qǐng)求
manager- >put(request, post_param.toUtf8());
}
4.8 編譯Windows上位機(jī)
編譯之后的效果:
4.9 配置Android環(huán)境
如果想編譯Android手機(jī)APP,可以參考此章節(jié)配置。 但是: 生成Android手機(jī)APP必須要先自己配置Android環(huán)境,這個(gè)配置相對(duì)比較復(fù)雜。
配置Android環(huán)境可以參考教程: https://blog.csdn.net/xiaolong1126626497/article/details/117254453
【1】創(chuàng)建Android配置文件
創(chuàng)建完成。
【2】配置Android圖標(biāo)與名稱(chēng)
【3】編譯Android上位機(jī)
Qt本身是跨平臺(tái)的,直接選擇Android的編譯器,就可以將程序編譯到Android平臺(tái)。
然后點(diǎn)擊構(gòu)建。
成功之后,在目錄下可以看到生成的apk
文件,也就是Android手機(jī)的安裝包,電腦端使用QQ
發(fā)送給手機(jī)QQ,手機(jī)登錄QQ接收,就能直接安裝。
生成的apk
的目錄在哪里呢?
從這里可以查看。
知道目錄在哪里之后,在Windows的文件資源管理器里,找到路徑,具體看下圖,找到生成的apk文件。
D:linux-share-dirQTbuild-Smarts_Fishbowl_HuaWeiYunIot-Android_for_arm64_v8a_Clang_Qt_5_12_6_for_Android_ARM64_v8a-Releaseandroid-buildbuildoutputsapkdebug
4.10 交互命令
上位機(jī)給設(shè)備下發(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設(shè)備端代碼設(shè)計(jì)
了解STM32F103的芯片配置:
5.1 硬件連線(xiàn)
1. ESP8266 WIFI接線(xiàn)
ATK-ESP8266串口WIFI模塊與STM32的串口2相連接。
PA2(TX)--RXD 模塊接收腳
PA3(RX)--TXD 模塊發(fā)送腳
GND---GND 地
VCC---VCC 3.3V
2. TFT 1.44 寸彩屏接線(xiàn)
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舵機(jī)-模擬魚(yú)缸換水-出水
VCC--- >5V
OUT--- >PA7
GND--- >GND
5. 水質(zhì)傳感器(ADC通道1)
VCC--- >5V
GND--- >GND
OUT--- >PA1
6. SG90舵機(jī)-模擬魚(yú)缸換水-進(jìn)水
OUT----PB5
GND---GND 地
VCC---5v
7. 魚(yú)缸水溫加熱--繼電器控制
GND----GND
VCC---3.3V
OUT---PB4
8. 增氧泵--繼電器控制
GND----GND
VCC---5V
OUT---PC11
9. PH值檢測(cè)
VCC--- >3.3V
GND--- >GND
OUT--- >PA4
10. 照明燈開(kāi)關(guān)
VCC--- >3.3V
GND--- >GND
OUT--- >PA6
11. 水位檢測(cè)
VCC--- >3.3V
GND--- >GND
OUT--- >PA5
13. 板載LED燈接線(xiàn)(這個(gè)不用接,這是開(kāi)發(fā)板本身的)
LED1---PA8
LED2---PD2
14. 板載按鍵接線(xiàn)(這個(gè)不用接,這是開(kāi)發(fā)板本身的)
K0---PA0
K1---PC5
K2---PA15
5.2 取模軟件使用
本地設(shè)備的LCD顯示屏上會(huì)顯示各種傳感器數(shù)據(jù),需要用到中文、數(shù)字、字母。
這是軟件的設(shè)置頁(yè)面:
5.3 通信協(xié)議
STM32設(shè)備端與華為云服務(wù)器通信的協(xié)議:
//如果WIFI已經(jīng)連接到網(wǎng)絡(luò)
if(esp8266_connect)
{
//組合JSON報(bào)文數(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");
}
手機(jī)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 按鍵的功能說(shuō)明
開(kāi)發(fā)板自帶了4個(gè)按鍵,其中第2是個(gè)RST
是復(fù)位鍵、另外3個(gè)按鍵是可編程的獨(dú)立按鍵。
按鍵1 功能: 顯示翻頁(yè)。
按鍵2 功能: 啟動(dòng)-SG90電機(jī)。
按鍵3: 功能: 開(kāi)啟或關(guān)閉照明燈。
詳細(xì)代碼如下:
key=KEY_Scan();
if(key)printf("key=%drn",key);
//按下按鍵1進(jìn)行翻頁(yè)
if(key==1)
{
Lcd_Clear(0); //清屏為黑色
page++;
if(page >=2)page=0;
if(page==0)
{
page_1();
}
else
{
page_2();
}
}
//按下按鍵2控制照明燈打開(kāi)
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 自動(dòng)模式控制邏輯
在while(1)循環(huán)里,每1秒鐘的周期整體執(zhí)行一次。讀取傳感器的數(shù)據(jù),處理,上傳到華為云IOT平臺(tái)。
如果檢測(cè)到水質(zhì)超過(guò)閥值,會(huì)啟用換水功能自動(dòng)換水。
如果檢測(cè)到溫度低于設(shè)置閥值,會(huì)啟用加熱功能自動(dòng)加熱升溫。
如果檢測(cè)到充氧時(shí)間到達(dá),會(huì)啟用充氧功能自動(dòng)充氧。
在LCD顯示屏上會(huì)實(shí)時(shí)當(dāng)前檢測(cè)到所有數(shù)據(jù)。
具體代碼如下:
//輪詢(xún)時(shí)間到達(dá)
if(time_cnt >20)
{
time_cnt=0;
LED1=!LED1;
//--------------------------------采集數(shù)據(jù)--------------------------------
//讀取水溫度
DS18B20_int=DS18B20_Get_Temp();
//轉(zhuǎn)換溫度為浮點(diǎn)數(shù)
sprintf(mqtt_message,"%d.%d",DS18B20_int >>4,DS18B20_int&0xF);
DS18B20=atof(mqtt_message);
//讀取水質(zhì)
//水質(zhì): 純凈水300多 自來(lái)水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;
//--------------------------------下次充氧時(shí)間倒計(jì)時(shí)計(jì)算--------------------------------
if(oxygen_food_sec<=0)
{
//默認(rèn)充氧5秒
oxygen_motor=1;
DelayMs(5000);
oxygen_motor=0;
//時(shí)間歸位
oxygen_food_sec=oxygen_motor_time*60;
}
//水質(zhì)太差 就啟動(dòng)換水
if(percentage >80)
{
//正轉(zhuǎn) 換水電機(jī)
open_water_motor();
}
else
{
//--反轉(zhuǎn) 換水電機(jī)
close_water_motor();
}
//顯示頁(yè)面1
if(page==0)
{
//實(shí)時(shí)時(shí)間與日期
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)
{
//實(shí)時(shí)時(shí)間與日期
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; //開(kāi)啟加熱
}
else
{
temp_heat=0; //停止加熱
}
//如果WIFI已經(jīng)連接到網(wǎng)絡(luò)
if(esp8266_connect)
{
//組合JSON報(bào)文數(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 手機(jī)APP遠(yuǎn)程控制
如果STM32收到APP遠(yuǎn)程下發(fā)的控制指令之后,會(huì)進(jìn)行判斷處理。
具體代碼如下:
// 接收WIFI返回的數(shù)據(jù)
if(USART2_RX_FLAG)
{
USART2_RX_BUFFER[USART2_RX_CNT]='?';
printf("WIFI收到數(shù)據(jù):rn");
//向串口打印服務(wù)器返回的數(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)
{
//開(kāi) 照明燈
if(strstr((char*)&USART2_RX_BUFFER[5],""lighting_led":1"))
{
lighting_led=1;
}
//關(guān) 照明燈
else if(strstr((char*)&USART2_RX_BUFFER[5],""lighting_led":0"))
{
lighting_led=0;
}
//開(kāi) 換水電機(jī)
else if(strstr((char*)&USART2_RX_BUFFER[5],""water_motor":1"))
{
//--反轉(zhuǎn) 換水電機(jī)
close_water_motor();
}
//關(guān) 換水電機(jī)
else if(strstr((char*)&USART2_RX_BUFFER[5],""water_motor":0"))
{
//正轉(zhuǎn) 換水電機(jī)
open_water_motor();
}
//開(kāi) 充氧電機(jī)
else if(strstr((char*)&USART2_RX_BUFFER[5],""oxygen_motor":1"))
{
oxygen_motor=1;
}
//關(guān) 充氧電機(jī)
else if(strstr((char*)&USART2_RX_BUFFER[5],""oxygen_motor":0"))
{
oxygen_motor=0;
}
//開(kāi) 換水電機(jī)
else if(strstr((char*)&USART2_RX_BUFFER[5],""clean_motor":1"))
{
//--反轉(zhuǎn) 換水電機(jī)-出水
close_clean_motor();
}
//關(guān) 換水電機(jī)-出水
else if(strstr((char*)&USART2_RX_BUFFER[5],""clean_motor":0"))
{
//正轉(zhuǎn) 換水電機(jī)-出水
open_clean_motor();
}
//充氧時(shí)間間隔
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; //轉(zhuǎn)為秒單位
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; //向后偏移,指向正確的時(shí)間
char *time=p;
int tm_sec; //秒
int tm_min; //分
int tm_hour; //時(shí)
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時(shí)間設(shè)置成功:%d-%d-%d %d:%d:%drn",tm_year,tm_mon,tm_mday,tm_hour,tm_min,tm_sec);
}
//下發(fā)指令請(qǐng)求回應(yīng)給服務(wù)器
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);
}
//上報(bào)數(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工程
六、使用STM32代碼的流程以及注意事項(xiàng)
6.1 第一步
照著設(shè)計(jì)文檔,買(mǎi)回來(lái)硬件模塊。 然后照著第五章節(jié)的第1小節(jié)(5.1章節(jié))的硬件連線(xiàn)說(shuō)明,將模塊與STM32開(kāi)發(fā)板之間連接好線(xiàn)。
注意:LCD顯示屏,直接插上去就行了,買(mǎi)的開(kāi)發(fā)板上本身就有排母,照著接,看準(zhǔn)開(kāi)發(fā)板板子上的 絲印說(shuō)明。
6.2 第二步
將Android手機(jī)APP安裝到自己的Android手機(jī)上,打開(kāi)手機(jī)APP,點(diǎn)擊更新Token按鈕,點(diǎn)擊更新數(shù)據(jù),然后就可以了。 (這時(shí)候無(wú)法點(diǎn)擊控制按鈕,點(diǎn)擊會(huì)報(bào)錯(cuò),因?yàn)樵O(shè)備沒(méi)有在線(xiàn),無(wú)法進(jìn)行遠(yuǎn)程控制設(shè)備,這是正常的)
6.3 第三步
使用手機(jī)開(kāi)一個(gè)熱點(diǎn)。
(1)名字設(shè)置為: abc
(2)密碼設(shè)置為:12345678
注意事項(xiàng):
WIFI頻段設(shè)置為:2.4GHZ
千萬(wàn)注意:熱點(diǎn)的名字,密碼,頻段一點(diǎn)要設(shè)置正確。 否則,到時(shí)候,ESP8266-WIFI連接不上。 ESP8266 只能連接2.4GHZ的WIFI。
6.4 第四步
打STM32的keil工程,編譯代碼、然后,使用USB線(xiàn)將開(kāi)發(fā)板的左邊的USB口(串口1)與電腦的USB連接,打開(kāi)程序下載軟件下載程序。
具體下載過(guò)程看下面圖:
打開(kāi)程序下載軟件:
6.5 第五步
下載成功之后,本地的LCD顯示屏?xí)@示硬件的初始化過(guò)程。 比如:ESP8266的初始化過(guò)程,以及WIFI熱點(diǎn)的連接過(guò)程。
如何提示ESP8266-錯(cuò)誤,那么就認(rèn)真檢查WIFI接線(xiàn)。
如果顯示W(wǎng)IFI連接失敗,請(qǐng)認(rèn)真檢查 第三步。
如果一切正常,就進(jìn)入了程序主界面。
這時(shí)候,打開(kāi)手機(jī)APP,也能看到設(shè)備的最新數(shù)據(jù),點(diǎn)擊控制按鈕,也能控制設(shè)備了。
到此,恭喜你,整個(gè)項(xiàng)目已經(jīng)完成開(kāi)發(fā)。
七、制作過(guò)程
串口調(diào)試助手:
WIFI模式:STA+TCP客戶(hù)端
Connect_WIFI熱點(diǎn)名稱(chēng):abc
Connect_WIFI熱點(diǎn)密碼:12345678
TCP服務(wù)器端口號(hào):1883
TCP服務(wù)器IP地址:117.78.5.125
ESP8266成功連接上熱點(diǎn)...
準(zhǔn)備連接MQTT服務(wù)器...
0x20 0x2 0 0 服務(wù)器連接成功.
八、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)服務(wù)器的設(shè)備信息
#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ā)布
//設(shè)置連接的路由器信息
#define CONNECT_WIFI "abc" //將要連接的路由器名稱(chēng) --不要出現(xiàn)中文、空格等特殊字符
#define CONNECT_PASS "12345678" //將要連接的路由器密碼
#define CONNECT_SERVER_IP "117.78.5.125" //服務(wù)器IP地址
#define CONNECT_SERVER_PORT 1883 //服務(wù)器端口號(hào)
//JTAG模式設(shè)置,用于設(shè)置JTAG的模式
//mode:jtag,swd模式設(shè)置;00,全使能;01,使能SWD;10,全關(guān)閉;
#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; //開(kāi)啟輔助時(shí)鐘
AFIO- >MAPR&=0XF8FFFFFF; //清除MAPR的[26:24]
AFIO- >MAPR|=temp; //設(shè)置jtag模式
}
char request_id[100];
char mqtt_message[100];
//WIFI發(fā)送數(shù)據(jù)存儲(chǔ)區(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; //充氧時(shí)間間隔: oxygen_motor_time
int oxygen_food_sec=300; // 充氧時(shí)間間隔 秒
int water_quality=0; //渾濁度檢測(cè) 水質(zhì)狀態(tài): 渾濁度檢測(cè);
int led_sw=0; //氛圍燈開(kāi)關(guān)
int ledNumber=1; //LED燈的編號(hào)
int percentage=0; //水質(zhì)
int water_monitor; //水位檢測(cè)
u32 SecCnt=0;
int PH; //PH值檢測(cè)
/*
函數(shù)功能: 定時(shí)器1的更新中斷服務(wù)函數(shù) 模擬RTC
*/
void TIM1_UP_IRQHandler(void)
{
//1秒鐘進(jìn)來(lái)一次
if(TIM1- >SR&1< 0)
{
//記錄時(shí)間
SecCnt++;
GetRtcTime(SecCnt); //轉(zhuǎn)換標(biāo)準(zhǔn)時(shí)間
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);
//倒計(jì)時(shí)
if(oxygen_food_sec >0)oxygen_food_sec--;
}
TIM1- >SR=0;
}
/*
這個(gè)函數(shù)接受一個(gè)整數(shù)參數(shù)(秒數(shù)),并返回一個(gè)指向固定長(zhǎng)度字符串的指針。
使用 sprintf 函數(shù)將小時(shí)、分鐘和秒格式化為 HH:MM:SS 的字符串,并將其存儲(chǔ)在 result 數(shù)組中,最后將其作為返回值返回。
在主函數(shù)中,程序要求用戶(hù)輸入秒數(shù),調(diào)用 format_time 函數(shù)將其轉(zhuǎn)換為格式化后的時(shí)分秒字符串,并將其打印輸出。
注意,這個(gè)程序假設(shè)用戶(hù)輸入的秒數(shù)不超過(guò)一天(86400秒)。如果需要處理更長(zhǎng)的時(shí)間單位,需要修改 format_time 函數(shù)的實(shí)現(xiàn)。
*/
char* format_time(int seconds)
{
static char result[9]; // 存儲(chǔ)結(jié)果的字符串,固定長(zhǎng)度為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;
}
/*
實(shí)時(shí)水溫水質(zhì)濁度投喂間隔充氧間隔恒溫溫度下次投喂時(shí)間下次充氧時(shí)間水位距離
*/
//頁(yè)面1
void page_1()
{
//實(shí)時(shí)水溫
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);
//魚(yú)缸水位
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);
}
//頁(yè)面2
void page_2()
{
//當(dāng)前實(shí)時(shí)時(shí)間
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);
//下次充氧時(shí)間
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; //記錄定時(shí)的時(shí)間
u8 page=0; //翻頁(yè)
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); //超時(shí)時(shí)間20ms
//LCD顯示屏初始化
Lcd_Init(); //LCD初始化
Lcd_Clear(0); //清屏為黑色
LCD_LED_SET;//通過(guò)IO控制背光亮(通過(guò)這個(gè)引腳控制顯示屏開(kāi)關(guān))
//ADC初始化 水質(zhì)狀態(tài)、PH值檢測(cè)、水位
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硬件檢測(cè)錯(cuò)誤.n");
}
}
//如果初始化成功。就去連接指定的熱點(diǎn)。
if(run_state)
{
Gui_DrawFont_GBK16(0,16*1+2,WHITE,0,(u8*)"Connect WIFI...");
printf("ESP8266硬件正常。準(zhǔn)備連接WIFI熱點(diǎn)(必須2.4GHZ)....rn");
printf("準(zhǔn)備連接熱點(diǎn)名稱(chēng):%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:
//開(kāi)始連接熱點(diǎn)
run_state=ESP8266_STA_TCP_Client_Mode(CONNECT_WIFI,CONNECT_PASS,CONNECT_SERVER_IP,CONNECT_SERVER_PORT,1);
//如果為真, 就表示連接錯(cuò)誤
if(run_state)
{
printf("熱點(diǎn)連接失敗:正在重試...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成功連接上熱點(diǎn)...rn");
printf("準(zhǔn)備連接MQTT服務(wù)器...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. 連接服務(wù)器
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("服務(wù)器連接失敗,正在重試...rn");
delay_ms(500);
}
//如果服務(wù)器已連接
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("服務(wù)器連接成功.rn");
printf("準(zhǔn)備訂閱主題...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("服務(wù)器連接失敗.請(qǐng)保證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");
//視覺(jué)停留
delay_ms(1000);delay_ms(1000);delay_ms(1000);delay_ms(1000);delay_ms(1000);
}
}
#endif
SetRtcTime(2023,03,22,22,22,10); //設(shè)置時(shí)間
//定時(shí)器初始化。1秒中斷一次,為了方便計(jì)時(shí)
TIMER1_Init(7200,15000); //1000000us 1000000us
//清屏為黑色
Lcd_Clear(0);
//復(fù)位 正轉(zhuǎn) 換水電機(jī)-出水
open_clean_motor();
//復(fù)位 正轉(zhuǎn) 換水電機(jī)
open_water_motor();
//默認(rèn)顯示頁(yè)面1
page_1();
while(1)
{
//---------------------------------按鍵檢測(cè)---------------------------------
key=KEY_Scan();
if(key)printf("key=%drn",key);
//按下按鍵1進(jìn)行翻頁(yè)
if(key==1)
{
Lcd_Clear(0); //清屏為黑色
page++;
if(page >=2)page=0;
if(page==0)
{
page_1();
}
else
{
page_2();
}
}
//按下按鍵2控制照明燈打開(kāi)
else if(key==2)
{
lighting_led=!lighting_led;
}
//按下按鍵3控制 控制魚(yú)缸清洗
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();
}
//輪詢(xún)時(shí)間到達(dá)
if(time_cnt >20)
{
time_cnt=0;
LED1=!LED1;
//--------------------------------采集數(shù)據(jù)--------------------------------
//讀取水溫度
DS18B20_int=DS18B20_Get_Temp();
//轉(zhuǎn)換溫度為浮點(diǎn)數(shù)
sprintf(mqtt_message,"%d.%d",DS18B20_int >>4,DS18B20_int&0xF);
DS18B20=atof(mqtt_message);
//讀取水質(zhì)
//水質(zhì): 純凈水300多 自來(lái)水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;
//--------------------------------下次充氧時(shí)間倒計(jì)時(shí)計(jì)算--------------------------------
if(oxygen_food_sec<=0)
{
//默認(rèn)充氧5秒
oxygen_motor=1;
DelayMs(5000);
oxygen_motor=0;
//時(shí)間歸位
oxygen_food_sec=oxygen_motor_time*60;
}
//水質(zhì)太差 就啟動(dòng)換水
if(percentage >80)
{
//正轉(zhuǎn) 換水電機(jī)
open_water_motor();
}
else
{
//--反轉(zhuǎn) 換水電機(jī)
close_water_motor();
}
//顯示頁(yè)面1
if(page==0)
{
//實(shí)時(shí)時(shí)間與日期
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)
{
//實(shí)時(shí)時(shí)間與日期
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; //開(kāi)啟加熱
}
else
{
temp_heat=0; //停止加熱
}
//如果WIFI已經(jīng)連接到網(wǎng)絡(luò)
if(esp8266_connect)
{
//組合JSON報(bào)文數(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");
//向串口打印服務(wù)器返回的數(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)
{
//開(kāi) 照明燈
if(strstr((char*)&USART2_RX_BUFFER[5],""lighting_led":1"))
{
lighting_led=1;
}
//關(guān) 照明燈
else if(strstr((char*)&USART2_RX_BUFFER[5],""lighting_led":0"))
{
lighting_led=0;
}
//開(kāi) 換水電機(jī)
else if(strstr((char*)&USART2_RX_BUFFER[5],""water_motor":1"))
{
//--反轉(zhuǎn) 換水電機(jī)
close_water_motor();
}
//關(guān) 換水電機(jī)
else if(strstr((char*)&USART2_RX_BUFFER[5],""water_motor":0"))
{
//正轉(zhuǎn) 換水電機(jī)
open_water_motor();
}
//開(kāi) 充氧電機(jī)
else if(strstr((char*)&USART2_RX_BUFFER[5],""oxygen_motor":1"))
{
oxygen_motor=1;
}
//關(guān) 充氧電機(jī)
else if(strstr((char*)&USART2_RX_BUFFER[5],""oxygen_motor":0"))
{
oxygen_motor=0;
}
//開(kāi) 換水電機(jī)-出水
else if(strstr((char*)&USART2_RX_BUFFER[5],""clean_motor":1"))
{
//--反轉(zhuǎn) 換水電機(jī)-出水
close_clean_motor();
}
//關(guān) 換水電機(jī)-出水
else if(strstr((char*)&USART2_RX_BUFFER[5],""clean_motor":0"))
{
//正轉(zhuǎn) 換水電機(jī)-出水
open_clean_motor();
}
//充氧時(shí)間間隔
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; //轉(zhuǎn)為秒單位
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; //向后偏移,指向正確的時(shí)間
char *time=p;
int tm_sec; //秒
int tm_min; //分
int tm_hour; //時(shí)
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時(shí)間設(shè)置成功:%d-%d-%d %d:%d:%drn",tm_year,tm_mon,tm_mday,tm_hour,tm_min,tm_sec);
}
//下發(fā)指令請(qǐng)求回應(yīng)給服務(wù)器
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);
}
//上報(bào)數(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++;
}
}
f
-
單片機(jī)
+關(guān)注
關(guān)注
6039文章
44579瀏覽量
636452 -
物聯(lián)網(wǎng)
+關(guān)注
關(guān)注
2910文章
44752瀏覽量
374587 -
STM32F103RCT6
+關(guān)注
關(guān)注
10文章
23瀏覽量
9919
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論