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

基于STM32F407+NBIOT+華為云IOT平臺(tái)設(shè)計(jì)的環(huán)境檢測(cè)系統(tǒng)

12小時(shí)前
388
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

更多詳細(xì)資料請(qǐng)聯(lián)系.docx

共1個(gè)文件

基于STM32F407+NBIOT+華為云IOT平臺(tái)設(shè)計(jì)的環(huán)境檢測(cè)系統(tǒng)

實(shí)現(xiàn)的功能:
【1】能夠采集本地環(huán)境的溫度、濕度、煙霧濃度,火光信息,在OLED顯示屏上顯示。 如果檢測(cè)到煙霧、溫度、火光超過(guò)閥值會(huì)觸發(fā)蜂鳴器報(bào)警。
【2】能夠通過(guò)NBIOT將本地設(shè)備采集的信息上傳到華為云物聯(lián)網(wǎng)云平臺(tái)。
【3】通過(guò)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ā)展,越來(lái)越多的設(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è),并通過(guò)物聯(lián)網(wǎng)技術(shù)將數(shù)據(jù)傳輸至云端,為用戶提供便捷的數(shù)據(jù)查詢和遠(yuǎn)程監(jiān)控功能。

該系統(tǒng)的主要功能包括:

(1)采集本地環(huán)境的溫度、濕度、煙霧濃度和火光信息,并在OLED顯示屏上顯示。當(dāng)檢測(cè)到煙霧、溫度或火光超過(guò)預(yù)設(shè)閾值時(shí),觸發(fā)蜂鳴器報(bào)警,以提醒用戶采取相應(yīng)措施。

(2)通過(guò)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)警信息。

image-20240620155458202

image-20240620151926293

【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ù)通過(guò)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)度超過(guò)預(yù)設(shè)安全范圍時(shí),系統(tǒng)將自動(dòng)激活高電平觸發(fā)的有源蜂鳴器,發(fā)出報(bào)警聲,即時(shí)提醒現(xiàn)場(chǎng)人員注意潛在的環(huán)境危險(xiǎn)。

(4)NBIOT通信: 通過(guò)集成BC26 NBIOT模塊,系統(tǒng)能夠?qū)⒈镜夭杉沫h(huán)境數(shù)據(jù)通過(guò)窄帶物聯(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ù)管理和分析能力,支持用戶通過(guò)云端界面查看歷史數(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)警信息,使用戶無(wú)論身在何處都能及時(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ù)警,還通過(guò)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)境中的溫度和濕度,通過(guò)I2C接口與STM32F407通信,提供高精度的溫濕度數(shù)據(jù),是環(huán)境監(jiān)測(cè)的基礎(chǔ)組成部分。

(3)煙霧傳感器 - MQ2:

  • 用于檢測(cè)環(huán)境中煙霧濃度,能對(duì)多種氣體敏感,包括煙霧、LPG、甲烷等,通過(guò)模擬信號(hào)輸出至STM32F407,用于評(píng)估火災(zāi)風(fēng)險(xiǎn)。

(4)火光檢測(cè)傳感器:

  • 專門設(shè)計(jì)用于探測(cè)火焰或高強(qiáng)度光源,通過(guò)其光電效應(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ù)通過(guò)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)能耗,延長(zhǎng)電池續(xù)航或確保持續(xù)穩(wěn)定供電。

(7)蜂鳴器報(bào)警模塊:

  • 高電平觸發(fā)的有源蜂鳴器,當(dāng)STM32F407檢測(cè)到環(huán)境參數(shù)超過(guò)設(shè)定閾值時(shí),通過(guò)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í)采集。通過(guò)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)程訪問(wèn)、存儲(chǔ)與分析。此外,項(xiàng)目還開發(fā)了基于Qt框架的Android手機(jī)APP,方便用戶通過(guò)移動(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ù)通過(guò)BC26模組實(shí)現(xiàn)數(shù)據(jù)的遠(yuǎn)程傳輸,看重其在低功耗、廣覆蓋方面的優(yōu)勢(shì),特別適合于長(zhǎng)時(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ī)則,通過(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ì),提供簡(jiǎn)潔直觀的操作界面,讓用戶能夠隨時(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ī)制。
