Измерване на AC RMS Ток с ESP32, ACS712 и Опорно Напрежение с TL431

ESP32 ACS712 TL431 AC RMS

В тази статия ще разгледаме как да измерим 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

Свържете сензора 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. Включването на външен референтен източник подобрява точността на измерванията и прави проекта по-надежден. Следвайки стъпките и кода в тази статия, можете лесно да реализирате този проект и да го адаптирате за свои нужди.