|
Цифровой вольтметр-амперметр-ваттметр на AVR для бытовой сети, некоторые вопросы |
|
|
|
Mar 16 2011, 09:17
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
Вот делаю такую штуку - сабж. Делается для себя, но хочется не только некий показометр (а-ля китайские барометры, которые показывают хрен знает что, мало зависящее от атмосферного давления), а прибор, на показания которого можно ориентироваться  . Схему измерительной части прилагаю. Резистор R2 - многооборотный. На выходе ТТ предполагается еще поставить ОУ с переключаемым Ку как в AVR465 (для низкоточных нагрузок), но пока его там нету - сразу в ATMega8. БП на LM7805, мегу и LCD рисовать не стал - все стандартно. Генератор внутренний, 8МГц. Я принципиально не стал ставить шунт и делитель. С гальванической развязкой надежнее. Измерительные узлы отдельно от МК и цифровой части проверены обычным мультиметром на различных нагрузках (от 25Вт паяльника до 10КВт кухонной печки) - они полностью адекватны и работают нормально. Обработка данных такая: 1. АЦП на частоте 125 кГц цифрует сигнал. Обработчик прерывания Считает суммы отсчетов и их кол-во: // ADC interrupt service routine interrupt [ADC_INT] void adc_isr(void) { dword adc_data, temp; // Read the AD conversion result adc_data=ADCW&0xFFFE; if(isU) { // U temp=adc_data; //*adc_data; sqr_summU+=temp; countU++; } // if else { // I temp=adc_data; //*adc_data; sqr_summI+=temp; countI++; } // else } // adc_isr 2. Главная программа меряет по очереди ток и напряжение: ............. // Измерение напряжения isU=1; sqr_summU=0; countU=0; ADMUX&=0xFE; // ADC0 - канал напряжения // Запуск АЦП ADCSRA|=0x40; // ADCSC - Start ADC startMs=ms; // ожидание 21 мс (20мс - период 50 Гц) while (abs (ms-startMs)<21); // стоп АЦП ADCSRA&=0xBF; // 10111111 = BF ............. для тока также, только переменные другие. Переменная ms глобальная - TC1 по прерыванию считает миллисекунды. 3. Когда оба померяли, вычисляем // Расчет напряжения // Среднеквадратическое // Urms=sqrt(sum(u(i)^2)/N); u(i) - мгновенные отсчеты (с АЦП), i=1..N f_sqr_summU = ((float)sqr_summU)/countU; // ср. арифм. // f_sqr_summ=sqrt(f_sqr_summ); // Urms (отсчеты АЦП) // Uацп=ADC*Vref/1024=ADC*0.005 U = f_sqr_summU*0.005; // Uвх=Urms*109.52 U*=109.52; // Расчет тока // Среднеквадратическое // Urms=sqrt(sum(u(i)^2)/N); u(i) - мгновенные отсчеты (с АЦП), i=1..N f_sqr_summI = ((float)sqr_summI)/countI; // ср. арифм. // f_sqr_summ=sqrt(f_sqr_summ); // Urms (отсчеты АЦП) // Uацп=ADC*Vref/1024=ADC*0.005 I = f_sqr_summI*0.005; // Iн=500*Uацп/148,86 =Uацп*3.359 I*=3.359; // S - Полная мощность S_temp=((dword)I*U); S=S_temp; 4. после этого вывод на дисплей. Калибровки пока нету, но будет. Заметил странности: 1. При среднеквадратических было завышение показаний почти в 2 раза - вместо 220-230в показывал 380-400. По току аналогично. Поставил среднеарифметическое - нормально стало.... Почему? Или я чего-то прозевал? 2. Показания "бегают" - часто меняются в небольших пределах. Я могу поставить в цикл задержку - типа мерять раз в секунду, но меня такой способ чего-то смущает.. Может кто что посоветует? Спасибо.
Сообщение отредактировал hd44780 - Mar 16 2011, 09:19
Эскизы прикрепленных изображений
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
 |
Ответов
(30 - 44)
|
Mar 22 2011, 07:11
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
К вопросу о тех кольцевых буферах. С какой частотой должны идти выборки в эти буфера? Сейчас у меня АЦП тактируется 125 кГц. Сколько там получится сэмплов в секунду я посчитать пока не удосужился (в доке как-то мутно про это написано  ), но, думается 100KSPS наберется. 1 сэмпл за 10 мкс. Т.е. 200 байт буфера полностью обновятся за 2 мс. Т.е. весь буфер не вмещает даже полпериода 50 герцового сигнала. Это нормально? Или надо понижать частоту выборки? e_one, не знаю. Посмотрел я схему, не понял ее.
Сообщение отредактировал hd44780 - Mar 22 2011, 07:15
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Mar 22 2011, 07:38
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 20-01-11
Из: Махачкала
Пользователь №: 62 364

