Шум АЦП
- Войдите на сайт для отправки комментариев
Подскажите что делать с шумом АЦП? Вот я привел значение аналоговых входов, когда к ним ничего не подключено. Шум в диапазоне 230-380
А7 А6 А5 А4 А3 А2 А1 А0
372 334 336 326 279 244 244 270
*****************
375 335 300 299 295 270 238 242
*****************
372 357 317 277 264 271 268 232
*****************
372 348 344 309 259 242 261 267
*****************
372 329 319 321 293 252 234 264
*****************
372 343 300 280 282 275 247 227
*****************
375 358 335 285 254 260 271 243
А вот я кратковременно подал на А0 - 5В - значение сразу стало 1023, отпустил, а потом подал опять но дольше. Из таблицы видно что значение шума после второй подачи 5В выросло по всем входам в 2-3 раза. Как с этим жить?
376 337 335 320 298 269 267 1023
*****************
376 340 327 307 292 264 255 702
*****************
376 351 338 303 287 275 267 653
*****************
376 346 348 319 287 268 278 534
*****************
376 338 330 316 297 270 274 1023
*****************
1014 792 648 532 446 374 350 1023
*****************
1007 905 799 678 571 479 437 1023
*****************
1006 938 866 768 661 565 514 0 1023
вопрос реторический но насколько я понимаю Вам нужно просто притянуть через резистор смотрите тут на форуме есть по пул ап резисторы( или поставить переменный для подстройки ) если есть более конкретная задача вы так и спросите
а так вообще свободно висящих пинов нодо стораться избегать
Запустил пример по прерываниям:
int pin = 13;
volatile int state = LOW;
void setup()
{
pinMode(pin, OUTPUT);
attachInterrupt(0, blink, CHANGE);
}
void loop()
{
digitalWrite(pin, state);
}
void blink()
{
state = !state;
}
Прерывания срабатывают даже от прикосновения пальцем ко входу прерывания.
Подключил подтягивающее сопротивление 8,2 кОм . В итоге дребезг от прикосновения ушел и случайные срабатывания ушли. Но при включении прерывания кнопкой, наблюдается дребезг. Я знаю что на клавиатуре обычно борятся с дребезгом, неужели надо в обработчике прерывания еще предусматривать алгоритм, позволяющий устранить дребезг прерывания?
Вот размышлял по поводу дребезга и пришел к выводу что его было бы удобней обрабатывать и фильтровать через внутреннее превывание.
Но с другой стороны грузить постоянно процессор тоже не хочется. Пришла идея сделать схему, к которой на вход подключаются параллельно процессору входа, и которая в свою очередь выдает импульс,0, или 1 при изменении состояния любого из входов. А этот импульс уже обрабатываем аппаратным прерыванием. Прерывание анализирует по какому конкретно входу произошло срабатывание, и включает алгоритм устранения дребезга. Таким образом обработка дребезга практически не будет отнимать время у процессора.
Если у вас есть свои алгоритмы обработки дребезга - выкладывайте.
Вот тут видеоуроки по Arduino www.youtube.com/watch
Там и про прерывания и про дребезг контактов есть.
Для избежания шумов в АЦП, нужно отключать таймер на момент от запуска АЦП до окончания преобразования.
Производители указывали на данный деффект, как результат близко расположенных на кристале АЦП и Таймера.
Я делал так:
- перед запуском
TCCR0 &= 0xFA;/*остановим таймер пока идет
преобразование, чтобы избежать помех*/\
- в прерывании по окончании обработки АЦП
TCCR0 |= 0b00000101;//запустим таймер
скажите, какую библиотеку нужно подключить и где ее взять, чтобы можно было обращаться к регистрам МК напрямую из Arduino IDE скетчей, как у Вас в примере TCCR0 |= 0b00000101; ?
Если не ошибаюсь, то "никакую". Вот прямо так "брать и писать."
Если же у вас кричит что TCCR0 неизвестное имя, то дело, скорее все-го в том, что у вас другой контроллер стоит в ардуине. Нужно брать даташит на вашу ардуину, смотреть какой в ней кристал стоит, потом брать даташит на этот кристал и смотреть как у него называется порт управляющий таймером. Возможно будет отличается только имя, возможно биты будут чуть-чуть другие.
По хорошему, было-бы неплохо узнать у pollstar для какого кристала он дал пример, посмотреть что означают для него эти значения TCCR0,"0xFA", "0b00000101" и искать их аналоги для вашего кристала.
А дребезг кнопки убирать можно двумя путями:
программно. Запоминаете время каждого срабатывания прерывания, если следующие произошло раньше некоего "порога" (например 100 милисекунд, подбираете опытным путем), то запоминаете новое время, но "ничего не делаете".
Либо аппаратно - конденсатором.
Пример из IAR немного подкорректированный. Код пишется для Меги16. В руки попал холодильный контроллер ID974 со слетевшей прошивкой. Теперь я его использую для обкатки своей прошивки.
Задача контроллера была мерять температуру по двум датчикам и управлять холодильной машиной.
Долго не мог понять почему температура скачет иногда с +20 до +50, а потом где то нашел в инете данную рекомендацию и проблема исчезла. Вот полный код работы с АЦП на IAR
/***************************************************
* Работа с АЦП
*
*
****************************************************/
#include "iom16.h"
//#include "a2d.h"
volatile char tmpTCCR0;
volatile unsigned int AdcBuf;
#define StartConvAdc() {ADCSRA |= (1<<ADSC);\
tmpTCCR0 = TCCR0 & B8(00000111);\
TCCR0 &= 0xF8;/*остановим таймер пока идет
преобразование, чтобы избежать помех*/\
}
void InitADC(){
//ион - напряжение питания, выравнивание влево, пятый канал
ADMUX = (0<<REFS1)|(1<<REFS0)|(0<<ADLAR)|(0<<MUX3)|(1<<MUX2)|(0<<MUX1)|(1<<MUX0);
//вкл. ацп, режим одиночного преобр., разрешение прерывания,частота преобр. = FCPU/128
ADCSRA = (1<<ADEN)|(0<<ADSC)|(0<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
};
//обработчик прерывания АЦП
#pragma vector=ADC_vect
__interrupt void adc_my(void)
{
int i;
i = ADC;
if((i > AdcBuf+2) || (i < AdcBuf-2)) //отсечение погрешности младшего разряда
AdcBuf = i;
TCCR0 |= B8(00000101);//запустим таймер
//какой-нибудь код
}
Исправил ошибку
Для избежания шумов в АЦП, нужно отключать таймер на момент от запуска АЦП до окончания преобразования.
[...]
Я делал так:
- перед запуском
TCCR0 &= 0xFA;/*остановим таймер пока идет
преобразование, чтобы избежать помех*/\
[...]
Небольшое уточнение
Таким образом Вы не останавливали/запускали таймер, а изменяли настройку предделителя/источник тактов. В некоторых случаях (Вам, видимо, везло) может произойти не остановка таймера, а настройка предделителя на FCLK/8.
Корректно остановить таймер можно, записав ТРИ нуля в младшие биты регистра TCCRn:
TCCR0 &= 0xFB;
Табличку возможных комбинаций битов выбора источника тактового сигнала для таймеров/счетчиков N0/T2 смотрим в даташите. Ну или где-нибудь на просторах Интернета, например, здесь.
Ну тогда точнее для Меги8
TCCR0 &= 0xF8;
Пардоньте меня - B и 8 перепутал.
leshak, Спасибо, буду знать. извините за оффтоп.
TCCR0 в заголовках обычно определяется так:
Котаны, есть ли программные способы подлечить сабж если случаи клинические, типа там от VCC до AVCC тупо перемычка, и до кучи от step-up или блокинг-генератора запитано? Ну потому что усреднять это хоть заусредняйся, там шумяра такой что половина цифр неадекватными получются. Было бы хоть 8 замеров из 10 нормальными, а так... Бесперспективняк.
Или ТОЛЬКО плату переделывать? Накидайте btw схему как надо. 220 uH + 0.1 uF достаточно? Или ещё электролит надо?
Котаны, есть ли программные способы подлечить сабж если случаи клинические, типа там от VCC до AVCC тупо перемычка, и до кучи от step-up или блокинг-генератора запитано? Ну потому что усреднять это хоть заусредняйся, там шумяра такой что половина цифр неадекватными получются. Было бы хоть 8 замеров из 10 нормальными, а так... Бесперспективняк.
Или ТОЛЬКО плату переделывать? Накидайте btw схему как надо. 220 uH + 0.1 uF достаточно? Или ещё электролит надо?
А какие частоты в шуме? Или "белый шум"? В зависимости от этого и конденсаторы и катушки...
Котаны, есть ли программные способы подлечить сабж если случаи клинические, типа там от VCC до AVCC тупо перемычка, и до кучи от step-up или блокинг-генератора запитано? Ну потому что усреднять это хоть заусредняйся, там шумяра такой что половина цифр неадекватными получются. Было бы хоть 8 замеров из 10 нормальными, а так... Бесперспективняк.
Или ТОЛЬКО плату переделывать? Накидайте btw схему как надо. 220 uH + 0.1 uF достаточно? Или ещё электролит надо?
Способы, естественно, есть.
Только вот в такой неконкретной постановке (типа на все случаи жизни) количество способов резко уменьшается, причем, остаются те, которые не очень приятны в реализации.
Итак, если:
- вот просто "шум" - и все. Ничего про этот шум не известно, кроме того, что он - шум (т.е. помеха, имеющая случайное распределение).
- что нам нужно измерять - неизвестно (абсолютное, относительное напряжение, коэффициент деления делителя...).
- по условию "половина цифр неадекватна". Что это значит, я не совсем понимаю, но предполагаю, что это "половина разрядов недостоверна".
- аппаратные решения нам не подходят.
При данных условиях можно порекомендовать один из двух способов:
1. Наиболее радикальный - соединить вход с землей. Накоротко. На выходе, правда, будет всегда ноль, но зато и шумов - никаких (а я предупреждал, что решение может не понравиться!).
2. Учитывая, что нам нужно восстановить половину разрядов, а половина от 10 это 5, значит, нужно уменьшить величину ошибки в 32 раза, что достигается усреднением 1024 измерений. Медленно - ну а что сделаешь!
Не снять мне частоты без оцоцылогграфа, ох не снять...
Батыр акомулятор. Повышайка. Через делитель внешний аккумулятор замеряется (с общим минусом) или собственный (до повышайки, поэтому способ "секретного вольтметра" не подходит). Допустим, заряжен на 99% (только что вытащен из зарядки). По кнопке замерить, скока заряд. Как часто кнопка может показывать? ну раз в 5 сек примерно.
Результат:
98%
99%
99%
31%
70%
99%
2%
и т д,
Что я бы сделал - повесил емкости по 10м + 0.1м на ногу Uref и питание (как можно ближе к ноге МК), к ноге измерения подводил через фильтр 10мкф 100 Ом, по нажатию кнопки делал 10 измерений и выводил среднее после отброса значений с максимальным отклонением от среднего. Обычно этого хватает получить приемлемое значение в шумных условиях.
Если цель измерять постоянное напряжение, то самое простое решение - это конденсатор параллельно входу АЦП. Размер емкости будет ограничен только его скорость разряда.
В общем, проблема решается аналогичным образом, как у операционных усилителей с высоким входным сопротивлением (коим обладает и АЦП):
1) Снижение входного сопротивления (низкоомный делитель на входе)
2) ВЧ фильтр (конденсатор на входе)
3) Сокращение длины выводов и экранирование проводов.
Но стоит начать с самого АЦП - непосредственно на вывод входа повесить низкоомный делитель из резисторов (может один переменный) и программно устранить все шумы связанные с платой контроллера.
А после этого уже переходить к устранению внешних шумов (резисторы конденсаторы, провода и т.д.).
В общем, проблема решается аналогичным образом, как у операционных усилителей с высоким входным сопротивлением (коим обладает и АЦП):
1) Снижение входного сопротивления (низкоомный делитель на входе)
2) ВЧ фильтр (конденсатор на входе)
НЧ фильтр.
3) Сокращение длины выводов и экранирование проводов.
...
НЧ фильтр.
Ну, да. Ход мысли не дошел до самого комментария (через ВЧ-фильтр посадить шум на землю).
И тут, скорее, не НЧ, а "фильтр постоянного напряжения" нужен.)) Если цель мерить напряжение на АКБ, то там можно всю переменную составляющую в ноль пускать, какой бы частоты она не была.
И тут, скорее, не НЧ, а "фильтр постоянного напряжения" нужен.)) Если цель мерить напряжение на АКБ, то там можно всю переменную составляющую в ноль пускать, какой бы частоты она не была.
А что такое фильтр постоянного напряжения? Это ФНЧ с частотой равной 0? Если фильтр срезает все частоты, у него на выходе будет постоянный ноль. Ну, либо какое-либо другое постоянное значение, установленное там в процессе изготовления данного фильтра.
Название написано в кавычках. Речь о фильтре инфранизких частот. Если проверка АЦП - это уровень напряжения на АКБ, то это, практически постоянное напряжение (меняющийся сигнал, но с очень большим периодом). Следовательно, конденсатор на входе может быть бесконечно большой емкости. Но если вход АЦП переключается между несколькими АКБ, то емкость будет ограничена частотой переключения между источниками (искажение переднего фронта сигнала). С другой стороны, даже в таком случае, это можно просто скорректировать программно.
Не надо оправдываться. Мы уже всё поняли. К сожалению слова, которые употреблены относятся к сферическому коню в вакууме. Поэтому ничего кроме улыбки не вызывают. Признайте уже что перегнули с определениями. В конце концов можно дойти до нулевой гармоники фурье спектра. Это будет куда продуктивнее, чем инфранизкие частоты.
lol
Собственно, ответил по эннерции, тем более самому себе.
А если по существу то:
Это ФНЧ с частотой равной 0?
Нет, только стремящейся к нулю.
Если фильтр срезает все частоты, у него на выходе будет постоянный ноль.
Нет, будет постоянная составляющая, что была на входе (если конечно речь о НЧ фильтре).
...установленное там в процессе изготовления данного фильтра.
А это уже источник опорного напряжения, а не фильтр.
Про ряд Фурье и нулевую гармонику, к сожалению уже не помню - давненько это было...
ФНЧ стремящийся к нулю = конденсатору стремящемуся к бесконечности.
Не снять мне частоты без оцоцылогграфа, ох не снять...
Батыр акомулятор. Повышайка.
Немного понятнее и много грустнее.
Короче - частота 20-50кГц, сигнал "пила", гармоник до чёрта. ФНЧ надо подбирать, как советовали.
Если фильтр срезает все частоты, у него на выходе будет постоянный ноль.
Нет, будет постоянная составляющая, что была на входе (если конечно речь о НЧ фильтре).
Не будет.
Точнее, будет через бесконечное время. Может быть.
А через конечное время будет ноль или ... (далее по тексту)
...установленное там в процессе изготовления данного фильтра.
А это уже источник опорного напряжения, а не фильтр.
Да, но Вы почему-то называете его фильтром постоянного напряжения.
Не прошло и 10 лет и тема снова ожила.
Пост № 0 от 21.06.2011г.