一、前言
1.1 項(xiàng)目開發(fā)背景
在現(xiàn)代城市交通日益便捷的背景下,單車以其綠色環(huán)保、便于停放的優(yōu)點(diǎn)成為了人們短途出行的重要工具。然而,隨之而來的單車被盜問題也日益嚴(yán)重,尤其是在城市的公共區(qū)域或偏僻地帶,傳統(tǒng)的機(jī)械鎖缺乏智能化手段,一旦遭遇非法移動(dòng)或破壞,用戶很難第一時(shí)間獲知,從而造成財(cái)產(chǎn)損失。因此,設(shè)計(jì)一款具備智能化、聯(lián)網(wǎng)化、遠(yuǎn)程監(jiān)控能力的單車防盜鎖成為了當(dāng)前智能出行領(lǐng)域的一項(xiàng)實(shí)際需求。
隨著物聯(lián)網(wǎng)技術(shù)的快速發(fā)展,嵌入式系統(tǒng)與移動(dòng)通信技術(shù)的融合愈發(fā)緊密,為智能防盜系統(tǒng)的設(shè)計(jì)提供了可靠的技術(shù)支撐。STM32系列單片機(jī)具備處理能力強(qiáng)、資源豐富、低功耗等特點(diǎn),適合部署在需要實(shí)時(shí)響應(yīng)和長(zhǎng)期穩(wěn)定運(yùn)行的應(yīng)用場(chǎng)景中。而4G通信模塊則提供了在無WiFi環(huán)境下的高速網(wǎng)絡(luò)連接,尤其適用于戶外場(chǎng)景的單車設(shè)備,實(shí)現(xiàn)數(shù)據(jù)的遠(yuǎn)程上傳與控制。同時(shí),借助GPS模塊實(shí)現(xiàn)對(duì)車輛位置的精準(zhǔn)定位,使得車輛被盜后能快速追蹤,為用戶提供更強(qiáng)的安全保障。
為了提升用戶體驗(yàn),本項(xiàng)目還引入了OLED顯示屏用于本地狀態(tài)提示,蜂鳴器實(shí)現(xiàn)現(xiàn)場(chǎng)聲響報(bào)警,結(jié)合APP彈窗提醒與短信告警的多重通知方式,增強(qiáng)系統(tǒng)的實(shí)時(shí)性和可靠性。APP與上位機(jī)均采用MQTT協(xié)議接入華為云物聯(lián)網(wǎng)平臺(tái),實(shí)現(xiàn)多終端、跨平臺(tái)的數(shù)據(jù)共享與控制,提升系統(tǒng)智能化和可擴(kuò)展性。
因此,本項(xiàng)目“基于STM32設(shè)計(jì)的智能防盜單車鎖”不僅聚焦于實(shí)際生活中的防盜需求,也融合了當(dāng)下先進(jìn)的嵌入式控制、移動(dòng)通信和物聯(lián)網(wǎng)技術(shù),具有較強(qiáng)的應(yīng)用前景和推廣價(jià)值,能夠?yàn)橹悄芙煌I(lǐng)域提供一種可行的、低成本的智能安全解決方案。
1.2 設(shè)計(jì)實(shí)現(xiàn)的功能
(1)智能防盜報(bào)警功能
當(dāng)單車處于鎖車狀態(tài)時(shí),如果被非法移動(dòng),系統(tǒng)通過加速度傳感器檢測(cè)到位移后,立即觸發(fā)本地蜂鳴器發(fā)出聲響進(jìn)行報(bào)警。同時(shí)通過4G模塊向預(yù)設(shè)的手機(jī)號(hào)碼發(fā)送報(bào)警短信,并通過MQTT協(xié)議上傳報(bào)警信息至華為云物聯(lián)網(wǎng)平臺(tái),Android APP和Windows上位機(jī)將彈出提醒窗口,提示用戶單車被移動(dòng),增強(qiáng)安全性與及時(shí)性。
(2)遠(yuǎn)程監(jiān)控與控制功能
通過華為云IOT物聯(lián)網(wǎng)平臺(tái),用戶可以通過Android APP或Windows上位機(jī)查看設(shè)備當(dāng)前狀態(tài),包括鎖的開關(guān)狀態(tài)、報(bào)警狀態(tài)、GPS定位信息等。同時(shí),用戶還可以通過遠(yuǎn)程操作實(shí)現(xiàn)對(duì)鎖的開關(guān)控制,真正實(shí)現(xiàn)智能化的單車鎖管理。
(3)數(shù)據(jù)上云功能
系統(tǒng)通過Air724UG 4G模塊接入互聯(lián)網(wǎng),采用MQTT協(xié)議將鎖的開關(guān)狀態(tài)、GPS定位信息、報(bào)警狀態(tài)等數(shù)據(jù)實(shí)時(shí)上傳至華為云IOT平臺(tái),支持多終端訪問和實(shí)時(shí)數(shù)據(jù)監(jiān)控,提升系統(tǒng)的可靠性與管理便捷性。
(4)短信告警功能
設(shè)備具備短信發(fā)送能力,借助Air724UG模塊內(nèi)置的短信功能,一旦發(fā)生非法移動(dòng)事件,除上傳云端外,還會(huì)同步發(fā)送短信至預(yù)設(shè)用戶手機(jī),確保即使在無網(wǎng)絡(luò)狀態(tài)下也能接收警報(bào)信息。
(5)GPS實(shí)時(shí)定位功能
采用ATGM336H-5N GPS模塊,實(shí)時(shí)獲取當(dāng)前設(shè)備地理位置,并通過4G模塊上傳至云平臺(tái),用戶可在APP或上位機(jī)地圖界面上查看車輛位置,為車輛防盜追蹤提供支持。
(6)本地OLED信息顯示功能
設(shè)備配備0.96寸SPI OLED顯示屏,可實(shí)時(shí)顯示鎖的當(dāng)前狀態(tài)(如“已鎖定”“已解鎖”)、GPS信號(hào)狀態(tài)等關(guān)鍵信息,方便用戶通過屏幕快速掌握設(shè)備運(yùn)行狀態(tài)。
(7)蜂鳴器本地聲響報(bào)警功能
當(dāng)系統(tǒng)判斷存在異常移動(dòng)時(shí),立即驅(qū)動(dòng)高電平觸發(fā)的有源蜂鳴器發(fā)出聲響,具備現(xiàn)場(chǎng)即時(shí)報(bào)警功能,威懾潛在盜竊行為。
(8)低功耗與可擴(kuò)展供電功能
設(shè)備主供電采用14500鋰電池,滿足低功耗便攜應(yīng)用需求,同時(shí)預(yù)留太陽能供電擴(kuò)展接口,支持在戶外環(huán)境下的長(zhǎng)時(shí)間無人值守運(yùn)行。
(9)跨平臺(tái)APP與上位機(jī)控制界面
Android手機(jī)APP和Windows上位機(jī)軟件均采用QT5(C++)開發(fā),界面統(tǒng)一、美觀,支持多平臺(tái)查看設(shè)備狀態(tài)、接收?qǐng)?bào)警提醒和控制操作,提高用戶使用體驗(yàn)與系統(tǒng)通用性。
1.3 項(xiàng)目硬件模塊組成
(1)STM32F103RCT6主控模塊
作為系統(tǒng)核心控制單元,負(fù)責(zé)處理各類傳感器數(shù)據(jù)、控制執(zhí)行模塊、通信管理、數(shù)據(jù)上傳及本地信息顯示等任務(wù),所有邏輯控制與功能實(shí)現(xiàn)均基于該芯片完成。
(2)Air724UG 4G通信模塊
用于實(shí)現(xiàn)設(shè)備與華為云物聯(lián)網(wǎng)平臺(tái)的遠(yuǎn)程通信,支持MQTT協(xié)議進(jìn)行數(shù)據(jù)上云,同時(shí)集成短信功能,能在單車被移動(dòng)時(shí)向用戶發(fā)送短信報(bào)警信息。
(3)ATGM336H-5N GPS定位模塊
用于實(shí)時(shí)獲取設(shè)備的地理位置信息,采集經(jīng)緯度數(shù)據(jù),通過STM32上傳至云平臺(tái),實(shí)現(xiàn)遠(yuǎn)程地圖定位及軌跡追蹤功能。
(4)ADXL345三軸加速度傳感器模塊
用于監(jiān)測(cè)車輛在鎖車狀態(tài)下是否發(fā)生移動(dòng),通過檢測(cè)姿態(tài)變化判斷是否觸發(fā)防盜報(bào)警邏輯,是實(shí)現(xiàn)智能防盜的關(guān)鍵傳感器模塊。
(5)0.96寸SPI OLED顯示模塊
用于顯示鎖的當(dāng)前狀態(tài)、GPS模塊狀態(tài)、網(wǎng)絡(luò)連接情況等信息,為用戶提供直觀的本地交互界面,提升使用便捷性與信息透明度。
(6)高電平觸發(fā)有源蜂鳴器模塊
在檢測(cè)到非法移動(dòng)時(shí)由STM32驅(qū)動(dòng)發(fā)出高分貝聲響,起到警示與威懾作用,是本地聲響報(bào)警的執(zhí)行裝置。
(7)鋰電池供電模塊(14500鋰電池)
為整套系統(tǒng)提供便攜式供電,支持長(zhǎng)時(shí)間戶外運(yùn)行,同時(shí)預(yù)留接口,可外接太陽能板,實(shí)現(xiàn)綠色能源補(bǔ)充與連續(xù)運(yùn)行保障。
(8)硬件連接模塊(洞洞板+杜邦線/焊接)
整套硬件系統(tǒng)搭建于洞洞板(萬能板)上,模塊之間通過杜邦線或焊接方式連接,方便原型搭建、系統(tǒng)調(diào)試與后期維護(hù),是硬件搭建的基礎(chǔ)平臺(tái)。
(9)調(diào)試與串口通信模塊
包含用于程序燒錄的串口接口、電源控制接口及串口調(diào)試接口,用于開發(fā)過程中進(jìn)行程序下載、數(shù)據(jù)監(jiān)測(cè)及調(diào)試信息輸出,保障開發(fā)效率與系統(tǒng)穩(wěn)定性。
1.4 設(shè)計(jì)思路
本項(xiàng)目設(shè)計(jì)并實(shí)現(xiàn)一款基于STM32的智能防盜單車鎖系統(tǒng),結(jié)合物聯(lián)網(wǎng)技術(shù)實(shí)現(xiàn)遠(yuǎn)程監(jiān)控、報(bào)警提醒和狀態(tài)管理。設(shè)計(jì)思路以“本地智能識(shí)別+遠(yuǎn)程數(shù)據(jù)聯(lián)動(dòng)”為核心,融合硬件控制、無線通信和云平臺(tái)服務(wù),實(shí)現(xiàn)一套既具備本地防護(hù)能力又支持遠(yuǎn)程操作的智能防盜方案。
系統(tǒng)整體架構(gòu)分為三個(gè)層級(jí):感知層、控制層和應(yīng)用層。感知層由GPS定位模塊、加速度傳感器和蜂鳴器組成,負(fù)責(zé)實(shí)時(shí)監(jiān)測(cè)車輛位置信息和狀態(tài)變化(如是否被非法移動(dòng)),并在異常情況發(fā)生時(shí)立即觸發(fā)報(bào)警機(jī)制。控制層以STM32F103RCT6為核心主控,通過寄存器方式開發(fā),負(fù)責(zé)數(shù)據(jù)采集、邏輯判斷、指令執(zhí)行和與通信模塊的數(shù)據(jù)交互。應(yīng)用層通過4G通信模塊(Air724UG)連接華為云IOT平臺(tái),采用MQTT協(xié)議進(jìn)行消息通信,支持將鎖的狀態(tài)、位置等數(shù)據(jù)上傳至云端,并接收遠(yuǎn)程下發(fā)的開鎖/關(guān)鎖等控制指令。
在用戶交互方面,系統(tǒng)配備一塊0.96寸SPI OLED顯示屏,顯示當(dāng)前鎖狀態(tài)和GPS工作狀態(tài),方便用戶在現(xiàn)場(chǎng)了解設(shè)備運(yùn)行情況。同時(shí),為滿足用戶遠(yuǎn)程監(jiān)控需求,設(shè)計(jì)了基于QT5的Android手機(jī)APP和Windows上位機(jī)應(yīng)用,實(shí)現(xiàn)遠(yuǎn)程查看鎖狀態(tài)、地圖定位、歷史記錄查詢、短信提醒等功能,并支持一鍵遠(yuǎn)程開關(guān)鎖。
為了適應(yīng)單車戶外運(yùn)行環(huán)境,系統(tǒng)采用14500鋰電池供電,并預(yù)留太陽能供電接口,實(shí)現(xiàn)綠色續(xù)航與長(zhǎng)時(shí)間運(yùn)行能力。硬件集成部分基于洞洞板搭建,采用模塊化設(shè)計(jì)思想,便于后期調(diào)試與硬件維護(hù)。整體設(shè)計(jì)在滿足安全性和實(shí)用性的基礎(chǔ)上,兼顧了低功耗、可擴(kuò)展性與用戶操作便利性,體現(xiàn)出物聯(lián)網(wǎng)在個(gè)人交通工具智能化保護(hù)方面的應(yīng)用前景。
1.5 系統(tǒng)功能總結(jié)
功能類別 | 功能描述 |
防盜報(bào)警功能 | 當(dāng)車輛在鎖車狀態(tài)下發(fā)生移動(dòng)時(shí),系統(tǒng)通過加速度傳感器檢測(cè)異常,觸發(fā)蜂鳴器發(fā)出聲響,同時(shí)通過4G模塊發(fā)送短信提醒并在APP上彈窗報(bào)警。 |
遠(yuǎn)程控制功能 | 用戶可通過Android手機(jī)APP或Windows上位機(jī),遠(yuǎn)程實(shí)現(xiàn)對(duì)單車鎖的開鎖、關(guān)鎖控制,提升用戶操作的便捷性與靈活性。 |
數(shù)據(jù)上云功能 | 設(shè)備通過Air724UG 4G模塊接入華為云IOT平臺(tái),使用MQTT協(xié)議將鎖狀態(tài)、定位信息等實(shí)時(shí)數(shù)據(jù)上傳至云端,實(shí)現(xiàn)遠(yuǎn)程監(jiān)控與數(shù)據(jù)記錄。 |
GPS定位功能 | 內(nèi)置GPS模塊可實(shí)時(shí)獲取設(shè)備位置信息,并上傳至云端用于地圖顯示、軌跡跟蹤、遠(yuǎn)程查詢等,增強(qiáng)車輛追蹤能力。 |
本地顯示功能 | OLED顯示屏可本地顯示鎖狀態(tài)、GPS模塊狀態(tài)、網(wǎng)絡(luò)連接情況等運(yùn)行信息,方便用戶在現(xiàn)場(chǎng)查看設(shè)備當(dāng)前狀態(tài)。 |
本地報(bào)警功能 | 內(nèi)置蜂鳴器在車輛被非法移動(dòng)時(shí)自動(dòng)發(fā)出高分貝報(bào)警音,對(duì)潛在盜竊行為進(jìn)行震懾和提醒。 |
電源管理功能 | 系統(tǒng)采用14500鋰電池供電,支持便攜式低功耗運(yùn)行,并預(yù)留太陽能供電接口,適應(yīng)戶外環(huán)境下長(zhǎng)時(shí)間運(yùn)行的需求。 |
姿態(tài)檢測(cè)功能 | 通過ADXL345加速度傳感器監(jiān)測(cè)車輛姿態(tài)變化,用于判斷是否處于被移動(dòng)狀態(tài),為防盜報(bào)警功能提供關(guān)鍵判斷依據(jù)。 |
用戶交互功能 | 用戶通過APP或上位機(jī)可視化界面與系統(tǒng)交互,查看鎖狀態(tài)、定位信息、報(bào)警記錄,接收通知并進(jìn)行控制,提升用戶體驗(yàn)與系統(tǒng)智能化程度。 |
1.6 模塊的技術(shù)詳情介紹
【1】Air724UG-4G模塊
Air724UG 是一款功能強(qiáng)大的 4G 全網(wǎng)通通信模塊,廣泛應(yīng)用于物聯(lián)網(wǎng)設(shè)備中,特別適用于對(duì)數(shù)據(jù)通信、短信發(fā)送和遠(yuǎn)程控制有較高要求的嵌入式系統(tǒng)。該模塊支持中國移動(dòng)、中國聯(lián)通和中國電信的 LTE 網(wǎng)絡(luò),具備良好的網(wǎng)絡(luò)兼容性和覆蓋能力,特別適合部署在戶外、流動(dòng)性強(qiáng)或無WiFi覆蓋的場(chǎng)景中,如智能車鎖、共享設(shè)備、遠(yuǎn)程監(jiān)控等。
Air724UG 模塊內(nèi)部集成了高性能的處理器,支持 AT 指令集,具備串口通信接口(UART),可方便地與 STM32 等主控芯片進(jìn)行通信。模塊支持 MQTT、TCP、HTTP等多種協(xié)議,特別是在本項(xiàng)目中,Air724UG 可用于將設(shè)備狀態(tài)、GPS位置信息等通過 MQTT 協(xié)議上傳至華為云物聯(lián)網(wǎng)平臺(tái),實(shí)現(xiàn)數(shù)據(jù)上云與遠(yuǎn)程管理。
除了數(shù)據(jù)通信功能外,Air724UG 還支持 SMS(短消息服務(wù))功能,可通過 AT 指令實(shí)現(xiàn)短信的發(fā)送與接收。在智能防盜單車鎖項(xiàng)目中,當(dāng)檢測(cè)到車輛被非法移動(dòng)時(shí),模塊能夠快速向預(yù)設(shè)聯(lián)系人發(fā)送報(bào)警短信,提高用戶的安全響應(yīng)效率。
在供電與功耗方面,Air724UG 支持低功耗待機(jī)模式,適合依賴鋰電池供電的應(yīng)用場(chǎng)景。同時(shí),其體積小巧、接口標(biāo)準(zhǔn)化,方便集成到各類嵌入式設(shè)備中。此外,模塊還具備掉線自動(dòng)重連、網(wǎng)絡(luò)狀態(tài)檢測(cè)等功能,提高通信的穩(wěn)定性和可靠性。
Air724UG 作為核心通信部件,在本項(xiàng)目中起到了“云-端”之間橋梁的關(guān)鍵作用,是實(shí)現(xiàn)智能控制、遠(yuǎn)程監(jiān)控和移動(dòng)報(bào)警的重要技術(shù)基礎(chǔ)。
【2】MQTT協(xié)議
MQTT(Message Queuing Telemetry Transport,消息隊(duì)列遙測(cè)傳輸協(xié)議)是一種輕量級(jí)、發(fā)布/訂閱模式的消息傳輸協(xié)議,專為低帶寬、不可靠網(wǎng)絡(luò)環(huán)境設(shè)計(jì)。它最早由IBM提出,現(xiàn)已成為物聯(lián)網(wǎng)(IoT)通信的重要協(xié)議之一。由于其高效、低功耗和實(shí)時(shí)性等特點(diǎn),MQTT在智能家居、工業(yè)自動(dòng)化、遠(yuǎn)程監(jiān)控和車聯(lián)網(wǎng)等領(lǐng)域得到了廣泛應(yīng)用。
MQTT的工作原理基于發(fā)布/訂閱模型。這種模型有別于傳統(tǒng)的客戶端-服務(wù)器模型,通信方不需要直接建立連接。MQTT由三個(gè)核心組件構(gòu)成:客戶端、代理(Broker)和主題(Topic)??蛻舳丝梢宰鳛橄⒌陌l(fā)布者或訂閱者,消息通過代理進(jìn)行路由。代理是一個(gè)中間服務(wù)端,用于接收和分發(fā)來自不同客戶端的消息。發(fā)布者發(fā)送消息到一個(gè)特定的主題上,代理負(fù)責(zé)將這些消息分發(fā)給所有訂閱了該主題的客戶端。通過這種解耦的架構(gòu)設(shè)計(jì),客戶端之間可以實(shí)現(xiàn)松耦合的通信,降低了復(fù)雜性和依賴性。
在MQTT協(xié)議中,消息被分為不同的主題(Topic),例如“home/sensor/temperature”可以用來代表溫度傳感器數(shù)據(jù)。客戶端可以訂閱這個(gè)主題,當(dāng)發(fā)布者發(fā)送新的數(shù)據(jù)到該主題時(shí),所有訂閱該主題的客戶端都會(huì)收到更新信息。這種靈活的主題結(jié)構(gòu)和層次化的命名規(guī)則,使得MQTT在復(fù)雜場(chǎng)景下也能快速組織和管理消息流。
MQTT協(xié)議支持三種服務(wù)質(zhì)量(QoS)等級(jí),分別為“至多一次”(QoS 0)、“至少一次”(QoS 1)和“僅一次”(QoS 2)。QoS 0表示消息傳輸盡力而為,可能會(huì)丟失或重復(fù);QoS 1確保消息至少送達(dá)一次,但可能會(huì)有重復(fù);QoS 2則確保消息恰好傳輸一次,保證消息的嚴(yán)格可靠性。這種設(shè)計(jì)使MQTT能夠適應(yīng)不同的應(yīng)用場(chǎng)景,用戶可以根據(jù)應(yīng)用需求選擇合適的QoS級(jí)別。
為了保證通信的安全性,MQTT支持用戶名和密碼驗(yàn)證,代理可以對(duì)連接進(jìn)行身份認(rèn)證。此外,許多實(shí)現(xiàn)中還支持TLS/SSL加密通信,確保數(shù)據(jù)在傳輸過程中不會(huì)被竊取或篡改。用戶也可以使用不同的認(rèn)證方式來增強(qiáng)系統(tǒng)的安全性,適應(yīng)物聯(lián)網(wǎng)應(yīng)用中對(duì)安全性的高需求。
MQTT非常注重輕量化和低功耗。它的報(bào)文頭非常小,通信開銷很低,這使其特別適合在資源受限的設(shè)備或不穩(wěn)定的網(wǎng)絡(luò)環(huán)境中使用。MQTT支持“保持連接”和“遺囑消息”功能,客戶端可以在連接斷開時(shí)自動(dòng)向代理發(fā)送遺囑消息,通知其他客戶端連接狀態(tài)的變化。這種特性有助于提高網(wǎng)絡(luò)的健壯性和系統(tǒng)的可用性。
MQTT的典型使用場(chǎng)景包括物聯(lián)網(wǎng)設(shè)備數(shù)據(jù)采集、實(shí)時(shí)監(jiān)控、消息推送和控制命令的發(fā)布。比如在智能家居中,傳感器可以發(fā)布環(huán)境數(shù)據(jù),如溫濕度、煙霧濃度等,控制設(shè)備根據(jù)收到的消息作出響應(yīng),實(shí)現(xiàn)自動(dòng)化操作。在工業(yè)場(chǎng)景中,MQTT可以幫助收集和管理大規(guī)模設(shè)備的運(yùn)行狀態(tài),實(shí)現(xiàn)集中化和高效的設(shè)備監(jiān)控。
總的來說,MQTT協(xié)議憑借其低功耗、高效能、實(shí)時(shí)性強(qiáng)等優(yōu)勢(shì),已成為物聯(lián)網(wǎng)通信的主要協(xié)議之一。它的發(fā)布/訂閱模式簡(jiǎn)化了設(shè)備之間的通信,使其特別適合多對(duì)多、低延遲、高可靠性的數(shù)據(jù)傳輸場(chǎng)景。MQTT易于使用、拓展性強(qiáng),為開發(fā)者提供了靈活的解決方案來構(gòu)建各種物聯(lián)網(wǎng)應(yīng)用。
【3】中科微ATGM336H-GPS模塊
中科微ATGM336H-GPS模塊是一款高性能、低功耗的全球定位模塊,專為衛(wèi)星定位導(dǎo)航應(yīng)用設(shè)計(jì)。該模塊集成了GNSS基帶處理器和RF接收器,支持GPS、GLONASS、BDS(北斗)等多種衛(wèi)星系統(tǒng)的定位信號(hào),能夠?qū)崿F(xiàn)快速精準(zhǔn)的定位,并提供穩(wěn)定可靠的位置、速度和時(shí)間數(shù)據(jù)。ATGM336H模塊廣泛應(yīng)用于車輛定位、物流跟蹤、無人機(jī)導(dǎo)航、智能穿戴設(shè)備、戶外運(yùn)動(dòng)設(shè)備和物聯(lián)網(wǎng)等領(lǐng)域。
ATGM336H模塊采用小巧的LCC封裝,尺寸為16mm x 12.2mm x 2.3mm,便于集成到各種緊湊型設(shè)備中。模塊內(nèi)置高靈敏度接收芯片,具有-165dBm的高靈敏度,即使在復(fù)雜環(huán)境下也能快速捕獲和跟蹤衛(wèi)星信號(hào)。其冷啟動(dòng)時(shí)間在開闊地帶一般小于30秒,熱啟動(dòng)時(shí)間約為1秒,重捕獲時(shí)間小于1秒,使其在車輛移動(dòng)和各種快速切換的場(chǎng)景下表現(xiàn)出色,定位精度可達(dá)2.5米。
該模塊支持多種工作模式,以滿足不同應(yīng)用的功耗要求。它不僅可以在普通模式下連續(xù)定位,還支持周期性模式和節(jié)電模式,通過關(guān)閉部分功能或降低數(shù)據(jù)輸出頻率來減少功耗,適合電池供電的便攜式設(shè)備。其最低功耗在微安級(jí)別,能夠顯著延長(zhǎng)電池續(xù)航時(shí)間,使其成為移動(dòng)設(shè)備的理想選擇。
ATGM336H-GPS模塊的接口豐富,支持UART、I2C、SPI等多種通信接口,方便與主控MCU進(jìn)行數(shù)據(jù)交換。模塊提供的標(biāo)準(zhǔn)NMEA協(xié)議輸出和二進(jìn)制格式數(shù)據(jù)能夠直接對(duì)接多種導(dǎo)航應(yīng)用程序。此外,模塊還具有內(nèi)置的天線檢測(cè)功能和動(dòng)態(tài)干擾抑制技術(shù),有助于在有較強(qiáng)電磁干擾的環(huán)境中保持定位精度,并能實(shí)時(shí)檢測(cè)和報(bào)告天線狀態(tài),進(jìn)一步提高定位可靠性。
為了提高用戶體驗(yàn)和簡(jiǎn)化開發(fā)過程,中科微為ATGM336H模塊提供了完善的開發(fā)手冊(cè)和技術(shù)支持,便于開發(fā)者快速上手并將其應(yīng)用到多種設(shè)備中。此外,模塊還支持多衛(wèi)星系統(tǒng)協(xié)同定位的功能,通過融合GPS、BDS、GLONASS等衛(wèi)星數(shù)據(jù),提高在市區(qū)、高山、森林等衛(wèi)星信號(hào)受限環(huán)境下的定位精度和穩(wěn)定性,使其適用于復(fù)雜環(huán)境的高精度定位需求。
二、硬件選型(搭建模型參考)
2.1 STM32開發(fā)板
2.2 USB下載線
2.3 Air724UG 4G模塊
2.4 繼電器
2.5 蜂鳴器模塊
2.6 ADXL345 三軸加速度計(jì)模塊
2.7 OLED顯示屏
三、部署華為云物聯(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
開通免費(fèi)單元。
點(diǎn)擊立即創(chuàng)建
。
正在創(chuàng)建標(biāo)準(zhǔn)版實(shí)例,需要等待片刻。
創(chuàng)建完成之后,點(diǎn)擊詳情。 可以看到標(biāo)準(zhǔn)版實(shí)例的設(shè)備接入端口和地址。
下面框起來的就是端口號(hào)
和域名
點(diǎn)擊實(shí)例名稱,可以查看當(dāng)前免費(fèi)單元
的配置情況。
開通之后,點(diǎn)擊接入信息
,也能查看接入信息。 我們當(dāng)前設(shè)備準(zhǔn)備采用MQTT協(xié)議接入華為云平臺(tái),這里可以看到MQTT協(xié)議的地址和端口號(hào)等信息。
總結(jié):
端口號(hào): ? MQTT (1883)| MQTTS (8883) ? ?
接入地址: dab1a1f2c6.st1.iotda-device.cn-north-4.myhuaweicloud.com
根據(jù)域名地址得到IP地址信息:
打開Windows電腦的命令行控制臺(tái)終端,使用ping
?命令。ping
一下即可。
Microsoft Windows [版本 10.0.19045.5011]
(c) Microsoft Corporation。保留所有權(quán)利。
C:UsersLenovo>ping dab1a1f2c6.st1.iotda-device.cn-north-4.myhuaweicloud.com
正在 Ping dab1a1f2c6.st1.iotda-device.cn-north-4.myhuaweicloud.com [117.78.5.125] 具有 32 字節(jié)的數(shù)據(jù):
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=37ms TTL=44
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=37ms TTL=44
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=37ms TTL=44
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=37ms TTL=44
117.78.5.125 的 Ping 統(tǒng)計(jì)信息:
? ? 數(shù)據(jù)包: 已發(fā)送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計(jì)時(shí)間(以毫秒為單位):
? ? 最短 = 37ms,最長(zhǎng) = 37ms,平均 = 37ms
C:UsersLenovo>
MQTT協(xié)議接入端口號(hào)有兩個(gè),1883是非加密端口,8883是證書加密端口,單片機(jī)無法加載證書,所以使用1883端口合適
。
3.3 創(chuàng)建產(chǎn)品
鏈接:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-dev/all-product?instanceId=03c5c68c-e588-458c-90c3-9e4c640be7af
(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)品詳情頁面,翻到最下面可以看到模型定義。
模型簡(jiǎn)單來說: 就是存放設(shè)備上傳到云平臺(tái)的數(shù)據(jù)。
你可以根據(jù)自己的產(chǎn)品進(jìn)行創(chuàng)建。
比如:
鎖可以叫 ? ?LOCK? ? ? (整數(shù))
定位可以叫 ?GPS? ? ? ? ?(字符串)
報(bào)警可以叫 ?BEEP? ? ? ? ?(整數(shù))
其他的傳感器自己用單詞簡(jiǎn)寫命名即可。 這就是你的單片機(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ā)更簡(jiǎn)單;MQTT協(xié)議是工作在TCP/IP協(xié)議上;由TCP/IP協(xié)議提供穩(wěn)定的網(wǎng)絡(luò)連接;所以,只要具備TCP協(xié)議棧的網(wǎng)絡(luò)設(shè)備都可以使用MQTT協(xié)議。 本次設(shè)備采用的ESP8266就具備TCP協(xié)議棧,能夠建立TCP連接,所以,配合STM32代碼里封裝的MQTT協(xié)議,就可以與華為云平臺(tái)完成通信。
華為云的MQTT協(xié)議接入幫助文檔在這里: https://support.huaweicloud.com/devg-iothub/iot_02_2200.html
業(yè)務(wù)流程:
(2)華為云平臺(tái)MQTT協(xié)議使用限制
描述 | 限制 |
支持的MQTT協(xié)議版本 | 3.1.1 |
與標(biāo)準(zhǔn)MQTT協(xié)議的區(qū)別 | 支持Qos 0和Qos 1支持Topic自定義不支持QoS2不支持will、retain msg |
MQTTS支持的安全等級(jí) | 采用TCP通道基礎(chǔ) + TLS協(xié)議(最高TLSv1.3版本) |
單帳號(hào)每秒最大MQTT連接請(qǐng)求數(shù) | 無限制 |
單個(gè)設(shè)備每分鐘支持的最大MQTT連接數(shù) | 1 |
單個(gè)MQTT連接每秒的吞吐量,即帶寬,包含直連設(shè)備和網(wǎng)關(guān) | 3KB/s |
MQTT單個(gè)發(fā)布消息最大長(zhǎng)度,超過此大小的發(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":{"你的字段名字1":30,"你的字段名字2":10,"你的字段名字3":1,"你的字段名字4":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ù)器通信是否正常。
MQTT軟件下載地址【免費(fèi)】:?https://download.csdn.net/download/xiaolong1126626497/89928772
(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":{"你的字段名字1":30,"你的字段名字2":10,"你的字段名字3":1,"你的字段名字4":0}}]}
3.8 創(chuàng)建IAM賬戶
創(chuàng)建一個(gè)IAM賬戶,因?yàn)榻酉聛黹_發(fā)上位機(jī),需要使用云平臺(tái)的API接口,這些接口都需要token進(jìn)行鑒權(quán)。簡(jiǎ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è)備的屬性
簡(jiǎn)單來說:設(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
3.10 訪問接口的代碼實(shí)現(xiàn)
(1)配置 Qt 項(xiàng)目
在 Qt 項(xiàng)目的?.pro
?文件中,加入對(duì)?libcurl
?的支持:
QT += core
CONFIG += console
CONFIG -= app_bundle
INCLUDEPATH += /usr/include/curl ?# 根據(jù)你的系統(tǒng)設(shè)置 libcurl 的路徑
LIBS += -lcurl ?# 鏈接 libcurl 庫
SOURCES += main.cpp
(2)代碼實(shí)現(xiàn)
main.cpp
?文件中實(shí)現(xiàn)代碼如下:
#include?<QCoreApplication>
#include?<curl/curl.h>
#include?<QDebug>
#include?<QString>
#include?<QByteArray>
// 回調(diào)函數(shù),處理libcurl下載數(shù)據(jù)
size_t?WriteCallback(void?*contents,?size_t?size,?size_t?nmemb,?void?*userp)?{
? ??size_t?totalSize = size * nmemb;
? ? QByteArray *response =?static_cast<QByteArray *>(userp);
? ? response->append(static_cast<char?*>(contents), totalSize);
? ??return?totalSize;
}
int?main(int?argc,?char?*argv[])?{
? ??QCoreApplication?a(argc, argv);
? ??// 初始化libcurl
? ? CURL *curl;
? ? CURLcode res;
? ? QByteArray responseData; ?// 用于存儲(chǔ)響應(yīng)數(shù)據(jù)
? ??curl_global_init(CURL_GLOBAL_DEFAULT);
? ? curl =?curl_easy_init();
? ??if?(curl) {
? ? ? ??// 設(shè)置訪問URL
? ? ? ??const?QString url =?"https://ad635970a1.st1.iotda-app.cn-north-4.myhuaweicloud.com:443/v5/iot/28add376c01e4a61ac8b621c714bf459/devices/663cb18871d845632a0912e7_dev1/shadow";
? ? ? ??// 設(shè)置HTTP請(qǐng)求頭
? ? ? ??struct?curl_slist?*headers =?NULL;
? ? ? ? headers =?curl_slist_append(headers,?"Authorization: Bearer <Your_Access_Token>");?// 這里需要替換為你的實(shí)際 token
? ? ? ??curl_easy_setopt(curl, CURLOPT_URL, url.toStdString().c_str());
? ? ? ??curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
? ? ? ??curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
? ? ? ??curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);
? ? ? ??// 發(fā)起GET請(qǐng)求
? ? ? ? res =?curl_easy_perform(curl);
? ? ? ??if?(res != CURLE_OK) {
? ? ? ? ? ??qDebug() <<?"Curl request failed:"?<<?curl_easy_strerror(res);
? ? ? ? }?else?{
? ? ? ? ? ??qDebug() <<?"Response data:"?<< responseData;
? ? ? ? }
? ? ? ??// 清理
? ? ? ??curl_easy_cleanup(curl);
? ? ? ??curl_slist_free_all(headers);
? ? }
? ??curl_global_cleanup();
? ??return?a.exec();
}
3.11 數(shù)據(jù)解析代碼
在 Qt 中使用 CJSON (一個(gè)用于解析 JSON 數(shù)據(jù)的輕量級(jí) C 庫) 來解析返回的 JSON 數(shù)據(jù)。
(1)配置 Qt 項(xiàng)目
在 Qt 項(xiàng)目的?.pro
?文件中,確保包括了 CJSON 的頭文件,并鏈接 CJSON 的源代碼。
QT += core
CONFIG += console
CONFIG -= app_bundle
SOURCES += main.cpp
? ? ? ? ? ?cJSON.c ?# 將 cJSON.c 文件添加到你的項(xiàng)目中
INCLUDEPATH += path/to/cjson/ ?# 添加 CJSON 頭文件的路徑
LIBS += -lcurl ?# 鏈接 libcurl 庫
(2)解析 JSON 數(shù)據(jù)的完整代碼
在?main.cpp
?中,以下代碼展示了如何解析你提供的 JSON 數(shù)據(jù)。
#include?<QCoreApplication>
#include?<curl/curl.h>
#include?<QDebug>
#include?<QString>
#include?<QByteArray>
#include?"cJSON.h"
// 回調(diào)函數(shù),處理libcurl下載數(shù)據(jù)
size_t?WriteCallback(void?*contents,?size_t?size,?size_t?nmemb,?void?*userp)?{
? ??size_t?totalSize = size * nmemb;
? ? QByteArray *response =?static_cast<QByteArray *>(userp);
? ? response->append(static_cast<char?*>(contents), totalSize);
? ??return?totalSize;
}
// 解析 JSON 數(shù)據(jù)
void?parseJson(const?QByteArray &data)?{
? ??// 將 QByteArray 轉(zhuǎn)換為 char*
? ??const?char* jsonData = data.constData();
? ??// 解析 JSON
? ? cJSON *root =?cJSON_Parse(jsonData);
? ??if?(root ==?NULL) {
? ? ? ??qDebug() <<?"Error parsing JSON.";
? ? ? ??return;
? ? }
? ??// 解析 "device_id"
? ? cJSON *deviceId =?cJSON_GetObjectItemCaseSensitive(root,?"device_id");
? ??if?(cJSON_IsString(deviceId) && (deviceId->valuestring !=?NULL)) {
? ? ? ??qDebug() <<?"Device ID:"?<< deviceId->valuestring;
? ? }
? ??// 解析 "shadow" 數(shù)組
? ? cJSON *shadow =?cJSON_GetObjectItemCaseSensitive(root,?"shadow");
? ??if?(cJSON_IsArray(shadow)) {
? ? ? ? cJSON *shadowItem =?NULL;
? ? ? ??cJSON_ArrayForEach(shadowItem, shadow) {
? ? ? ? ? ??// 解析每個(gè) shadow 項(xiàng)目
? ? ? ? ? ? cJSON *serviceId =?cJSON_GetObjectItemCaseSensitive(shadowItem,?"service_id");
? ? ? ? ? ??if?(cJSON_IsString(serviceId) && (serviceId->valuestring !=?NULL)) {
? ? ? ? ? ? ? ??qDebug() <<?"Service ID:"?<< serviceId->valuestring;
? ? ? ? ? ? }
? ? ? ? ? ??// 解析 "reported" 對(duì)象
? ? ? ? ? ? cJSON *reported =?cJSON_GetObjectItemCaseSensitive(shadowItem,?"reported");
? ? ? ? ? ??if?(cJSON_IsObject(reported)) {
? ? ? ? ? ? ? ??// 解析 "properties" 對(duì)象
? ? ? ? ? ? ? ? cJSON *properties =?cJSON_GetObjectItemCaseSensitive(reported,?"properties");
? ? ? ? ? ? ? ??if?(cJSON_IsObject(properties)) {
? ? ? ? ? ? ? ? ? ? cJSON *data1 =?cJSON_GetObjectItemCaseSensitive(properties,?"data1");
? ? ? ? ? ? ? ? ? ??if?(cJSON_IsNumber(data1)) {
? ? ? ? ? ? ? ? ? ? ? ??qDebug() <<?"data1:"?<< data1->valueint;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? cJSON *data2 =?cJSON_GetObjectItemCaseSensitive(properties,?"data2");
? ? ? ? ? ? ? ? ? ??if?(cJSON_IsNumber(data2)) {
? ? ? ? ? ? ? ? ? ? ? ??qDebug() <<?"data2:"?<< data2->valueint;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? cJSON *data3 =?cJSON_GetObjectItemCaseSensitive(properties,?"data3");
? ? ? ? ? ? ? ? ? ??if?(cJSON_IsNumber(data3)) {
? ? ? ? ? ? ? ? ? ? ? ??qDebug() <<?"data3:"?<< data3->valueint;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? cJSON *data4 =?cJSON_GetObjectItemCaseSensitive(properties,?"data4");
? ? ? ? ? ? ? ? ? ??if?(cJSON_IsNumber(data4)) {
? ? ? ? ? ? ? ? ? ? ? ??qDebug() <<?"data4:"?<< data4->valueint;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ??// 解析 "event_time"
? ? ? ? ? ? ? ? cJSON *eventTime =?cJSON_GetObjectItemCaseSensitive(reported,?"event_time");
? ? ? ? ? ? ? ??if?(cJSON_IsString(eventTime) && (eventTime->valuestring !=?NULL)) {
? ? ? ? ? ? ? ? ? ??qDebug() <<?"Event Time:"?<< eventTime->valuestring;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ??// 解析 version
? ? ? ? ? ? cJSON *version =?cJSON_GetObjectItemCaseSensitive(shadowItem,?"version");
? ? ? ? ? ??if?(cJSON_IsNumber(version)) {
? ? ? ? ? ? ? ??qDebug() <<?"Version:"?<< version->valueint;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ??// 釋放 JSON 對(duì)象
? ??cJSON_Delete(root);
}
int?main(int?argc,?char?*argv[])?{
? ??QCoreApplication?a(argc, argv);
? ??// 模擬獲取到的 JSON 數(shù)據(jù)
? ? QByteArray jsonData =?R"(
? ? {
? ? ? ? "device_id": "663cb18871d845632a0912e7_dev1",
? ? ? ? "shadow": [
? ? ? ? ? ? {
? ? ? ? ? ? ? ? "service_id": "stm32",
? ? ? ? ? ? ? ? "desired": {
? ? ? ? ? ? ? ? ? ? "properties": null,
? ? ? ? ? ? ? ? ? ? "event_time": null
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? "reported": {
? ? ? ? ? ? ? ? ? ? "properties": {
? ? ? ? ? ? ? ? ? ? ? ? "data1": 18,
? ? ? ? ? ? ? ? ? ? ? ? "data2": 90,
? ? ? ? ? ? ? ? ? ? ? ? "data3": 38,
? ? ? ? ? ? ? ? ? ? ? ? "data4": 70
? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? "event_time": "20240509T113448Z"
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? "version": 3
? ? ? ? ? ? }
? ? ? ? ]
? ? })";
? ??// 調(diào)用解析函數(shù)
? ??parseJson(jsonData);
? ??return?a.exec();
}
四、STM32設(shè)備端代碼設(shè)計(jì)
以下是該項(xiàng)目的?main.c
?完整代碼以及整體代碼的設(shè)計(jì)思路。涵蓋了4G通信、短信報(bào)警、GPS定位、蜂鳴器報(bào)警、姿態(tài)檢測(cè)、OLED顯示等功能。
4.1 整體代碼設(shè)計(jì)思路
系統(tǒng)的主控芯片為 STM32F103RCT6,采用寄存器方式進(jìn)行編程。整體設(shè)計(jì)分為以下幾個(gè)模塊,代碼通過主函數(shù)進(jìn)行初始化和任務(wù)調(diào)度:
-
- 1.
系統(tǒng)初始化階段
-
- :
-
- ? 時(shí)鐘系統(tǒng)初始化(使用 HSE)? 串口初始化(用于與 Air724UG 4G 模塊、GPS 模塊通信)? OLED 顯示初始化? 加速度傳感器 ADXL345 初始化(通過 I2C)? 蜂鳴器 GPIO 初始化? 相關(guān)中斷使能(如串口接收中斷)
-
2.?主循環(huán)任務(wù)調(diào)度階段:
-
-
- ? 循環(huán)讀取 ADXL345 判斷是否發(fā)生車輛移動(dòng)? 如果發(fā)生移動(dòng),觸發(fā)本地蜂鳴器報(bào)警,并調(diào)用4G模塊發(fā)送短信? 獲取 GPS 位置信息并通過 MQTT 上傳至云平臺(tái)? 實(shí)時(shí)更新鎖狀態(tài)和GPS信息到 OLED 屏幕? 接收上位機(jī)或APP發(fā)來的遠(yuǎn)程開鎖/關(guān)鎖指令并控制鎖狀態(tài)
-
3.?中斷服務(wù)程序:
-
- ? 串口接收中斷,處理4G模塊和GPS模塊返回的數(shù)據(jù)? 定時(shí)器或輪詢機(jī)制定時(shí)上傳狀態(tài)信息至云端
4.2 main.c 完整示例代碼
#include?"stm32f10x.h"
#include?"oled.h"
#include?"usart.h"
#include?"adxl345.h"
#include?"gps.h"
#include?"delay.h"
#include?"buzzer.h"
#include?"mqtt.h"
#include?"lock.h"
#include?"string.h"
// 全局狀態(tài)變量
uint8_t?bike_locked =?1;
uint8_t?movement_detected =?0;
char?gps_data[100];
char?lock_status[10];
// 主函數(shù)
int?main(void)
{
? ??// 基礎(chǔ)外設(shè)初始化
? ? SystemInit();
? ? delay_init();
? ? USART1_Init(9600); ??// 用于GPS
? ? USART2_Init(115200);?// 用于Air724UG模塊
? ? OLED_Init();
? ? ADXL345_Init();
? ? BUZZER_Init();
? ? LOCK_Init();
? ? OLED_ShowString(0,?0,?"Smart Bike Lock");
? ? delay_ms(1000);
? ? OLED_Clear();
? ??// MQTT初始化
? ? MQTT_Init();
? ??while?(1)
? ? {
? ? ? ??// 姿態(tài)檢測(cè)模塊讀取
? ? ? ??if?(ADXL345_DetectMovement())
? ? ? ? {
? ? ? ? ? ? movement_detected =?1;
? ? ? ? }
? ? ? ??// 如果處于鎖車狀態(tài)并且檢測(cè)到移動(dòng)
? ? ? ??if?(bike_locked && movement_detected)
? ? ? ? {
? ? ? ? ? ? BUZZER_On();
? ? ? ? ? ? OLED_ShowString(0,?0,?"ALARM: Movement!");
? ? ? ? ? ? Send_SMS("警告:?jiǎn)诬嚤环欠ㄒ苿?dòng)!");
? ? ? ? ? ? MQTT_Publish_Alert("bike/move",?"Bike Moved!");
? ? ? ? ? ? movement_detected =?0;
? ? ? ? ? ? delay_ms(5000);
? ? ? ? ? ? BUZZER_Off();
? ? ? ? ? ? OLED_Clear();
? ? ? ? }
? ? ? ??// 獲取GPS信息并上傳
? ? ? ? GPS_GetLocation(gps_data);
? ? ? ? MQTT_Publish("bike/gps", gps_data);
? ? ? ? OLED_ShowString(0,?2,?"GPS:");
? ? ? ? OLED_ShowString(0,?3, gps_data);
? ? ? ??// 更新鎖狀態(tài)顯示
? ? ? ??strcpy(lock_status, bike_locked ??"Locked"?:?"Unlocked");
? ? ? ? OLED_ShowString(0,?5,?"Lock:");
? ? ? ? OLED_ShowString(36,?5, lock_status);
? ? ? ? MQTT_Publish("bike/status", lock_status);
? ? ? ??// 處理遠(yuǎn)程開鎖指令(模擬)
? ? ? ??if?(MQTT_Received_Unlock())
? ? ? ? {
? ? ? ? ? ? bike_locked =?0;
? ? ? ? ? ? LOCK_Unlock();
? ? ? ? ? ? OLED_ShowString(0,?6,?"Unlock by remote");
? ? ? ? }
? ? ? ??// 處理遠(yuǎn)程關(guān)鎖指令
? ? ? ??if?(MQTT_Received_Lock())
? ? ? ? {
? ? ? ? ? ? bike_locked =?1;
? ? ? ? ? ? LOCK_Lock();
? ? ? ? ? ? OLED_ShowString(0,?6,?"Lock by remote");
? ? ? ? }
? ? }
}
說明
-
- ?
USART1
-
- :用于與GPS模塊通信?
USART2
-
- :用于與Air724UG模塊通信(發(fā)送MQTT/短信)?
ADXL345_DetectMovement()
-
- :檢測(cè)車輛是否移動(dòng)(閾值判斷)?
Send_SMS()
-
- :通過AT指令調(diào)用Air724UG發(fā)送短信?
MQTT_Publish()
-
- :上傳數(shù)據(jù)到華為云?
MQTT_Received_Unlock()
-
- ?/
Lock()
-
- :接收遠(yuǎn)程指令?
OLED_ShowString()
-
- :顯示實(shí)時(shí)信息?
LOCK_Unlock()
-
- ?/
LOCK_Lock()
4.3 ADXL345模塊
ADXL345.h
#ifndef?__ADXL345_H
#define?__ADXL345_H
#include?"stm32f10x.h"
// I2C引腳定義(使用軟件模擬)
#define?ADXL_SCL_GPIO ? ?GPIOB
#define?ADXL_SCL_PIN ? ? GPIO_Pin_6
#define?ADXL_SDA_GPIO ? ?GPIOB
#define?ADXL_SDA_PIN ? ? GPIO_Pin_7
// 宏函數(shù)控制SCL/SDA
#define?ADXL_SCL_HIGH() ?GPIO_SetBits(ADXL_SCL_GPIO, ADXL_SCL_PIN)
#define?ADXL_SCL_LOW() ? GPIO_ResetBits(ADXL_SCL_GPIO, ADXL_SCL_PIN)
#define?ADXL_SDA_HIGH() ?GPIO_SetBits(ADXL_SDA_GPIO, ADXL_SDA_PIN)
#define?ADXL_SDA_LOW() ? GPIO_ResetBits(ADXL_SDA_GPIO, ADXL_SDA_PIN)
#define?ADXL_SDA_READ() ?GPIO_ReadInputDataBit(ADXL_SDA_GPIO, ADXL_SDA_PIN)
void?ADXL345_Init(void);
uint8_t?ADXL345_Read_Byte(uint8_t?reg);
void?ADXL345_Write_Byte(uint8_t?reg,?uint8_t?data);
void?ADXL345_ReadXYZ(int16_t?*x,?int16_t?*y,?int16_t?*z);
uint8_t?ADXL345_DetectMovement(void);
#endif
ADXL345.c
#include?"ADXL345.h"
#include?"delay.h"
#define?ADXL345_ADDRESS ?0xA6 ?// 7位地址為0x53,左移1位即為0xA6
// 模擬I2C初始化
static?void?I2C_GPIO_Init(void)
{
? ? RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
? ? GPIO_InitTypeDef GPIO_InitStructure;
? ? GPIO_InitStructure.GPIO_Pin = ADXL_SCL_PIN | ADXL_SDA_PIN;
? ? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
? ? GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
? ? GPIO_Init(ADXL_SCL_GPIO, &GPIO_InitStructure);
? ? ADXL_SCL_HIGH();
? ? ADXL_SDA_HIGH();
}
static?void?I2C_Start(void)
{
? ? ADXL_SDA_HIGH();
? ? ADXL_SCL_HIGH();
? ? delay_us(5);
? ? ADXL_SDA_LOW();
? ? delay_us(5);
? ? ADXL_SCL_LOW();
}
static?void?I2C_Stop(void)
{
? ? ADXL_SDA_LOW();
? ? ADXL_SCL_HIGH();
? ? delay_us(5);
? ? ADXL_SDA_HIGH();
? ? delay_us(5);
}
static?void?I2C_SendAck(uint8_t?ack)
{
? ??if?(ack)
? ? ? ? ADXL_SDA_LOW();
? ??else
? ? ? ? ADXL_SDA_HIGH();
? ? ADXL_SCL_HIGH();
? ? delay_us(5);
? ? ADXL_SCL_LOW();
? ? delay_us(5);
}
static?uint8_t?I2C_WaitAck(void)
{
? ??uint8_t?ack;
? ? ADXL_SDA_HIGH();
? ? ADXL_SCL_HIGH();
? ? delay_us(5);
? ? ack = ADXL_SDA_READ();
? ? ADXL_SCL_LOW();
? ??return?ack;
}
static?void?I2C_WriteByte(uint8_t?byte)
{
? ??for?(int?i =?0; i <?8; i++)
? ? {
? ? ? ??if?(byte &?0x80)
? ? ? ? ? ? ADXL_SDA_HIGH();
? ? ? ??else
? ? ? ? ? ? ADXL_SDA_LOW();
? ? ? ? byte <<=?1;
? ? ? ? ADXL_SCL_HIGH();
? ? ? ? delay_us(5);
? ? ? ? ADXL_SCL_LOW();
? ? ? ? delay_us(5);
? ? }
}
static?uint8_t?I2C_ReadByte(uint8_t?ack)
{
? ??uint8_t?byte =?0;
? ? ADXL_SDA_HIGH();
? ??for?(int?i =?0; i <?8; i++)
? ? {
? ? ? ? ADXL_SCL_HIGH();
? ? ? ? delay_us(5);
? ? ? ? byte <<=?1;
? ? ? ??if?(ADXL_SDA_READ())
? ? ? ? ? ? byte |=?0x01;
? ? ? ? ADXL_SCL_LOW();
? ? ? ? delay_us(5);
? ? }
? ? I2C_SendAck(ack);
? ??return?byte;
}
void?ADXL345_Write_Byte(uint8_t?reg,?uint8_t?data)
{
? ? I2C_Start();
? ? I2C_WriteByte(ADXL345_ADDRESS);
? ? I2C_WaitAck();
? ? I2C_WriteByte(reg);
? ? I2C_WaitAck();
? ? I2C_WriteByte(data);
? ? I2C_WaitAck();
? ? I2C_Stop();
}
uint8_t?ADXL345_Read_Byte(uint8_t?reg)
{
? ??uint8_t?value;
? ? I2C_Start();
? ? I2C_WriteByte(ADXL345_ADDRESS);
? ? I2C_WaitAck();
? ? I2C_WriteByte(reg);
? ? I2C_WaitAck();
? ? I2C_Start();
? ? I2C_WriteByte(ADXL345_ADDRESS |?0x01);
? ? I2C_WaitAck();
? ? value = I2C_ReadByte(0);
? ? I2C_Stop();
? ??return?value;
}
void?ADXL345_ReadXYZ(int16_t?*x,?int16_t?*y,?int16_t?*z)
{
? ??uint8_t?x0 = ADXL345_Read_Byte(0x32);
? ??uint8_t?x1 = ADXL345_Read_Byte(0x33);
? ??uint8_t?y0 = ADXL345_Read_Byte(0x34);
? ??uint8_t?y1 = ADXL345_Read_Byte(0x35);
? ??uint8_t?z0 = ADXL345_Read_Byte(0x36);
? ??uint8_t?z1 = ADXL345_Read_Byte(0x37);
? ? *x = ((int16_t)(x1 <<?8) | x0);
? ? *y = ((int16_t)(y1 <<?8) | y0);
? ? *z = ((int16_t)(z1 <<?8) | z0);
}
void?ADXL345_Init(void)
{
? ? I2C_GPIO_Init();
? ? ADXL345_Write_Byte(0x2D,?0x08);?// POWER_CTL - 測(cè)量模式
? ? ADXL345_Write_Byte(0x31,?0x0B);?// 數(shù)據(jù)格式 - 全分辨率 ±16g
? ? ADXL345_Write_Byte(0x2C,?0x0A);?// BW_RATE - 100Hz
}
// 檢測(cè)是否發(fā)生移動(dòng)(簡(jiǎn)單閾值判斷)
uint8_t?ADXL345_DetectMovement(void)
{
? ??int16_t?x, y, z;
? ? ADXL345_ReadXYZ(&x, &y, &z);
? ??if?(x >?200?|| x <?-200?|| y >?200?|| y <?-200?|| z >?200?|| z <?-200)
? ? ? ??return?1;
? ??return?0;
}
五、上位機(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)境安裝
可以在網(wǎng)盤里找到安裝包下載:?https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink
打開下載鏈接后選擇下面的版本進(jìn)行下載:
軟件安裝時(shí)斷網(wǎng)安裝,否則會(huì)提示輸入賬戶。
安裝的時(shí)候,第一個(gè)復(fù)選框里的編譯器可以全選,直接點(diǎn)擊下一步繼續(xù)安裝。
選擇編譯器: (一定要看清楚了)
前面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í)候選擇了2種編譯器。 一種是mingw32
這個(gè)編譯Windows下運(yùn)行的程序。 一種是Android
編譯器,可以生成Android
手機(jī)APP。
不過要注意:Android的編譯器需要配置一些環(huán)境才可以正常使用,這個(gè)大家可以看下面的教程配置一下就行了。
Android環(huán)境搭建的博客鏈接:?https://blog.csdn.net/xiaolong1126626497/article/details/117254453
windows的編譯器就沒有這么麻煩,安裝好Qt就可以編譯使用。
下面我這里就選擇的?mingw32
這個(gè)編譯器,編譯Windows下運(yùn)行的程序。
5.4 編譯測(cè)試功能
創(chuàng)建完畢之后,編譯測(cè)試一下功能是否OK。
點(diǎn)擊左下角的綠色三角形按鈕
。
正常運(yùn)行就可以看到彈出一個(gè)白色的框框。這就表示工程環(huán)境沒有問題了。 接下來就可以放心的設(shè)計(jì)界面了。
5.5 設(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文件。
? -- File: D:/QtProject/build-265_AgritechIoTManager-Android_for_arm64_v8a_Clang_Qt_5_12_6_for_Android_ARM64_v8a-Release/android-build//build/outputs/apk/debug/android-build-debug.apk
六、總結(jié)
本項(xiàng)目基于STM32F103RCT6單片機(jī)設(shè)計(jì)了一套功能完整、運(yùn)行穩(wěn)定的智能防盜單車鎖系統(tǒng),融合了物聯(lián)網(wǎng)通信技術(shù)、傳感檢測(cè)技術(shù)與移動(dòng)端控制手段,實(shí)現(xiàn)了本地與遠(yuǎn)程相結(jié)合的智能防護(hù)與管理。系統(tǒng)通過多模塊協(xié)作,能夠有效對(duì)單車的使用狀態(tài)進(jìn)行監(jiān)控,對(duì)非法移動(dòng)行為做出及時(shí)報(bào)警,并通過短信與APP進(jìn)行多端同步提醒,大幅提升單車的安全保障能力。
項(xiàng)目充分考慮了單車運(yùn)行環(huán)境的特殊性,在硬件設(shè)計(jì)上選擇了低功耗、高集成度的器件,采用鋰電池供電并預(yù)留太陽能擴(kuò)展接口,增強(qiáng)了系統(tǒng)的戶外適應(yīng)能力與續(xù)航性能。通信方面,選用Air724UG 4G模塊確保了在無WiFi環(huán)境下依然能夠穩(wěn)定聯(lián)網(wǎng),并借助華為云物聯(lián)網(wǎng)平臺(tái)實(shí)現(xiàn)數(shù)據(jù)的實(shí)時(shí)上傳與遠(yuǎn)程管理,體現(xiàn)出云端協(xié)同與邊緣智能的結(jié)合。
在軟件設(shè)計(jì)方面,采用了嵌入式寄存器級(jí)編程實(shí)現(xiàn)了主控芯片的高效控制,同時(shí)借助QT5平臺(tái)開發(fā)了跨平臺(tái)的APP和上位機(jī)軟件,提升了用戶交互體驗(yàn)。系統(tǒng)整體架構(gòu)清晰、功能完整、可擴(kuò)展性強(qiáng),為后續(xù)功能升級(jí)與規(guī)?;瘧?yīng)用提供了良好基礎(chǔ)。
綜上所述,本系統(tǒng)不僅具有較高的實(shí)用價(jià)值和技術(shù)含量,同時(shí)也展現(xiàn)了物聯(lián)網(wǎng)在智能交通工具防護(hù)中的廣闊應(yīng)用前景,具備良好的推廣與開發(fā)潛力。