我们在做物联网应用时,电流检测是监控设备能耗、优化电源管理的重要手段,本文介绍如何利用MicroPython开发ESP32与ACS712霍尔电流传感器模块,实现高精度电流测量,并提供硬件连接、代码实现及校准方法,适用于智能家居、工业自动化等场景。
ACS712模块特性
- 低噪声模拟信号路径,确保信号传输过程中的高信噪比。
- 通过新增FILTER引脚设置器件带宽,可灵活调节滤波范围以适应不同应用场景。
- 阶跃输入电流下输出上升时间为5微秒,可快速响应电流变化。
- 具有80kHz带宽,支持高频电流检测。
- 在环境温度为25°C时总输出误差仅为1.5%,常温下测量精度高。
- 小尺寸、薄型SOIC8封装,节省电路板空间,适合紧凑设计。
- 内阻低至1.2 mΩ,可减少电流测量时的额外功耗。
- 引脚1-4与引脚5-8之间的最小隔离电压为2.1 kVRMS(千伏有效值,隔离电压单位),电气隔离安全性高。
- 5.0 V单电源供电,大大简化系统电源设计。
- 输出灵敏度66至185 mV/A(依型号而定),适配不同量程(±5A/±20A/±30A)。
- 输出电压与交流或直流电流成比例,可兼容交/直流测量。
- 出厂校准确保高精度,无需用户额外校准。
- 极稳定的输出偏移电压,降低温度漂移影响。
- 近乎零磁滞,可提升重复测量一致性。
- 输出与电源电压比率相关,电压波动时仍保持比例关系,减少供电不稳定的干扰。
ACS712的典型应用
下图是ACS712的典型应用原理图,ACS712输出模拟信号VOUT(输出电压),该信号与检测范围内的单向或双向交流/直流主电流IP呈线性变化。推荐使用CF(滤波电容)进行噪声管理,其容值需根据具体应用场景选择。
管脚说明
编号 | 名称 | 描述 |
---|---|---|
1、2 | IP+ | 被测电流输入正极端子,内置保险丝 |
3、4 | IP- | 被测电流输入负极端子,内置保险丝 |
5 | GND | 信号地端子(参考电平基准) |
6 | FILTER | 连接外部电容以设置器件带宽的引脚(电容值决定滤波频率) |
7 | VIOUT | 模拟信号输出引脚,输出电压与电流值成比例(范围:0~VCC) |
8 | VCC | 模块电源正极输入端子(典型值5V) |
ACS712的量程
ACS712根据电流的量程不同有三种不同的芯片,分别是5A、10A和30A的芯片。以5A为例,测量时当电流为0时,输出端电压为2.5V,根据被测电流的方向不同,输出端的电压会大于或小于2.5V,当测量直流电流时,可以通过电压值来判断电流的方向,如果不考虑电流方向,可以取测量值与2.5V差值的绝对值。需要注意的是,输入电压对测量结果会产生明显的影响,在使用时应该尽量保持输入电压的稳定,并且根据输入电压的不同来校准一下零点电压。
ACS712模组
这是万能的某宝能买到的最常见的ACS712电流测量模组,分为5A、10A、30A的量程,不同的量程芯片不一样。
这个模组电路非常简单,下面是它的原理图:
电路中有一个电源指示led,有两个滤波电容,测量信号直接从7脚接出,使用时需要注意输出管脚电压与输入电路电压的匹问题。
ESP32使用ACS712模块
ESP32的ADC允许的输入电压范围为0-3.3v,超过此范围可能会导致芯片损坏,而ACS712的额定工作电压是5V,理论上的输出电压为0-5V,会超过ESP32的允许电压,因此,需要使用分压电路对输出电压进行衰减,如下图所示,这是ACS712手册中推荐的一个针对3.3V的AD转换器的电路。通过电阻分压后,输出端的电压为4V,通过一个二极管后,压降约为0.7V,所以输出电压的最大值为:5*0.8-0.7=3.3V。
源码示例
下面是使用MicroPython和ESP32读取ACS712电流值的例子,可以根据自己不同的情况来确定零电流时的电压
SENSITIVITY = 0.1 # 100mV/A(ACS712-20A型号)
ZERO_VOLTAGE = 2.345 # 零电流时电压
def read_current(adc):
"""读取电流值(单位:A)"""
sum_val = 0
for _ in range(20):
sum_val += adc.read()
time.sleep_ms(1)
adc_value = sum_val / 20
print("adc 值:", adc_value)
voltage = adc_value * 3.3 / 4095
print("电压值:", voltage)
return (voltage - ZERO_VOLTAGE) / SENSITIVITY
def main():
# ADC配置(GPIO4)
adc = machine.ADC(machine.Pin(4))
adc.atten(machine.ADC.ATTN_11DB) # 0-3.3V量程
for i in range(100):
print('current is:', read_current(adc))
time.sleep(1)
main()