Вольт-ампер-energy-метр на Arduino. Часть 2. Амперметр | 04s.ru

Вольт-ампер-energy-метр на Arduino. Часть 2. Амперметр

Исходные данные и доработка

Итак к этому момент у нас есть вольтметр постоянного напряжения с пределом 0..20в  (смотрите предыдущую часть). Теперь мы добавляем к нему амперметр 0..5а. Для этого немного модифицируем схему — она станет проходной, то есть имеет как вход так и выход.

Часть касающуюся отображения на LCD я убрал — она не будет меняться. Впринципе основной новый элемент — шунт Rx на 0.1 Ом. Цепочка R1-C1-VD1 служит для защиты аналогового входа. Такую же имеет смысл поставить и по входу A0. Поскольку мы предполагаем достаточно большие токи, есть требования к монтажу — силовые линии должны быть выполнены достаточно толстым проводом и соединяться с выводами шунта непосредственно (проще говоря, припаяны), иначе показания будут далеки от реальности. Есть так же замечание по току — впринципе опорное напряжение 1.1в позволяет регистрировать на шунте 0.1 Ом ток до 11 ампер с точностью немного хуже 0.01а, но при падении на Rх такого напряжения выделяемая мощность превысит 10 Вт, что совсем не весело. Для решения проблемы можно было бы использовать усилитель с коэффициентом усиления 11 на качественном ОУ  и шунт на 10 мОм (0.01Ом). Но пока мы не будем усложнять себе жизнь и просто ограничимся в токе до 5а (при этом мощность Rx можно выбрать порядка 3-5 Вт).

На этом этапе меня ждал сюрприз — оказалось что АЦП контроллера имеет достаточно большое смешение нуля — около -3мВ. То есть АЦП просто не видит сигналы менее 3мВ, а сигналы чуть большего уровня видны с характерной неточностью -3мВ, что портит линейность в начале диапазона. Беглый поиск не дал явных ссылок на такую проблему (смещение нуля это нормально, но оно должно быть существенно меньше), поэтому вполне возможно это проблема конкретного экземпляра Atmega 328. Решение я выбрал двоякое — по напряжению — программную ступеньку в начале диапазона (отображение начинается с 0.06 вольт), по току — подтягивающий резистор на шину 5в. Резистор обозначен пунктиром.

Исходный код

Полную версию этого вольт-ампер-метра (в варианте с I2C) можно скачать по ссылке в конце статье. Далее я покажу изменения в исходном коде.  Добавилось чтение аналогового входа A1 с таким же усреднением как и для вольтметра. По сути это тот же вольтметр, только без делителя, а амперы мы получаем по формуле Ома: I = U/Rx (например, если падение напряжения на Rx = 0.01 В, то ток равен 0.1А). Также я ввел константу усиления по току AmpMult — на будущее. Константу AmpRx с сопротивлением шунта вероятно придется подобрать — учесть неточность резистора шунта. Ну и раз уже это это вольт-ампер-метр и на дисплее 1602 еще осталось место, то осталось вывести текущую потребляемую мощность в ваттах, получив не сложный дополнительный функционал.

....
// Аналоговый вход
#define PIN_VOLT A0
#define PIN_AMP A1
// Внутреннее опорное напряжение (подобрать)
const float VRef = 1.10;
// Коэффициент входного резистивного делителя (Rh + Rl) / Rl. IN <-[ Rh ]--(analogInPin)--[ Rl ]--|GND
const float VoltMult = (180.0 + 10.0) / 10.0;
// Усиление по току
const float AmpMult = 1.0;
// Сопротивление шунта в омах (подобать)
const float AmpRx = 0.098;

....
void loop() {
 unsigned long CalcStart = millis();
 float InVolt = 0;
 float InAmp = 0;
 int ReadCnt = 0;
 // Чтение из порта с усреднением
 while ((millis() - CalcStart) < REFRESH_TIME) {
 InVolt += analogRead(PIN_VOLT);
 InAmp += analogRead(PIN_AMP);
 ReadCnt++;
 }
 InVolt = InVolt / ReadCnt;
 InAmp = InAmp / ReadCnt;
 // Компенсация смещения 0 АЦП (подобрать)
 if (InVolt > 0.2) InVolt += 3;
 // Перевод в вольты (In: 0..1023 -> (0..VRef) scaled by Mult)
 float Volt = InVolt * VoltMult * VRef / 1023;
 float Amp = InAmp * VRef / AmpMult / AmpRx / 1023 ;
 // Для учета падения на шунте раскомментировать 2 строки
 //float RxVolt = InAmp * VRef / 1023 / AmpMult;
 // Volt -= RxVolt;
 float Watt = Volt * Amp;
 // Вывод данных
 lcd.setCursor (8, 0);
 lcd.print(Watt);
 lcd.print("W ");
 lcd.setCursor (0, 1);
 lcd.print(Volt);
 lcd.print("V ");
 lcd.setCursor (8, 1);
 lcd.print(Amp);
 lcd.print("A ");
}
5/5 - (1 голос)


Место для продажи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *