вольтметр переменного напряжения
- Войдите на сайт для отправки комментариев
Решил поделится весьма скудными знаниями по созданию вольтметра переменного напряжения от 1 до 300 вольт. Заранее хочу выразить благодарность всем кто помог мне в этом нелегком деле!
материалы которые помогли разобратся привожу в виде ссылок:
1http://samou4ka.net/page/tajmer-schetchik-mikrokontrollerov-avr //тема о настройке таймеров
2http://samou4ka.net/page/analogo-cifrovoj-preobrazovatel-mk-atmega8 // настройка АЦП
3http://www.stepwood.com/avrsuite/2012/10/03/atmega-rezhimyi-rabotyi-taymerov/ еще немного о таймерах
4http://arv.radioliga.com/content/view/107/43/ про измерение напряжения теория
5http://cxem.net/izmer/izmer90.php полезная ссылочка
В этих статьях описанно как использовать Таймеры и АЦП управляя ими напрямую!
Итак сам вольтметр состоит из Аналоговой и цифровой части, В качестве АЦП применен встроенный преобразователь с разрешением в 10 бит микроконтроллера ATmega328 установленный на плату Arduino MIni. Я использовал на нем 2 аналоговых входа из восьми возможных!
Аналоговая часть состоит из2 ОУ схема достаточно простая и взята она от китайского стабилизатора, на 1 ОУ реализуется уменьшение 5 вольтового напряжения до уровня 2 вольта, второй через делитель напряжения получает входную величину и поднимает ее относительно 2 вольт. Очень важно выбрать хороший ОУ я применил MCP617 (По непонятной причине LM324 совершенно не подходит для этой схемы появляется двоение синусоиды) И желательно использовать сопративление ряда Е96 +-1%. Переменный резистор многооборотный 10кОм.
Можно было использовать схему приведенную ниже, но если захотите контролировать несколько фаз эта схема не пойдет и проблемы с ней обсуждались в этой теме.http://arduino.ru/forum/apparatnye-voprosy/kak-borotsya-s-dannym-yavleniem , некоторые люди пишут что применение диодов вносит погрешности при измерении чесно говоря я их не заметил, но это не говорит о том что их нет.
Цифровая часть написана в ArduinoIDE. Алгоритм измерения следеюший каждые 0.3 секунды запускается таймер с частотой прерывания 5000Гц(использован 8 битный таймер 2) следовательно если брать частоту 50 Гц то период равен 20мсек, за данный период в обработчике прерывания сохраняем 100 выборок напряжения в массив. после того как программа собрала 100 значений запрещаем прерывание и расчет переходит в основном цикле LOOP/
В цикле for происходит математические вычисления(вычитание подъема синусоиды на 2 вольта, возведение в квадрат и сложение этих значений) согласно вот этой теории :
по завершению цикла происходит вычисление реальной величины напряжения.
Переменная coef расчитывается с учетом напряжения делителя , я ее подбирал эксперементально, сравнивал измеренную величину и подаваемую источником переменного тока, и эту разницу выравнивал коэфициентом!
значение я выводил по сериал соединению!
* переменные работающие в обработчике прерывания */ volatile int Umass_A[101]; //масив переменных для хранения мгновенных напряжений фазы А int Ucor = 0; long Uism_A = 0; // переменная для хранения измеренного напряжения и квадрата фазы А long Usumm_A = 0; // переменная для хранения сумм квадратов фазы А volatile byte counter = 0; // счетчик в обработчике прерывания int ADC0 = 0; // аналоговый вход 0 для переменной Ucor! int ADC1 = 1; #define ADC1 1 volatile byte flag = 0; /* переменные для усреднения напряжений*/ float sqrtUsum_A = 0; int real_U_A = 0; float coff = 0.138; unsigned long timeOut = 0;// переменная для хранения времени!!! //массивы // кнопки и светодиоды void setup() { TIMSK2 = 0b00000000; // запрещение прерывания по совпадению таймера/счетчика Т2 TCCR2A = 0b00000010; // режим работы СТС TCCR2B = 0b00000011; // предделитель на 32 ASSR &= ~(1<<AS2); // Выбор источника синхронизации таймера(от системного генератора OCR2A = 98; // срабатывание таймера 16000000/32/100=5000 раз в секунду 100 раз за секунду ADMUX = (0<<REFS1)|(1<<REFS0)|(0<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0); ADCSRA = 0b10000111; Serial.begin(9600); } void loop() { if(millis()-timeOut > 400) { timeOut = millis(); metod(); } if(flag == 3) { for ( int i = 1; i<101; i++) { Uism_A = Umass_A [i]; Uism_A -= Ucor;// убираем подьем синусоиды на 2 вольт Uism_A *= Uism_A; Usumm_A += Uism_A; } sqrtUsum_A = sqrt(Usumm_A); //вычисляем квадратный корень из суммы квадратов real_U_A = coff * sqrtUsum_A; //вычисляем реальное напряжение для фазы А Usumm_A = 0; counter = 0; flag = 0; Serial.println(real_U_A); } } void metod() { Ucor = analogRead(ADC0); TIMSK2 |= (1<<OCIE2A); // разрешаем прерывание while(flag<3); TIMSK2 = 0b00000000; // останавливаем таймер } word read_adc(byte adc_input) { ADMUX = adc_input | (ADMUX & 0xF0); //задержка для стабилизации входного напряжения //начинаем преобразование (ADSC = 1) ADCSRA |= (1<<ADSC); while((ADCSRA & 0x10)==0); //ждем, пока АЦП закончит преобразование (ADIF = 0) ADCSRA|=0x10;//устанавливаем ADIF return ADCW;//ADCW - содержит ADCH и ADCL как нам нужно } //****************обработчик прерывания******************** ISR(TIMER2_COMPA_vect) { counter++; if((counter<= 100)&&flag == 0) { Umass_A[counter] = read_adc(ADC1); if(counter == 100) { flag = 3; counter = 1; } } }
вообщем получилось достаточно неплохо точность около 1%
Вот в принципе и все!
Интерес к измерениям переменного тока есть. Но,хотелось бы замерять значения не самим ацп Ардуино ,а внешним ацп . Например
в щитке ввода в дом ,а затем данные передавать в Ардуино. Тогда возникает вопрос как делать выборки.
И ещё ,почему для приведения к уровню вместо делителя не использовать трансформатор с выпрямителем. Всё таки развязка.
. Тогда возникает вопрос как делать выборки.
А что вам мешает в обработчике прерывания опрашивать не собственный АЦП, а внешний АЦП который будет подключен по SPI? Я думаю все вполне реализуемо.
А вот по поводу гальванической развязки это хороший вопрос!!!
http://www.microchip.su/showthread.php?t=2788&highlight=%C8%E7%EC%E5%F0%E5%ED%E8%E5+%EF%E5%F0%E5%EC%E5%ED%ED%EE%E3%EE
вот на этом форуме очень оживленно обсуждали данный вопрос, Один утверждал что смог сделать трансформатор из гайки М8 и первичную обмотку подключил через конденсатор! и это дало неплохие результаты, Но лично мои эксперементы с трансформатором дают странные рзультаты, изменяя напряжение с помощью ЛАТРа я заметил некоторую нелинейность т.е подаю с латра 100 вольт мой вольтметр показывает 110, увеличиваю до 200 показывает 197, и я таки не разобрался в чем было дело!
И ещё ,почему для приведения к уровню вместо делителя не использовать трансформатор с выпрямителем. Всё таки развязка.
а чем вам плечо в 3МОм не развязка... да и трасформаторы это увеличение размера устройства. А в таком смд исполнении датчик напряжения на ОУ ~2-3см2 на плате.
И ещё ,почему для приведения к уровню вместо делителя не использовать трансформатор с выпрямителем. Всё таки развязка.
а чем вам плечо в 3МОм не развязка... да и трасформаторы это увеличение размера устройства. А в таком смд исполнении датчик напряжения на ОУ ~2-3см2 на плате.
У меня даже меньше получилоссь, если еще и оу взять смд!
Хорошая статья о измерении переменного напряжения http://512volt.ru/s2.htm
Да статья то хорошая но есть одно но, цена LTC1968IMS8 примерно 500 рублей, а если захотим измерять 3 фазы это уже 1500 не считая остальной мелочевки и контроллера!
Лайнер обычно не дешев. Не полторы, конечно, тыщи (у китайцев за 850 руб можно пять штук взять и это включая стоимость доставки), но все равно ощутимо. Можно погуглить аналоги по сочетанию rms-to-dc -- там много чего в выдаче найти можно.
полторы тысячи это я посчитал для 3 фаз!! гуглил по теме самый дешевый лайнер без учета доставки стоит 8.9$ ну это по первой попавшейся ссылке.
Это в принципе не дорого!!
DimaP, спасибо за труды. Однако, у меня схемка вроде как не рабочая. По крайней мере, кручу я подстроечный резистор на 10К - и на DSO138 (типа осцилограф сделай сам) не наблюдаю никаких изменений. Вообще никаких. Замер делал между ADC1 и ADC0, и между ADC1 и GND и между ADC0 и GND. Может еще что-то забыли указать? Применил тоже, как и увас MCP617 - я так понял это два ОУ в одном корпусе.
DimaP, забыл я просто подать питание на ОУ, вот же... Теперь все заработало, еще раз спасибо! Единственное не могу понять, как лучше переделать схему под 3 фазы. Ведь получается, что ноль то общий.
возможно вам поможет, коментировал что мог по максимуму, измерение 3 фаз, + реакция при выходе из установленных пределов...
схема устройства не сохранилась, только микропрограмма. Наверное если сесть и вниматильно изуть код то можно понять как реализованна аппаратная часть, точно знаю что железная часть для считывание фаз напряженийреализованна с помощью картинки из поста №1 картинка 1...
Библиотеки использованные в коде, взяты с данного форума, с помощью поиска их легко найти.
вот еще несколько картинок печатные платы ну и передняя панель прибора ))
спустя 3 года XD
Спасибо, за схему и за код. Вижу что программа использует 6 аналоговых выходов для измерения (по 2 на фазу). Хочу переделать на 4 выхода. 3 фазы и 1 ноль. Вот не могу понять, зачем сигнал 2В (с делителя напряжения) повторяется через ОУ? Чем вызвана такая необходимость. Я знаю, что сигнал повторяют через ОУ, если надо на него подцепить нагрузку. Если кто-то пояснит, толково и незаумно, был бы рад.
А от чего Ардуино питается? И, надеюсь, с компьютером не соединяется?
Нельзя без трансформаторов или оптических развязок сетевые напряжения куда-либо пихать.
Хорошая статья о измерении переменного напряжения http://512volt.ru/s2.htm
Что за спам, конкретную ссылку дайте!!!
Подскажите, а что за номинал резистора стоит в самой первой схеме слева, обозначенный W3 LB-O?
Собрал первую предлагаему схему, залил код. Все работает отлично, кроме одного момента, связанного со скачками напряжения в пределах 2 вольт. То есть, напирмер, в сети 220В, а показания Arduino меняются от 219 до 221. Это нормальная работа или все же виной тому помехи, связанные с работой схемы?
Добрый день, можна ли переделать код под таймер1 ? (просто уже таймер2 занят функцией вывода звука tone(). )
гальваническая развязка обсуждалась в жж сообществе "рожденный с паяльником". там предложили использовать китайский трасформатор тока (стоит копейки) включенный через через токограничиващий резистор в 220в так чтоб ток был 60-90% от максимума. дальше математика.
вот нашел схему с пояснениями - http://easyelectronics.ru/zamer-setevogo-napryazheniya.html
Спасибо за публикацию, повторил Вашу разработку с выводом напряжения на не дорогой индикатор ТМ1637 за 48руб. https://aliexpress.ru/item/4000587257525.html
Доброго времени суток, может кто-то подсказать как организовать цикл в представленной разработке, чтоб выводилось среднее из допустим 10 значений напряжений? (да я глуп и у меня не получается, да только начал изучать этот огромный пласт и схемотехнику, мои жалкие попытки приводили к тому что в протеусе в серийный порт выводятся только нули или значения без усреднения, ссылку на википедию с определением среднего арифметического оценю как высшее проявление юмора).
И огромное спасибо за схему с пояснениями и код.
мои жалкие попытки приводили к тому что в протеусе в серийный порт выводятся только нули или значения без усреднения
показывайте свои "жалкие попытки". иначе разговор не о чем
Как итог получаю одни нули.
Вот тут нужно почитать:
http://www.psychiatry.ru/siteconst/userfiles/file/PDF/2606/Karpov.pdf
По шкале от ноля до Задорнова поставил бы Петросяна.
что-то слишком накручено... какой это хотя бы МК?
Arduino uno. Я "нагло позаимствовал" код автора этого проекта, схему повторил в протеусе и экспериментировал, в первоначальном виде в серийный порт выдаются значения с погрешностью +- 1,5 %, мне скорость измерения не важна, одного значения на секунду будет более чем достаточно, поэтому захотел усреднить полученные значения, но в виду того что в коде используется пока сложные для меня прерывания таймера добиться результата я не могу. Мне кажется ошибка в том что я для вычисления среднего беру не измеренные значения и обрабатываю, а беру из функций, но это не точно.
Для того, чтобы не возникало таких подозрений, код надо не "заимствовать", а писать самостоятельно. Да и Протеус в случае имитации случайных процессов - плохой помощник.
В общем, пишите код сами и проверяйте его на реальном "железе".