Измерение переменного напряжения микроконтроллером

           Довольно часто возникают задачи, которые требуют автоматизированного определения величины переменного напряжения. Например, цифровые вольтметры, стабилизаторы сети питания. В рамках данной статьи рассмотрим один из простых методов, который реализует измерение переменного напряжения при помощи микроконтроллера.

           Когда мы работаем с питанием от сети 220 В, то под этим числом подразумевается среднеквадратичное значение.

           Среднеквадратичное (действующее, эффективное) значение переменного напряжения Uср.квадр. соответствует величине постоянного напряжения, которое при прохождении через активную нагрузку выделит одинаковую мощность (выполнит такую же работу) за один и тот же промежуток времени (период). В англоязычной терминологии используется выражение Root Mean Square (RMS).

           Один из методов определения Uср.квадр. подразумевает использование соотношения между амплитудным значением Uамп и среднеквадратичным. В зависимости от формы сигнала (синусоида, прямоугольные импульсы, пилообразная или треугольная формы) это соотношение известно (например, Uамп синусоиды 50 Гц в √2 больше Uср.квадр.). Здесь √2 — это коэффициент амплитуды Kа. Ниже представлена сводная таблица форма сигналов и соответствующих коэффициентов:

           Для наглядности ниже представлен график синусоиды с указанием уровней Uср.квадр. и Uамп. Также укажем математическое выражение с применением интеграла синусоидальной функции U = Uамп * sin(t) для одного периода T:

           Для реализации такого метода (соотношение Uср.квадр. и Uамп) делается конечная выборка мгновенных значений напряжения (Uмгновен.) в течение определённого периода времени (например, обрабатывают при помощи АЦП 20 точек в течение 20 мс через каждые 1 мс). После выполняется сортировка на выявление наибольшего значения, которое соответствует амплитудному. По нему и вычисляется Uср.квадр..

           Но довольно часто в сети питания не совсем идеальный синус из-за различных помех (к той же фазе подключена мощная индуктивная нагрузка), а может мощность на нагрузке регулируется фазовым регулятором, который «вырезает» часть синусоиды. В таких случаях следует прибегнуть к измерению истинного среднеквадратичного значения — True RMS. Оно учитывает форму сигнала.

           Для вычисления истинного Uср.квадр. сигнал можно рассматривать как набор функций в пределах периода. Допустим, у нас искаженная синусоида с периодом 20 мс. Разделим её на 20 частей по 1 мс. И вот каждую миллисекунду представим как отдельную функцию сигнала. Соответственно, Uср.квадр. будет представлять собой квадратный корень из среднего арифметического значений интегралов каждой функций в квадрате. Причём каждый интеграл ограничен своим временным интервалом (1 мс), который выделен из общего периода (20 мс). Наглядно формула будет выглядеть так:

где T — период сигнала, в течение которого выполняются сбор Uмгновен.;

0…T1, T1…T2 и т.д. — периоды времени, соответствующие выделенному интервалу.

           Упрощённо формулу вычисления UTrue RMS можно представить следующим образом:

Измерение переменного напряжения с помощью ZMPT101B и Arduino

где N — количество собранных точек;

Un — величина Uмгновен. в момент регистрации точки n.

           Таким образом, величина UTrue RMS — это квадратный корень из среднего арифметического квадратов Uмгновен., зафиксированных за определённый период времени.

           Удобство этого метода в том, что нет жесткой привязки ко времени. То есть нужно просто собрать данные хотя бы из 1000 измерений подряд (при меньшем количестве точность сильно уменьшается) через цикл for в программе, без временных задержек. В идеале собираемые данные должны охватывать как минимум один-два целых периода синусоиды (20-40 мс), и это можно реализовать через прерывания по таймеру. Но в нашем эксперименте обойдёмся без прерываний.