本地顯示 - 通過(guò)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ù)留接口,支持未來(lái)接入更多類型傳感器。
- 通信方式和技術(shù)框架易于升級(jí),以適應(yīng)技術(shù)發(fā)展和應(yīng)用需求變化。

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

【1】設(shè)備端開發(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ǔ)言開發(fā)。

開發(fā)工具選擇Keil,keil是一家世界領(lǐng)先的嵌入式微控制器軟件開發(fā)商,在2015年,keil被ARM公司收購(gòu)。因?yàn)楫?dāng)前芯片選擇的是STM32F103系列,STMF103是屬于ARM公司的芯片構(gòu)架、Cortex-M3內(nèi)核系列的芯片,所以使用Kile來(lái)開發(fā)STM32是有先天優(yōu)勢(shì)的,而keil在各大高校使用的也非常多,很多教科書里都是以keil來(lái)教學(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ā)。從軟件的使用上來(lái)講,IAR比keil更加簡(jiǎn)潔,功能相對(duì)少一些。如果之前使用過(guò)keil,而且使用頻率較多,已經(jīng)習(xí)慣再使用IAR是有點(diǎn)不適應(yīng)界面的。

【2】上位機(jī)開發(fā)

上位機(jī)的開發(fā)選擇Qt框架,編程語(yǔ)言采用C++;Qt是一個(gè)1991年由Qt Company開發(fā)的跨平臺(tái)C++圖形用戶界面應(yīng)用程序開發(fā)框架。它既可以開發(fā)GUI程序,也可用于開發(fā)非GUI程序,比如控制臺(tái)工具和服務(wù)器。Qt是面向?qū)ο蟮目蚣埽褂锰厥獾拇a生成擴(kuò)展(稱為元對(duì)象編譯器(Meta Object Compiler, moc))以及一些宏,Qt很容易擴(kuò)展,并且允許真正地組件編程。Qt能輕松創(chuàng)建具有原生C++性能的連接設(shè)備、用戶界面(UI)和應(yīng)用程序。它功能強(qiáng)大且結(jié)構(gòu)緊湊,擁有直觀的工具和庫(kù)。

image-20230218001243591

image-20230218001219105

二、硬件選型

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

image-20240620153303301

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

image-20231120103302046

2.3 SHT30溫濕度模塊

鏈接: https://detail.tmall.com/item.htm?abbucket=8&id=624272456739&ns=1&skuId=4420709624009&spm=a21n57.1.item.4.5097523cBtlCji

image-20240406155431203

img

2.4 OLED顯示屏(4線IIC接口)

鏈接:https://item.taobao.com/item.htm?spm=a21n57.1.0.0.2ad7523cyZF6lC&id=43639171586&ns=1&abbucket=18#detail

image-20231222104957425

2.5 MQ2 煙霧傳感器

鏈接:https://detail.tmall.com/item.htm?abbucket=5&id=17949567819&ns=1&spm=a21n57.1.0.0.242b523cwrRqcB&skuId=4078848750990

image-20231111145502643

2.6 火焰檢測(cè)模塊

1、可以檢測(cè)火焰或者波長(zhǎng)在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),超過(guò)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

image-20221210231044318

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

image-20240410095312092

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

image-20230226222801899

2.9 NBIOT模塊

鏈接:https://item.taobao.com/item.htm?abbucket=3&id=583282366803&ns=1&skuId=4749833023376&spm=a21n57.1.item.3.1ed9523cnUBQwb

image-20240428165331614

img

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

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

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

image-20221204193824815

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è)備可以通過(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)景。

img

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

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

image-20221204194233414

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

image-20240117134653452

正在創(chuàng)建標(biāo)準(zhǔn)版實(shí)例,需要等待片刻。

image-20240117134729401

創(chuàng)建完成之后,點(diǎn)擊實(shí)例名稱。 可以看到標(biāo)準(zhǔn)版實(shí)例的設(shè)備接入端口和地址。

image-20240425180759670

在上面也能看到 免費(fèi)單元的限制。

image-20240425180817704

開通之后,點(diǎn)擊總覽,也能查看接入信息。 我們當(dāng)前設(shè)備準(zhǔn)備采用MQTT協(xié)議接入華為云平臺(tái),這里可以看到MQTT協(xié)議的地址和端口號(hào)等信息。

image-20240425180845461

總結(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ù):
來(lái)自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=35ms TTL=93
來(lái)自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=36ms TTL=93
來(lái)自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=36ms TTL=93
來(lái)自 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,最長(zhǎng) = 39ms,平均 = 36ms

C:Users11266>

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

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

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

image-20230109164412041

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

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

image-20240612094809689

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

image-20240612095148945

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

image-20240612095134263

(4)添加自定義模型

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

模型簡(jiǎn)單來(lái)說(shuō): 就是存放設(shè)備上傳到云平臺(tái)的數(shù)據(jù)。

你可以根據(jù)自己的產(chǎn)品進(jìn)行創(chuàng)建。

比如:

煙霧可以叫  MQ2
溫度可以叫  Temperature
濕度可以叫  humidity
火焰可以叫  flame
其他的傳感器自己用單詞簡(jiǎn)寫命名即可。 這就是你的單片機(jī)設(shè)備端上傳到服務(wù)器的數(shù)據(jù)名字。

先點(diǎn)擊自定義模型。

image-20240612095517900

再創(chuàng)建一個(gè)服務(wù)ID。

image-20240612095542749

接著點(diǎn)擊新增屬性。

image-20240612095648815

image-20240612095711898

3.4 添加設(shè)備

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

(1)注冊(cè)設(shè)備

image-20240425181935561

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

image-20240612100115167

(3)保存設(shè)備信息

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

image-20240612100128061

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

image-20240612100147232

(5)設(shè)備詳情

image-20240612100202960

image-20240612100217236

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ā)更簡(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

img

業(yè)務(wù)流程:

img

(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

image-20221207153310037

對(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è)備來(lái)說(shuō),主題發(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

image-20221207153637391

根據(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三元組。

接下來(lái)介紹,華為云平臺(tái)的MQTT三元組參數(shù)如何得到。

(1)MQTT服務(wù)器地址

要登錄MQTT服務(wù)器,首先記得先知道服務(wù)器的地址是多少,端口是多少。

幫助文檔地址:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-portal/home

image-20240509193207359

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

image-20240425182610048

(2)生成MQTT三元組

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

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

下面是打開的頁(yè)面:

image-20240425183025893

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

直接得到三元組信息。

image-20240509193310020

得到三元組之后,設(shè)備端通過(guò)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)過(guò)上面的步驟介紹,已經(jīng)創(chuàng)建了產(chǎn)品,設(shè)備,數(shù)據(jù)模型,得到MQTT登錄信息。 接下來(lái)就用MQTT客戶端軟件模擬真實(shí)的設(shè)備來(lái)登錄平臺(tái)。測(cè)試與服務(wù)器通信是否正常。

(1)填入登錄信息

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

image-20240509193457358

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

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

image-20240612100508790

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

image-20240612100529581

到此,云平臺(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)榻酉聛?lái)開發(fā)上位機(jī),需要使用云平臺(tái)的API接口,這些接口都需要token進(jìn)行鑒權(quán)。簡(jiǎn)單來(lái)說(shuō),就是身份的認(rèn)證。 調(diào)用接口獲取Token時(shí),就需要填寫IAM賬號(hào)信息。所以,接下來(lái)演示一下過(guò)程。

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

**【1】獲取項(xiàng)目憑證 ** 點(diǎn)擊左上角用戶名,選擇下拉菜單里的我的憑證

image-20240509193646253

image-20240509193701262

項(xiàng)目憑證:

28add376c01e4a61ac8b621c714bf459

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

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

image-20240509193729078

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

image-20240509193744287

image-20240314153208692

image-20240314153228359

image-20240314153258229

創(chuàng)建成功:

image-20240314153315444

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

image-20240509193828289

用戶信息如下:

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

3.9 獲取影子數(shù)據(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è)備是否在線,都可以通過(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)行在線調(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ù)。

image-20240509194152229

設(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)試成功之后,可以得到訪問(wèn)影子數(shù)據(jù)的真實(shí)鏈接,接下來(lái)的代碼開發(fā)中,就采用Qt寫代碼訪問(wèn)此鏈接,獲取影子數(shù)據(jù),完成上位機(jī)開發(fā)。

image-20240509194214716

鏈接如下:

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)換過(guò)數(shù)據(jù)
char TrueLatitude[11];//轉(zhuǎn)換過(guò)數(shù)據(jù)
char getstautus;//獲取到定位的標(biāo)志狀態(tài)	
float gpsdata[2];
}LongLatidata;
LongLatidata latdata;

