能源監控器,無論是覆蓋整個公寓還是部署為僅監控一個設備,都為您提供了一種跟蹤您的消耗并進行必要調整的方法。雖然它們在市場上越來越多,但我心中的制造商仍然認為構建一個可以定制以滿足特定個人需求的 DIY 版本將是一個好主意。因此,在今天的教程中,我們將構建一個能夠獲取能耗并上傳到 Adafruit.io的Raspberry Pi 功耗監視器。
顯示系統如何工作的框圖如下所示。
一個接一個地挑選單位;
電流感應單元:電流感應單元由SCT -013 電流傳感器組成,可測量高達 100A 的電流,具體取決于您購買的版本。傳感器將通過導線的電流轉換成小電流,然后通過分壓器網絡饋入 ADC 。
電壓傳感單元: 雖然我無法將手放在電壓傳感器模塊上,但我們將構建一個 DIY 無變壓器電壓傳感器,使用分壓器原理測量電壓。DIY 電壓傳感器涉及分壓器階段,其中高壓轉換為適合輸入到 ADC 的值。
處理單元:處理單元包括ADC和樹莓派。ADC 接收模擬信號并將其發送到樹莓派,然后樹莓派計算消耗的確切電量并將其發送到指定的設備云。出于本教程的目的,我們將使用Adafruit.io 作為我們的設備云。我們還建立了其他
免責聲明:在我們開始之前,重要的是要提到這個項目涉及到危險的交流電源連接,如果不安全處理可能會致命。在嘗試此操作之前,請確保您有使用 AC 的經驗。
準備好?讓我們潛入。
所需組件
構建此項目需要以下組件;
Raspberry Pi 3 或 4(帶有 WiFi 加密狗的 RPI2 的過程應該相同)
ADS1115 16 位 I2C ADC
YHDC SCT-013-000
2.5A 5V MicroUSB 電源適配器
2W 10K電阻 (1)
1/2W 10K 電阻 (2)
33歐姆電阻 (1)
2W 3.3k 電阻 (1)
IN4007 二極管 (4)
3.6v 穩壓二極管 (1)
10k 電位器(或預設) (1)
50v 1uf 電容
50v 10uf 電容器 (2)
面包板
跳線
Raspberry Pi 使用的其他配件。
除了上面列出的硬件組件外,該項目還需要一些軟件依賴項和庫,我們將繼續安裝它們。
盡管無論使用何種樹莓派操作系統,本教程都可以工作,但我將使用在 Pi 3 上運行的 Raspberry Pi buster OS(也應該在 Pi 4 上工作) ,并且我假設您熟悉如何設置 Raspberry Pi Raspbian Buster OS(與以前的版本幾乎相同的過程),并且您知道如何使用 hyper 之類的終端軟件通過 SSH 進入它。如果您對此有任何疑問,本網站上有大量Raspberry Pi 教程可以提供幫助
準備 Pi
在我們開始連接組件和編碼之前,我們需要在樹莓派上執行一些簡單的任務,以確保我們準備好了。
第 1 步:啟用 Pi I2C
今天項目的核心不僅僅是樹莓派,還有基于 ADS1115 16 位 I2C 的 ADC。ADC 允許我們將模擬傳感器連接到 Raspberry Pi,因為 Pi 本身沒有內置 ADC。它通過自己的 ADC 接收數據并通過 I2C 將其轉發到樹莓派。因此,我們需要在 Pi 上啟用 I2C 通信,以便它可以與之通信。
可以通過樹莓派的配置頁面啟用或禁用 Pi 的 I2C 總線。要啟動它,請單擊桌面上的 Pi 圖標并選擇首選項,然后選擇 Raspberry pi 配置。
這應該會打開配置頁面。檢查 I2C 的已啟用單選按鈕,然后單擊 OK 保存并重新啟動 Pi 以使更改生效。
如果您在無頭模式下運行 Pi,則可以通過運行sudo raspi-config 訪問 Raspbian 配置頁面。
第 2 步:從 Adafruit 安裝 ADS11xx 庫
我們需要做的第二件事是安裝 ADS11xx python 庫,其中包含使我們能夠輕松編寫 python 腳本以從 ADC 獲取值的函數和例程。
請按照以下步驟執行此操作。
通過運行更新您的 pi;sudo apt-get update后跟sudo apt-get upgrade這將更新 pi ,確保您選擇安裝的任何新軟件都沒有兼容性問題。
接下來,運行cd ~命令以確保您位于主目錄中。
接下來,通過運行安裝 build-essentials;sudo apt-get install build-essential python-dev python-smbus git
接下來,通過運行克隆包含 ADS 庫的 Adafruit git 文件夾;git 克隆https://github.com/adafruit/Adafruit_Python_ADS1x15.git
切換到克隆文件的目錄并使用以下命令運行安裝文件;cd Adafruit_Python_ADS1x1z 后跟sudo python setup.py install
完成后,安裝現在應該完成了。
您可以通過連接 ADS1115 來測試庫安裝,如下面的原理圖部分所示,然后首先運行庫附帶的示例代碼,使用以下命令切換到其文件夾;cd 示例并使用運行示例;python simpletest.py
第 3 步:安裝 Adafruit.IO Python 模塊
正如在介紹中提到的,我們會將電壓和電流傳感器的讀數發布到 Adafruit IO Cloud,從中可以從世界各地查看它或與 IFTTT 連接以執行您想要的任何操作。
Adafruit.IO python 模塊包含我們將利用的子例程和函數,以便輕松地將數據流式傳輸到云。請按照以下步驟安裝模塊。
運行cd ~返回主目錄。
接下來,運行命令;須藤 pip3 安裝 adafruit-io。它應該安裝 Adafruit IO python 模塊。
第 4 步:設置您的 Adafruit.io 帳戶
要使用 Adafruit IO,肯定需要先創建一個帳戶并獲取 AIO 密鑰。您的 python 腳本將使用此 AIO 密鑰和您的用戶名來訪問 Adafruit IO 云服務。要創建帳戶,請訪問;https://io.adafruit.com/,點擊免費開始按鈕并填寫所有必需的參數。注冊完成后,您應該會在主頁右側看到查看 AIO 密鑰按鈕。
單擊它以獲取您的 AIO 密鑰。
復制好密鑰后,我們就可以開始了。但是,為了使將數據發送到云服務的過程更容易,您還可以創建數據將發送到的提要。(可以在此處找到有關 AIO 提要的更多信息)。由于我們基本上將發送功耗,我們將創建一個電源饋送。要創建提要,請單擊 AIO 頁面頂部的“提要”,然后單擊添加新提要。
給它起任何你想要的名字,但為了簡單起見,我將稱之為能源消耗。您還可以決定創建電壓和電流源,并調整代碼以向它們發布數據。
有了所有這些,我們現在就可以開始構建項目了。
Pi電能表電路圖
Raspberry Pi Energy Monitor項目的原理圖相對復雜,如前所述,它涉及連接到交流電壓,請確保您采取所有必要的預防措施以避免觸電。如果您不熟悉如何安全地處理交流電壓,那么讓在不通電的情況下在面包板上實現這一點的樂趣就可以令人滿意了。
原理圖涉及將電壓和電流傳感器單元連接到 ADC,然后將數據從傳感器發送到 Raspberry Pi。為了使連接更容易理解,每個單元的原理圖都單獨呈現。
電流傳感器示意圖
如下圖所示連接電流傳感器的組件。
該項目中使用的電流互感器如下圖所示,如您所見,我們從它有三根線,即地線、Cout 和 3.3V
電壓傳感器原理圖
如下圖所示連接電壓傳感器的組件。
處理單元示意圖
將所有東西與連接到樹莓派的 ADC(ADS1115)以及分別連接到 ADS1115 的引腳 A0 和 A1 的電流和電壓傳感器的輸出連接在一起。
確保兩個傳感單元的 GND 引腳都連接到 ADC 或樹莓派的 GND。
為了讓事情變得不那么不穩定,我在 Protoboard 上實現了電壓和電流傳感器。此外,不建議在面包板上構建交流電源電路。如果您這樣做,您的最終設置可能如下圖所示;
連接完成后,我們現在可以為項目編寫代碼了。
Pi 電能表的 Python 代碼
與我們的樹莓派項目一樣,我們將使用 python 為項目開發代碼。單擊桌面上的樹莓派圖標,選擇編程并啟動您要使用的任何 python 版本。我將使用 Python 3,python 3 中的一些函數可能不適用于 python 2.7。因此,如果您想使用 python 2.7,可能需要對代碼進行一些重大更改。我會將代碼分解成小片段,并在最后與您分享完整的代碼。
準備好?涼爽的。
代碼背后的算法很簡單。我們的 python 腳本查詢 ADS1115(通過 I2C)以獲取電壓和電流讀數。接收到的模擬值被接收,采樣得到電壓和電流的均方根值。計算以千瓦為單位的功率,并在特定時間間隔后發送到 Adafruit IO 饋送。
我們通過包含我們將使用的所有庫來啟動腳本。這包括內置庫,如時間和數學庫以及我們之前安裝的其他庫。?
?
導入時間 import Adafruit_ADS1x15 from Adafruit_IO import * import math
?
接下來,我們創建 ADS1115 庫的一個實例,該庫將用于處理未來的物理 ADC。
?
# 創建一個 ADS1115 ADC(16 位)實例.. adc1 = Adafruit_ADS1x15.ADS1115()
?
接下來,提供您的 adafruit IO 用戶名和“AIO”密鑰。
?
username = '在引號之間輸入你的用戶名' AIO_KEY = '你的 aio 密鑰' aio = Client(username, AIO_KEY)
?
請妥善保管鑰匙。它可用于在未經您許可的情況下訪問您的 adafruit io 帳戶。
接下來,我們創建一些變量,例如 ADC 的增益、我們想要的樣本數量并設置絕對不重要的舍入。
?
GAIN = 1 # 請參閱 ads1015/1115 文檔了解潛在價值。 samples = 200 # 從 ads1115 位置獲取的樣本數 = int(2) # 設置舍入
?
接下來,我們創建一個while循環來監控電流和電壓,并每隔一段時間將數據發送到Adafruit io。while 循環首先將所有變量設置為零。
?
while True: # 重置變量 count = int(0) datai = [] datav = [] maxIValue = 0 #樣本內的最大電流值maxVValue = 0 # 樣本內的最大電壓值IrmsA0 = 0 # 均方根電流 VrmsA1 = 0 #均方根電壓 ampsA0 = 0 #電流峰值 voltsA1 =0 #電壓 千瓦 = float(0)
?
由于我們正在使用交流電路,SCT-013 的輸出和電壓傳感器將是正弦波,因此為了從正弦波計算電流和電壓,我們需要獲得峰值。為了獲得峰值,我們將同時采樣電壓和電流(200 個樣本),并找到最高值(峰值)。
?
對于范圍內的計數(樣本): datai.insert(count, (abs(adc1.read_adc(0, gain=GAIN)))) datav.insert(count, (abs(adc1.read_adc(1, gain=GAIN)) )) # 查看是否有新的 maxValue print (datai[count]) if datai[count] > maxIValue: maxIValue = datai[count] if datav[count] > maxVValue: maxVValue = datav[count]
?
接下來,我們通過將 ADC 值轉換為實際值來標準化這些值,然后我們使用均方根方程找到 RMS 電壓和電流。
?
#使用采樣數據計算電流 # 正在使用的 sct-013 校準為 1000mV 輸出 @ 30A。 IrmsA0 = float(maxIValue / float(2047) * 30) IrmsA0 = round(IrmsA0, places) ampsA0 = IrmsA0 / math.sqrt(2) ampsA0 = round(ampsA0, places) # 計算電壓 VrmsA1 = float(maxVValue * 1100/ float(2047)) VrmsA1 = round(VrmsA1,places) voltsA1 = VrmsA1 / math.sqrt(2) voltsA1 = round(voltsA1,places) print('Voltage: {0}'.format(voltsA1)) print('Current : {0}'.format(ampsA0))
?
完成后,計算功率并將數據發布在 adafruit.io
?
#計算功率 power = round(ampsA0 * voltsA1,places) print('Power: {0}'.format(power)) #post 數據到 adafruit.io EnergyUsage = aio.feeds('EnergyUsage') aio.send_data(' EnergyUsage',功率)
?
對于免費帳戶,adafruit 要求在請求或數據上傳之間存在一定的時間延遲。?
?
# 在重復循環之前等待 time.sleep(0)
?
演示
代碼完成后,保存并點擊 python IDE 上的運行按鈕。在此之前,請確保 Pi 已通過 WiFi 或 LAN 連接到互聯網,并且您的 aio 密鑰和用戶名正確。一段時間后,您應該開始在 Adafruit.io 的提要上看到能量數據(功率)。我在演示期間的硬件設置是這樣的
更進一步,您可以在 adafruit.io 上創建一個儀表板并添加一個圖形組件,以便您可以獲得數據的圖形視圖,如下圖所示。
就是這樣,您現在可以從世界任何地方監控您的能源消耗。重要的是要注意,肯定要進行更多的微調和校準才能將其轉換為真正準確的解決方案,但我相信這幾乎可以為您提供繼續進行所需的一切。
?
#!/usr/bin/env python3 進口時間 進口 Adafruit_ADS1x15 從 Adafruit_IO 導入 * 導入數學 # 創建一個 ADS1115 ADC(16 位)實例.. adc1 = Adafruit_ADS1x15.ADS1115() 用戶名 = '你的用戶名' AIO_KEY = '你的 aio-key' aio = 客戶端(用戶名,AIO_KEY) GAIN = 1 # 請參閱 ads1015/1115 文檔了解潛在價值。 samples = 5 # 從 ads1115 中提取的樣本數 places = int(2) # 設置舍入 # 創建一個while循環來監控電流和電壓并發送到Adafruit io。 而真: # 重置變量 計數 = int(0) 數據 = [] 數據v = [] 最大值 = 0 最大V值 = 0 IrmsA0 = 0 VrmsA1 = 0 ampsA0 = 0 伏特A1 = 0 千瓦 = 浮點數(0) # 因為我們正在測量交流電路,所以 SCT-013 棒的輸出電壓傳感器將是正弦波。 # 為了從正弦波計算安培,我們需要得到峰值電壓 # 來自每個輸入并使用均方根公式 (RMS) # 這個循環將從每個輸入中獲取 200 個樣本,并為您提供最高(峰值) 對于范圍內的計數(5): datai.insert(count, (abs(adc1.read_adc(0, gain=GAIN)))) datav.insert(count, (abs(adc1.read_adc(1, gain=GAIN)))) # 查看是否有新的 maxValue 打印 (datai[count]) 如果 datai[count] > maxIValue: maxIValue = datai[count] 如果 datav[count] > maxVValue: maxVValue = datav[計數] print("新的 maxv 值:") 打印(最大V值) #使用采樣數據計算電流 # 我使用了一個 sct-013,它針對 30A 時的 1000mV 輸出進行了校準。通常上面印有 30A/1V。 打印(“繼續”) IrmsA0 = float(maxIValue / float(2047) * 30) IrmsA0 = 圓形(IrmsA0,位) ampsA0 = IrmsA0 / math.sqrt(2) # RMS 公式以獲取電流讀數以匹配電流表顯示的值。 ampsA0 = 圓形(ampsA0,地方) # 計算電壓 VrmsA1 = float(maxVValue * 1100/ float(2047)) VrmsA1 = 圓形(VrmsA1,位) voltsA1 = VrmsA1 / math.sqrt(2) # RMS 公式使電壓讀數與電壓表顯示的值相匹配。 voltsA1 = round(voltsA1, 地方) print('電壓:{0}'.format(voltsA1)) print('當前:{0}'.format(ampsA0)) #計算功率 功率 = 圓形(ampsA0 * voltsA1,位) print('Power: {0}'.format(power)) #post 數據到 adafruit.io 能源消耗 = aio.feeds('能源消耗') aio.send_data('能源消耗', 功率) # 在重復循環之前等待 時間.sleep(30)
?
?
評論
查看更多