一、前言
1.1 項(xiàng)目開發(fā)背景
隨著智能家居和物聯(lián)網(wǎng)技術(shù)的快速發(fā)展,電力管理系統(tǒng)逐漸成為現(xiàn)代家庭和商業(yè)建筑中不可或缺的一部分。傳統(tǒng)的電表主要提供基本的用電量計(jì)量功能,但無法滿足用戶對電力管理日益增長的需求。在這一背景下,智能電度表應(yīng)運(yùn)而生。通過結(jié)合先進(jìn)的傳感器技術(shù)、數(shù)據(jù)采集與處理技術(shù)以及無線通信技術(shù),智能電度表能夠?qū)崟r(shí)監(jiān)測、精確測量電力使用情況,并通過智能化手段提供便捷的電能管理方案。
本項(xiàng)目基于STM32微控制器設(shè)計(jì)的智能電度表,實(shí)現(xiàn)對電力使用情況的精確監(jiān)控、用電數(shù)據(jù)的智能管理以及遠(yuǎn)程控制。通過采用電壓和電流互感器對電網(wǎng)進(jìn)行實(shí)時(shí)監(jiān)測,智能電度表能夠?qū)崟r(shí)計(jì)算功率、電量等參數(shù),確保用戶能夠隨時(shí)掌握用電情況。與傳統(tǒng)的電表相比,智能電度表不僅能夠提供實(shí)時(shí)的用電數(shù)據(jù),還支持遠(yuǎn)程管理和控制,滿足家庭和商業(yè)用戶對電能管理的多樣化需求。
此外,隨著電力資源的緊張和用電成本的逐漸上升,科學(xué)合理的電能管理顯得尤為重要。智能電度表通過提供預(yù)付費(fèi)電量管理功能,幫助用戶在用電過程中按需付費(fèi),避免因電量耗盡導(dǎo)致的中斷問題。用戶通過微信小程序可以實(shí)時(shí)查詢電量余額、進(jìn)行充值操作,從而確保用電不受影響。同時(shí),系統(tǒng)還具備功率過載保護(hù)功能,在用電超負(fù)荷的情況下自動(dòng)切斷電源,有效防止電氣設(shè)備因過載而受到損壞。
智能電度表的設(shè)計(jì)還考慮了數(shù)據(jù)可視化的需求,系統(tǒng)能夠通過LCD顯示屏實(shí)時(shí)展示電力使用數(shù)據(jù),便于用戶直觀地了解設(shè)備工作狀態(tài)。為了提升用戶體驗(yàn),電度表通過WiFi模塊將數(shù)據(jù)上傳至云平臺(tái),支持遠(yuǎn)程查看和控制。用戶可以通過微信小程序隨時(shí)查看用電數(shù)據(jù)、余額信息,并進(jìn)行設(shè)備開關(guān)的遠(yuǎn)程操作。此外,系統(tǒng)還提供用電記錄和歷史數(shù)據(jù)分析功能,幫助用戶優(yōu)化用電習(xí)慣,提高能源使用效率。
隨著物聯(lián)網(wǎng)技術(shù)的進(jìn)一步發(fā)展,智能電度表不再是單純的電量計(jì)量工具,它已經(jīng)成為智能家居系統(tǒng)中的一個(gè)重要組成部分。通過無線通信和云平臺(tái)的支持,智能電度表不僅能夠?yàn)橛脩籼峁┍憬莸碾娏芾砉ぞ?,還能夠?yàn)殡娏竞臀飿I(yè)管理方提供精準(zhǔn)的用電數(shù)據(jù)和實(shí)時(shí)監(jiān)控服務(wù)。通過這種智能化的電力管理方式,不僅能夠提升用戶的生活品質(zhì),還能夠有效節(jié)約能源,推動(dòng)綠色低碳的可持續(xù)發(fā)展。
因此,基于STM32設(shè)計(jì)的智能電度表,不僅是對傳統(tǒng)電表功能的擴(kuò)展和創(chuàng)新,也是對現(xiàn)代電能管理需求的積極響應(yīng)。它通過精確的監(jiān)測、靈活的控制和智能化的管理,為用戶提供了一種高效、便捷的用電解決方案,推動(dòng)了電力管理技術(shù)向智能化、網(wǎng)絡(luò)化方向的發(fā)展。
1.2 設(shè)計(jì)實(shí)現(xiàn)的功能
(1)電能監(jiān)測與數(shù)據(jù)采集
系統(tǒng)通過電壓互感器(TV1005M)和電流互感器(TA1005M)精確測量電網(wǎng)的電壓和電流,實(shí)時(shí)計(jì)算功率和電量。系統(tǒng)持續(xù)監(jiān)控電力使用情況,并將數(shù)據(jù)通過WiFi模塊實(shí)時(shí)傳輸至微信小程序,便于用戶隨時(shí)查看電力消耗情況,幫助用戶合理管理電能使用,避免浪費(fèi)。
(2)預(yù)付費(fèi)功能
為滿足用戶對電能管理的需求,系統(tǒng)設(shè)計(jì)了預(yù)付費(fèi)電量管理功能。用戶可通過微信小程序進(jìn)行余額查詢、充值等操作,確保用電過程中的按需付費(fèi)。系統(tǒng)通過WiFi模塊與微信小程序進(jìn)行實(shí)時(shí)數(shù)據(jù)同步,用戶能夠隨時(shí)查看剩余電量,避免因電量耗盡導(dǎo)致的用電中斷。
(3)功率過載保護(hù)
系統(tǒng)具備過載保護(hù)功能,當(dāng)監(jiān)測到功率超過設(shè)定閾值(如200W)時(shí),系統(tǒng)會(huì)自動(dòng)斷開繼電器,切斷電源,防止過載引發(fā)設(shè)備損壞或安全隱患。在功率未超過閾值的情況下,用戶可通過微信小程序手動(dòng)控制繼電器開關(guān),以適應(yīng)不同的用電需求。
(4)計(jì)時(shí)與用電記錄
系統(tǒng)能夠?qū)崟r(shí)顯示設(shè)備的使用時(shí)長,幫助用戶了解電器設(shè)備的工作狀態(tài)。與此同時(shí),系統(tǒng)還具備用電記錄功能,用戶可以查看歷史用電數(shù)據(jù),便于進(jìn)行能效分析與用電習(xí)慣的優(yōu)化調(diào)整。
(5)微信小程序與云平臺(tái)遠(yuǎn)程控制
通過WiFi模塊與云平臺(tái)實(shí)現(xiàn)遠(yuǎn)程控制功能,用戶可通過微信小程序隨時(shí)查看電度表數(shù)據(jù)、控制設(shè)備開關(guān),查看電量消耗和余額信息。同時(shí),系統(tǒng)支持與云平臺(tái)的數(shù)據(jù)同步,通過云平臺(tái)為用戶提供遠(yuǎn)程監(jiān)控、統(tǒng)計(jì)分析及智能管理服務(wù),提升用電管理的智能化和便捷性。
(6)數(shù)據(jù)上傳至云平臺(tái)
系統(tǒng)支持通過WiFi模塊與MQTT協(xié)議將采集的數(shù)據(jù)上傳至OneNet物聯(lián)網(wǎng)云平臺(tái)。用戶可以通過微信小程序遠(yuǎn)程查看設(shè)備數(shù)據(jù),確保用電管理更加透明和智能。數(shù)據(jù)上云不僅方便了遠(yuǎn)程操作,還為未來的數(shù)據(jù)分析與優(yōu)化提供了基礎(chǔ)。
(7)本地LCD顯示屏顯示測量數(shù)據(jù)
智能電度表配備1.44寸LCD顯示屏,用于本地顯示電壓、電流、功率、電量、剩余電量等實(shí)時(shí)測量數(shù)據(jù)。用戶可以直接通過LCD屏幕查看設(shè)備當(dāng)前的用電狀態(tài),無需依賴其他設(shè)備。
(8)設(shè)備安全性與蜂鳴器報(bào)警功能
系統(tǒng)設(shè)計(jì)了安全報(bào)警機(jī)制,采用有源蜂鳴器,當(dāng)系統(tǒng)檢測到功率過載或其他異常情況時(shí),會(huì)觸發(fā)蜂鳴器報(bào)警,提醒用戶及時(shí)采取措施,防止發(fā)生安全隱患。
1.3 項(xiàng)目硬件模塊組成
(1)STM32主控芯片
項(xiàng)目采用STM32F103RCT6作為主控芯片。該芯片具有較高的處理能力、豐富的外設(shè)接口和較低的功耗,能夠滿足智能電度表對實(shí)時(shí)數(shù)據(jù)采集、處理和通信的需求。STM32主控芯片負(fù)責(zé)處理傳感器數(shù)據(jù)、控制繼電器和蜂鳴器、管理與云平臺(tái)和微信小程序的通信等功能。
(2)電壓與電流互感器(TV1005M 和 TA1005M)
電壓互感器(TV1005M)和電流互感器(TA1005M)用于精確測量電網(wǎng)的電壓和電流,并實(shí)時(shí)傳輸測量數(shù)據(jù)給STM32主控芯片。電流互感器主要用于采集用電設(shè)備的電流數(shù)據(jù),電壓互感器則用于監(jiān)測電網(wǎng)的電壓狀態(tài),確保電力使用的安全和穩(wěn)定。
(3)電力參數(shù)采集模塊
電力參數(shù)采集模塊通過串口接口與STM32主控芯片進(jìn)行數(shù)據(jù)交互,采集電壓、電流、功率、電量等電力參數(shù),并將實(shí)時(shí)數(shù)據(jù)傳送給主控芯片。該模塊為智能電度表提供精確的電力監(jiān)測數(shù)據(jù)支持。
(4)LCD顯示屏
系統(tǒng)采用1.44寸LCD顯示屏,用于實(shí)時(shí)顯示電度表的各項(xiàng)數(shù)據(jù),如電壓、電流、功率、電量、剩余電量等信息。LCD屏幕提供本地?cái)?shù)據(jù)展示,便于用戶直觀地查看當(dāng)前用電狀態(tài)。
(5)WiFi模塊(如ESP8266/ESP32)
WiFi模塊負(fù)責(zé)智能電度表與外部設(shè)備(如微信小程序和云平臺(tái))之間的數(shù)據(jù)傳輸。通過WiFi連接,系統(tǒng)能夠?qū)?shí)時(shí)采集的數(shù)據(jù)上傳至OneNet物聯(lián)網(wǎng)云平臺(tái),并與微信小程序進(jìn)行數(shù)據(jù)同步,實(shí)現(xiàn)遠(yuǎn)程監(jiān)控和控制。
(6)MQTT通信模塊
通過MQTT協(xié)議,WiFi模塊將采集的數(shù)據(jù)上傳至OneNet物聯(lián)網(wǎng)云平臺(tái)。MQTT是輕量級(jí)的消息傳輸協(xié)議,適用于物聯(lián)網(wǎng)環(huán)境,能有效保證設(shè)備與云平臺(tái)之間的低延遲、高可靠的通信。
(7)繼電器模塊
繼電器用于控制電源的開關(guān),當(dāng)電力使用超過設(shè)定的安全閾值(如200W)時(shí),繼電器會(huì)自動(dòng)切斷電源,防止過載引發(fā)設(shè)備損壞或安全隱患。此外,繼電器還可以由用戶通過微信小程序遠(yuǎn)程手動(dòng)控制,滿足不同場景的用電需求。
(8)蜂鳴器模塊
蜂鳴器用于系統(tǒng)報(bào)警功能。當(dāng)系統(tǒng)檢測到電力使用異常(如功率過載、低電量等)時(shí),蜂鳴器會(huì)發(fā)出警報(bào)聲音,提醒用戶及時(shí)檢查并處理異常情況,確保系統(tǒng)的安全運(yùn)行。
(9)電源管理模塊
為了保證系統(tǒng)的穩(wěn)定運(yùn)行,電源管理模塊負(fù)責(zé)為STM32主控芯片、WiFi模塊、LCD顯示屏等各個(gè)模塊提供穩(wěn)定的電源。該模塊還負(fù)責(zé)電池電量監(jiān)控,確保系統(tǒng)能夠在電量不足時(shí)進(jìn)行預(yù)警和自動(dòng)斷電操作。
(10)按鍵/開關(guān)模塊
按鍵或開關(guān)模塊用于用戶與設(shè)備的交互,例如手動(dòng)控制繼電器的開關(guān)、啟動(dòng)和停止系統(tǒng)、設(shè)置閾值等操作。通過按鍵模塊,用戶能夠直接在本地對電度表進(jìn)行操作,方便使用。
(11)外部傳感器與接口模塊
除了電流和電壓傳感器,系統(tǒng)還可能集成其他傳感器模塊(如溫度傳感器、功率因數(shù)傳感器等),用于進(jìn)一步增強(qiáng)電度表的功能。接口模塊提供與外部傳感器的連接,確保數(shù)據(jù)采集的多樣化和精準(zhǔn)性。
(12)外部存儲(chǔ)模塊(可選)
為方便存儲(chǔ)和備份數(shù)據(jù),系統(tǒng)可以選擇集成外部存儲(chǔ)模塊(如SD卡)。該模塊可以用于存儲(chǔ)歷史用電數(shù)據(jù)、用戶設(shè)置參數(shù)等信息,確保在沒有網(wǎng)絡(luò)連接的情況下仍能持續(xù)運(yùn)行并記錄數(shù)據(jù)。
1.4 設(shè)計(jì)思路
在設(shè)計(jì)基于STM32的智能電度表時(shí),我們的主要目標(biāo)是實(shí)現(xiàn)高效、精準(zhǔn)的電力監(jiān)測與管理,同時(shí)提供便捷的用戶交互和遠(yuǎn)程控制功能。整個(gè)設(shè)計(jì)的核心思路是結(jié)合實(shí)時(shí)數(shù)據(jù)采集、智能化管理、遠(yuǎn)程控制和用戶體驗(yàn)優(yōu)化等方面,提供一個(gè)全面的電能管理解決方案。
在硬件設(shè)計(jì)方面,系統(tǒng)選擇STM32F103RCT6作為主控芯片,具備較高的性能和豐富的接口資源,能夠支持電壓、電流等多項(xiàng)電力參數(shù)的實(shí)時(shí)采集、處理和數(shù)據(jù)傳輸。為了保證電力參數(shù)的準(zhǔn)確性,系統(tǒng)采用電壓互感器(TV1005M)和電流互感器(TA1005M)對電網(wǎng)的電壓和電流進(jìn)行精確測量,并通過電力參數(shù)采集模塊將這些數(shù)據(jù)傳輸給STM32主控芯片。主控芯片對采集的數(shù)據(jù)進(jìn)行實(shí)時(shí)處理,計(jì)算功率和電量等指標(biāo),并通過WiFi模塊將數(shù)據(jù)上傳至云平臺(tái)和微信小程序,實(shí)現(xiàn)遠(yuǎn)程監(jiān)控和控制。
為了提升用戶體驗(yàn),系統(tǒng)集成了1.44寸LCD顯示屏,本地展示電度表的實(shí)時(shí)數(shù)據(jù),包括電壓、電流、功率和電量等參數(shù)。用戶可以通過LCD屏直觀地查看設(shè)備的工作狀態(tài),了解當(dāng)前的用電情況,避免對電力使用情況的不清楚。與此同時(shí),系統(tǒng)支持通過微信小程序進(jìn)行遠(yuǎn)程操作,用戶能夠隨時(shí)查看電力消耗、余額信息,并進(jìn)行繼電器的遠(yuǎn)程開關(guān)控制。這一設(shè)計(jì)使得智能電度表不僅具備本地?cái)?shù)據(jù)展示功能,還能為用戶提供更加便捷的遠(yuǎn)程管理手段。
此外,系統(tǒng)設(shè)計(jì)了預(yù)付費(fèi)電量管理功能。通過與微信小程序的數(shù)據(jù)同步,用戶可以隨時(shí)查看剩余電量并進(jìn)行充值,確保電力使用不受干擾。為避免因電力過載導(dǎo)致的設(shè)備損壞或安全問題,系統(tǒng)還配備了功率過載保護(hù)功能。當(dāng)電力負(fù)荷超過設(shè)定閾值時(shí),系統(tǒng)會(huì)自動(dòng)切斷電源,防止過載情況發(fā)生,從而提高系統(tǒng)的安全性。
在通信部分,系統(tǒng)使用WiFi模塊與OneNet物聯(lián)網(wǎng)云平臺(tái)進(jìn)行數(shù)據(jù)上傳和同步。通過MQTT協(xié)議,電度表能夠?qū)⒉杉降臄?shù)據(jù)實(shí)時(shí)上傳至云平臺(tái),并支持與微信小程序進(jìn)行數(shù)據(jù)同步,使得用戶能夠隨時(shí)遠(yuǎn)程監(jiān)控和控制設(shè)備。云平臺(tái)還為用戶提供數(shù)據(jù)分析和統(tǒng)計(jì)功能,幫助用戶更好地了解自己的用電習(xí)慣,優(yōu)化電能使用。
另外,為了進(jìn)一步提升電度表的安全性和可靠性,系統(tǒng)集成了蜂鳴器模塊,用于在電力使用異常(如功率過載、電量低等)時(shí)發(fā)出警報(bào)。蜂鳴器作為一個(gè)重要的安全提醒模塊,能夠及時(shí)通知用戶采取相應(yīng)的措施,避免由于忽視警告導(dǎo)致的潛在安全問題。
在總體設(shè)計(jì)上,智能電度表以用戶需求為中心,通過無線通信技術(shù)和智能化管理手段,整合了實(shí)時(shí)監(jiān)測、遠(yuǎn)程控制、安全保護(hù)和數(shù)據(jù)分析等功能,提升了電力管理的智能化水平。系統(tǒng)的設(shè)計(jì)不僅提高了電能使用的便捷性和可靠性,也通過數(shù)據(jù)的可視化和云平臺(tái)支持,幫助用戶更好地了解和優(yōu)化自己的用電行為,從而達(dá)到節(jié)能降耗、提高能源利用效率的目的。
1.5 系統(tǒng)功能總結(jié)
功能模塊 | 功能描述 |
電能監(jiān)測與數(shù)據(jù)采集 | 精確測量電網(wǎng)電壓和電流,實(shí)時(shí)計(jì)算功率和電量,并將數(shù)據(jù)上傳至云平臺(tái)和微信小程序進(jìn)行查看。 |
預(yù)付費(fèi)功能 | 提供余額查詢和充值功能,確保用戶按需付費(fèi),避免因電量耗盡導(dǎo)致用電中斷。 |
功率過載保護(hù) | 當(dāng)功率超過設(shè)定閾值時(shí),自動(dòng)切斷電源,防止過載造成設(shè)備損壞或安全隱患。 |
計(jì)時(shí)與用電記錄 | 實(shí)時(shí)顯示設(shè)備使用時(shí)長,記錄歷史用電數(shù)據(jù),幫助用戶分析用電行為。 |
微信小程序與云平臺(tái)遠(yuǎn)程控制 | 通過WiFi模塊與云平臺(tái)進(jìn)行數(shù)據(jù)同步,支持用戶遠(yuǎn)程查看電度表數(shù)據(jù)和控制設(shè)備開關(guān)。 |
數(shù)據(jù)上傳至云平臺(tái) | 通過WiFi模塊和MQTT協(xié)議將實(shí)時(shí)數(shù)據(jù)上傳至OneNet云平臺(tái),實(shí)現(xiàn)遠(yuǎn)程監(jiān)控與數(shù)據(jù)存儲(chǔ)。 |
本地LCD顯示屏顯示測量數(shù)據(jù) | LCD顯示屏實(shí)時(shí)顯示電壓、電流、功率和電量等電力數(shù)據(jù),方便用戶本地查看。 |
設(shè)備安全性與蜂鳴器報(bào)警 | 在檢測到功率過載或電量低等異常情況時(shí),觸發(fā)蜂鳴器報(bào)警提醒用戶,確保系統(tǒng)安全運(yùn)行。 |
1.7 模塊的技術(shù)詳情介紹
1.?STM32主控芯片(STM32F103RCT6)
STM32F103RCT6是本項(xiàng)目的核心控制單元,采用ARM Cortex-M3架構(gòu),具有較高的處理性能、低功耗、豐富的外設(shè)接口(如串口、I2C、SPI、GPIO等),非常適合用于物聯(lián)網(wǎng)設(shè)備的嵌入式控制。STM32F103RCT6負(fù)責(zé)處理電流和電壓傳感器的數(shù)據(jù),進(jìn)行功率計(jì)算、控制繼電器、管理與WiFi模塊及云平臺(tái)的數(shù)據(jù)通信等任務(wù)。該芯片的高效能和低功耗特性使其成為智能電度表設(shè)計(jì)中的理想選擇。
2.?電壓與電流互感器(TV1005M 和 TA1005M)
??電壓互感器(TV1005M):用于精確測量電網(wǎng)電壓。電壓互感器的輸出信號(hào)通過采樣轉(zhuǎn)換為數(shù)字信號(hào),傳送給STM32主控芯片進(jìn)行處理。該互感器通常具有較高的精度和穩(wěn)定性,能夠確保電網(wǎng)電壓的準(zhǔn)確檢測。
??電流互感器(TA1005M):用于監(jiān)測電流信號(hào),尤其是在大功率電器中,能夠?qū)崟r(shí)反映電流的變化。電流互感器將電流信號(hào)轉(zhuǎn)換為與負(fù)載成比例的電壓信號(hào),STM32通過ADC采樣獲取數(shù)據(jù),進(jìn)而計(jì)算用電功率。
3.?電力參數(shù)采集模塊
該模塊通過串口(如UART)與STM32主控芯片進(jìn)行通信,采集電網(wǎng)的電壓、電流、功率等數(shù)據(jù)。電力參數(shù)采集模塊通過傳感器實(shí)時(shí)測量電氣參數(shù),并通過串行接口將數(shù)據(jù)傳輸給STM32控制器。通過該模塊,系統(tǒng)能夠?qū)崟r(shí)監(jiān)測并計(jì)算電力使用的各項(xiàng)指標(biāo),包括功率、功率因數(shù)、功耗等,為用戶提供全面的電能數(shù)據(jù)支持。
4.?LCD顯示屏(1.44寸)
該LCD屏幕用于本地顯示實(shí)時(shí)測量的電力數(shù)據(jù),包括電壓、電流、功率、電量、剩余電量等信息。LCD顯示屏采用SPI或并行接口與STM32進(jìn)行通信,能夠?qū)⒂?jì)算結(jié)果即時(shí)顯示在用戶面前。1.44寸顯示屏具有小巧、低功耗的特點(diǎn),適合于小型設(shè)備的集成。用戶可以通過LCD屏幕查看設(shè)備的實(shí)時(shí)運(yùn)行狀態(tài),無需其他外部顯示設(shè)備。
5.?WiFi模塊(如ESP8266/ESP32)
WiFi模塊通過無線通信與云平臺(tái)及微信小程序進(jìn)行數(shù)據(jù)同步。模塊支持802.11b/g/n無線標(biāo)準(zhǔn),能夠連接到本地Wi-Fi網(wǎng)絡(luò)。通過WiFi,電度表能夠?qū)?shí)時(shí)采集的電力數(shù)據(jù)上傳至物聯(lián)網(wǎng)云平臺(tái)(如OneNet),并通過MQTT協(xié)議與云端進(jìn)行數(shù)據(jù)交換。此外,WiFi模塊還支持與微信小程序進(jìn)行實(shí)時(shí)同步,方便用戶查看電力使用情況、余額信息及進(jìn)行設(shè)備遠(yuǎn)程控制。
6.?MQTT協(xié)議
MQTT(消息隊(duì)列遙測傳輸協(xié)議)是一種輕量級(jí)的、基于發(fā)布/訂閱模式的消息傳輸協(xié)議,專為低帶寬、高延遲或不穩(wěn)定的網(wǎng)絡(luò)環(huán)境設(shè)計(jì)。該協(xié)議非常適用于物聯(lián)網(wǎng)設(shè)備的數(shù)據(jù)傳輸。在本項(xiàng)目中,MQTT協(xié)議被用于WiFi模塊與OneNet云平臺(tái)之間的數(shù)據(jù)通信,確保設(shè)備數(shù)據(jù)能夠穩(wěn)定、實(shí)時(shí)地上傳到云端,并支持云平臺(tái)與設(shè)備之間的雙向數(shù)據(jù)交換。
7.?繼電器模塊
繼電器模塊負(fù)責(zé)控制電度表的電源開關(guān)。當(dāng)系統(tǒng)檢測到功率過載時(shí),繼電器會(huì)自動(dòng)斷開電路,切斷電源以避免過載引起的設(shè)備損壞或火災(zāi)等安全隱患。此外,繼電器還可以通過微信小程序或本地按鍵進(jìn)行手動(dòng)控制,滿足用戶不同的用電需求。繼電器模塊通過低電壓信號(hào)控制高電壓電路的開關(guān),確保系統(tǒng)操作安全。
8.?蜂鳴器模塊
蜂鳴器用于系統(tǒng)的報(bào)警功能。當(dāng)電力負(fù)荷超過設(shè)定閾值,或者剩余電量低至警戒線時(shí),蜂鳴器會(huì)發(fā)出警報(bào)聲音,提醒用戶采取必要的措施,防止電力過載或電量耗盡。蜂鳴器通常采用高電平觸發(fā)的方式,通過STM32的GPIO口控制。該模塊能夠有效地提高系統(tǒng)的安全性,避免因忽視警告而導(dǎo)致的電力安全問題。
9.?電源管理模塊
電源管理模塊為整個(gè)智能電度表系統(tǒng)提供穩(wěn)定的電源。該模塊包括電池、穩(wěn)壓芯片等組件,用于轉(zhuǎn)換并穩(wěn)定電壓,確保STM32主控芯片、WiFi模塊、LCD顯示屏等各個(gè)模塊能夠穩(wěn)定工作。電源管理模塊還負(fù)責(zé)電池電量監(jiān)測,確保在電池電量低時(shí)提供充電提醒或自動(dòng)進(jìn)入節(jié)能模式。
10.?按鍵/開關(guān)模塊
按鍵模塊用于用戶與設(shè)備的交互,用戶可以通過按鍵控制繼電器的開關(guān)、設(shè)置參數(shù)、啟動(dòng)或停止某些功能等。按鍵模塊通過STM32的GPIO接口與主控芯片連接,負(fù)責(zé)接收用戶輸入的命令。通過這種方式,用戶可以根據(jù)需要靈活操作電度表,調(diào)整設(shè)備設(shè)置。
二、微信小程序接入
必備參數(shù)
頂置說明: 應(yīng)用端接入OneNet 需要下面幾個(gè)參數(shù)。要自己找到位置。
#?用戶ID(用戶頭像->訪問權(quán)限->user_id)
user_id?=?''
#?訪問密鑰(用戶頭像->訪問權(quán)限->access_key)
access_key?=?""
#產(chǎn)品id(產(chǎn)品->產(chǎn)品ID)
product_id?=?""
#設(shè)備名稱
device_name?=?""
2.1 接入OneNet
幫助文檔地址:https://open.iot.10086.cn/doc/v5/fuse/detail/1418
【1】查詢設(shè)備數(shù)據(jù)點(diǎn)
使用這個(gè)接口的時(shí)候,要注意。你的設(shè)備是不是創(chuàng)建的數(shù)據(jù)流類型。創(chuàng)建產(chǎn)品的時(shí)候會(huì)讓你選擇的。是數(shù)據(jù)流還是OneJSON
接口功能
根據(jù)產(chǎn)品id和設(shè)備名稱查詢,時(shí)間范圍參數(shù),查詢設(shè)備歷史數(shù)據(jù)點(diǎn)信息
備注
僅支持?jǐn)?shù)據(jù)流、IPSO數(shù)據(jù)協(xié)議,設(shè)備能正常下發(fā)上報(bào)
接口地址
http(s)://iot-api.heclouds.com/datapoint/history-datapoints
API說明
請求方式:GET
http query 請求參數(shù):
參數(shù) | 類型 | 是否必選 | 描述 |
datastream_id | string | 否 | 數(shù)據(jù)流ID,多個(gè)id之間用逗號(hào)分開,缺省時(shí)取數(shù)據(jù)流或數(shù)據(jù)流模板100條為缺省數(shù)據(jù)流id條件 |
product_id | string | 是 | 產(chǎn)品ID,平臺(tái)生成唯一ID |
device_name | string | 是 | 設(shè)備名稱 |
imei | string | 否 | lwm2m協(xié)議時(shí)傳,設(shè)備imei |
start | string | 否 | 提取數(shù)據(jù)點(diǎn)的開始時(shí)間,精確到秒,示例:2015-01-10T08:00:35 |
end | string | 否 | 提取數(shù)據(jù)點(diǎn)的結(jié)束時(shí)間,精確到秒,示例:2015-01-10T08:00:35 |
duration | int | 否 | 查詢時(shí)間區(qū)間,單位為秒 |
limit | int | 否 | 限定本次請求最多返回的數(shù)據(jù)點(diǎn)數(shù),默認(rèn)100,范圍為(0,6000] |
cursor | string | 否 | 指定本次請求繼續(xù)從cursor位置開始提取數(shù)據(jù) |
sort | enum | 否 | 時(shí)間排序方式,DESC:倒序,ASC:升序,默認(rèn)為DESC |
返回?cái)?shù)據(jù)
參數(shù)名稱 | 類型 | 描述 |
code | int | 調(diào)用成功或失敗時(shí),返回的code碼 |
msg | string | 調(diào)用成功或失敗時(shí),返回的msg信息 |
request_id | string | 調(diào)用API生成的請求標(biāo)識(shí) |
data | - | 調(diào)用成功時(shí),返回的業(yè)務(wù)數(shù)據(jù) |
data.count | int | 本次返回的數(shù)據(jù)點(diǎn)數(shù)量 |
data.cursor | string | 本次請求若未能返回所有數(shù)據(jù),則會(huì)返回cursor參數(shù),用戶可以攜帶cursor參數(shù)進(jìn)行再次請求,獲取剩下的數(shù)據(jù) |
data.datastreams | array-json | 設(shè)備數(shù)據(jù)流信息的json數(shù)組,見datastreams描述 |
datastreams描述表
參數(shù)名稱 | 格式 | 說明 |
id | string | 數(shù)據(jù)流名稱 |
datapoints | array-json | 數(shù)據(jù)點(diǎn)信息的json數(shù)組,見datapoints描述表 |
datapoints描述表
參數(shù)名稱 | 格式 | 說明 |
at | string | 數(shù)據(jù)記錄時(shí)間 |
value | string/int/json... | 數(shù)據(jù)點(diǎn)的值 |
特別說明
1. 當(dāng)start,end時(shí)間均為空
i) limit
不傳值或傳值等于1時(shí):排序?yàn)樯騽t查詢最早一個(gè)數(shù)據(jù)點(diǎn)(30天內(nèi)),否則查詢最新數(shù)據(jù)點(diǎn)(最新緩存數(shù)據(jù))ii) limit
傳值大于1時(shí):排序?yàn)樯騽t查詢最早x條數(shù)據(jù)點(diǎn),否則查詢最新x條數(shù)據(jù)點(diǎn)(30天內(nèi),x=limit)
示例
請求示例
GET?http(s)://iot-api.heclouds.com/datapoint/history-datapoints
?product_id=XhONWQ5zV5&device_name=mqtts-dev&datastream_id=ds&start=2017-01-01T00:00:00&limit=100
響應(yīng)示例
{
????"data":{
????????"cursor":"25971_564280_1448961152173",
????????"count":5,
????????"datastreams":[
????????????{
????????????????"datapoints":[
????????????????????{
????????????????????????"at":"2015-12-01?17:10:24.981",
????????????????????????"value":"35"
????????????????????},
????????????????????{
????????????????????????"at":"2015-12-01?17:10:53.406",
????????????????????????"value":"38"
????????????????????},
????????????????????...
????????????????],
????????????????"id":"3200_0_5501"
????????????},
????????????...
????????]
????},
????"request_id":?"a25087f46df04b69b29e90ef0acfd115",?
????"msg":?"succ",
????"code":??0
}
在Qt項(xiàng)目包含網(wǎng)絡(luò)模塊,在.pro
文件中添加:
QT?+=?network
演示了如何使用Qt發(fā)出HTTP GET請求:
#include?<QCoreApplication>
#include?<QNetworkAccessManager>
#include?<QNetworkRequest>
#include?<QNetworkReply>
#include?<QUrl>
#include?<QDebug>
int?main(int?argc,?char?*argv[])
{
????QCoreApplication?a(argc,?argv);
????QNetworkAccessManager?manager;
????QUrl?url("https://open.iot.10086.cn/api/your-endpoint");?//?替換為實(shí)際URL
????QNetworkRequest?request(url);
????//?設(shè)置請求頭
????request.setRawHeader("Authorization",?"Bearer?YOUR_ACCESS_TOKEN");?//?示例:?使用Bearer?Token
????QNetworkReply?*reply?=?manager.get(request);
????QObject::connect(reply,?&QNetworkReply::finished,?[&]()?{
????????if?(reply->error()?==?QNetworkReply::NoError)?{
????????????QString?response_data?=?reply->readAll();
????????????qDebug()?<<?"Response?data:"?<<?response_data;
????????}?else?{
????????????qDebug()?<<?"Error:"?<<?reply->errorString();
????????}
????????reply->deleteLater();
????????a.quit();?//?結(jié)束應(yīng)用程序
????});
????return?a.exec();
}
【2】MQTT命令下發(fā)
使用這個(gè)接口的時(shí)候,要注意。你的設(shè)備是不是創(chuàng)建的數(shù)據(jù)流類型。創(chuàng)建產(chǎn)品的時(shí)候會(huì)讓你選擇的。是數(shù)據(jù)流還是OneJSON
接口功能
根據(jù)產(chǎn)品id和設(shè)備名稱查詢,時(shí)間范圍參數(shù),查詢設(shè)備歷史數(shù)據(jù)點(diǎn)信息
備注
僅支持?jǐn)?shù)據(jù)流、IPSO數(shù)據(jù)協(xié)議,設(shè)備能正常下發(fā)上報(bào)
接口地址
http(s)://iot-api.heclouds.com/datapoint/history-datapoints
API說明
請求方式:GET
http query 請求參數(shù):
參數(shù) | 類型 | 是否必選 | 描述 |
datastream_id | string | 否 | 數(shù)據(jù)流ID,多個(gè)id之間用逗號(hào)分開,缺省時(shí)取數(shù)據(jù)流或數(shù)據(jù)流模板100條為缺省數(shù)據(jù)流id條件 |
product_id | string | 是 | 產(chǎn)品ID,平臺(tái)生成唯一ID |
device_name | string | 是 | 設(shè)備名稱 |
imei | string | 否 | lwm2m協(xié)議時(shí)傳,設(shè)備imei |
start | string | 否 | 提取數(shù)據(jù)點(diǎn)的開始時(shí)間,精確到秒,示例:2015-01-10T08:00:35 |
end | string | 否 | 提取數(shù)據(jù)點(diǎn)的結(jié)束時(shí)間,精確到秒,示例:2015-01-10T08:00:35 |
duration | int | 否 | 查詢時(shí)間區(qū)間,單位為秒 |
limit | int | 否 | 限定本次請求最多返回的數(shù)據(jù)點(diǎn)數(shù),默認(rèn)100,范圍為(0,6000] |
cursor | string | 否 | 指定本次請求繼續(xù)從cursor位置開始提取數(shù)據(jù) |
sort | enum | 否 | 時(shí)間排序方式,DESC:倒序,ASC:升序,默認(rèn)為DESC |
返回?cái)?shù)據(jù)
參數(shù)名稱 | 類型 | 描述 |
code | int | 調(diào)用成功或失敗時(shí),返回的code碼 |
msg | string | 調(diào)用成功或失敗時(shí),返回的msg信息 |
request_id | string | 調(diào)用API生成的請求標(biāo)識(shí) |
data | - | 調(diào)用成功時(shí),返回的業(yè)務(wù)數(shù)據(jù) |
data.count | int | 本次返回的數(shù)據(jù)點(diǎn)數(shù)量 |
data.cursor | string | 本次請求若未能返回所有數(shù)據(jù),則會(huì)返回cursor參數(shù),用戶可以攜帶cursor參數(shù)進(jìn)行再次請求,獲取剩下的數(shù)據(jù) |
data.datastreams | array-json | 設(shè)備數(shù)據(jù)流信息的json數(shù)組,見datastreams描述 |
datastreams描述表
參數(shù)名稱 | 格式 | 說明 |
id | string | 數(shù)據(jù)流名稱 |
datapoints | array-json | 數(shù)據(jù)點(diǎn)信息的json數(shù)組,見datapoints描述表 |
datapoints描述表
參數(shù)名稱 | 格式 | 說明 |
at | string | 數(shù)據(jù)記錄時(shí)間 |
value | string/int/json... | 數(shù)據(jù)點(diǎn)的值 |
特別說明
1. 當(dāng)start,end時(shí)間均為空
i) limit
不傳值或傳值等于1時(shí):排序?yàn)樯騽t查詢最早一個(gè)數(shù)據(jù)點(diǎn)(30天內(nèi)),否則查詢最新數(shù)據(jù)點(diǎn)(最新緩存數(shù)據(jù))ii) limit
傳值大于1時(shí):排序?yàn)樯騽t查詢最早x條數(shù)據(jù)點(diǎn),否則查詢最新x條數(shù)據(jù)點(diǎn)(30天內(nèi),x=limit)
示例
請求示例
GET?http(s)://iot-api.heclouds.com/datapoint/history-datapoints
?product_id=XhONWQ5zV5&device_name=mqtts-dev&datastream_id=ds&start=2017-01-01T00:00:00&limit=100
響應(yīng)示例
{
????"data":{
????????"cursor":"25971_564280_1448961152173",
????????"count":5,
????????"datastreams":[
????????????{
????????????????"datapoints":[
????????????????????{
????????????????????????"at":"2015-12-01?17:10:24.981",
????????????????????????"value":"35"
????????????????????},
????????????????????{
????????????????????????"at":"2015-12-01?17:10:53.406",
????????????????????????"value":"38"
????????????????????},
????????????????????...
????????????????],
????????????????"id":"3200_0_5501"
????????????},
????????????...
????????]
????},
????"request_id":?"a25087f46df04b69b29e90ef0acfd115",?
????"msg":?"succ",
????"code":??0
}
【3】API鑒權(quán)
平臺(tái)需要對API調(diào)用方進(jìn)行資源權(quán)限校驗(yàn),使用API時(shí),需要在請求Header中攜帶統(tǒng)一的安全鑒權(quán)信息。
不同情形下的鑒權(quán)方式
??平臺(tái)支持三種鑒權(quán)方式:用戶鑒權(quán)、產(chǎn)品鑒權(quán)、項(xiàng)目鑒權(quán)
??添加設(shè)備后未轉(zhuǎn)移:
1、設(shè)備未轉(zhuǎn)移,但綁定了項(xiàng)目時(shí),鑒權(quán)支持【用戶鑒權(quán)】、【項(xiàng)目鑒權(quán)】。
2、設(shè)備未轉(zhuǎn)移,且沒有綁定任何項(xiàng)目時(shí),鑒權(quán)支持【用戶鑒權(quán)】、【產(chǎn)品鑒權(quán)】。
??添加設(shè)備后進(jìn)行設(shè)備轉(zhuǎn)移:
1、用戶在平臺(tái)嘗試“設(shè)備轉(zhuǎn)移”時(shí),需要先解除項(xiàng)目綁定,才能進(jìn)行轉(zhuǎn)移操作。
2、轉(zhuǎn)移后,再次綁定項(xiàng)目時(shí),支持【用戶鑒權(quán)】、【項(xiàng)目鑒權(quán)】。
3、轉(zhuǎn)移后,沒有綁定項(xiàng)目時(shí),僅支持【用戶鑒權(quán)】。
安全鑒權(quán)機(jī)制
安全鑒權(quán)authorization由多個(gè)參數(shù)構(gòu)成,每個(gè)參數(shù)均采用key = value的形式表示,并用&作為分隔符:
authorization:?version=2022-05-01&res=userid%2F{userId}&et={expireTime}&method=sha1&sign={sign}
Token生成工具
? 為便于開發(fā)者開發(fā),OneNET提供了Token生成工具,填寫字段后可以快速生成安全鑒權(quán)信息。前往下載https://open.iot.10086.cn/doc/v5/fuse/detail/1487
參數(shù)說明
序 號(hào) | 參數(shù) | 類型 | 說明 | 示例 |
1 | version | string | 簽名算法版本 | 目前僅支持 2022-05-01 |
2 | res | string | 訪問資源信息 | 支持主用戶、產(chǎn)品、項(xiàng)目三種方式:1)主用戶訪問res為:userid/{userid}, userid為平臺(tái)用戶id,access_key為主用戶access_key,參數(shù)在個(gè)人「賬號(hào)信息」、「訪問權(quán)限」中查看。2)產(chǎn)品訪問res為:products/{productid},access_key為產(chǎn)品access_key,進(jìn)入「產(chǎn)品開發(fā)」菜單的「產(chǎn)品列表」中,點(diǎn)擊「操作」列下的「產(chǎn)品開發(fā)」鏈接,進(jìn)入「產(chǎn)品信息頁面」查看。3)項(xiàng)目訪問res為:projects/{projectid},access_key為項(xiàng)目key,進(jìn)入「應(yīng)用開發(fā)」-「項(xiàng)目管理」菜單的「我的項(xiàng)目」列表中,點(diǎn)擊「操作」列下的「進(jìn)入項(xiàng)目管理」鏈接,進(jìn)入「項(xiàng)目信息頁面」,在「項(xiàng)目概況」的「項(xiàng)目信息」中查看。注* 以上提到的不同access_key獲取方式在下文中會(huì)有詳細(xì)描述 |
3 | et | string | 訪問過期時(shí)間 | 10位秒級(jí)時(shí)間戳,1537255523 表示:北京時(shí)間 2018-09-18 15:25:23 |
4 | method | string | 簽名方法 | 目前支持md5、sha1、sha256 |
5 | sign | string | 簽名結(jié)果字符串 | version、res、et、method參數(shù)計(jì)算生成 |
accessKey參數(shù)獲取
主用戶accessKey
產(chǎn)品accessKey
項(xiàng)目accessKey
sign的生成算法為:
sign?=?base64(hmac_<method>(base64decode(accessKey),?utf-8(StringForSignature)))?
? accessKey為平臺(tái)分配的訪問密鑰(用戶訪問權(quán)限頁面查看),如果訪問資源以主用戶形式訪問, 使用主用戶的accessKey;如果訪問資源以產(chǎn)品方式訪問,使用產(chǎn)品的accessKey,且只能對產(chǎn)品下的設(shè)備進(jìn)行操作;如果訪問資源以項(xiàng)目方式訪問,使用項(xiàng)目的accessKey,且只能對項(xiàng)目下的設(shè)備進(jìn)行操作。
? accessKey參與計(jì)算前應(yīng)先進(jìn)行base64decode操作。
? 用于計(jì)算簽名的字符串 StringForSignature按照et、method、res、version的順序,以"n"作為分隔符進(jìn)行排列,如下所示:
StringForSignature?=?et?+?"n"?+?method?+?"n"?+?res?+?"n"?+?version
參數(shù)編碼
authorization中key=value的形式的value部分需要經(jīng)過URL編碼,需要進(jìn)行編碼的特殊符號(hào)如下:
序號(hào) | 符號(hào) | 編碼 |
1 | + | %2B |
2 | 空格 | %20 |
3 | / | %2F |
4 | ? | %3F |
5 | % | %25 |
6 | # | %23 |
7 | & | %26 |
8 | = | %3D |
authorization生成示例
nodejs代碼示例
'use?strict';
const?crypto?=?require('crypto');
/**
?*?authorization生成函數(shù)
?*
?*?@param?{String}?method????????-?hash?method
?*?@param?{String}?res???????????-?resource
?*?@param?{String}?accessKey?????-?access?key
?*?@param?{Number}?et????????????-?effective?time
?*?@return?{String}?-?authorization
?*/
function?generateAuthorization(method,?res,?accessKey,?et)?{
??const?version?=?'2022-05-01';
??const?et?=?Math.ceil((Date.now()?+?et)?/?1000);?//?token有效時(shí)間
??const?base64Key?=?Buffer.from(accessKey,?'base64');?//?accessKey?base64編碼
??const?StringForSignature?=?et?+?'n'?+?method?+?'n'?+?res?+?'n'?+?version;
??const?sign?=?encodeURIComponent(crypto.createHmac(method,?base64Key).update(StringForSignature).digest('base64'));
??const?encodeRes?=?encodeURIComponent(res);
??return?`version=${version}&res=${encodeRes}&et=${et}&method=${method}&sign=${sign}`;
}
const?method?=?'sha1';
const?accessKey?=?'mjgvkTCYTBF6DguxMmm+aV9EkDp2CYfL5jzRTph5Th6KhU8gqZz/cBivPTA7tfY5';
const?res?=?'userid/130037';
const et = 3600?* 1000;?//?有效時(shí)間:1小時(shí)
const?authorization?=?generateAuthorization(method,?res,?accessKey,?et);
python代碼示例
????import?base64
????import?hmac
????import?time
????from?urllib.parse?import?quote
????
????def?token(user_id,access_key):
????????version?=?'2022-05-01'
????????res?=?'userid/%s'?%?user_id
????????#?用戶自定義token過期時(shí)間
????????et?=?str(int(time.time())?+?3600)
????????#?簽名方法,支持md5、sha1、sha256
????????method?=?'sha1'
????????#?對access_key進(jìn)行decode
????????key?=?base64.b64decode(access_key)
????????#?計(jì)算sign
????????org?=?et?+?'n'?+?method?+?'n'?+?res?+?'n'?+?version
????????sign_b?=?hmac.new(key=key,?msg=org.encode(),?digestmod=method)
????????sign?=?base64.b64encode(sign_b.digest()).decode()
????????#?value?部分進(jìn)行url編碼,method/res/version值較為簡單無需編碼
????????sign?=?quote(sign,?safe='')
????????res?=?quote(res,?safe='')
????????#?token參數(shù)拼接
????????token?=?'version=%s&res=%s&et=%s&method=%s&sign=%s'?%?(version,?res,?et,?method,?sign)
????
????????return?token
????
????if?__name__?==?'__main__':
????????user_id?=?'37715'
????????access_key?=?'mjgvkTCYTBF6DguxMmm+aV9EkDp2CYfL5jzRTph5Th6KhU8gqZz/cBivPTA7tfY5'
????
????????print(token(user_id,access_key))
Java代碼示例
????import?javax.crypto.Mac;
????import?javax.crypto.spec.SecretKeySpec;
????import?java.io.UnsupportedEncodingException;
????import?java.net.URLEncoder;
????import?java.security.InvalidKeyException;
????import?java.security.NoSuchAlgorithmException;
????import?java.util.Base64;
????
????
????public?class?Token?{
????
????????public?static?String?assembleToken(String?version,?String?resourceName,?String?expirationTime,?String?signatureMethod,?String?accessKey)
????????????????throws?UnsupportedEncodingException,?NoSuchAlgorithmException,?InvalidKeyException?{
????????????StringBuilder?sb?=?new?StringBuilder();
????????????String?res?=?URLEncoder.encode(resourceName,?"UTF-8");
????????????String?sig?=?URLEncoder.encode(generatorSignature(version,?resourceName,?expirationTime,?accessKey,?signatureMethod),?"UTF-8");
????????????sb.append("version=")
????????????????????.append(version)
????????????????????.append("&res=")
????????????????????.append(res)
????????????????????.append("&et=")
????????????????????.append(expirationTime)
????????????????????.append("&method=")
????????????????????.append(signatureMethod)
????????????????????.append("&sign=")
????????????????????.append(sig);
????????????return?sb.toString();
????????}
????
????????public?static?String?generatorSignature(String?version,?String?resourceName,?String?expirationTime,?String?accessKey,?String?signatureMethod)?
????????????????throws?NoSuchAlgorithmException,?InvalidKeyException?{
????????????String?encryptText?=?expirationTime?+?"n"?+?signatureMethod?+?"n"?+?resourceName?+?"n"?+?version;
????????????String?signature;
????????????byte[]?bytes?=?HmacEncrypt(encryptText,?accessKey,?signatureMethod);
????????????signature?=?Base64.getEncoder().encodeToString(bytes);
????????????return?signature;
????????}
????
????????public?static?byte[]?HmacEncrypt(String?data,?String?key,?String?signatureMethod)
????????????????throws?NoSuchAlgorithmException,?InvalidKeyException?{
????????????//根據(jù)給定的字節(jié)數(shù)組構(gòu)造一個(gè)密鑰,第二參數(shù)指定一個(gè)密鑰算法的名稱
????????????SecretKeySpec?signinKey?=?null;
????????????signinKey?=?new?SecretKeySpec(Base64.getDecoder().decode(key),
????????????????????"Hmac"?+?signatureMethod.toUpperCase());
????????????//生成一個(gè)指定?Mac?算法?的?Mac?對象
????????????Mac?mac?=?null;
????????????mac?=?Mac.getInstance("Hmac"?+?signatureMethod.toUpperCase());
????????????//用給定密鑰初始化?Mac?對象
????????????mac.init(signinKey);
????????????//完成?Mac?操作
????????????return?mac.doFinal(data.getBytes());
????????}
????
????????public?enum?SignatureMethod?{
????????????SHA1,?MD5,?SHA256;
????????}
????
????????public?static?void?main(String[]?args)?throws?UnsupportedEncodingException,?NoSuchAlgorithmException,?InvalidKeyException?{
????????????String?version?=?"2022-05-01";
????????????String?resourceName?=?"userid/12321";
????????????//用戶自定義token過期時(shí)間
????????????String?expirationTime?=?System.currentTimeMillis()?/?1000?+?3600?+?"";
????????????String?signatureMethod?=?SignatureMethod.SHA1.name().toLowerCase();
????????????String?accessKey?=?"KuF3NT/jUBJ62LNBB/A8XZA9CqS3Cu79B/ABmfA1UCw=";
????????????String?token?=?assembleToken(version,?resourceName,?expirationTime,?signatureMethod,?accessKey);
????????????System.out.println("Authorization:"?+?token);
????????}
????}
go代碼示例
func??(s?*SignService)?GenerateSign(params_map?map[string]string,?access_key?string)?(string,?error){
????signature_str?:=?params_map["et"]?+?"n"?+?params_map["method"]?+?"n"?+?params_map["res"]?+?"n"?+?params_map["version"]
????hmac_str?:=?""
????switch?strings.ToLower(params_map["method"])?{
????????case?"sha1":
?????????????hmac_str?=?tools.HmacSha1(signature_str,?tools.Base64Decode(access_key))
????????case?"sha256":
????????????hmac_str?=?tools.HmacSha256(signature_str,?tools.Base64Decode(access_key))
????????case?"md5":
????????????hmac_str?=?tools.HmacMd5(signature_str,?tools.Base64Decode(access_key))
????????default:
????????????return?"",errors.New("簽名參數(shù)錯(cuò)誤!")
????}
????sign?:=tools.Base64Encode(hmac_str)
????return?sign,nil
}
func?Base64Encode(message?string)?string?{
????return?base64.StdEncoding.EncodeToString([]byte(message))
}
func?Base64Decode(message?string)?string?{
????decode_str,?err?:=?base64.StdEncoding.DecodeString(message)
????if?err?!=?nil?{
????????return?""
????}
????return?string(decode_str)
}
func?HmacSha256(data?string,?secret?string)?string?{
????h?:=?hmac.New(sha256.New,?[]byte(secret))
????h.Write([]byte(data))
????return?string(h.Sum(nil))
}
func?HmacMd5(data?string,?secret?string)?string?{
????h?:=?hmac.New(md5.New,?[]byte(secret))
????h.Write([]byte(data))
????return?string(h.Sum(nil))
}
func?HmacSha1(data?string,?secret?string)?string?{
????h?:=?hmac.New(sha1.New,?[]byte(secret))
????h.Write([]byte(data))
????return?string(h.Sum(nil))
}
php代碼示例
class?SafetyAuth
{
????private??$_version?=?'2022-05-01';//版本
????private??$_method?=?'sha1';//加密方法,還可以用md5、sha256
????private??$_access_key;//訪問密鑰
????private??$_res?;//資源參數(shù)
????private??$_et;//到期時(shí)間戳
????private??$_expiration;//有效期,有效時(shí)間
????public?function?__construct($access_key,?$expiration,$res){
????????$this->_expiration?=?$expiration;
????????$this->_access_key?=?$access_key;
????????$this->_res?=?$res;
????}
????//生成sign
????private?function?_makeSign()?{
????????date_default_timezone_set('PRC');
????????$this->_et?=time()?+?$this->_expiration;
????????$string_for_signature?=?$this->_et?.?"n"?.?$this->_method?.?"n"?.?$this->_res??.?"n"?.?$this->_version;
????????$b64_decode_acckey?=?base64_decode($this->_access_key);
????????$hmac_key?=?hash_hmac($this->_method,?$this->_strToUtf8($string_for_signature),?$b64_decode_acckey,?true);
????????$sign?=?base64_encode($hmac_key);
????????return?$sign;
????}
????private?function?_strToUtf8($str)?{
????????$encode?=?mb_detect_encoding($str,?array("ASCII",'UTF-8',"GB2312","GBK",'BIG5'));
????????if?($encode?==?'UTF-8')?{
????????????return?$str;
????????}?else?{
????????????return?mb_convert_encoding($str,?'UTF-8',?$encode);
????????}
????}
????//生成token
????public?function?makeToken()?{
????????$sign?=?$this->_makeSign();
????????$token?=?sprintf("version=2022-05-01&res=%s&et=%s&method=sha1&sign=%s",?urlencode($this->_res),?$this->_et,?urlencode($sign));
????????return?$token;
????}
}
2.2 搭建開發(fā)環(huán)境
開發(fā)工具下載:https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html
2.3 小程序頁面設(shè)計(jì)
1.?創(chuàng)建微信小程序工程
打開微信開發(fā)者工具,選擇“創(chuàng)建項(xiàng)目”,在創(chuàng)建時(shí)選擇JavaScript模板。接著,設(shè)置項(xiàng)目名稱、AppID(如果是測試可以使用“測試號(hào)”)、項(xiàng)目目錄等。
2.?修改?app.json
?文件
app.json
?是小程序的全局配置文件,配置小程序的頁面路徑、窗口樣式等。你需要在該文件中定義頁面。
{
??"pages":?[
????"pages/index/index",
????"pages/details/details",
????"pages/control/control"
??],
??"window":?{
????"navigationBarTitleText":?"智能電度表",
????"navigationBarBackgroundColor":?"#2e2e2e",
????"navigationBarTextStyle":?"white"
??}
}
這里我們假設(shè)你有三個(gè)頁面:
??index:主頁面,展示電度表的主要信息。
??details:展示更詳細(xì)的電力消耗歷史記錄。
??control:用于控制電度表的繼電器開關(guān)、查看余額等。
3.?創(chuàng)建頁面目錄
在項(xiàng)目目錄下,創(chuàng)建頁面目錄,并創(chuàng)建相應(yīng)的文件:
/pages
??/index
????-?index.wxml
????-?index.wxss
????-?index.js
????-?index.json
??/details
????-?details.wxml
????-?details.wxss
????-?details.js
????-?details.json
??/control
????-?control.wxml
????-?control.wxss
????-?control.js
????-?control.json
4.?設(shè)計(jì)靜態(tài)頁面(index.wxml
)
在?index.wxml
?中,展示電度表的當(dāng)前狀態(tài)(電壓、電流、功率、電量等)。例如:
<view?class="container">
??<view?class="header">
????<text?class="title">智能電度表</text>
??</view>
??<view?class="status">
????<text?class="label">電壓:</text>
????<text?class="value">{{voltage}}?V</text>
??</view>
??
??<view?class="status">
????<text?class="label">電流:</text>
????<text?class="value">{{current}}?A</text>
??</view>
??
??<view?class="status">
????<text?class="label">功率:</text>
????<text?class="value">{{power}}?W</text>
??</view>
??<view?class="status">
????<text?class="label">電量:</text>
????<text?class="value">{{energy}}?kWh</text>
??</view>
??<button?class="button"?bindtap="goToDetails">查看歷史</button>
??<button?class="button"?bindtap="goToControl">控制電度表</button>
</view>
5.?設(shè)置樣式(index.wxss
)
為頁面元素設(shè)置一些基本的樣式。
.container?{
??padding:?20px;
}
.header?{
??text-align:?center;
??margin-bottom:?20px;
}
.title?{
??font-size:?30px;
??font-weight:?bold;
}
.status?{
??display:?flex;
??justify-content:?space-between;
??margin-bottom:?15px;
}
.label?{
??font-size:?20px;
}
.value?{
??font-size:?20px;
??color:?#ff7f00;
}
.button?{
??width:?100%;
??padding:?10px;
??margin-top:?15px;
??background-color:?#ff7f00;
??color:?white;
??border-radius:?5px;
??text-align:?center;
??font-size:?18px;
}
6.?頁面邏輯(index.js
)
在?index.js
?中,可以編寫頁面的邏輯代碼,主要是展示數(shù)據(jù)(電壓、電流、功率等)。這些數(shù)據(jù)自云平臺(tái)或本地存儲(chǔ)。為了簡化示例,假設(shè)數(shù)據(jù)是靜態(tài)的。
Page({
??data:?{
????voltage:?220.5,
????current:?5.0,
????power:?1100,
????energy:?35.2
??},
??onLoad:?function()?{
????//?在頁面加載時(shí)獲取電度表數(shù)據(jù)(此處可以調(diào)用API)
????console.log('電度表數(shù)據(jù)加載');
??},
??goToDetails:?function()?{
????wx.navigateTo({
??????url:?'/pages/details/details'
????});
??},
??goToControl:?function()?{
????wx.navigateTo({
??????url:?'/pages/control/control'
????});
??}
});
7.?詳細(xì)頁面(details.wxml
)
在?details.wxml
?中展示電力歷史記錄。
<view?class="container">
??<view?class="header">
????<text?class="title">用電歷史記錄</text>
??</view>
??<view?class="history-list">
????<view?class="history-item"?wx:for="{{history}}"?wx:key="index">
??????<text?class="date">{{item.date}}</text>
??????<text?class="usage">用電量:?{{item.energy}}?kWh</text>
????</view>
??</view>
??<button?class="button"?bindtap="goBack">返回首頁</button>
</view>
8.?控制頁面(control.wxml
)
在?control.wxml
?中,可以設(shè)計(jì)一個(gè)界面,允許用戶控制電度表(例如控制繼電器、查看余額等)。
<view?class="container">
??<view?class="header">
????<text?class="title">控制電度表</text>
??</view>
??<button?class="button"?bindtap="turnOnRelay">開啟電源</button>
??<button?class="button"?bindtap="turnOffRelay">關(guān)閉電源</button>
??
??<view?class="balance">
????<text?class="label">剩余電量:</text>
????<text?class="value">{{remaining_balance}}?kWh</text>
??</view>
??<button?class="button"?bindtap="goBack">返回首頁</button>
</view>
9.?頁面邏輯(details.js
?和?control.js
)
這些頁面的邏輯和?index.js
?類似。處理用戶交互,比如獲取歷史記錄、控制電源開關(guān)等。
例如,在?details.js
?中可以從云平臺(tái)或本地存儲(chǔ)獲取用電歷史數(shù)據(jù)。
Page({
??data:?{
????history:?[
??????{?date:?'2025-02-17',?energy:?1.5?},
??????{?date:?'2025-02-16',?energy:?1.2?},
??????{?date:?'2025-02-15',?energy:?2.0?}
????]
??},
??goBack:?function()?{
????wx.navigateBack();
??}
});
10.?運(yùn)行與測試
完成代碼后,可以在微信開發(fā)者工具中進(jìn)行調(diào)試和測試,確保頁面的顯示效果符合預(yù)期,并且各個(gè)頁面的跳轉(zhuǎn)、數(shù)據(jù)展示功能正常。
微信小程序的界面展示了智能電度表的核心功能:實(shí)時(shí)電力監(jiān)控、歷史數(shù)據(jù)查看、設(shè)備控制等。通過簡單的設(shè)計(jì)和實(shí)現(xiàn),用戶能夠方便地查看電力消耗情況,并進(jìn)行相關(guān)操作。這個(gè)界面為后續(xù)增加更多功能(如實(shí)時(shí)數(shù)據(jù)同步、余額管理等)提供了良好的基礎(chǔ)。
三、STM32代碼設(shè)計(jì)
當(dāng)前項(xiàng)目使用的相關(guān)軟件工具、模塊源碼已經(jīng)上傳到網(wǎng)盤:https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink
main.c
包含了主控制代碼,初始化硬件模塊、處理數(shù)據(jù)采集、功率計(jì)算、LCD顯示、Wi-Fi通信、MQTT數(shù)據(jù)上傳等功能。
#include?"stm32f1xx_hal.h"
#include?"lcd.h"
#include?"wifi_module.h"
#include?"mqtt_client.h"
#include?"power_monitor.h"
#include?"relay_control.h"
#include?"buzzer.h"
#include?"tim.h"
#include?"usart.h"
#include?"gpio.h"
//?定義全局變量
float?voltage?=?0.0f;
float?current?=?0.0f;
float?power?=?0.0f;
float?energy?=?0.0f;
float?remaining_balance?=?100.0f;??
//?MQTT連接參數(shù)
const?char?*mqtt_broker?=?"?";
const?char?*mqtt_topic?=?"?";
const?char?*mqtt_client_id?=?"";
//?初始化所有硬件模塊
void?System_Init(void)
{
????HAL_Init();??//?初始化HAL庫
????SystemClock_Config();??//?配置系統(tǒng)時(shí)鐘
????MX_GPIO_Init();??//?初始化GPIO
????MX_USART1_UART_Init();??//?初始化串口
????MX_TIM2_Init();??//?初始化定時(shí)器
????MX_LCD_Init();??//?初始化LCD顯示屏
????MX_WiFi_Init();??//?初始化Wi-Fi模塊
????MX_MQTT_Init();??//?初始化MQTT客戶端
????MX_Relay_Init();??//?初始化繼電器
????MX_Buzzer_Init();??//?初始化蜂鳴器
}
//?獲取電壓、電流、功率和電量數(shù)據(jù)
void?Get_Power_Data(void)
{
????voltage?=?Get_Voltage();??//?從電壓互感器獲取電壓
????current?=?Get_Current();??//?從電流互感器獲取電流
????power?=?Calculate_Power(voltage,?current);??//?根據(jù)電壓和電流計(jì)算功率
????energy?=?Calculate_Energy(power);??//?根據(jù)功率計(jì)算電量
}
//?更新LCD顯示屏上的電力數(shù)據(jù)
void?Update_LCD_Display(void)
{
????LCD_Clear();
????LCD_Printf("Voltage:?%.2f?V",?voltage);
????LCD_Printf("Current:?%.2f?A",?current);
????LCD_Printf("Power:?%.2f?W",?power);
????LCD_Printf("Energy:?%.2f?kWh",?energy);
}
//?上傳數(shù)據(jù)到云平臺(tái)
void?Upload_Data_To_Cloud(void)
{
????char?payload[256];
????snprintf(payload,?sizeof(payload),?"{"voltage":?%.2f,?"current":?%.2f,?"power":?%.2f,?"energy":?%.2f}",?voltage,?current,?power,?energy);
????
????MQTT_Publish(mqtt_broker,?mqtt_topic,?payload);??//?將數(shù)據(jù)通過MQTT協(xié)議發(fā)布到云平臺(tái)
}
//?檢查功率是否過載,并進(jìn)行保護(hù)
void?Check_Overload_Protection(void)
{
????if?(power?>?200.0f)??//?設(shè)定功率過載閾值為200W
????{
????????Relay_Off();??//?斷開繼電器,切斷電源
????????Buzzer_Alert();??//?發(fā)出蜂鳴器報(bào)警
????}
}
//?主循環(huán)
int?main(void)
{
????//?系統(tǒng)初始化
????System_Init();
????//?主循環(huán)
????while?(1)
????{
????????//?獲取電力數(shù)據(jù)
????????Get_Power_Data();
????????
????????//?更新LCD顯示屏
????????Update_LCD_Display();
????????//?檢查功率是否過載,并進(jìn)行保護(hù)
????????Check_Overload_Protection();
????????//?上傳數(shù)據(jù)到云平臺(tái)
????????Upload_Data_To_Cloud();
????????//?每10秒鐘更新一次數(shù)據(jù)
????????HAL_Delay(10000);??//?延時(shí)10秒
????????//?周期性任務(wù)(Wi-Fi連接、MQTT保持連接等)
????????WiFi_Connect();
????????MQTT_KeepAlive();
????}
}
代碼說明:
1.?初始化函數(shù):System_Init()
?中包含了所有硬件的初始化,包括時(shí)鐘、GPIO、UART、定時(shí)器、LCD顯示、Wi-Fi模塊、MQTT客戶端、繼電器和蜂鳴器。
2.?獲取電力數(shù)據(jù):Get_Power_Data()
?調(diào)用相應(yīng)的電壓、電流獲取函數(shù)并計(jì)算功率和電量。
3.?更新LCD顯示:Update_LCD_Display()
?在LCD屏上實(shí)時(shí)顯示電壓、電流、功率和電量。
4.?上傳數(shù)據(jù)到云平臺(tái):Upload_Data_To_Cloud()
?將采集到的數(shù)據(jù)封裝成JSON格式并通過MQTT協(xié)議上傳到云平臺(tái)。
5.?過載保護(hù):Check_Overload_Protection()
?檢查功率是否超過預(yù)設(shè)的200W閾值,如果過載,斷開繼電器并觸發(fā)蜂鳴器報(bào)警。
6.?主循環(huán):main()
?函數(shù)是程序的主執(zhí)行部分,在其中定時(shí)采集數(shù)據(jù)、更新LCD、檢查過載保護(hù)并上傳數(shù)據(jù)到云平臺(tái)。
四、總結(jié)
本項(xiàng)目設(shè)計(jì)并實(shí)現(xiàn)了一款基于STM32的智能電度表,提升家庭和商業(yè)用戶的電能管理能力。通過實(shí)時(shí)監(jiān)控電力使用情況、靈活控制電源、提供安全保護(hù)功能,并與云平臺(tái)和微信小程序?qū)崿F(xiàn)數(shù)據(jù)同步,項(xiàng)目實(shí)現(xiàn)了電能管理的智能化、便捷化和高效化。
項(xiàng)目的主要功能包括電能監(jiān)測與數(shù)據(jù)采集、預(yù)付費(fèi)功能、功率過載保護(hù)、用電記錄與計(jì)時(shí)、遠(yuǎn)程控制與數(shù)據(jù)上傳等,極大地提高了用戶對電能的控制能力和使用效率。通過電壓互感器和電流互感器,系統(tǒng)能夠精確測量電壓、電流、功率等電力數(shù)據(jù),確保電能使用的實(shí)時(shí)性和準(zhǔn)確性。
在技術(shù)實(shí)現(xiàn)方面,STM32作為核心控制單元,承擔(dān)了數(shù)據(jù)采集、功率計(jì)算、顯示控制等任務(wù)。通過Wi-Fi模塊和MQTT協(xié)議,系統(tǒng)實(shí)現(xiàn)了與OneNet物聯(lián)網(wǎng)平臺(tái)和微信小程序的實(shí)時(shí)數(shù)據(jù)同步,方便用戶隨時(shí)了解電力消耗情況,進(jìn)行余額查詢和充值操作。此外,系統(tǒng)還具備過載保護(hù)功能,當(dāng)功率超出設(shè)定閾值時(shí),自動(dòng)切斷電源,避免設(shè)備損壞或安全隱患。
本項(xiàng)目的創(chuàng)新之處在于將傳統(tǒng)電度表的功能與現(xiàn)代物聯(lián)網(wǎng)技術(shù)相結(jié)合,提供了更智能、更便捷的電能管理解決方案。通過微信小程序,用戶不僅可以實(shí)時(shí)查看電力使用數(shù)據(jù),還可以進(jìn)行電器設(shè)備的遠(yuǎn)程控制,提升了用戶體驗(yàn)和用電安全。
隨著智能家居和物聯(lián)網(wǎng)技術(shù)的不斷發(fā)展,本項(xiàng)目可進(jìn)一步優(yōu)化和擴(kuò)展,支持更多智能電器和能源管理功能,如設(shè)備狀態(tài)監(jiān)控、智能調(diào)節(jié)電力負(fù)載等,進(jìn)一步提升用戶對能源使用的智能管理能力。
本項(xiàng)目為電能管理領(lǐng)域帶來了創(chuàng)新性的解決方案,充分利用了STM32的高性能處理能力、Wi-Fi模塊的無線通信功能,以及MQTT協(xié)議的數(shù)據(jù)傳輸能力,成功實(shí)現(xiàn)了一個(gè)集成化、智能化的電度表系統(tǒng),具備了較強(qiáng)的實(shí)用價(jià)值和市場潛力。