|
Цитата(hd44780 @ Mar 21 2011, 11:25)  128 мега потому, что они есть на фирме, а остальных нет вроде. И вообще я думал и ваттметр и вольтметр объединить в одном устройстве. А вольты выводить или ватты - переключается каким-нибудь тумблером. Возможна ли такая реализация?
Сообщение отредактировал azizcheg - Mar 22 2011, 07:41
|
|
|
|
|
Mar 22 2011, 08:02
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
Цитата(azizcheg @ Mar 22 2011, 09:38)  128 мега потому, что они есть на фирме, а остальных нет вроде. И вообще я думал и ваттметр и вольтметр объединить в одном устройстве. А вольты выводить или ватты - переключается каким-нибудь тумблером. Возможна ли такая реализация? Возможна. В принципе, все равно, какая там мега. Главное, чтобы АЦП был. Но он у любой меги есть. Идея простая - меряете всегда и все. А выводите на дисплей что-то одно. Лично у меня пока проблемы с измерениями  . Напряжение вроде нормально показывает, но все время "бегает"...
Сообщение отредактировал hd44780 - Mar 22 2011, 08:07
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Mar 22 2011, 08:13
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 20-01-11
Из: Махачкала
Пользователь №: 62 364

|
Цитата(hd44780 @ Mar 22 2011, 11:02)  Лично у меня пока проблемы с измерениями  . Напряжение вроде нормально показывает, но все время "бегает"... Что значит бегает? Как вообще, в принципе осуществляется измерение этого напряжения(тока)? Чуть дайте теории пожалуйста :-)
|
|
|
|
|
Mar 22 2011, 08:34
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
Цитата(azizcheg @ Mar 22 2011, 10:13)  Что значит бегает? Как вообще, в принципе осуществляется измерение этого напряжения(тока)? Чуть дайте теории пожалуйста :-) Схема в первом посте темы. Мега там не нарисована, только моя измерительная часть. Программная часть у меня такая (наиболее удачный вариант на текущий момент). АЦП работает на 125кГц. Обработчик АЦП суммирует все получаемые отсчеты и считает их кол-во. Как насчитает 1000 штук - останов АЦП (по флагу, в главной программе). Далее считает среднее арифметическое этих отсчетов. По нему вычисляется напряжение на входе АЦП (формула из ДШ на проц). И умножается на коэффициент делителя (в моем случае это коэф транса*коэф деления потенциометра). Это есть напряжение в сети. "Бегает" - меняется в небольших пределах. Я "на глаз" наблюдал диапазон примерно 210..230в. Мультиметр показывает где-то 230. Наверное, можно втупую брать максимум, но я не уверен. Для тока алгоритм такой же, только последний коэффициент другой, он зависит от того, как вы ток меряете. Если шунтом - просто закон ома. Если ТТ, то иначе... Для мощности посложнее. Поэтому и хочется не коэффициентами подгонять, а понять, что там происходит.
Сообщение отредактировал hd44780 - Mar 22 2011, 08:36
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Mar 22 2011, 08:52
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040

