Новичок
Регистрация: 13.02.2015
Адрес: Тула
Сообщений: 13
Репутация: 10
|
Всем доброго времени суток!
Уважаемые форумчане, требуется Ваша помощь! Пытаюсь сделать амперметр переменного тока в корпусе на 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; // счетчик обновления индикатора 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 + ADCW; // накапливаем и записываем показания в value if (adc_count==480) // если произведено 480 измерений ( ~100мс ) { indication = (value/adc_count)%10000; // вычисляем значение тока 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-й разряд - десятые доли Ампера }; I=0; // обнуляем счетчик обновления индикатора }; }; if (adc_count>480) // если произведено более 480 измерений ( ~100мс ) { value = 0; // обнуляем переменную максимального значения напряжения adc_count = 0; // обнуляем счётчик количества измерений }; } Инициализация АЦП: ADMUX=ADC_VREF_TYPE; // опорное напр. AVCC и сдвигаем результат преобразования влево ADCSRA = (1 << ADPS2)|(1 << ADPS1)|(0 << ADPS0) // предделитель на 64 (частота АЦП 62,500 kHz) |(1 << ADEN) // разрешение работы АЦП |(1 << ADFR); // непрерывный режим работы АЦП while (1) { sampleADC(); // работа АЦП } Подскажите, в чем может быть проблема. Может обвязку входа АЦП неправильно сделал? Хотя перед этим перебрал много всяких вариантов обвязки и программу работы АЦП - результат один - в изделии отказывается работать. Вот схема в Протеусе:
Последний раз редактировалось EvgenyVK; 24.08.2015 в 14:06.
|
||
Оценка
|
Специалист
Регистрация: 22.09.2010
Адрес: г. Донецк
Сообщений: 873
Репутация: 381
|
EvgenyVK, Вы зря не выложили весь проект "как есть", а также перенасытили текст комментариями (что в общем-то хорошо).
Забегая вперёд. Извините, если скажу очевидное. Когда в симуляторе схема работает, а в железе нет, то в первую очередь нужно искать огрехи на плате - непропаянные места или замыкания, обрывы проводников, неправильную установку элементов (перевёрнутые корпуса), нестабильное питание. Если сомневаетесь в обвязке на ОУ, мультиметру не доверяете, а осциллографа под рукой нет, то порядок действий приблизительно такой: а) разорвите цепь после R20 и на аналоговый вход АЦП подключите просто потенциометр (питание U1_VCC, GND); б) код функции sampleADC() упростите до вывода на индикацию единичного замера ADCW*0.004882. При этом бит ADLAR не нужно выставлять; в) вращая ручку потенциометра убедитесь, что МК умеет измерять постоянное напряжение в диапазоне 0-5 вольт, и индикация вольтметра работает правильно. Затем проверьте, работает ли часть кода с усреднением adc_count++; г) если вольтметр работает, значит проблема во внешнем усилителе и датчике тока. В первую очередь проверьте датчик (с ЛАТРа нагрузите лампочку). Проверять вход/выход усилителя лучше двухлучевым осциллографом (будет видно сигнал с датчика и сдвинутый сигнал после ОУ), но подойдёт и мультиметр. Всё должно работать как положено - скажем, Вы не ошиблись с выбором коэффициента усиления, усилитель не самовозбуждается, смещение по входам равно половине питания. Относительно устройства функции sampleADC(). Нет необходимости каждый раз писать в ADMUX (Вы используете один канал АЦП) - достаточно единожды выбрать источник опорного (1<<REFS0) и номер канала (1<<MUX1). Это лучше сделать еще при инициализации портов и прочей периферии. Запуск преобразования у Вас выполнен правильно (1<<ADSC). Но тат как Вы вручную управляете АЦП и не используете прерывания, то воспользуйтесь условием окончания преобразования вида: while(ADCSRA & (1<<ADSC)) (см. раздел "ADC Control and Status Register A" даташит). Так никаких флагов сбрасывать не нужно. Аналогично, при инициализации АЦП нет необходимости выставлять бит ADFR регистра ADCSRA. Вот так: ADMUX = (1<<MUX1)|(1<<REFS0); ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS1)|(1<<ADPS2); // Init Да вот, запись вида (0<<BIT) не имеет смысла. К тому же, после старта МК начальные значения регистров ADCSRA, ADMUX - нули. Также стоит избегать объявления статических переменных внутри функций, ведь программа не большая, сделайте их глобальными с явной инициализацией. |
||
Оценка
|
Новичок
Регистрация: 13.02.2015
Адрес: Тула
Сообщений: 13
Репутация: 10
|
antonydublin, спасибо за рекомендации, в ближайшее время попробую подать на вход АЦП сигнал с потенциометра, проверить ОУ и ТТ и отпишусь. По поводу записей 0 в биты. Запись (0<<REFS1) | (1<<REFS0) | (1<<ADLAR) мне удобна тем, что я могу оперативно сбросить или установить нужный бит в процессе написания кода. После того как устройство в железе начинает "правильно" работать, я все нулевые биты удаляю из окончательного кода. А вот по-поводу глобальных и статических переменных почему-то все советуют по-разному, но последую Вашему совету и объявлю их как глобальные.
|
||
Оценка
|
Новичок
Регистрация: 13.02.2015
Адрес: Тула
Сообщений: 13
Репутация: 10
|
Проверил работу АЦП - отключил R20 от входа МК, вместо него подключил движок потенциометра на 100к, крайние выводы соответственно на +5 и общий. Бит ADLAR сбросил. Результат - при вращении потенциометра на индикаторе меняются значения от 0,0 до 99,9 (и чуть дальше, опять начиная от 0,0 - то есть значения по индикатору превышают 100 - потребуется корректировка программы - это будет проще, чем подбирать сопротивления делителя R12 и R13). Далее отключил потенциометр, восстановил связь с R20, закоротил С4, отключил трансформатор тока. Показания индикатора 51,1. Затем подключил движок потенциометра к выводу 2 операционника, а крайние выводы опять же соответственно на +5 и общий. Результат - показания индикатора меняются от 0 до 99. Осталось заменить ТТ, но увы сейчас другого у меня нет. Кстати, сопротивление ТТ постоянному току близко к нулю - мультиметр точнее не может измерить. Вот у меня вопрос - какое сопротивление у него должно быть, в Инете я не нашел такой информации. Может проблема в ТТ?
|
||
Оценка
|
Гуру
Регистрация: 08.05.2006
Адрес: москва
Сообщений: 8,284
Репутация: 2221
|
EvgenyVK
Сопротивление обмоток ТТ делается минимально возможнным. Следует заметить, что при ра*боте трансформатора тока вторичная обмотка всегда должна быть замкнута на нагрузку. Реальный ТТ, в диапазоне токов 0-4% от номинально допустимого дают значительную погрешность. Это связано с затратами на намагничивание сердечника (если таковой есть). |
||
Оценка
|
Новичок
Регистрация: 13.02.2015
Адрес: Тула
Сообщений: 13
Репутация: 10
|
Гуру
Спасибо, я понял. Про большую погрешность на токах до 1 Ампера у ТТ Talema я в курсе, в даташите график от 1 А начинается. Остается мне только поменять трансформатор тока на новый, и то, если найду у себя в городе. Если и это не поможет, тогда даже и не знаю, в каком направлении дальше копать. |
||
Оценка
|
Новичок
Регистрация: 20.11.2012
Сообщений: 43
Репутация: 25
|
вот вот. Почему у вас делитель в первом варианте на ИЗМЕРЯЕМЫЙ ВХОД подключен, вместо входа референского напряжения, он вам сигнал и банит, поскольку конденсатором от операционника отвязаны, а так бы операционник его перебивал - там ток больше (вообще выход делителя нужно на ногу AREF подать). Вообще говоря в меге есть очень удобный встроенный источник опорного напряжения 2.56 вольта - как раз половина от питания, да еще и в бинарной кратности - для его выбора нужно старшие 2 бита ADMUX в 1 выставить, а на AREF просто конденсатор буферный повесить. Я бы электролиты С3 С4 тоже выкинул (на трансе итак переменка, а как она будет через вашу RC на ОУ проходить при таких номиналах ... не для 50гц какие-то номиналы ) - пусть мгновенное значение на трансе вытягивает, а резисторы операционника R14 R15 перегнал в диапазон сотни килоом - операционнику хватит - меньше будет погрешность вносить (200 ом нагрузки транса против 3к операционника - это же порядка 8% замеряющий вносит).
|
||
Оценка
|
Гуру
Регистрация: 08.05.2006
Адрес: москва
Сообщений: 8,284
Репутация: 2221
|
EvgenyVK
Вы не рассматривали вариант использовать измерительные датчики тока на эффекте Холла? Выпускаются и доступны как контактные (например)http://www.prosoft.ru/products/brands/allegro/367517/ так и безконтактные http://www.niiem46.ru/current_sensors/ |
||
Оценка
|
Новичок
Регистрация: 13.02.2015
Адрес: Тула
Сообщений: 13
Репутация: 10
|
dvz
За основу для своей конструкции я брал материал отсюда http://kazus.ru/forums/showthread.php?t=16845&page=2 - 2-я страница, верхнее сообщение. Конденсаторы С3 и С4 - это неполярная SMD керамика. Выбор в качестве опорного AVCC (+5В) обусловлен следующим. ОУ работает от однополярного источника, поэтому делителем R18 и R21 "поднимаем" выход наполовину напряжения питания - это будет условный уровень отсчета при измерении. При установке бита ADLAR в 1, результат преобразования сдвигается влево - первые 8 разрядов в регистр ADCH, оставшиеся 2 - в регистр ADCL. При подаче сигнала с ОУ получается, что отсчет значений будет производится от искусственно созданной "земли" - половина напр. питания. Берем результат преобразования АЦП и вычисляем среднее значение. По крайней мере, я так предполагаю, что должно быть. Протеус это подтверждает, но вот в "железе" - некорректно работает. Кстати, по Вашему совету, попоробую заменить R14 и R15 на более высокоомные. |
||
Оценка
|
Обратная связь РадиоЛоцман Вверх |