Амперметр переменного тока на ATmega8

Модератор: boogyman

Ответить
Аватара пользователя
EvgenyVK
Новичок
Сообщения: 6
Зарегистрирован: 10 июл 2014, 20:17

Амперметр переменного тока на ATmega8

#1

Сообщение EvgenyVK »

Всем доброго времени суток!
Уважаемые форумчане, требуется Ваша помощь! Пытаюсь сделать амперметр переменного тока в корпусе на DIN-рейку (2 места) на ATmega8 и трансформаторе тока ASM-030. Высокая точность не нужна, хотя хотелось бы, чтобы отсчет показаний начинался с 0,5А, правда по даташиту на ТТ равномерная характеристика начинается примерно с 1 Ампера. Для этих целей в схеме стоит ОУ AD8541AS, чтобы усилить напряжение с ТТ, и фиксировать значения менее 1 А (хотя оно будет сильно нелинейное). В Протеусе симуляция идет прекрасно, в изделии - непонятные показания в пределах 40-70 ампер хаотически меняющиеся, причем независимо от тока нагрузки. Опорное напряжение для АЦП - AVCC. Делитель на резисторах на входе, чтобы получить половину AVCC. Бит ADLAR установлен в 1. АЦП измеряет среднее, а не среднеквадратичное напряжение.
Именно с битом ADLAR и опорным напряжением я окончательно запутался, а от них собственно и зависит код программы.
Вот фрагмент кода, написанный в CVAVR для АЦП, частота МК - 4МГц.

#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (1<<ADLAR)) // опорное напр. AVCC и сдвигаем результат преобразования влево
void sampleADC() // работа АЦП
{
static unsigned long int indication; // переменная значения измеренного напряжения
static unsigned int adc_count; // внутренный счётчик количества измерений
static unsigned long int value;
static unsigned char I; // счетчик обновления индикатора
static unsigned long int M;

ADMUX = ADC_VREF_TYPE | (0x02); // вход PINC.2
delay_us(10);

ADCSRA |= (1<<ADSC); // запуск АЦП
while(!(ADCSRA & (1<<ADIF))); // ждём окончания конвертирования
ADCSRA |=(1<<ADIF); // сбрасываем флаг записью 1

adc_count++; // увеличиваем счетчик счётчик количества измерений на 1

// value=value+(M*M); // накапливаем и записываем показания в value
// M = ADCW;

value = value + ADCW; // накапливаем и записываем показания в value

if (adc_count==480) // если произведено 480 измерений ( ~200мс )
{
// indication = (sqrt((value/adc_count)+20))*12/13; // симуляция в Протеусе
// indication = (sqrt(value/adc_count))*100;

indication = (value/adc_count)%10000; // симуляция в Протеусе без усилителя AD8541
// indication = (((value+50)*9/5/adc_count)+1)%1000; // симуляция в Протеусе без усилителя AD8541
// indication = (value/2/adc_count)%1000; // симуляция в Протеусе с усилителем AD8541

#asm("nop");

Iporog = indication%1000; // записываем в Iporog значение в Амперах

I++; // увеличиваем счетчик обновления индикатора

if (I>=10) // если счетчик досчитал до 10 ( ~1с )
{
if (Iporog>=100) // если показания больше 10 Ампер
{
count3 = indication%1000/100; // 1-й разряд - десятки Ампер
count2 = indication%100/10; // 2-Й разряд - единицы Ампер
count1 = indication%10/1; // 3-й разряд - десятые доли Ампера
}
else
{
count3 = 10; // 1-й разряд - гасим разряд
count2 = indication%100/10; // 2-Й разряд - единицы Ампер
count1 = indication%10/1; // 3-й разряд - десятые доли Ампера
};
#asm("nop");

I=0; // обнуляем счетчик обновления индикатора
};
};

if (adc_count>480) // если произведено более 480 измерений ( ~200мс )
{
value = 0; // обнуляем переменную максимального значения напряжения
adc_count = 0; // обнуляем счётчик количества измерений
// PORTC|=0b0100000;
};
}

Инициализация АЦП:
ADMUX=ADC_VREF_TYPE; // опорное напр. AVCC и сдвигаем результат преобразования влево
ADCSRA = (1 << ADPS2)|(1 << ADPS1)|(0 << ADPS0) // предделитель на 64 (частота АЦП 62,500 kHz)
|(1 << ADEN) // разрешение работы АЦП
|(1 << ADFR); // непрерывный режим работы АЦП

while (1)
{
sampleADC(); // работа АЦП
}

Подскажите, в чем может быть проблема. Может обвязку входа АЦП неправильно сделал? Хотя перед этим перебрал много всяких вариантов обвязки и программу работы АЦП - результат один - в изделии отказывается работать.

Вот схема в Протеусе:
Вложения
10.jpg
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Амперметр переменного тока на ATmega8

#2

Сообщение AntonChip »

На выводе Aref конденсатор на 10мкФ полярный, нужен на 100нФ неполярный
Аватара пользователя
EvgenyVK
Новичок
Сообщения: 6
Зарегистрирован: 10 июл 2014, 20:17

Re: Амперметр переменного тока на ATmega8

#3

Сообщение EvgenyVK »

Я изготовил около 2-х десятков всяких мелких поделок на AVR, и там, где используется АЦП, на Aref ставил полярный 10 мкФ - все прекрасно работало. Ради чистоты эксперимента, заменил на 100нФ - результат тот же, хаотично меняющиеся показания в районе 40-50 Ампер. Никак не могу понять, в каком направлении искать решение.
Аватара пользователя
EvgenyVK
Новичок
Сообщения: 6
Зарегистрирован: 10 июл 2014, 20:17

Re: Амперметр переменного тока на ATmega8

#4

Сообщение EvgenyVK »

Забыл совсем, резисторы делителя R12 и R13 в симуляции не участвуют. С ними на индикатор выводится ерунда.
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Амперметр переменного тока на ATmega8

#5

Сообщение AntonChip »

А с внешним ИОН пробовали типа TL431, также можно попробовать считывать данные по прерыванию от АЦП
Аватара пользователя
EvgenyVK
Новичок
Сообщения: 6
Зарегистрирован: 10 июл 2014, 20:17

Re: Амперметр переменного тока на ATmega8

#6

Сообщение EvgenyVK »

Прихожу к выводу, что лучшее решение - использовать выпрямитель на ОУ и компенсировать смещение на выходе при нулевом токе нагрузке. Такую схему уже 4 раза делал в "железе", но без компенсации смещения. Из-за этого приходилось в формулу расчета тока вводить поправочный коэффициент, что не есть хорошо.
Вот схема и файлы проекта.
Вложения
AMP.7z
(62.59 КБ) 2090 скачиваний
scheme1.jpg
Ответить