能源监控器,无论是覆盖整个公寓还是部署为仅监控一个设备,都为您提供了一种跟踪您的消耗并进行必要调整的方法。虽然它们在市场上越来越多,但我心中的制造商仍然认为构建一个可以定制以满足特定个人需求的 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)
评论
查看更多