![ESP32 ACS712 TL431 AC RMS](http://ardudevelop.eu/wp-content/uploads/2024/08/ESP32-ACS712-TL431-AC-RMS.jpg)
В тази статия ще разгледаме как да измерим AC RMS ток с помощта на ESP32-C3 Super Mini и външен източник на опорно напрежение (TL431). Ще обясним кода стъпка по стъпка и ще предоставим всички необходими подробности, за да можете сами да реализирате проекта. Ще използваме и библиотека за външно опорно напрежение, която ще включим в проекта. С нея се запознахме в нашата предишна статия “Измерване на напрежение с ESP32-C3 и външно опорно напрежение с TL431“
Необходими компоненти
- ESP32-C3 Super Mini
- Сензор за ток ACS712 (5A версия)
- Външен референтен източник TL431
- Резистор 330ом и кабели за свързване
- Бредборд
- Мултицет за калибриране
Може да видите пин диаграмата (pinout) на развойната платка ESP32-C3 Super Mini в нашето ревю за нея.
Схема на свързване
![ESP32-C3 ACS712 TL431 AC RMS](http://ardudevelop.eu/wp-content/uploads/2024/08/ESP32-C3-ACS712-TL431-AC-RMS-1024x513.jpg)
Свържете сензора ACS712 към ESP32-C3 както следва:
- VCC на ACS712 към 5V на ESP32
- GND на ACS712 към GND на ESP32
- OUT на ACS712 към ADC0 (Pin 0) на ESP32
Свържете референтния източник TL431 към ESP32-C3 както следва:
- VCC на TL431 към 5V на ESP32 през резистор 330ом
- GND на TL431 към GND на ESP32
- REF на TL431 към ADC1 (Pin 1) на ESP32
Може да разгледате схема на свързване на TL431 в нашата статия за “Опорно напрежение (Voltage Reference)“.
Документация на ACS712
ACS712Библиотека за Външно Опорно Напрежение (VRef)
from machine import Pin, ADC
import time
class VRef:
def __init__(self, pin, known_voltage, num_samples=500):
self.adc = ADC(Pin(pin))
self.adc.width(ADC.WIDTH_12BIT)
self.adc.atten(ADC.ATTN_11DB)
self.known_voltage = known_voltage
self.num_samples = num_samples
def get_vref(self):
total = 0
for _ in range(self.num_samples):
total += self.adc.read()
time.sleep(0.001) # Малко забавяне между прочитанията (1 ms)
avg_value = total / self.num_samples
ref_voltage = (self.known_voltage * 4095) / avg_value
return ref_voltage
Основен Код за Измерване на RMS Ток
from machine import Pin, ADC
from vref import VRef
import time
import math
# Конфигурация на ADC и пин за измерване
adc = ADC(Pin(0))
adc.atten(ADC.ATTN_11DB) # Обхват на ADC (максимално входно напрежение 3.3V)
adc.width(ADC.WIDTH_12BIT) # Разделителна способност на ADC
# инстанция за VRef
vref = VRef(pin=1, known_voltage=2.5) # Използване на външен източник TL431
# Параметри на ACS712
V_REF = vref.get_vref() # Референтно напрежение на ADC (V)
SENSITIVITY = 0.185 # Чувствителност на ACS712 (V/A) за 5A версия
# Параметри на EMA филтъра
alpha = 0.3 # Параметър за изглаждане (между 0 и 1)
ema_current = 0
# Параметър за допълнитела външна донастройка получена при калибраци с мултимер
V_calibre = 0.1
# Функция за калибриране на нулевото напрежение (без товар)
def calibrate_zero(samples=500):
total = 0
for _ in range(samples):
total += adc.read()
time.sleep_us(10)
zero_level = total / samples
zero_level = zero_level * V_REF / 4095
return zero_level
# Калибриране на нулевото ниво
V_ZERO = calibrate_zero()
# Функция за измерване на RMS ток с EMA филтър
def measure_current_rms(samples=1000, delay=1):
global ema_current
total = 0
for _ in range(samples):
voltage = adc.read() * V_REF / 4095 # Преобразуване на ADC стойността в напрежение
current = (voltage - V_ZERO) / SENSITIVITY # Изчисляване на тока
total += current ** 2
time.sleep_us(delay)
rms_current = math.sqrt(total / samples) # Изчисляване на RMS тока
# Прилагане на EMA филтър
ema_current = (alpha * rms_current) + ((1 - alpha) * ema_current)
return ema_current
while True:
current = measure_current_rms() - V_calibre
if current < 0.01:
current = 0
print("RMS Current = ", round(current, 2), "A")
print("Calibrate_Zero = " , round(calibrate_zero(), 2), "V")
print("Vref = " , round(vref.get_vref(), 2), "V")
Обяснение на кода
Импортиране на библиотеки и инициализация на ADC
from machine import Pin, ADC
from vref import VRef
import time
import math
adc = ADC(Pin(0))
adc.atten(ADC.ATTN_11DB)
adc.width(ADC.WIDTH_12BIT)
Тук импортираме необходимите библиотеки и конфигурираме ADC на пин 0 с разделителна способност 12 бита и максимално входно напрежение 3.3V.
Инициализация на VRef и параметри на ACS712
vref = VRef(pin=1, known_voltage=2.5)
V_REF = vref.get_vref()
SENSITIVITY = 0.185
Създаваме инстанция на VRef с пин 1 и известно напрежение 2.5V от TL431. Изчисляваме референтното напрежение и задаваме чувствителността на ACS712.
EMA филтър и калибрация
alpha = 0.3
ema_current = 0
V_calibre = 0.1
def calibrate_zero(samples=500):
total = 0
for _ in range(samples):
total += adc.read()
time.sleep_us(10)
zero_level = total / samples
zero_level = zero_level * V_REF / 4095
return zero_level
V_ZERO = calibrate_zero()
Настройваме параметрите на EMA филтъра. Този филтър се използва за изглаждане на измерванията, като дава повече тежест на последните измервания. Параметърът alpha определя колко тежест да се даде на новите стойности спрямо старите. Стойностите му са между 0 и 1. По лична преценка може да зададете стойности на параметър alpha между 0.2-0.4. По-надолу от 0.2 филтъра става “муден” а в по-горните стойности от 0.4 е “колеблив”. В статията ни Изглаждане на данни с EMA филтър на ESP32 с MicroPython може да се запознаете по-подробно с него както и да свалите написаната от нас библиотека за EMA филтър.
Калибриране на нулевото ниво на ACS712: Тази функция “calibrate_zero“измерва напрежението на изхода на ACS712 без товар (когато няма ток през сензора). Това е необходимо, защото изходът на ACS712 не е точно 0V при нулев ток, а е около средата на захранващото напрежение (2.5V при 5V захранване). Чрез калибриране на нулевото ниво, можем да коригираме тези измервания, за да бъдат по-точни.
Измерване на RMS ток
def measure_current_rms(samples=1000, delay=1):
global ema_current
total = 0
for _ in range(samples):
voltage = adc.read() * V_REF / 4095
current = (voltage - V_ZERO) / SENSITIVITY
total += current ** 2
time.sleep_us(delay)
rms_current = math.sqrt(total / samples)
ema_current = (alpha * rms_current) + ((1 - alpha) * ema_current)
return ema_current
Функцията “measure_current_rms” е предназначена за измерване на RMS (корен от средно квадратично) ток с помощта на ACS712 токов сензор. Тази функция използва ADC (аналогово-цифров преобразувател) на ESP32 за четене на напрежението, което се преобразува в ток. След това изчислява RMS стойността на тока и прилага EMA (експоненциално изглаждане на средната стойност) филтър за изглаждане на резултатите.
Основен цикъл
while True:
current = measure_current_rms() - V_calibre
if current < 0.01:
current = 0
print("RMS Current = ", round(current, 2), "A")
print("Calibrate_Zero = " , round(calibrate_zero(), 2), "V")
print("Vref = " , round(vref.get_vref(), 2), "V")
time.sleep(0.5)
В основния цикъл непрекъснато измерваме RMS тока и отпечатваме резултатите. корекционен фактор (V_calibre), който е определен по време на калибриране с мултицед. Също така сме включили условност когато измереният ток е по-малък от 0.01A, го задаваме на 0 за по-точни резултати при малки товари.
Тези редове отпечатват измерените стойности на екрана:
- RMS Current: Измерената стойност на RMS тока, закръглена до два знака след десетичната запетая.
- Calibrate_Zero: Нулевото напрежение, калибрирано при стартиране на програмата. Тази стойност се отпечатва, за да се провери дали нулевото напрежение остава стабилно.
- Vref: Референтното напрежение, получено от външния източник (TL431), също закръглено до два знака след десетичната запетая. Това е важно, за да се гарантира точността на ADC измерванията.
Видео Демонстрация
Заключение
Този проект показва как да използваме външен референтен източник за калибриране на ADC измерванията с ESP32-C3 Super Mini и да измерваме RMS ток с помощта на сензор ACS712. Включването на външен референтен източник подобрява точността на измерванията и прави проекта по-надежден. Следвайки стъпките и кода в тази статия, можете лесно да реализирате този проект и да го адаптирате за свои нужди.