float tempdata[2];
char latStrAF[64];          //存放數(shù)據(jù)經(jīng)緯度用來(lái)發(fā)送
char lonStrAF[64];   				//存放數(shù)據(jù)經(jīng)緯度用來(lái)顯示
//火星糾偏結(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í)別不到,剩余的工作就沒(méi)法做了
    }
    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)營(yíng)商,支持移動(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 濕度值
** 輸    出	: 有效載荷字符串
** 返    回	: 有效載荷字符串長(zhǎng)度
*********************************************************************************/
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ù)長(zhǎng)度
	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ù)長(zhǎng)度
	//printf("rn有效載荷長(zhǎng)度(%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é)表示有效載荷的長(zhǎng)度的固定顯示
	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);//返回長(zhǎng)度
}

u8 CSTX_4G_MQTT_Senddata(char *data)
{	
	u8 JsonLen;//Json包數(shù)據(jù)長(zhǎng)度
	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ù)長(zhǎng)度
	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ù)長(zhǎng)度
	//printf("rn有效載荷長(zhǎng)度(%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é)表示有效載荷的長(zhǎng)度的固定顯示
	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);//返回長(zhǎng)度
}

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)庫(kù)需要的支持函數(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;//字長(zhǎng)為8位數(shù)據(jù)格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個(gè)停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;//無(wú)奇偶校驗(yàn)位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無(wú)硬件數(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;//字長(zhǎng)為8位數(shù)據(jù)格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個(gè)停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;//無(wú)奇偶校驗(yàn)位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無(wú)硬件數(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寄存器、


}
//配置來(lái)對(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:波特率                             */
/*返回值:無(wú)                                        */
/*-------------------------------------------------*/
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ù),接下來(lái)利用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/image-20221207160550486

image-20221207160606892

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ù)安裝。

image-20221203151742653

選擇MinGW 32-bit 編譯器: (一定要看清楚了)

image-20221203151750344

說(shuō)明: 我這里只是介紹PC端,也就是Windows系統(tǒng)下的Qt環(huán)境搭建。 Android的開發(fā)環(huán)境比較麻煩,如果想學(xué)習(xí)Android開發(fā),想編譯Android程序的APP,需要自己去搭建Android環(huán)境。