|
Цитата(hd44780 @ Mar 22 2011, 10:11)  К вопросу о тех кольцевых буферах. С какой частотой должны идти выборки в эти буфера? Сейчас у меня АЦП тактируется 125 кГц. Сколько там получится сэмплов в секунду я посчитать пока не удосужился (в доке как-то мутно про это написано  ), но, думается 100KSPS наберется. 1 сэмпл за 10 мкс. Т.е. 200 байт буфера полностью обновятся за 2 мс. Т.е. весь буфер не вмещает даже полпериода 50 герцового сигнала. Это нормально? Или надо понижать частоту выборки? Семён Семёныч! В кольцевые буферы я предлагал складывать уже вычисленные значения напряжения и тока  Я думаю, вполне хватит по 16 значений тока и напряжения. Чтобы не было неоднозначностей, набросаю код. CODE #define MY_BUFFER_SIZE 16
float get_voltage( const float mesuredVoltage ) { static float voltage[MY_BUFFER_SIZE] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; static int pos = 0; int i; float result = 0;
// voltage[pos++] = mesuredVoltage; // if ( pos >= MY_BUFFER_SIZE ) pos = 0; // for ( i = 0; i < MY_BUFFER_SIZE; i++ ) { // result += voltage[i]; } // return result / MY_BUFFER_SIZE; }
И такую же фигню для тока
Сообщение отредактировал RabidRabbit - Mar 22 2011, 10:05
|
|
|
|
|
Mar 22 2011, 09:12
|
Местный
  
Группа: Свой
Сообщений: 302
Регистрация: 24-07-06
Из: Донецк, Украина
Пользователь №: 19 042

|
Цитата(hd44780 @ Mar 21 2011, 13:34)  Не понял  ... Я ж получаю полож. полуволну с верхнего входа моста .... Зачем ее смещать? Если б была 2-я вторичка, там были бы обе полуволны. А зачем вообще выпрямлять? Делителем уменьшаете ПЕРЕМЕННОЕ напряжение трансформатора напряжения до 2/3 максимального входного АЦП и смещаете его до середины шкалы. Разность Umax-Umin=Ua дает Вам амплитудное значение измеренного напряжения. Действующее значение для синусоиды U=0,707Ua. Этим избавляетесь от всяких нелинейностей от диодов и значительно упрощаете схему (3 резистора!). Это же касается и цепи тока. Лично считаю, что усложнять схему ради упрощения программы - дурной тон.
|
|
|
|
|
Mar 22 2011, 09:28
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040

|
Цитата(hd44780 @ Mar 22 2011, 11:34)  АЦП работает на 125кГц. Обработчик АЦП суммирует все получаемые отсчеты и считает их кол-во. Как насчитает 1000 штук - останов АЦП (по флагу, в главной программе). Далее считает среднее арифметическое этих отсчетов. По нему вычисляется напряжение на входе АЦП (формула из ДШ на проц). И умножается на коэффициент делителя (в моем случае это коэф транса*коэф деления потенциометра). Это есть напряжение в сети. Как-то это по-моему не очень правильно. На мой взгляд, лучше зарядить таймер на частоту 1000 Гц, в обработчике прерывания запускать одиночное преобразование, дожидаться его завершения и результат приплюсовывать к накопителю. 100 отсчётов АЦП в таком случае перекроют 5 периодов частоты 50 Гц, что снимает необходимость ловить переход через 0 (я надеюсь, у Вас мега от кварца тактируется). По сумме этих 100 отсчётов (ну или 200, лишь бы на 20 делилось) можно вычислить напряжение. Скакать не должно
|
|
|
|
|
Mar 22 2011, 09:45
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
RabidRabbit, спасибо. я так не пытался  . Попробую. Если, конечно потянет считать float значения прямо в прерывании. Но можно и целочисленно сделать, в умноженных на 1000, например. Цитата(RabidRabbit @ Mar 22 2011, 11:28)  лучше зарядить таймер на частоту 1000 Гц, в обработчике прерывания запускать одиночное преобразование, дожидаться его завершения и результат приплюсовывать к накопителю. 100 отсчётов АЦП в таком случае перекроют 5 периодов частоты 50 Гц, что снимает необходимость ловить переход через 0 (я надеюсь, у Вас мега от кварца тактируется). По сумме этих 100 отсчётов (ну или 200, лишь бы на 20 делилось) можно вычислить напряжение. Скакать не должно  Есть у меня такая мысль. Наверное сделаю. Сейчас мега тактируется от внутренних 8MHz, просто ног не хватает  . На PB (там, где кварц) у меня ШД LCD сидит. Можно поставить и 16-ю мегу ... Цитата(ASZ @ Mar 22 2011, 11:12)  А зачем вообще выпрямлять? Делителем уменьшаете ПЕРЕМЕННОЕ напряжение трансформатора напряжения до 2/3 максимального входного АЦП и смещаете его до середины шкалы. Разность Umax-Umin=Ua дает Вам амплитудное значение измеренного напряжения. Действующее значение для синусоиды U=0,707Ua. А можно потенциометр включить ко вторичке параллельно мосту, а напряжение на движке смещать?
Сообщение отредактировал hd44780 - Mar 22 2011, 09:54
Эскизы прикрепленных изображений
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Mar 22 2011, 10:03
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040

|
Цитата(hd44780 @ Mar 22 2011, 12:45)  Попробую. Если, конечно потянет считать float значения прямо в прерывании. Но можно и целочисленно сделать, в умноженных на 1000, например. Вы правильно понимаете - не нужны float'ы в прерывании. В прерывании, например, можно суммировать целочисленные значения от АЦП (как есть, не надо их ни на что умножать, только в случае 8-битных значений для 100 замеров хватит 16-битной переменной, а для 10-битных значений уже надо 24-битную или 32-битную). Просуммировали 100 значений - скопировать в какую-нибудь глобальную переменную, увеличить другую глобальную переменную на 1, чтобы просигналить основной задаче о доступности нового результата, и снова суммировать сотню значений  Если я недоступно излагаю - спрашивайте в личке, например
|
|
|
|
|
Mar 22 2011, 10:24
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
Цитата(RabidRabbit @ Mar 22 2011, 12:03)  Если я недоступно излагаю - спрашивайте в личке, например  Да нет, все понятно. Спасибо. Напишу, проверю вечером. Я на работе, железо дома  . У меня отсчеты 10-битные, суммирую в беззнаковый 32 бит.
Сообщение отредактировал hd44780 - Mar 22 2011, 10:26
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Mar 22 2011, 12:53
|
Местный
  
Группа: Свой
Сообщений: 302
Регистрация: 24-07-06
Из: Донецк, Украина
Пользователь №: 19 042

|
Цитата(hd44780 @ Mar 22 2011, 12:45)  ...skipped... А можно потенциометр включить ко вторичке параллельно мосту, а напряжение на движке смещать? Можно, если постоянное напряжение после моста НИКАК не связано с измерительной схемой.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|