基于STM32F407+NBIOT+華為云IOT平臺(tái)設(shè)計(jì)的環(huán)境檢測(cè)系統(tǒng)
實(shí)現(xiàn)的功能:
【1】能夠采集本地環(huán)境的溫度、濕度、煙霧濃度,火光信息,在OLED顯示屏上顯示。 如果檢測(cè)到煙霧、溫度、火光超過閥值會(huì)觸發(fā)蜂鳴器報(bào)警。
【2】能夠通過NBIOT將本地設(shè)備采集的信息上傳到華為云物聯(lián)網(wǎng)云平臺(tái)。
【3】通過Qt(C++)開發(fā)Android手機(jī)APP,從華為云物聯(lián)網(wǎng)云平臺(tái)獲取設(shè)備最新的數(shù)據(jù)進(jìn)行顯示,完成信息展示,在手機(jī)APP上可以顯示檢測(cè)到的溫度、濕度、煙霧報(bào)警、火光報(bào)警信息。
硬件選型:
【1】主控芯片選擇STM32F407
【2】環(huán)境溫濕度傳感器采用SHT30
【3】煙霧傳感器采用MQ2
【4】火焰檢測(cè)傳感器采用火光檢測(cè)傳感器
【5】NBIOT采用BC26
【6】電源采用USB接口5V供電。
【7】蜂鳴器采用高電平觸發(fā)的有源蜂鳴器。
【8】顯示屏采用0.96寸IIC協(xié)議OLED顯示屏。
一、前言
1.1 項(xiàng)目介紹
【1】項(xiàng)目開發(fā)背景
隨著物聯(lián)網(wǎng)技術(shù)的快速發(fā)展,越來越多的設(shè)備和系統(tǒng)開始融入我們的生活和工作中。環(huán)境監(jiān)測(cè)作為一個(gè)重要的應(yīng)用領(lǐng)域,對(duì)于保障人們的健康和安全具有重要意義?;赟TM32F407+NBIOT+華為云IOT平臺(tái)設(shè)計(jì)的環(huán)境檢測(cè)系統(tǒng),實(shí)現(xiàn)對(duì)室內(nèi)環(huán)境的實(shí)時(shí)監(jiān)測(cè),并通過物聯(lián)網(wǎng)技術(shù)將數(shù)據(jù)傳輸至云端,為用戶提供便捷的數(shù)據(jù)查詢和遠(yuǎn)程監(jiān)控功能。
該系統(tǒng)的主要功能包括:
(1)采集本地環(huán)境的溫度、濕度、煙霧濃度和火光信息,并在OLED顯示屏上顯示。當(dāng)檢測(cè)到煙霧、溫度或火光超過預(yù)設(shè)閾值時(shí),觸發(fā)蜂鳴器報(bào)警,以提醒用戶采取相應(yīng)措施。
(2)通過NBIOT技術(shù)將本地設(shè)備采集的信息上傳至華為云物聯(lián)網(wǎng)云平臺(tái),實(shí)現(xiàn)數(shù)據(jù)的遠(yuǎn)程存儲(chǔ)和管理。
(3)利用Qt(C++)開發(fā)的Android手機(jī)APP,從華為云物聯(lián)網(wǎng)云平臺(tái)獲取設(shè)備最新的數(shù)據(jù)進(jìn)行顯示,完成信息展示。在手機(jī)APP上可以顯示檢測(cè)到的溫度、濕度、煙霧報(bào)警和火光報(bào)警信息。
硬件選型方面,選擇了以下組件:
(1)主控芯片:STM32F407,具有較高的處理能力和豐富的外設(shè)接口,適合作為本系統(tǒng)的控制核心。
(2)環(huán)境溫濕度傳感器:SHT30,具有高精度、低功耗等特點(diǎn),適用于室內(nèi)環(huán)境監(jiān)測(cè)。
(3)煙霧傳感器:MQ2,能夠檢測(cè)空氣中的煙霧濃度,及時(shí)發(fā)現(xiàn)火災(zāi)隱患。
(4)火焰檢測(cè)傳感器:火光檢測(cè)傳感器,用于檢測(cè)火焰產(chǎn)生的光輻射,實(shí)現(xiàn)火焰報(bào)警功能。
(5)NBIOT模塊:BC26,支持NBIOT網(wǎng)絡(luò)通信,實(shí)現(xiàn)數(shù)據(jù)的遠(yuǎn)程傳輸。
(6)電源:采用USB接口5V供電,方便設(shè)備接入各種電源環(huán)境。
(7)蜂鳴器:高電平觸發(fā)的有源蜂鳴器,用于發(fā)出報(bào)警聲音。
(8)顯示屏:0.96寸IIC協(xié)議OLED顯示屏,用于顯示采集到的環(huán)境參數(shù)和報(bào)警信息。
【2】設(shè)計(jì)實(shí)現(xiàn)的功能
(1)環(huán)境參數(shù)采集: 利用STM32F407微控制器集成的高精度ADC及數(shù)字信號(hào)處理能力,系統(tǒng)能夠?qū)崟r(shí)采集SHT30溫濕度傳感器輸出的溫濕度數(shù)據(jù),以及MQ2煙霧傳感器和火光檢測(cè)傳感器提供的煙霧濃度和火光信息。這些傳感器的選擇確保了對(duì)環(huán)境狀態(tài)的全面監(jiān)控。
(2)數(shù)據(jù)顯示: 采集到的數(shù)據(jù)通過I2C接口傳輸至0.96寸OLED顯示屏上實(shí)時(shí)顯示,提供直觀的溫濕度讀數(shù)、煙霧濃度指標(biāo)和火光警告信息。OLED屏因其自發(fā)光特性,即便在低光照環(huán)境下也能清晰顯示數(shù)據(jù)。
(3)本地預(yù)警系統(tǒng): 設(shè)定合理的閾值,當(dāng)檢測(cè)到的溫度、濕度、煙霧濃度或火光強(qiáng)度超過預(yù)設(shè)安全范圍時(shí),系統(tǒng)將自動(dòng)激活高電平觸發(fā)的有源蜂鳴器,發(fā)出報(bào)警聲,即時(shí)提醒現(xiàn)場(chǎng)人員注意潛在的環(huán)境危險(xiǎn)。
(4)NBIOT通信: 通過集成BC26 NBIOT模塊,系統(tǒng)能夠?qū)⒈镜夭杉沫h(huán)境數(shù)據(jù)通過窄帶物聯(lián)網(wǎng)技術(shù)遠(yuǎn)程上傳至華為云物聯(lián)網(wǎng)平臺(tái)。NBIOT技術(shù)因其低功耗、廣覆蓋的特點(diǎn),特別適合于遠(yuǎn)程、低速數(shù)據(jù)傳輸?shù)膽?yīng)用場(chǎng)景。
(5)云端數(shù)據(jù)處理與存儲(chǔ): 上傳至華為云的環(huán)境監(jiān)測(cè)數(shù)據(jù)會(huì)被自動(dòng)接收并存儲(chǔ),華為云物聯(lián)網(wǎng)平臺(tái)提供強(qiáng)大的數(shù)據(jù)管理和分析能力,支持用戶通過云端界面查看歷史數(shù)據(jù)趨勢(shì),設(shè)置告警規(guī)則等。
(6)Android手機(jī)APP開發(fā): 利用Qt框架(C++)開發(fā)的Android手機(jī)應(yīng)用程序,用戶可以遠(yuǎn)程實(shí)時(shí)查看連接到華為云物聯(lián)網(wǎng)平臺(tái)的環(huán)境監(jiān)測(cè)設(shè)備的最新數(shù)據(jù)。APP界面友好,直觀展示當(dāng)前的溫度、濕度、煙霧報(bào)警狀態(tài)和火光報(bào)警信息,使用戶無論身在何處都能及時(shí)了解環(huán)境狀況。
(7)交互性與控制: 手機(jī)APP除了被動(dòng)接收數(shù)據(jù)展示外,還可以進(jìn)一步設(shè)計(jì)實(shí)現(xiàn)遠(yuǎn)程控制功能,如調(diào)整報(bào)警閾值、查詢歷史記錄或發(fā)送指令給STM32F407控制端進(jìn)行特定操作,增強(qiáng)系統(tǒng)的互動(dòng)性和管理效率。
本項(xiàng)目不僅實(shí)現(xiàn)了對(duì)環(huán)境參數(shù)的精準(zhǔn)監(jiān)測(cè)與本地預(yù)警,還通過NBIOT技術(shù)與華為云物聯(lián)網(wǎng)平臺(tái)的結(jié)合,提供了遠(yuǎn)程監(jiān)控和數(shù)據(jù)分析的能力,配以定制化的移動(dòng)端應(yīng)用,極大地提升了環(huán)境監(jiān)測(cè)的智能化和便捷性。
【3】項(xiàng)目硬件模塊組成
(1)主控單元 - STM32F407微控制器:
- 作為整個(gè)系統(tǒng)的核心,STM32F407是一款高性能的32位ARM Cortex-M4內(nèi)核微控制器,具備豐富的外設(shè)資源和高速處理能力,負(fù)責(zé)數(shù)據(jù)采集、處理、顯示控制以及與外部模塊的通信協(xié)調(diào)。
(2)溫濕度傳感器 - SHT30:
- 用于測(cè)量環(huán)境中的溫度和濕度,通過I2C接口與STM32F407通信,提供高精度的溫濕度數(shù)據(jù),是環(huán)境監(jiān)測(cè)的基礎(chǔ)組成部分。
(3)煙霧傳感器 - MQ2:
- 用于檢測(cè)環(huán)境中煙霧濃度,能對(duì)多種氣體敏感,包括煙霧、LPG、甲烷等,通過模擬信號(hào)輸出至STM32F407,用于評(píng)估火災(zāi)風(fēng)險(xiǎn)。
(4)火光檢測(cè)傳感器:
- 專門設(shè)計(jì)用于探測(cè)火焰或高強(qiáng)度光源,通過其光電效應(yīng)產(chǎn)生電信號(hào),經(jīng)處理后由STM32F407判斷是否有火光存在,實(shí)現(xiàn)火災(zāi)的早期預(yù)警。
(5)NBIOT通信模組 - BC26:
- 負(fù)責(zé)將STM32F407處理后的環(huán)境監(jiān)測(cè)數(shù)據(jù)通過NBIOT網(wǎng)絡(luò)上傳至華為云物聯(lián)網(wǎng)平臺(tái)。BC26模組支持低功耗、遠(yuǎn)程連接,為系統(tǒng)提供穩(wěn)定的數(shù)據(jù)傳輸通道。
(6)電源模塊:
- 采用USB接口5V供電,為整個(gè)系統(tǒng)提供穩(wěn)定可靠的能源。設(shè)計(jì)中需考慮電源管理,以優(yōu)化系統(tǒng)能耗,延長電池續(xù)航或確保持續(xù)穩(wěn)定供電。
(7)蜂鳴器報(bào)警模塊:
- 高電平觸發(fā)的有源蜂鳴器,當(dāng)STM32F407檢測(cè)到環(huán)境參數(shù)超過設(shè)定閾值時(shí),通過GPIO輸出高電平信號(hào),激活蜂鳴器發(fā)出報(bào)警聲音,實(shí)現(xiàn)本地即時(shí)警告。
(8)OLED顯示屏:
- 采用0.96英寸I2C接口OLED顯示屏,用于實(shí)時(shí)顯示溫濕度、煙霧濃度和火光報(bào)警等信息。OLED屏具有自發(fā)光、視角寬、響應(yīng)速度快等特點(diǎn),適合在不同光照條件下清晰展示數(shù)據(jù)。
【4】摘要
本項(xiàng)目設(shè)計(jì)并實(shí)現(xiàn)一款基于STM32F407微控制器、結(jié)合NBIOT通信技術(shù)與華為云物聯(lián)網(wǎng)平臺(tái)的智能環(huán)境監(jiān)測(cè)系統(tǒng)。系統(tǒng)整合了SHT30溫濕度傳感器、MQ2煙霧傳感器以及火光檢測(cè)傳感器,實(shí)現(xiàn)對(duì)環(huán)境的多維度監(jiān)控,包括溫度、濕度、煙霧濃度和火光信息的實(shí)時(shí)采集。通過OLED顯示屏現(xiàn)場(chǎng)展示監(jiān)測(cè)數(shù)據(jù),并在檢測(cè)到異常時(shí)啟動(dòng)蜂鳴器報(bào)警,確保即時(shí)預(yù)警。利用BC26 NBIOT模塊,系統(tǒng)將監(jiān)測(cè)數(shù)據(jù)遠(yuǎn)程傳輸至華為云物聯(lián)網(wǎng)平臺(tái),借助云平臺(tái)的強(qiáng)大數(shù)據(jù)處理能力,實(shí)現(xiàn)數(shù)據(jù)的遠(yuǎn)程訪問、存儲(chǔ)與分析。此外,項(xiàng)目還開發(fā)了基于Qt框架的Android手機(jī)APP,方便用戶通過移動(dòng)設(shè)備遠(yuǎn)程查看實(shí)時(shí)環(huán)境數(shù)據(jù)及歷史記錄,提升環(huán)境管理的便捷性和效率。本系統(tǒng)有效融合了物聯(lián)網(wǎng)、云計(jì)算與移動(dòng)應(yīng)用技術(shù),為環(huán)境保護(hù)、火災(zāi)預(yù)防等應(yīng)用場(chǎng)景提供了智能化解決方案。
關(guān)鍵字:
- STM32F407
- NBIOT通信
- 華為云物聯(lián)網(wǎng)平臺(tái)
- 環(huán)境監(jiān)測(cè)系統(tǒng)
- 溫濕度傳感器(SHT30)
- 煙霧傳感器(MQ2)
- 火光檢測(cè)
- OLED顯示屏
- Qt/C++移動(dòng)應(yīng)用開發(fā)
- 智能預(yù)警系統(tǒng)
1.2 設(shè)計(jì)思路
(1)模塊化設(shè)計(jì):
- 將系統(tǒng)劃分為多個(gè)獨(dú)立但相互協(xié)作的模塊,包括數(shù)據(jù)采集模塊(溫濕度、煙霧、火光)、數(shù)據(jù)處理與控制模塊(STM32F407)、本地顯示模塊(OLED)、遠(yuǎn)程通信模塊(NBIOT BC26)、報(bào)警模塊(蜂鳴器)和移動(dòng)應(yīng)用模塊(Android APP)。這種設(shè)計(jì)便于系統(tǒng)維護(hù)、升級(jí)和故障排查,同時(shí)也利于模塊復(fù)用和擴(kuò)展新功能。
(2)高效數(shù)據(jù)采集與處理:
- 選用高精度的SHT30溫濕度傳感器和靈敏的MQ2煙霧傳感器,結(jié)合火光檢測(cè)傳感器,確保數(shù)據(jù)采集的準(zhǔn)確性。STM32F407作為主控芯片,利用其強(qiáng)大計(jì)算能力和豐富的外設(shè)接口,負(fù)責(zé)實(shí)時(shí)處理采集數(shù)據(jù),執(zhí)行邏輯判斷,控制報(bào)警與顯示。
(3)低功耗遠(yuǎn)程通信策略:
- 采用NBIOT技術(shù)通過BC26模組實(shí)現(xiàn)數(shù)據(jù)的遠(yuǎn)程傳輸,看重其在低功耗、廣覆蓋方面的優(yōu)勢(shì),特別適合于長時(shí)間運(yùn)行、部署位置偏遠(yuǎn)的環(huán)境監(jiān)測(cè)設(shè)備,確保數(shù)據(jù)傳輸?shù)姆€(wěn)定性和經(jīng)濟(jì)性。
(4)云端數(shù)據(jù)管理與分析:
- 利用華為云物聯(lián)網(wǎng)平臺(tái)強(qiáng)大的數(shù)據(jù)處理能力,實(shí)現(xiàn)數(shù)據(jù)的遠(yuǎn)程存儲(chǔ)、實(shí)時(shí)分析與可視化展示,為用戶提供歷史數(shù)據(jù)查詢、趨勢(shì)分析等功能,同時(shí)支持設(shè)置報(bào)警規(guī)則,通過云端平臺(tái)實(shí)現(xiàn)對(duì)多個(gè)監(jiān)測(cè)點(diǎn)的集中管理和遠(yuǎn)程監(jiān)控。
(5)移動(dòng)終端交互體驗(yàn)優(yōu)化:
- 開發(fā)基于Qt的Android手機(jī)APP,注重用戶體驗(yàn)設(shè)計(jì),提供簡潔直觀的操作界面,讓用戶能夠隨時(shí)隨地查看環(huán)境監(jiān)測(cè)數(shù)據(jù),接收?qǐng)?bào)警通知,甚至進(jìn)行遠(yuǎn)程配置和控制,提升系統(tǒng)的實(shí)用性和用戶參與度。
1.3 系統(tǒng)功能總結(jié)
功能模塊 | 具體功能描述 |
---|---|
數(shù)據(jù)采集 | - 使用SHT30溫濕度傳感器實(shí)時(shí)監(jiān)測(cè)并采集環(huán)境溫度與濕度數(shù)據(jù)。 |
- 利用MQ2煙霧傳感器監(jiān)測(cè)煙霧濃度,支持多種氣體檢測(cè)。 | |
- 火光檢測(cè)傳感器,對(duì)環(huán)境中的火光或強(qiáng)光源進(jìn)行實(shí)時(shí)監(jiān)測(cè)。 | |
數(shù)據(jù)處理與控制 | - STM32F407微控制器負(fù)責(zé)數(shù)據(jù)處理、邏輯判斷及系統(tǒng)控制。 |
- 實(shí)現(xiàn)數(shù)據(jù)閾值判斷,當(dāng)檢測(cè)值超限時(shí),觸發(fā)報(bào)警機(jī)制。 | |
本地顯示 | - 通過0.96寸OLED顯示屏,實(shí)時(shí)展示溫濕度、煙霧濃度、火光報(bào)警信息。 |
遠(yuǎn)程通信 | - BC26 NBIOT模塊實(shí)現(xiàn)與華為云物聯(lián)網(wǎng)平臺(tái)的數(shù)據(jù)上傳。 |
云端服務(wù) | - 華為云物聯(lián)網(wǎng)平臺(tái)存儲(chǔ)、處理接收到的環(huán)境數(shù)據(jù)。 |
- 支持?jǐn)?shù)據(jù)的歷史記錄查詢、統(tǒng)計(jì)分析與可視化展示。 | |
移動(dòng)端監(jiān)控 | - Qt開發(fā)的Android手機(jī)APP,遠(yuǎn)程查看實(shí)時(shí)環(huán)境監(jiān)測(cè)數(shù)據(jù)。 |
- 顯示溫度、濕度、煙霧濃度報(bào)警狀態(tài)及火光報(bào)警信息。 | |
- 用戶可設(shè)置報(bào)警閾值、查看歷史記錄等。 | |
安全與可靠性 | - 數(shù)據(jù)傳輸采用加密技術(shù),保障云端數(shù)據(jù)安全。 |
- 設(shè)備內(nèi)置錯(cuò)誤處理與恢復(fù)機(jī)制,提高系統(tǒng)穩(wěn)定性。 | |
可擴(kuò)展性 | - 系統(tǒng)設(shè)計(jì)預(yù)留接口,支持未來接入更多類型傳感器。 |
- 通信方式和技術(shù)框架易于升級(jí),以適應(yīng)技術(shù)發(fā)展和應(yīng)用需求變化。 |
1.4 開發(fā)工具的選擇
【1】設(shè)備端開發(fā)
STM32的編程語言選擇C語言,C語言執(zhí)行效率高,大學(xué)里主學(xué)的C語言,C語言編譯出來的可執(zhí)行文件最接近于機(jī)器碼,匯編語言執(zhí)行效率最高,但是匯編的移植性比較差,目前在一些操作系統(tǒng)內(nèi)核里還有一些低配的單片機(jī)使用的較多,平常的單片機(jī)編程還是以C語言為主。C語言的執(zhí)行效率僅次于匯編,語法理解簡單、代碼通用性強(qiáng),也支持跨平臺(tái),在嵌入式底層、單片機(jī)編程里用的非常多,當(dāng)前的設(shè)計(jì)就是采用C語言開發(fā)。
開發(fā)工具選擇Keil,keil是一家世界領(lǐng)先的嵌入式微控制器軟件開發(fā)商,在2015年,keil被ARM公司收購。因?yàn)楫?dāng)前芯片選擇的是STM32F103系列,STMF103是屬于ARM公司的芯片構(gòu)架、Cortex-M3內(nèi)核系列的芯片,所以使用Kile來開發(fā)STM32是有先天優(yōu)勢(shì)的,而keil在各大高校使用的也非常多,很多教科書里都是以keil來教學(xué),開發(fā)51單片機(jī)、STM32單片機(jī)等等。目前作為MCU芯片開發(fā)的軟件也不只是keil一家獨(dú)大,IAR在MCU微處理器開發(fā)領(lǐng)域里也使用的非常多,IAR擴(kuò)展性更強(qiáng),也支持STM32開發(fā),也支持其他芯片,比如:CC2530,51單片機(jī)的開發(fā)。從軟件的使用上來講,IAR比keil更加簡潔,功能相對(duì)少一些。如果之前使用過keil,而且使用頻率較多,已經(jīng)習(xí)慣再使用IAR是有點(diǎn)不適應(yīng)界面的。
【2】上位機(jī)開發(fā)
上位機(jī)的開發(fā)選擇Qt框架,編程語言采用C++;Qt是一個(gè)1991年由Qt Company開發(fā)的跨平臺(tái)C++圖形用戶界面應(yīng)用程序開發(fā)框架。它既可以開發(fā)GUI程序,也可用于開發(fā)非GUI程序,比如控制臺(tái)工具和服務(wù)器。Qt是面向?qū)ο蟮目蚣?,使用特殊的代碼生成擴(kuò)展(稱為元對(duì)象編譯器(Meta Object Compiler, moc))以及一些宏,Qt很容易擴(kuò)展,并且允許真正地組件編程。Qt能輕松創(chuàng)建具有原生C++性能的連接設(shè)備、用戶界面(UI)和應(yīng)用程序。它功能強(qiáng)大且結(jié)構(gòu)緊湊,擁有直觀的工具和庫。
二、硬件選型
2.1 STM32F407系統(tǒng)板
鏈接:https://item.taobao.com/item.htm?spm=a21n57.1.item.6.3406523cr317ux&priceTId=213e38bb17188687576681904e683b&utparam=%7B%22aplus_abtest%22:%22781d5aaa75dd4af6ad2408d4a62768ea%22%7D&id=560814289385&ns=1&abbucket=12&skuId=4346181285287
2.2 杜邦線(2排)
作用: 連接模塊與單片機(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.3 SHT30溫濕度模塊
鏈接: https://detail.tmall.com/item.htm?abbucket=8&id=624272456739&ns=1&skuId=4420709624009&spm=a21n57.1.item.4.5097523cBtlCji
2.4 OLED顯示屏(4線IIC接口)
鏈接:https://item.taobao.com/item.htm?spm=a21n57.1.0.0.2ad7523cyZF6lC&id=43639171586&ns=1&abbucket=18#detail
2.5 MQ2 煙霧傳感器
鏈接:https://detail.tmall.com/item.htm?abbucket=5&id=17949567819&ns=1&spm=a21n57.1.0.0.242b523cwrRqcB&skuId=4078848750990
2.6 火焰檢測(cè)模塊
1、可以檢測(cè)火焰或者波長在760納米~1100納米范圍內(nèi)的光源,打火機(jī)測(cè)試火焰距離為80cm,對(duì)火焰越大,測(cè)試距離越遠(yuǎn)
2、探測(cè)角度60度左右,對(duì)火焰光譜特別靈敏3、靈敏度可調(diào)(圖中藍(lán)色數(shù)字電位器調(diào)節(jié))
4、比較器輸出,信號(hào)干凈,波形好,驅(qū)動(dòng)能力強(qiáng),超過15mA
5、配可調(diào)精密電位器調(diào)節(jié)靈敏度
6、工作電壓3.3V-5V
7、輸出形式:do數(shù)字開關(guān)量輸出(o和1)和ao模擬電壓輸出
鏈接:https://detail.tmall.com/item.htm?abbucket=12&id=41197526279&ns=1&spm=a230r.1.14.13.82631c79yq9mvA&skuId=3954176793928
2.7 電源擴(kuò)展接口(x2)
買電源擴(kuò)展板,方便擴(kuò)展5v電源 和 3.3V電源。
鏈接:https://item.taobao.com/item.htm?id=647681090119&skuId=4672158745999&spm=a1z0d.6639537/tb.1997196601.4.754374841n18eN
2.8 蜂鳴器模塊
鏈接: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.9 NBIOT模塊
鏈接:https://item.taobao.com/item.htm?abbucket=3&id=583282366803&ns=1&skuId=4749833023376&spm=a21n57.1.item.3.1ed9523cnUBQwb
三、部署華為云物聯(lián)網(wǎng)平臺(tái)
華為云官網(wǎng): https://www.huaweicloud.com/
打開官網(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)大的開放能力,支撐行業(yè)用戶構(gòu)建各種物聯(lián)網(wǎng)解決方案。
設(shè)備可以通過固網(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)用通過調(diào)用物聯(lián)網(wǎng)平臺(tái)提供的API,實(shí)現(xiàn)設(shè)備數(shù)據(jù)采集、命令下發(fā)、設(shè)備管理等業(yè)務(wù)場(chǎng)景。
3.2 開通物聯(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)擊實(shí)例名稱。 可以看到標(biāo)準(zhǔn)版實(shí)例的設(shè)備接入端口和地址。
在上面也能看到 免費(fèi)單元的限制。
開通之后,點(diǎn)擊總覽
,也能查看接入信息。 我們當(dāng)前設(shè)備準(zhǔn)備采用MQTT協(xié)議接入華為云平臺(tái),這里可以看到MQTT協(xié)議的地址和端口號(hào)等信息。
總結(jié):
端口號(hào): MQTT (1883)| MQTTS (8883)
接入地址:ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com
**根據(jù)域名地址得到IP地址信息: **
打開Windows電腦的命令行控制臺(tái)終端,使用ping
命令。ping
一下即可。
Microsoft Windows [版本 10.0.19045.4170]
(c) Microsoft Corporation。保留所有權(quán)利。
C:Users11266>ping ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com
正在 Ping ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com [117.78.5.125] 具有 32 字節(jié)的數(shù)據(jù):
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=35ms TTL=93
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=36ms TTL=93
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=36ms TTL=93
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=39ms TTL=93
117.78.5.125 的 Ping 統(tǒng)計(jì)信息:
數(shù)據(jù)包: 已發(fā)送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計(jì)時(shí)間(以毫秒為單位):
最短 = 35ms,最長 = 39ms,平均 = 36ms
C:Users11266>
MQTT協(xié)議接入端口號(hào)有兩個(gè),1883是非加密端口,8883是證書加密端口,單片機(jī)無法加載證書,所以使用1883端口比較合適。 接下來的ESP8266就采用1883端口連接華為云物聯(lián)網(wǎng)平臺(tái)。
3.3 創(chuàng)建產(chǎn)品
(1)創(chuàng)建產(chǎn)品
(2)填寫產(chǎn)品信息
根據(jù)自己產(chǎn)品名字填寫,下面的設(shè)備類型選擇自定義類型。
(3)產(chǎn)品創(chuàng)建成功
創(chuàng)建完成之后點(diǎn)擊查看詳情。
(4)添加自定義模型
產(chǎn)品創(chuàng)建完成之后,點(diǎn)擊進(jìn)入產(chǎn)品詳情頁面,翻到最下面可以看到模型定義。
模型簡單來說: 就是存放設(shè)備上傳到云平臺(tái)的數(shù)據(jù)。
你可以根據(jù)自己的產(chǎn)品進(jìn)行創(chuàng)建。
比如:
煙霧可以叫 MQ2
溫度可以叫 Temperature
濕度可以叫 humidity
火焰可以叫 flame
其他的傳感器自己用單詞簡寫命名即可。 這就是你的單片機(jī)設(shè)備端上傳到服務(wù)器的數(shù)據(jù)名字。
先點(diǎn)擊自定義模型。
再創(chuàng)建一個(gè)服務(wù)ID。
接著點(diǎn)擊新增屬性。
3.4 添加設(shè)備
產(chǎn)品是屬于上層的抽象模型,接下來在產(chǎn)品模型下添加實(shí)際的設(shè)備。添加的設(shè)備最終需要與真實(shí)的設(shè)備關(guān)聯(lián)在一起,完成數(shù)據(jù)交互。
(1)注冊(cè)設(shè)備
(2)根據(jù)自己的設(shè)備填寫
(3)保存設(shè)備信息
創(chuàng)建完畢之后,點(diǎn)擊保存并關(guān)閉,得到創(chuàng)建的設(shè)備密匙信息。該信息在后續(xù)生成MQTT三元組的時(shí)候需要使用。
(4)設(shè)備創(chuàng)建完成
(5)設(shè)備詳情
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是專門針對(duì)物聯(lián)網(wǎng)開發(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è)備上的客戶端,已經(jīng)形成了初步的生態(tài)系統(tǒng)。
MQTT是一種消息隊(duì)列協(xié)議,使用發(fā)布/訂閱消息模式,提供一對(duì)多的消息發(fā)布,解除應(yīng)用程序耦合,相對(duì)于其他協(xié)議,開發(fā)更簡單;MQTT協(xié)議是工作在TCP/IP協(xié)議上;由TCP/IP協(xié)議提供穩(wěn)定的網(wǎng)絡(luò)連接;所以,只要具備TCP協(xié)議棧的網(wǎng)絡(luò)設(shè)備都可以使用MQTT協(xié)議。 本次設(shè)備采用的ESP8266就具備TCP協(xié)議棧,能夠建立TCP連接,所以,配合STM32代碼里封裝的MQTT協(xié)議,就可以與華為云平臺(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ù) | 無限制 |
單個(gè)設(shè)備每分鐘支持的最大MQTT連接數(shù) | 1 |
單個(gè)MQTT連接每秒的吞吐量,即帶寬,包含直連設(shè)備和網(wǎng)關(guān) | 3KB/s |
MQTT單個(gè)發(fā)布消息最大長度,超過此大小的發(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ù) | 無限制 |
(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/663cb18871d845632a0912e7_dev1/sys/messages/down
(4)主題發(fā)布格式
對(duì)于設(shè)備來說,主題發(fā)布表示向云平臺(tái)上傳數(shù)據(jù),將最新的傳感器數(shù)據(jù),設(shè)備狀態(tài)上傳到云平臺(tái)。
這個(gè)操作稱為:屬性上報(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/663cb18871d845632a0912e7_dev1/sys/properties/report
發(fā)布主題時(shí),需要上傳數(shù)據(jù),這個(gè)數(shù)據(jù)格式是JSON格式。
上傳的JSON數(shù)據(jù)格式如下:
{
"services": [
{
"service_id": <填服務(wù)ID>,
"properties": {
"<填屬性名稱1>": <填屬性值>,
"<填屬性名稱2>": <填屬性值>,
..........
}
}
]
}
根據(jù)JSON格式,一次可以上傳多個(gè)屬性字段。 這個(gè)JSON格式里的,服務(wù)ID,屬性字段名稱,屬性值類型,在前面創(chuàng)建產(chǎn)品的時(shí)候就已經(jīng)介紹了,不記得可以翻到前面去查看。
根據(jù)這個(gè)格式,組合一次上傳的屬性數(shù)據(jù):
{"services": [{"service_id": "stm32","properties":{"DHT11_T":30,"DHT11_H":10,"BH1750":1,"MQ135":0}}]}
3.6 MQTT三元組
MQTT協(xié)議登錄需要填用戶ID,設(shè)備ID,設(shè)備密碼等信息,就像我們平時(shí)登錄QQ,微信一樣要輸入賬號(hào)密碼才能登錄。MQTT協(xié)議登錄的這3個(gè)參數(shù),一般稱為MQTT三元組。
接下來介紹,華為云平臺(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è)備支持填寫域名可以直接填域名,不支持就直接填寫IP地址。 (IP地址就是域名解析得到的)
華為云的MQTT服務(wù)器地址:117.78.5.125
華為云的MQTT端口號(hào):1883
如何得到IP地址?如何域名轉(zhuǎn)IP? 打開Windows的命令行輸入以下命令。
ping ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com
(2)生成MQTT三元組
華為云提供了一個(gè)在線工具,用來生成MQTT鑒權(quán)三元組: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/
打開這個(gè)工具,填入設(shè)備的信息(也就是剛才創(chuàng)建完設(shè)備之后保存的信息),點(diǎn)擊生成,就可以得到MQTT的登錄信息了。
下面是打開的頁面:
填入設(shè)備的信息: (上面兩行就是設(shè)備創(chuàng)建完成之后保存得到的)
直接得到三元組信息。
得到三元組之后,設(shè)備端通過MQTT協(xié)議登錄鑒權(quán)的時(shí)候,填入?yún)?shù)即可。
ClientId 663cb18871d845632a0912e7_dev1_0_0_2024050911
Username 663cb18871d845632a0912e7_dev1
Password 71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac237
3.7 模擬設(shè)備登錄測(cè)試
經(jīng)過上面的步驟介紹,已經(jīng)創(chuàng)建了產(chǎn)品,設(shè)備,數(shù)據(jù)模型,得到MQTT登錄信息。 接下來就用MQTT客戶端軟件模擬真實(shí)的設(shè)備來登錄平臺(tái)。測(cè)試與服務(wù)器通信是否正常。
(1)填入登錄信息
打開MQTT客戶端軟件,對(duì)號(hào)填入相關(guān)信息(就是上面的文本介紹)。然后,點(diǎn)擊登錄,訂閱主題,發(fā)布主題。
(2)打開網(wǎng)頁查看
完成上面的操作之后,打開華為云網(wǎng)頁后臺(tái),可以看到設(shè)備已經(jīng)在線了。
點(diǎn)擊詳情頁面,可以看到上傳的數(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): 183
//物聯(lián)網(wǎng)服務(wù)器的設(shè)備信息
#define MQTT_ClientID "663cb18871d845632a0912e7_dev1_0_0_2024050911"
#define MQTT_UserName "663cb18871d845632a0912e7_dev1"
#define MQTT_PassWord "71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac237"
//訂閱與發(fā)布的主題
#define SET_TOPIC "$oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down" //訂閱
#define POST_TOPIC "$oc/devices/663cb18871d845632a0912e7_dev1/sys/properties/report" //發(fā)布
發(fā)布的數(shù)據(jù):
{"services": [{"service_id": "stm32","properties":{"DHT11_T":30,"DHT11_H":10,"BH1750":1,"MQ135":0}}]}
3.8 創(chuàng)建IAM賬戶
創(chuàng)建一個(gè)IAM賬戶,因?yàn)榻酉聛黹_發(fā)上位機(jī),需要使用云平臺(tái)的API接口,這些接口都需要token進(jìn)行鑒權(quán)。簡單來說,就是身份的認(rèn)證。 調(diào)用接口獲取Token時(shí),就需要填寫IAM賬號(hào)信息。所以,接下來演示一下過程。
地址: https://console.huaweicloud.com/iam/?region=cn-north-4#/iam/users
**【1】獲取項(xiàng)目憑證 ** 點(diǎn)擊左上角用戶名,選擇下拉菜單里的我的憑證
項(xiàng)目憑證:
28add376c01e4a61ac8b621c714bf459
【2】創(chuàng)建IAM用戶
鼠標(biāo)放在左上角頭像上,在下拉菜單里選擇統(tǒng)一身份認(rèn)證
。
點(diǎn)擊左上角創(chuàng)建用戶
。
創(chuàng)建成功:
【3】創(chuàng)建完成
用戶信息如下:
主用戶名 l19504562721
IAM用戶 ds_abc
密碼 DS12345678
3.9 獲取影子數(shù)據(jù)
幫助文檔:https://support.huaweicloud.com/api-iothub/iot_06_v5_0079.html
設(shè)備影子介紹:
設(shè)備影子是一個(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ù)
無論該設(shè)備是否在線,都可以通過該影子獲取和設(shè)置設(shè)備的屬性
簡單來說:設(shè)備影子就是保存,設(shè)備最新上傳的一次數(shù)據(jù)。
我們?cè)O(shè)計(jì)的軟件里,如果想要獲取設(shè)備的最新狀態(tài)信息,就采用設(shè)備影子接口。
如果對(duì)接口不熟悉,可以先進(jìn)行在線調(diào)試:https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?product=IoTDA&api=ShowDeviceShadow
在線調(diào)試接口,可以請(qǐng)求影子接口,了解請(qǐng)求,與返回的數(shù)據(jù)格式。
調(diào)試完成看右下角的響應(yīng)體,就是返回的影子數(shù)據(jù)。
設(shè)備影子接口返回的數(shù)據(jù)如下:
{
"device_id": "663cb18871d845632a0912e7_dev1",
"shadow": [
{
"service_id": "stm32",
"desired": {
"properties": null,
"event_time": null
},
"reported": {
"properties": {
"DHT11_T": 18,
"DHT11_H": 90,
"BH1750": 38,
"MQ135": 70
},
"event_time": "20240509T113448Z"
},
"version": 3
}
]
}
調(diào)試成功之后,可以得到訪問影子數(shù)據(jù)的真實(shí)鏈接,接下來的代碼開發(fā)中,就采用Qt寫代碼訪問此鏈接,獲取影子數(shù)據(jù),完成上位機(jī)開發(fā)。
鏈接如下:
https://ad635970a1.st1.iotda-app.cn-north-4.myhuaweicloud.com:443/v5/iot/28add376c01e4a61ac8b621c714bf459/devices/663cb18871d845632a0912e7_dev1/shadow
四、STM32設(shè)備端代碼設(shè)計(jì)
4.1 BC26-NBIOT配置代碼
#include "ec20.h"
#include "stdlib.h"
#include "string.h"
#include "usart.h"
#include "iwdg.h"
int errcount = 0;
char atstr[BUFLEN];
char AtStrBuf[BUFLEN];
char *strx,*extstrx,*Readystrx;
extern char AtRxBuffer[512],Rxcouter;
char GPRMCSTR[128]; //轉(zhuǎn)載GPS信息 GPRMC 經(jīng)緯度存儲(chǔ)的字符串
char GPRMCSTRLON[64]; //經(jīng)度存儲(chǔ)字符串 也就是119.20694
char GPRMCSTRLAT[64]; //維度存儲(chǔ)字符串,也就是26.06451
char IMEINUMBER[64];//+CGSN: "869523052178994"
//下面是糾正火星坐標(biāo)的變量定義/
int Get_GPSdata(void);
void Getdata_Change(char status);
typedef struct
{
char UtcDate[6];
char longitude[11];//經(jīng)度原數(shù)據(jù)
char Latitude[10];//緯度源數(shù)據(jù)
char longitudess[4];//整數(shù)部分
char Latitudess[3];
char longitudedd[8];//小數(shù)點(diǎn)部分
char Latitudedd[8];
char Truelongitude[12];//轉(zhuǎn)換過數(shù)據(jù)
char TrueLatitude[11];//轉(zhuǎn)換過數(shù)據(jù)
char getstautus;//獲取到定位的標(biāo)志狀態(tài)
float gpsdata[2];
}LongLatidata;
LongLatidata latdata;
float tempdata[2];
char latStrAF[64]; //存放數(shù)據(jù)經(jīng)緯度用來發(fā)送
char lonStrAF[64]; //存放數(shù)據(jù)經(jīng)緯度用來顯示
//火星糾偏結(jié)束///
只要修改三要素/
#define PRODUCEKEY "6402ac07352830580e48ff7b_dev1_0_0_2023030403" //設(shè)備ID
#define DEVICENAME "6402ac07352830580e48ff7b_dev1" //用戶名
#define DEVICESECRET "517f1c8f18d6b7b2e4c134653dc892edd38c3e86153506df57f7c296d13b37f7" //密碼
void Clear_Buffer(void)//清空緩存
{
u8 i;
NBIOTSend_RecAccessMode();
printf(AtRxBuffer);
for(i=0;i<Rxcouter;i++)
AtRxBuffer[i]=0;//緩存
Rxcouter=0;
}
//初始化模塊
void NBIOT_Init(void)
{
Uart2_SendStr("ATrn");
delay_ms(500);
strx=strstr((const char*)AtRxBuffer,(const char*)"OK");//返回OK
errcount = 0;
while(strx==NULL)
{
errcount++;
printf("rn單片機(jī)正在連接到模塊...rn");
Clear_Buffer();
Uart2_SendStr("ATrn");
delay_ms(500);
strx=strstr((const char*)AtRxBuffer,(const char*)"OK");//返回OK
if(errcount>50) //防止死循環(huán)
{
errcount = 0;
reset_4g();
__set_FAULTMASK(1); //關(guān)閉總中斷
NVIC_SystemReset(); //請(qǐng)求單片機(jī)重啟
break;
}
}
Uart2_SendStr("ATE1rn"); //回顯
delay_ms(500);
Clear_Buffer();
/
Uart2_SendStr("AT+CPIN?rn");//檢查SIM卡是否在位
delay_ms(500);
strx=strstr((const char*)AtRxBuffer,(const char*)"+CPIN: READY");//查看是否返回ready
while(strx==NULL)
{
Clear_Buffer();
Uart2_SendStr("AT+CPIN?rn");
delay_ms(500);
strx=strstr((const char*)AtRxBuffer,(const char*)"+CPIN: READY");//檢查SIM卡是否在位,等待卡在位,如果卡識(shí)別不到,剩余的工作就沒法做了
}
Clear_Buffer();
///
Uart2_SendStr("AT+CSQrn"); //檢查CSQ
delay_ms(500);
Clear_Buffer();
Uart2_SendStr("ATIrn"); //檢查模塊的版本號(hào)
delay_ms(500);
Clear_Buffer();
///
Uart2_SendStr("AT+CREG?rn");//查看是否注冊(cè)GSM網(wǎng)絡(luò)
delay_ms(500);
Clear_Buffer();
Uart2_SendStr("AT+CEREG?rn");//查看注冊(cè)到哪個(gè)運(yùn)營商,支持移動(dòng) 聯(lián)通 電信
delay_ms(500);
Clear_Buffer();
Uart2_SendStr("AT+CIMIrn");//獲取卡號(hào),類似是否存在卡的意思,比較重要。
delay_ms(1000);
strx=strstr((const char*)AtRxBuffer,(const char*)"OK");//只要卡不錯(cuò)誤 基本就成功
if(strx)
{
printf("============rn我的卡號(hào)是 : %s rn===============rn",AtRxBuffer);
delay_ms(1000);
Clear_Buffer();
}
else
{
// printf("卡錯(cuò)誤 : %s rn",AtRxBuffer);
delay_ms(300);
Clear_Buffer();
}
Clear_Buffer();
Uart2_SendStr("AT+CGSNrn");//激活網(wǎng)絡(luò),PDP
delay_ms(300);
strx=strstr((const char*)AtRxBuffer,(const char*)"OK");//返OK
Clear_Buffer();
Uart2_SendStr("AT+CGATT?rn");//查詢激活狀態(tài)
delay_ms(300);
strx=strstr((const char*)AtRxBuffer,(const char*)"+CGATT: 1");//返1 表明激活成功 獲取到IP地址了
Clear_Buffer();
errcount = 0;
while(strx==NULL)
{
errcount++;
Clear_Buffer();
Uart2_SendStr("AT+CGATT?rn");//獲取激活狀態(tài)
delay_ms(300);
strx=strstr((const char*)AtRxBuffer,(const char*)"+CGATT: 1");//返回1,表明注網(wǎng)成功
if(errcount>100) //防止死循環(huán)
{
errcount = 0;
reset_4g();
__set_FAULTMASK(1); //關(guān)閉總中斷
NVIC_SystemReset(); //請(qǐng)求單片機(jī)重啟
break;
}
}
Uart2_SendStr("AT+QCCIDrn");//獲取當(dāng)前卡的IP地址
delay_ms(500);
Clear_Buffer();
}
void Start_GPS(void)
{
Clear_Buffer();
Uart2_SendStr("AT+QGPS=1rn");//查詢激活狀態(tài)
delay_ms(300);
strx=strstr((const char*)AtStrBuf,(const char*)"OK");//返1
if(strx==NULL)
{
//__set_FAULTMASK(1);
//NVIC_SystemReset(); //超時(shí)重啟
delay_ms(300);
}
Clear_Buffer();
}
//獲取定位數(shù)據(jù)/
/*
AT+QGPSGNMEA="RMC"
+QGPSGNMEA: $GNRMC,035645.00,A,2603.9111,N,11912.4140,E,0.336,,140821,,,A,V*19
OK
AT+QGPSGNMEA="RMC"
+QGPSGNMEA: $GPRMC,145620.00,A,2603.972207,N,11912.411739,E,0.0,0.0,171022,3.5,W,A*2F
*/
char *Get_GPS_RMC(char type)
{
Clear_Buffer();
memset(GPRMCSTR,0,128);
Uart2_SendStr("AT+QGPSGNMEA="RMC"rn");//查詢激活狀態(tài)
delay_ms(300);
strx=strstr((const char*)AtRxBuffer,(const char*)"$GPRMC");//返1
while(strx==NULL)
{
Clear_Buffer();
Uart2_SendStr("AT+QGPSGNMEA="RMC"rn");//獲取激活狀態(tài)
delay_ms(300);
strx=strstr((const char*)AtRxBuffer,(const char*)"$GPRMC");//返回1,表明注網(wǎng)成功
}
sprintf(GPRMCSTR,"%s",strx);
Clear_Buffer(); //打印收到的GPS信息
GPRMCSTR[2]= 'P';
//printf("============GETGPRMC==============rn%s",GPRMCSTR); //打印GPRMC
if(GPRMCSTR[17]=='A')
{
memset(latStrAF,0,64);
memset(lonStrAF,0,64);
Get_GPSdata();
if(type==1)
return latStrAF;
if(type==2)
return lonStrAF;
}
return 0;
}
/*****************************************************
下面是矯正火星坐標(biāo)的
*****************************************************/
//解GPS析函數(shù)
//$GPRMC,134952.00,A,2603.9576,N,11912.4098,E,0.154,,280821,,,A,V*18
int Get_GPSdata()
{
int i=0;
strx=strstr((const char*)GPRMCSTR,(const char*)"A,");//獲取緯度的位置
if(strx)
{
for(i=0;i<9;i++)
{
latdata.Latitude[i]=strx[i+2];//獲取緯度值2603.9576
}
strx=strstr((const char*)GPRMCSTR,(const char*)"N,");//獲取經(jīng)度值
if(strx)
{
for(i=0;i<10;i++) //獲取經(jīng)度 11912.4098
{
latdata.longitude[i]=strx[i+2];
}
}
printf("latdata.Latitude ,%s rn",latdata.Latitude);
printf("latdata.longitude ,%s rn",latdata.longitude);
latdata.getstautus=1;//
}
else
{
latdata.getstautus=0;
}
Getdata_Change(latdata.getstautus);//數(shù)據(jù)換算
Clear_Buffer();
return 0;
}
/*************解析出經(jīng)緯度數(shù)據(jù),然后直接提交數(shù)據(jù)*******************/
void Getdata_Change(char status)
{
unsigned char i;
if(status)
{
for(i=0;i<3;i++)
latdata.longitudess[i]=latdata.longitude[i];
for(i=3;i<10;i++)
latdata.longitudedd[i-3]=latdata.longitude[i];
latdata.gpsdata[0]=(latdata.longitudess[0]-0x30)*100+(latdata.longitudess[1]-0x30)*10+(latdata.longitudess[2]-0x30)
+((latdata.longitudedd[0]-0x30)*10+(latdata.longitudedd[1]-0x30)+(float)(latdata.longitudedd[3]-0x30)/10+
(float)(latdata.longitudedd[4]-0x30)/100+(float)(latdata.longitudedd[5]-0x30)/1000+(float)(latdata.longitudedd[6]-0x30)/10000)/60.0;//獲取完整的數(shù)據(jù)
///
for(i=0;i<2;i++)
latdata.Latitudess[i]=latdata.Latitude[i];
for(i=2;i<9;i++)
latdata.Latitudedd[i-2]=latdata.Latitude[i];
latdata.gpsdata[1]=(float)(latdata.Latitudess[0]-0x30)*10+(latdata.Latitudess[1]-0x30)
+((latdata.Latitudedd[0]-0x30)*10+(latdata.Latitudedd[1]-0x30)+(float)(latdata.Latitudedd[3]-0x30)/10+
(float)(latdata.Latitudedd[4]-0x30)/100+(float)(latdata.Latitudedd[5]-0x30)/1000+(float)(latdata.Latitudedd[6]-0x30)/10000)/60.0;//獲取完整的數(shù)據(jù)b
sprintf(latStrAF,"%f",latdata.gpsdata[1]);
sprintf(lonStrAF,"%f",latdata.gpsdata[0]);
printf("latStrAF,%s rn",latStrAF);
printf("lonStrAF,%s rn",lonStrAF);
}
else
{
latdata.gpsdata[0]=0;
latdata.gpsdata[1]=0;
}
}
/*****************************************************
糾偏結(jié)束
*****************************************************/
/*********************************************************************************
** 函數(shù)名稱 : MakeOnenetPayload(char *Str,u8 Temp,u8 Humi)
** 函數(shù)功能 : 將溫度與濕度封裝成Onenet有效載荷包
** 輸 入 : *str有效載荷保存的目標(biāo)字符串,
** 輸 入 : Temp 溫度值
** 輸 入 : Humi 濕度值
** 輸 出 : 有效載荷字符串
** 返 回 : 有效載荷字符串長度
*********************************************************************************/
char JsonBuf[256];//臨時(shí)數(shù)據(jù)緩存
u8 MakeOnenetPayload(u8 *Str,u8 Temp,u8 Humi)//將溫度與濕度封裝成Onenet有效載荷包
{
char Payload[] = "{"datastreams":[{"id":"Temp","datapoints":[{"value":%d}]},{"id":"Humi","datapoints":[{"value":%d}]}]}";//onenet有效載荷固定格式
unsigned short StrLen;//有效載荷數(shù)據(jù)長度
memset(JsonBuf,0,256);
sprintf(JsonBuf,Payload,Temp,Humi);//合成數(shù)據(jù)有效載荷封裝
//printf("rn有效載荷(%d):[%s]rn",strlen(JsonBuf),(char *)JsonBuf);
StrLen = strlen(JsonBuf)/sizeof(char);//計(jì)算有效載荷的數(shù)據(jù)長度
//printf("rn有效載荷長度(%d)rn",StrLen);
Str[0] = 'x01';//報(bào)文第一個(gè)字節(jié)的固定顯示
//printf("rnStr[0]=0X(%02X)rn",Str[0]);
//報(bào)文第2個(gè)字節(jié)和第三個(gè)字節(jié)表示有效載荷的長度的固定顯示
Str[1] = (StrLen & 0XFF00) >>8;//高位
//printf("rnStr[1]=0X(%02X)rn",Str[1]);
Str[2] = StrLen & 0XFF;//低位
//printf("rnStr[2]=0X(%02X)rn",Str[2]);
//拷貝有效載荷數(shù)據(jù)到Str
memcpy(Str+3,JsonBuf,StrLen);//從第三個(gè)字節(jié)開始拷貝
return (StrLen+3);//返回長度
}
u8 CSTX_4G_MQTT_Senddata(char *data)
{
u8 JsonLen;//Json包數(shù)據(jù)長度
memset(AtStrBuf,0,BUFLEN);
Clear_Buffer();
sprintf(AtStrBuf,"AT+QMTPUB=0,0,0,0,"$oc/devices/6402ac07352830580e48ff7b_dev1/sys/properties/report"rn");
// printf("ATSTR = %s rn",AtStrBuf);
Uart2_SendStr(AtStrBuf);//mqtt提交
delay_ms(300);
strx=strstr((const char*)AtRxBuffer,(const char*)">");//準(zhǔn)備發(fā)送數(shù)據(jù)
errcount=0;
while(strx==NULL)
{
errcount++;
strx=strstr((const char*)AtRxBuffer,(const char*)">");//準(zhǔn)備發(fā)送數(shù)據(jù) 模塊的反饋
delay_ms(30);
if(errcount>10) //超時(shí)退出
{
errcount = 0;
break;
}
}
Clear_Buffer();
USART2_Send((char *)data,strlen(data));//發(fā)送json數(shù)據(jù)
UART2_send_byte(0x1A);
delay_ms(300);
errcount=0;
strx=strstr((const char*)AtRxBuffer,(const char*)"+QMTPUB: 0,0,0");//返SEND OK +QMTPUB: 0,0,0
while(strx==NULL)
{
errcount++;
strx=strstr((const char*)AtRxBuffer,(const char*)"+QMTPUB: 0,0,0");//返SEND OK
delay_ms(30);
if(errcount>10) //超時(shí)退出
{
errcount = 0;
break;
}
}
Clear_Buffer();
return 0;
}
u8 MakeOnenetPayloadGPS(u8* Str,char *latstr,char * lonstr)//將溫度與濕度封裝成Onenet有效載荷包
{
char Payload[] = "{"datastreams":[{"id":"location","datapoints":[{"value":{"lon":%s,"lat":%s}}]}]}";//onenet有效載荷固定格式
unsigned short StrLen;//有效載荷數(shù)據(jù)長度
memset(JsonBuf,0,256);
sprintf(JsonBuf,Payload,lonstr,latstr);//合成數(shù)據(jù)有效載荷封裝
printf("JSONEND= %s rn",JsonBuf);
//printf("rn有效載荷(%d):[%s]rn",strlen(JsonBuf),(char *)JsonBuf);
StrLen = strlen(JsonBuf)/sizeof(char);//計(jì)算有效載荷的數(shù)據(jù)長度
//printf("rn有效載荷長度(%d)rn",StrLen);
Str[0] = 'x01';//報(bào)文第一個(gè)字節(jié)的固定顯示
//printf("rnStr[0]=0X(%02X)rn",Str[0]);
//報(bào)文第2個(gè)字節(jié)和第三個(gè)字節(jié)表示有效載荷的長度的固定顯示
Str[1] = (StrLen & 0XFF00) >>8;//高位
//printf("rnStr[1]=0X(%02X)rn",Str[1]);
Str[2] = StrLen & 0XFF;//低位
//printf("rnStr[2]=0X(%02X)rn",Str[2]);
//拷貝有效載荷數(shù)據(jù)到Str
memcpy(Str+3,JsonBuf,StrLen);//從第三個(gè)字節(jié)開始拷貝
return (StrLen+3);//返回長度
}
void CSTX_4G_ONENETIOTSenddataGPS(char *latstr,char *lonstr)//上發(fā)數(shù)據(jù),上發(fā)的數(shù)據(jù)跟對(duì)應(yīng)的插件有關(guān)系,用戶需要注意插件然后對(duì)應(yīng)數(shù)據(jù)即可
{
// int JsonLen= 0;
// memset(AtStrBuf,0,BUFLEN);
//
// Clear_Buffer(); //發(fā)送命令之前清空之前的模塊反饋的數(shù)據(jù)
// sprintf(AtStrBuf,"AT+QMTPUB=0,0,0,0,"$dp"rn"); //發(fā)送ONENET命令
// printf("AtStrBuf = %s rn",AtStrBuf);
// Uart2_SendStr(AtStrBuf);//mqtt提交
// delay_ms(300);
// strx=strstr((const char*)AtRxBuffer,(const char*)">");//模塊反饋可以發(fā)送數(shù)據(jù)了
// errcount=0;
// while(strx==NULL)
// {
// errcount++;
// strx=strstr((const char*)AtRxBuffer,(const char*)">");//模塊反饋可以發(fā)送數(shù)據(jù)了
// delay_ms(30);
// if(errcount>100) //防止死循環(huán)跳出
// {
// errcount = 0;
// break;
// }
// }
// //命令發(fā)送成功下面就去發(fā)送數(shù)據(jù)了
// //Clear_Buffer();
// JsonLen = MakeOnenetPayloadGPS((u8*)Send_Json,latstr,lonstr); //組建CJSON數(shù)據(jù)
// USART2_Send((char *)Send_Json,JsonLen);//發(fā)送json 數(shù)據(jù)
// delay_ms(10);
// UART2_send_byte(0x1A);
// strx=strstr((const char*)AtRxBuffer,(const char*)"+QMTPUB: 0,0,0");//返發(fā)送成功
// errcount=0;
// while(strx==NULL)
// {
// errcount++;
// strx=strstr((const char*)AtRxBuffer,(const char*)"+QMTPUB: 0,0,0");//返發(fā)送成功
// delay_ms(10);
// if(errcount>100) //超時(shí)退出死循環(huán) 表示服務(wù)器連接失敗
// {
// errcount = 0;
// break;
// }
// }
//
// Clear_Buffer();
}
4.2 定時(shí)器代碼封裝
#include "timer.h"
#include "led.h"
//通用定時(shí)器3中斷初始化
//arr:自動(dòng)重裝值。
//psc:時(shí)鐘預(yù)分頻數(shù)
//定時(shí)器溢出時(shí)間計(jì)算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定時(shí)器工作頻率,單位:Mhz
//這里使用的是定時(shí)器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能TIM3時(shí)鐘
TIM_TimeBaseInitStructure.TIM_Period = arr; //自動(dòng)重裝載值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定時(shí)器分頻
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上計(jì)數(shù)模式
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允許定時(shí)器3更新中斷
TIM_Cmd(TIM3,ENABLE); //使能定時(shí)器3
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定時(shí)器3中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //搶占優(yōu)先級(jí)1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子優(yōu)先級(jí)3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int tnk = 0;
int timeSend = 0;
//定時(shí)器3中斷服務(wù)函數(shù)
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中斷
{
LED1=!LED1;//DS1翻轉(zhuǎn)
tnk++;
if(tnk>10)
{
timeSend=1;
tnk = 0;
}
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中斷標(biāo)志位
}
4.3 串口配置代碼
#include "sys.h"
#include "usart.h"
u8 AtRxBuffer[512],Rxcouter;
//
//加入以下代碼,支持printf函數(shù),而不需要選擇use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//標(biāo)準(zhǔn)庫需要的支持函數(shù)
struct __FILE
{
int handle;
};
FILE __stdout;
//定義_sys_exit()以避免使用半主機(jī)模式
void _sys_exit(int x)
{
x = x;
}
//重定義fputc函數(shù)
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循環(huán)發(fā)送,直到發(fā)送完畢
USART1->DR = (u8) ch;
return ch;
}
#endif
#if EN_USART1_RX //如果使能了接收
//串口1中斷服務(wù)程序
//注意,讀取USARTx->SR能避免莫名其妙的錯(cuò)誤
u8 USART_RX_BUF[USART_REC_LEN]; //接收緩沖,最大USART_REC_LEN個(gè)字節(jié).
//接收狀態(tài)
//bit15, 接收完成標(biāo)志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字節(jié)數(shù)目
u16 USART_RX_STA=0; //接收狀態(tài)標(biāo)記
//初始化IO 串口1
//bound:波特率
void uart_init(u32 bound){
//GPIO端口設(shè)置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA時(shí)鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1時(shí)鐘
//串口1對(duì)應(yīng)引腳復(fù)用映射
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9復(fù)用為USART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10復(fù)用為USART1
//USART1端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9與GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//復(fù)用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽復(fù)用輸出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10
//USART1 初始化設(shè)置
USART_InitStructure.USART_BaudRate = bound;//波特率設(shè)置
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個(gè)停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗(yàn)位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發(fā)模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_Cmd(USART1, ENABLE); //使能串口1
USART_ClearFlag(USART1, USART_FLAG_TC);
#if EN_USART1_RX
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟相關(guān)中斷
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//搶占優(yōu)先級(jí)3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子優(yōu)先級(jí)3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據(jù)指定的參數(shù)初始化VIC寄存器、
#endif
}
void uart2_init(u32 bound)
{
//GPIO端口設(shè)置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA時(shí)鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2時(shí)鐘
//串口1對(duì)應(yīng)引腳復(fù)用映射
GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2); //GPIOA2復(fù)用為USART2
GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2); //GPIOA3復(fù)用為USART2
//USART1端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; //GPIOA2與GPIOA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//復(fù)用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽復(fù)用輸出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA2,PA3
//USART1 初始化設(shè)置
USART_InitStructure.USART_BaudRate = bound;//波特率設(shè)置
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個(gè)停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗(yàn)位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發(fā)模式
USART_Init(USART2, &USART_InitStructure); //初始化串口2
USART_Cmd(USART2, ENABLE); //使能串口2
USART_ClearFlag(USART2, USART_FLAG_TC);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//開啟相關(guān)中斷
//Usart2 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;//串口2中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//搶占優(yōu)先級(jí)1
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子優(yōu)先級(jí)3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據(jù)指定的參數(shù)初始化VIC寄存器、
}
//配置來對(duì)串口2波特率進(jìn)行修改 和模塊通信
void USART_Config(uint32_t baud)
{
USART_InitTypeDef USART_InitStructure;
USART_Cmd(USART2, DISABLE);
USART_InitStructure.USART_BaudRate =baud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
}
//串口1接收中斷
void USART1_IRQHandler(void) //串口1中斷服務(wù)程序
{
u8 Res;
Res=Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中斷
{
Res =USART_ReceiveData(USART1);//(USART1->DR); //讀取接收到的數(shù)據(jù)
}
}
//串口2的接收中斷函數(shù)
void USART2_IRQHandler(void) //串口2中斷服務(wù)程序
{
u8 Res;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中斷
{
Res =USART_ReceiveData(USART2);//(USART1->DR); //讀取接收到的數(shù)據(jù)
AtRxBuffer[Rxcouter++]=Res;//
}
}
void UART2_send_byte(char data)
{
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
USART_SendData(USART2, data);
}
/*-------------------------------------------------*/
/*函數(shù)名:串口2 發(fā)送數(shù)組 */
/*參 數(shù):bound:波特率 */
/*返回值:無 */
/*-------------------------------------------------*/
void USART2_Send(char *Data,uint16_t Len)
{
uint16_t i;
for(i=0; i<Len; i++)
{
UART2_send_byte(Data[i]);
}
}
//串口2的發(fā)送函數(shù)
void Uart2_SendStr(char*SendBuf) //串口2打印數(shù)據(jù)
{
while(*SendBuf)
{
while((USART2->SR&0X40)==0);//等待發(fā)送完成
USART2->DR = (u8) *SendBuf;
SendBuf++;
}
}
#endif
五、上位機(jī)開發(fā)
為了方便查看設(shè)備上傳的數(shù)據(jù),接下來利用Qt開發(fā)一款A(yù)ndroid手機(jī)APP 和 Windows上位機(jī)。
使用華為云平臺(tái)提供的API接口獲取設(shè)備上傳的數(shù)據(jù),進(jìn)行可視化顯示,以及遠(yuǎn)程控制設(shè)備。
5.1 Qt開發(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
打開下載鏈接后選擇下面的版本進(jìn)行下載:
qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details
軟件安裝時(shí)斷網(wǎng)安裝,否則會(huì)提示輸入賬戶。
安裝的時(shí)候,第一個(gè)復(fù)選框里勾選一個(gè)mingw 32
編譯器即可,其他的不管默認(rèn)就行,直接點(diǎn)擊下一步繼續(xù)安裝。
選擇MinGW 32-bit 編譯器: (一定要看清楚了)
說明: 我這里只是介紹PC端,也就是Windows系統(tǒng)下的Qt環(huán)境搭建。 Android的開發(fā)環(huán)境比較麻煩,如果想學(xué)習(xí)Android開發(fā),想編譯Android程序的APP,需要自己去搭建Android環(huán)境。
也可以看下面這篇文章,不過這個(gè)文章是在Qt開發(fā)專欄里付費(fèi)的,需要訂閱專欄才可以看。 如果不想付費(fèi)看,也可以自行找其他教程,自己搭建好必須的環(huán)境就行了
Android環(huán)境搭建的博客鏈接: https://blog.csdn.net/xiaolong1126626497/article/details/117254453
5.2 新建上位機(jī)工程
前面2講解了需要用的API接口,接下來就使用Qt設(shè)計(jì)上位機(jī),設(shè)計(jì)界面,完成整體上位機(jī)的邏輯設(shè)計(jì)。
【1】新建工程
【2】設(shè)置項(xiàng)目的名稱。
【3】選擇編譯系統(tǒng)
【4】選擇默認(rèn)繼承的類
【5】選擇編譯器
【6】點(diǎn)擊完成
【7】工程創(chuàng)建完成
5.3 設(shè)計(jì)UI界面與工程配置
【1】打開UI文件
打開默認(rèn)的界面如下:
【2】開始設(shè)計(jì)界面
根據(jù)自己需求設(shè)計(jì)界面。
5.5 編譯Windows上位機(jī)
點(diǎn)擊軟件左下角的綠色三角形按鈕進(jìn)行編譯運(yùn)行。
編譯之后的效果:
5.6 配置Android環(huán)境
如果想編譯Android手機(jī)APP,必須要先自己配置好自己的Android環(huán)境。(搭建環(huán)境的過程可以自行百度搜索學(xué)習(xí))
然后才可以進(jìn)行下面的步驟。
【1】選擇Android編譯器
【2】創(chuàng)建Android配置文件
創(chuàng)建完成。
【3】配置Android圖標(biāo)與名稱
【3】編譯Android上位機(jī)
Qt本身是跨平臺(tái)的,直接選擇Android的編譯器,就可以將程序編譯到Android平臺(tái)。
然后點(diǎn)擊構(gòu)建。
成功之后,在目錄下可以看到生成的apk
文件,也就是Android手機(jī)的安裝包,電腦端使用QQ
發(fā)送給手機(jī)QQ,手機(jī)登錄QQ接收,就能直接安裝。
生成的apk
的目錄在哪里呢? 編譯完成之后,在控制臺(tái)會(huì)輸出APK文件的路徑。
知道目錄在哪里之后,在Windows的文件資源管理器里,找到路徑,具體看下圖,找到生成的apk文件。
D:/linux-share-dir/QT/build-app_Huawei_Eco_tracking-Android_for_arm64_v8a_Clang_Qt_5_12_6_for_Android_ARM64_v8a-Release/android-build//build/outputs/apk/debug/android-build-debug.apk
六、 BC26-NBIOT模塊調(diào)試過程
6.1 模塊調(diào)試接線
6.2 測(cè)試模塊
第一步接上之后,串口調(diào)試助手選擇波特率為115200,勾選軟件上的發(fā)送新行選項(xiàng)。發(fā)送AT
過去,正常模塊會(huì)返回OK
。
只有收到了OK,才表示模塊工作正常。
6.3 上電初始化操作
【1】查詢模塊是否正常
AT
OK
【2】獲取卡號(hào),查詢卡是否插好
AT+CIMI
460041052911195
OK
【3】激活網(wǎng)絡(luò)
AT+CGATT=1
OK
【4】獲取網(wǎng)絡(luò)激活狀態(tài)
AT+CGATT?
+CGATT: 1
OK
【5】查詢網(wǎng)絡(luò)質(zhì)量
AT+CSQ
+CSQ: 26,0
OK
【6】 檢查網(wǎng)絡(luò)狀態(tài)
AT+CEREG=? //
+CEREG: 0,1 //找網(wǎng)成功
OK
6.4 開啟GPS定位
如果需要使用GPS定位就開,不需要使用就不用管。
使用GPS定位還需要將模塊上的GPS天線接好,否則也是沒有信號(hào)的。
官方文檔:
【1】激活GPS,要等一段時(shí)間
AT+QGNSSC=1
OK
【2】查詢激活狀態(tài),1表示成功激活
AT+QGNSSC?
+QGNSSC: 1
OK
【3】獲取一次GPS定位語句
AT+QGNSSRD="NMEA/RMC"
+QGNSSRD: $GNRMC,120715.00,A,3150.78179,N,11711.93433,E,0.000,,310818,,,A,V*19
OK
七、總結(jié)
基于STM32F407、NBIOT模塊BC26和華為云物聯(lián)網(wǎng)云平臺(tái)設(shè)計(jì)的環(huán)境檢測(cè)系統(tǒng)是一個(gè)集環(huán)境數(shù)據(jù)采集、本地顯示、遠(yuǎn)程監(jiān)控和預(yù)警功能于一體的綜合性系統(tǒng)。該系統(tǒng)通過STM32F407作為主控芯片,實(shí)現(xiàn)環(huán)境參數(shù)的采集與處理,包括使用SHT30傳感器進(jìn)行溫濕度檢測(cè),MQ2傳感器進(jìn)行煙霧濃度檢測(cè),以及火焰檢測(cè)傳感器進(jìn)行火光信息捕獲。采集到的數(shù)據(jù)不僅能在本地通過0.96寸IIC協(xié)議OLED顯示屏實(shí)時(shí)顯示,還能通過NBIOT模塊BC26實(shí)時(shí)上傳到華為云物聯(lián)網(wǎng)云平臺(tái),實(shí)現(xiàn)遠(yuǎn)程監(jiān)控和數(shù)據(jù)存儲(chǔ)。
當(dāng)系統(tǒng)檢測(cè)到環(huán)境中的煙霧濃度、溫度或火光超過預(yù)設(shè)的閾值時(shí),會(huì)立即觸發(fā)高電平觸發(fā)的有源蜂鳴器進(jìn)行聲光報(bào)警,以提醒用戶注意環(huán)境安全。這種實(shí)時(shí)預(yù)警功能大大增強(qiáng)了系統(tǒng)的實(shí)用性和安全性。
為了使用戶能夠方便地獲取環(huán)境檢測(cè)數(shù)據(jù)并進(jìn)行監(jiān)控,系統(tǒng)還開發(fā)了基于Qt(C++)的Android手機(jī)APP。該APP能夠從華為云物聯(lián)網(wǎng)云平臺(tái)獲取設(shè)備最新的數(shù)據(jù),并以直觀的方式展示給用戶,包括溫度、濕度、煙霧報(bào)警和火光報(bào)警等信息。用戶無需現(xiàn)場(chǎng)操作,即可通過手機(jī)APP隨時(shí)隨地了解環(huán)境狀況,極大地提高了系統(tǒng)的便捷性和靈活性。
該環(huán)境檢測(cè)系統(tǒng)通過整合先進(jìn)的硬件設(shè)備和軟件技術(shù),實(shí)現(xiàn)了環(huán)境參數(shù)的實(shí)時(shí)監(jiān)測(cè)、數(shù)據(jù)遠(yuǎn)程上傳和預(yù)警功能,為用戶提供了一個(gè)高效、便捷、安全的環(huán)境檢測(cè)解決方案。無論是在家庭、辦公室還是工業(yè)環(huán)境中,該系統(tǒng)都具有廣泛的應(yīng)用前景和實(shí)用價(jià)值。