也可以看下面這篇文章,不過(guò)這個(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接口,接下來(lái)就使用Qt設(shè)計(jì)上位機(jī),設(shè)計(jì)界面,完成整體上位機(jī)的邏輯設(shè)計(jì)。

【1】新建工程

image-20240117144052547

【2】設(shè)置項(xiàng)目的名稱。

image-20240509195711965

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

image-20240117144239681

【4】選擇默認(rèn)繼承的類

image-20240117144302275

【5】選擇編譯器

image-20240314162137170

【6】點(diǎn)擊完成

image-20240117144354252

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

image-20230421094133333

5.3 設(shè)計(jì)UI界面與工程配置

【1】打開UI文件

image-20230421094815236

打開默認(rèn)的界面如下:

image-20240425194845233

【2】開始設(shè)計(jì)界面

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

image-20240620151816878

5.5 編譯Windows上位機(jī)

點(diǎn)擊軟件左下角的綠色三角形按鈕進(jìn)行編譯運(yùn)行。

image-20240509202031739

編譯之后的效果:

image-20240620151858925

5.6 配置Android環(huán)境

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

然后才可以進(jìn)行下面的步驟。

【1】選擇Android編譯器

image-20240425232651515

image-20240509202408776

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

image-20240117144604025

image-20240117144635052

image-20240117144652014

創(chuàng)建完成。

【3】配置Android圖標(biāo)與名稱

image-20240612100947190

【3】編譯Android上位機(jī)

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

然后點(diǎn)擊構(gòu)建。

image-20240509202534407

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

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

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

image-20240509202712295

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)試過(guò)程

6.1 模塊調(diào)試接線

image-20240511223245187

image-20240511223256788

image-20240511223308721

6.2 測(cè)試模塊

第一步接上之后,串口調(diào)試助手選擇波特率為115200,勾選軟件上的發(fā)送新行選項(xiàng)。發(fā)送AT過(guò)去,正常模塊會(huì)返回OK

只有收到了OK,才表示模塊工作正常。

image-20240511204301353

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天線接好,否則也是沒(méi)有信號(hào)的。

官方文檔:

image-20220220191400115

【1】激活GPS,要等一段時(shí)間
AT+QGNSSC=1

OK


【2】查詢激活狀態(tài),1表示成功激活
AT+QGNSSC?

+QGNSSC: 1

OK


【3】獲取一次GPS定位語(yǔ)句
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)通過(guò)STM32F407作為主控芯片,實(shí)現(xiàn)環(huán)境參數(shù)的采集與處理,包括使用SHT30傳感器進(jìn)行溫濕度檢測(cè),MQ2傳感器進(jìn)行煙霧濃度檢測(cè),以及火焰檢測(cè)傳感器進(jìn)行火光信息捕獲。采集到的數(shù)據(jù)不僅能在本地通過(guò)0.96寸IIC協(xié)議OLED顯示屏實(shí)時(shí)顯示,還能通過(guò)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)境中的煙霧濃度、溫度或火光超過(guò)預(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)警等信息。用戶無(wú)需現(xiàn)場(chǎng)操作,即可通過(guò)手機(jī)APP隨時(shí)隨地了解環(huán)境狀況,極大地提高了系統(tǒng)的便捷性和靈活性。

該環(huán)境檢測(cè)系統(tǒng)通過(guò)整合先進(jìn)的硬件設(shè)備和軟件技術(shù),實(shí)現(xiàn)了環(huán)境參數(shù)的實(shí)時(shí)監(jiān)測(cè)、數(shù)據(jù)遠(yuǎn)程上傳和預(yù)警功能,為用戶提供了一個(gè)高效、便捷、安全的環(huán)境檢測(cè)解決方案。無(wú)論是在家庭、辦公室還是工業(yè)環(huán)境中,該系統(tǒng)都具有廣泛的應(yīng)用前景和實(shí)用價(jià)值。

  • 更多詳細(xì)資料請(qǐng)聯(lián)系.docx
    下載
意法半導(dǎo)體

意法半導(dǎo)體

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

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

查看更多

相關(guān)推薦

方案定制

去合作
方案開發(fā)定制化,2000+方案商即時(shí)響應(yīng)!