Схема

           В качестве эксперимента создадим макет цифрового вольтметра на базе отладочной платы Arduino UNO. Попробуем определить истинное Uср.квадр. для синусоидального переменного напряжения (50 Гц).

           Чтобы при помощи микроконтроллера измерять 220 В, нужно как-то масштабировать такую величину до приемлемых 5 В. Можно воспользоваться делителем. Но лучше применить измерительный трансформатор, например, ZMPT101B (подробнее можно прочитать в этой статье). 

           Данный модуль обеспечивается гальваническую развязку между высоковольтной цепью и микроконтроллером. Также плюсом является то, что на выходе этого модуля ноль синусоиды смещён до уровня +2,5 В. Благодаря этому однополярное АЦП контроллера сможет регистрировать полную синусоиду сигнала.

           Отметим, что модуль ZMPT101B при измерении величин меньше 50 вольт искажает выходной сигнал, поэтому экспериментировать будем в диапазоне (50…220) В.

           Ниже представлена схема подключения датчика к отладочной плате:

Измерение переменного напряжения с помощью ZMPT101B и Arduino
Рисунок 1 — Схема измерения True RMS посредством ZMPT101B и Arduino UNO

           Воспользуемся лабораторным автотрансформатором (ЛАТР) в качестве источника переменного напряжения, уровень которого будем контролировать мультиметром. Для калибровки трансформатора применим осциллограф. Результаты работы будут отображаться на жидкокристаллическом индикаторе (ЖКИ), который подключается к отладочной плате по I2C-интерфейсу.


Калибровка модуля ZMPT101B

           Сперва необходимо откалибровать модуль трансформатора. Подадим на его вход с ЛАТРа Uср.квадр. = 220 В. Сигнал на выходе регистрируем посредством осциллографа. Также можно смотреть через плоттер в инструментах Arduino IDE (выход датчика подключить к аналоговому входу АЦП отладочной платы и запустить analogRead(A0)).

           Ниже представлен скриншот, демонстрирующий соответствующие осциллограммы.

Рисунок 2 — Осциллограммы сигналов на входе (бирюзовый канал CH1) и выходе (жёлтый канал CH2) модуля ZMPT101B

           Регулируя подстроечный резистор на плате модуля, нужно добиться без искажений формы синусоиды с максимальной амплитудой.

           Так как уровень ноля на выходе датчика смещён в плюс на 2,5 вольта (на осциллограмме уровень помечен как “Vb: 2.50V”. Истинный ноль канала CH2 обозначен желтой стрелочкой “2” в левом нижнем углу), то определим пиковую амплитуду синусоиды при помощи курсора в осциллографе. На рисунке выше в левом верхнем углу видно эту величину — ΔV: 1,3 В. Определим отношение амплитудных значений на входе и выходе: 310 / 1,3 = 238. Будем использовать это число как калибровочный коэффициент.


Скетч для Arduino

           Часть программы, которая отвечает за определение искомого истинного Uср.квадр., выделена в отдельную функцию readTrueRMS. Работаем с формулой:

где N — количество точек;

Un — величина Uмгновен. в момент регистрации точки n.

           Полный листинг программы:

#include <Wire.h>
#include <LiquidCrystal_I2C.h> 
LiquidCrystal_I2C lcd(0x27,16,2);

// функция для определения True RMS
float readTrueRMS() {
  float samples = 1000.0;   // Количество выборок
  float vref_volt = 5.0;    // Опорное напряжение Arduino по умолчанию
  long sum = 0;             //
  float voltage_raw = 0;    //
  float quadrant = 0;       //
  int raw = 0;              //
  float mean = 0;           //
  float true_rms = 0;       //

  // в цикле делаем выборку
  for (long i = 0; i < samples; i++) {
    raw = analogRead(A0) - 512;
    voltage_raw = (float)raw * vref_volt;
    voltage_raw /= 1023.0;
    voltage_raw *= 238.0;
    quadrant = voltage_raw * voltage_raw;
    sum += (long)quadrant;
  }

  mean = sum / samples;   // Среднее арифметическое значение квадратов
  true_rms = sqrt(mean);  // Квадратный корень из среднего арифметического

  return true_rms;
}


void setup() {

  Serial.begin(9600);

  lcd.init();                     
  lcd.backlight();  // Включаем подсветку индикатора
  lcd.print("True RMS");
  delay(200);
  lcd.clear();

}

void loop() {
  float voltage = readTrueRMS();  // определяем True RMS

  // выводим данные в монитор порта
  Serial.print("True RMS Voltage: ");
  Serial.print(voltage);
  Serial.println(" V");
    
  // выводим данные на ЖКИ
  lcd.setCursor(0, 0);
  lcd.print("True RMS: ");
  lcd.setCursor(0, 1);
  lcd.print(voltage);
  lcd.setCursor(7, 1);
  lcd.print("V");

  delay(500);
}

           Алгоритм её работы следующий:

           1) в цикле for производится сбор данных из 1000 (в формуле обозначено как N, в программе — переменная samples) измерений Uмгновен.:

for (int i = 0; i < samples; i++)

           2) в каждой итерации цикла АЦП микроконтроллера (вход A0) выполняет считывание аналогового сигнала (Uмгновен.):

raw = analogRead(A0);

           Помним, что уровень ноля на выходе датчика смещён и соответствует уровню 2,5 вольта (то есть на половину опорного напряжения Uопорное, которое по умолчанию равно уровню питания микросхемы — 5 В). А так как в Arduino UNO АЦП 10-разрядный, то 2,5 вольта соответствует 512 отсчётам (5 вольт — 1024 отсчётов). Таким образом, что убрать смещение, мы из зарегистрированной величины вычитаем соответствующие отсчёты:

raw = analogRead(A0) – 512;

           3) далее отсчёты преобразуем в вольты, умножив их на Uопорное = 5В и разделив на 1023 (10-разрядный АЦП преобразует сигнал в (0…1023) отсчётов, поскольку 210 = 1024):

voltage_raw = (float)raw * vref_volt;
voltage_raw /= 1023.0;

           4) полученное число умножим на калибровочный коэффициент (в нашем случае 238), и в итоге будем иметь реальное Uмгновен. (в формуле Un), которое было на входе датчика:

voltage_raw *= 238.0;

           5) далее возводим в квадрат Uмгновен.:

quadrant = voltage_raw * voltage_raw;

           6) и полученное число добавляем в общую сумму квадратов Uмгновен.:

sum += (long)quadrant;

           7) после того, как будет собрано и просуммировано 1000 точек, вычислим среднее арифметическое:

mean = sum / samples;

           8) и финальное — извлекаем квадратный корень:

true_rms = sqrt(mean);

Эксперимент

           На рисунке ниже представлена фотография собранного макета:

Измерение переменного напряжения с помощью ZMPT101B и Arduino
Рисунок 3 — Экспериментальный макет

           В процессе эксперимента будем поэтапно повышать Uср.квадр. на входе трансформаторного датчика, контролируя величину мультиметром. Результаты вычислений микроконтроллером будут отображаться на ЖКИ.

— 50 В

— 100 В

— 150 В

— 200 В

— 220 В

           Сравнивая показания на ЖКИ и мультиметре, видно, что полученные при помощи Arduino показания несколько выше (примерно на 3…4 %). На точность могут влиять следующие факторы:

            — калибровочный коэффициент модуля ZMPT101B (отношение амплитудных значений на входе и выходе модуля);

           — разрядность встроенного в микроконтроллер АЦП;

           — величина выборки (количество измеренных точек) для вычисления.


Выводы

           Предложенный способ является простым и достаточно эффективным методом измерения True RMS при помощи микроконтроллера.

           Точность зависит от применяемого устройства масштабирования напряжения (делитель или трансформатор) и его коэффициента передачи, разрядности АЦП и величины выборки.

           Тем не менее, рассмотренная система на базе датчика ZMPT101B и контроллера Arduino UNO позволяет создать цифровой вольтметр с погрешностью ±3 %.