Шум АЦП

RainMan
Offline
Зарегистрирован: 21.06.2011

Подскажите что делать с шумом АЦП? Вот я привел значение аналоговых входов, когда к ним ничего не подключено.  Шум в диапазоне 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
 

kikia99
Offline
Зарегистрирован: 22.03.2011

вопрос реторический но насколько я понимаю Вам нужно просто притянуть через резистор смотрите тут на форуме есть по пул ап резисторы( или поставить переменный для подстройки  ) если есть более конкретная задача вы так и спросите  

а так вообще свободно висящих пинов нодо стораться избегать 

RainMan
Offline
Зарегистрирован: 21.06.2011

Запустил пример по прерываниям:

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 кОм . В итоге дребезг от прикосновения ушел и случайные срабатывания ушли. Но при включении прерывания кнопкой, наблюдается дребезг. Я знаю что на клавиатуре обычно борятся с дребезгом, неужели надо в обработчике прерывания еще предусматривать алгоритм, позволяющий устранить дребезг прерывания?   

RainMan
Offline
Зарегистрирован: 21.06.2011

Вот размышлял по поводу дребезга и пришел к выводу что его было бы удобней обрабатывать и фильтровать через внутреннее превывание.

Но с другой стороны грузить постоянно процессор тоже не хочется. Пришла идея сделать схему, к которой на вход подключаются параллельно процессору входа, и которая в свою очередь выдает импульс,0, или 1 при изменении состояния любого из входов. А этот импульс  уже обрабатываем аппаратным прерыванием. Прерывание анализирует по какому конкретно входу произошло срабатывание, и включает алгоритм устранения дребезга. Таким образом обработка дребезга практически не будет отнимать время у процессора.

Если у вас есть свои алгоритмы обработки дребезга - выкладывайте. 

Evgen
Evgen аватар
Offline
Зарегистрирован: 10.06.2011

Вот тут видеоуроки по Arduino www.youtube.com/watch

Там и про прерывания и про дребезг контактов есть.

pollstar
Offline
Зарегистрирован: 16.10.2011

Для избежания шумов в АЦП, нужно отключать таймер на момент от запуска АЦП до окончания преобразования.

Производители указывали на данный деффект, как результат близко расположенных на кристале АЦП и Таймера.

Я делал так:

- перед запуском 

TCCR0 &= 0xFA;/*остановим таймер пока идет
преобразование, чтобы избежать помех*/\
 

- в прерывании по окончании обработки АЦП

TCCR0 |= 0b00000101;//запустим таймер
 

 

Fluffy
Offline
Зарегистрирован: 01.06.2011

 скажите, какую библиотеку нужно подключить и где ее взять, чтобы можно было обращаться к регистрам МК напрямую из Arduino IDE скетчей, как у Вас в примере TCCR0 |= 0b00000101;  ?

leshak
Offline
Зарегистрирован: 29.09.2011

 Если не ошибаюсь, то "никакую". Вот прямо так "брать и писать."

Если же у вас кричит что TCCR0 неизвестное имя, то дело, скорее все-го в том, что у вас другой контроллер стоит в ардуине. Нужно брать даташит на вашу ардуину, смотреть какой в ней кристал стоит, потом брать даташит на этот кристал и смотреть как у него называется порт управляющий таймером. Возможно будет отличается только имя, возможно биты будут чуть-чуть другие.

По хорошему, было-бы неплохо узнать у pollstar для какого кристала он дал пример, посмотреть что означают для него эти значения TCCR0,"0xFA", "0b00000101" и искать их аналоги для вашего кристала.

leshak
Offline
Зарегистрирован: 29.09.2011

 А дребезг кнопки убирать можно двумя путями:

программно. Запоминаете время каждого срабатывания прерывания, если следующие произошло раньше некоего "порога" (например 100 милисекунд, подбираете опытным путем), то запоминаете новое время, но "ничего не делаете".

Либо аппаратно - конденсатором.

pollstar
Offline
Зарегистрирован: 16.10.2011

Пример из 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);//запустим таймер

  //какой-нибудь код

}
 

Исправил ошибку

step962
Offline
Зарегистрирован: 23.05.2011

pollstar пишет:

Для избежания шумов в АЦП, нужно отключать таймер на момент от запуска АЦП до окончания преобразования.

[...]

Я делал так:

- перед запуском 

TCCR0 &= 0xFA;/*остановим таймер пока идет
преобразование, чтобы избежать помех*/\
  [...]

Небольшое уточнение

Таким образом Вы не останавливали/запускали таймер, а изменяли настройку предделителя/источник тактов. В некоторых случаях (Вам, видимо, везло) может произойти не остановка таймера, а настройка предделителя на FCLK/8.

Корректно остановить таймер можно, записав ТРИ нуля в младшие биты регистра TCCRn:

TCCR0 &= 0xFB;

Табличку возможных комбинаций битов выбора источника тактового сигнала для таймеров/счетчиков N0/T2 смотрим в даташите. Ну или где-нибудь на просторах Интернета, например, здесь.

pollstar
Offline
Зарегистрирован: 16.10.2011

Ну тогда точнее для Меги8

TCCR0 &= 0xF8;

step962
Offline
Зарегистрирован: 23.05.2011

Пардоньте меня - B и 8 перепутал.

Fluffy
Offline
Зарегистрирован: 01.06.2011

 leshak, Спасибо, буду знать. извините за оффтоп.

Schrodinger_Kater
Offline
Зарегистрирован: 30.05.2017

TCCR0 в заголовках обычно определяется так:

#define TCCR0	_SFR_IO8(0x33)	/* Timer/Counter 0 Control Register */

 

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

Котаны, есть ли программные способы подлечить сабж если случаи клинические, типа там от VCC до AVCC тупо перемычка, и до кучи от step-up или блокинг-генератора запитано? Ну потому что усреднять это хоть заусредняйся, там шумяра такой что половина цифр неадекватными получются. Было бы хоть 8 замеров из 10 нормальными, а так... Бесперспективняк.

Или ТОЛЬКО плату переделывать? Накидайте btw схему как надо. 220 uH + 0.1 uF достаточно? Или ещё электролит надо?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Voodoo Doll пишет:

Котаны, есть ли программные способы подлечить сабж если случаи клинические, типа там от VCC до AVCC тупо перемычка, и до кучи от step-up или блокинг-генератора запитано? Ну потому что усреднять это хоть заусредняйся, там шумяра такой что половина цифр неадекватными получются. Было бы хоть 8 замеров из 10 нормальными, а так... Бесперспективняк.

Или ТОЛЬКО плату переделывать? Накидайте btw схему как надо. 220 uH + 0.1 uF достаточно? Или ещё электролит надо?

А какие частоты в шуме? Или "белый шум"? В зависимости от этого и конденсаторы и катушки...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Voodoo Doll пишет:

Котаны, есть ли программные способы подлечить сабж если случаи клинические, типа там от VCC до AVCC тупо перемычка, и до кучи от step-up или блокинг-генератора запитано? Ну потому что усреднять это хоть заусредняйся, там шумяра такой что половина цифр неадекватными получются. Было бы хоть 8 замеров из 10 нормальными, а так... Бесперспективняк.

Или ТОЛЬКО плату переделывать? Накидайте btw схему как надо. 220 uH + 0.1 uF достаточно? Или ещё электролит надо?

Способы, естественно, есть.

Только вот в такой неконкретной постановке (типа на все случаи жизни) количество способов резко уменьшается, причем, остаются те, которые не очень приятны в реализации.

Итак, если:

- вот просто "шум" - и все. Ничего про этот шум не известно, кроме того, что он - шум (т.е. помеха, имеющая случайное распределение).

- что нам нужно измерять - неизвестно (абсолютное, относительное напряжение, коэффициент деления делителя...).

- по условию "половина цифр неадекватна". Что это значит, я не совсем понимаю, но предполагаю, что это "половина разрядов недостоверна".

- аппаратные решения нам не подходят.

При данных условиях можно порекомендовать один из двух способов:

1. Наиболее радикальный - соединить вход с землей. Накоротко. На выходе, правда, будет всегда ноль, но зато и шумов - никаких (а я предупреждал, что решение может не понравиться!).

2. Учитывая, что нам нужно восстановить половину разрядов, а половина от 10 это 5, значит, нужно уменьшить величину ошибки в 32 раза, что достигается усреднением 1024 измерений. Медленно - ну а что сделаешь!

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

mykaida пишет:
А какие частоты в шуме?

Не снять мне частоты без оцоцылогграфа, ох не снять...

Батыр акомулятор. Повышайка. Через делитель внешний аккумулятор замеряется (с общим минусом) или собственный (до повышайки, поэтому способ "секретного вольтметра" не подходит). Допустим, заряжен на 99% (только что вытащен из зарядки). По кнопке замерить, скока заряд. Как часто кнопка может показывать? ну раз в 5 сек примерно.

Результат:

98%

99%

99%

31%

70%

99%

2%

и т д,

nik182
Offline
Зарегистрирован: 04.05.2015

Что я бы сделал - повесил емкости по 10м + 0.1м на ногу Uref и питание (как можно ближе к ноге МК), к ноге измерения подводил через фильтр 10мкф 100 Ом, по нажатию кнопки делал 10 измерений и выводил среднее после отброса значений с максимальным отклонением от среднего. Обычно этого хватает получить приемлемое значение в шумных условиях. 

Schrodinger_Kater
Offline
Зарегистрирован: 30.05.2017

Если цель измерять постоянное напряжение, то самое простое решение - это конденсатор параллельно входу АЦП. Размер емкости будет ограничен только его скорость разряда.
В общем, проблема решается аналогичным образом, как у операционных усилителей с высоким входным сопротивлением (коим обладает и АЦП):
1) Снижение входного сопротивления (низкоомный делитель на входе)
2) ВЧ фильтр (конденсатор на входе)
3) Сокращение длины выводов и экранирование проводов.

Но стоит начать с самого АЦП - непосредственно на вывод входа повесить низкоомный делитель из резисторов (может один переменный) и программно устранить все шумы связанные с платой контроллера.
А после этого уже переходить к устранению внешних шумов (резисторы конденсаторы, провода и т.д.).

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Schrodinger_Kater пишет:
Если цель измерять постоянное напряжение, то самое простое решение - это конденсатор параллельно входу АЦП. Размер емкости будет ограничен только его скорость разряда.

В общем, проблема решается аналогичным образом, как у операционных усилителей с высоким входным сопротивлением (коим обладает и АЦП):

1) Снижение входного сопротивления (низкоомный делитель на входе)

2) ВЧ фильтр (конденсатор на входе)

НЧ фильтр.

Цитата:

3) Сокращение длины выводов и экранирование проводов.

...

Schrodinger_Kater
Offline
Зарегистрирован: 30.05.2017

andriano пишет:

НЧ фильтр.

Ну, да. Ход мысли не дошел до самого комментария (через ВЧ-фильтр посадить шум на землю).

Schrodinger_Kater
Offline
Зарегистрирован: 30.05.2017

И тут, скорее, не НЧ, а "фильтр постоянного напряжения" нужен.)) Если цель мерить напряжение на АКБ, то там можно всю переменную составляющую в ноль пускать, какой бы частоты она не была.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Schrodinger_Kater пишет:

И тут, скорее, не НЧ, а "фильтр постоянного напряжения" нужен.)) Если цель мерить напряжение на АКБ, то там можно всю переменную составляющую в ноль пускать, какой бы частоты она не была.

А что такое фильтр постоянного напряжения? Это ФНЧ с частотой равной 0? Если фильтр срезает все частоты, у него на выходе будет постоянный ноль. Ну, либо какое-либо другое постоянное значение, установленное там в процессе изготовления данного фильтра.

Schrodinger_Kater
Offline
Зарегистрирован: 30.05.2017

Название написано в кавычках. Речь о фильтре инфранизких частот. Если проверка АЦП - это уровень напряжения на АКБ, то это, практически постоянное напряжение (меняющийся сигнал, но с очень большим периодом). Следовательно, конденсатор на входе может быть бесконечно большой емкости. Но если вход АЦП переключается между несколькими АКБ, то емкость будет ограничена частотой переключения между источниками (искажение переднего фронта сигнала). С другой стороны, даже в таком случае, это можно просто скорректировать программно.

nik182
Offline
Зарегистрирован: 04.05.2015

Не надо оправдываться. Мы уже всё поняли. К сожалению слова, которые употреблены относятся к сферическому коню в вакууме. Поэтому ничего кроме улыбки не вызывают. Признайте уже что перегнули с определениями. В конце концов можно дойти до нулевой гармоники фурье спектра. Это будет куда продуктивнее, чем инфранизкие частоты. 

Schrodinger_Kater
Offline
Зарегистрирован: 30.05.2017

lol

Собственно, ответил по эннерции, тем более самому себе.

А если по существу то:

andriano пишет:

Это ФНЧ с частотой равной 0?

Нет, только стремящейся к нулю.

andriano пишет:

Если фильтр срезает все частоты, у него на выходе будет постоянный ноль.

Нет, будет постоянная составляющая, что была на входе (если конечно речь о НЧ фильтре).

andriano пишет:

...установленное там в процессе изготовления данного фильтра.

А это уже источник опорного напряжения, а не фильтр.

Про ряд Фурье и нулевую гармонику, к сожалению уже не помню - давненько это было...

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

ФНЧ стремящийся к нулю = конденсатору стремящемуся к бесконечности.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Voodoo Doll пишет:

Не снять мне частоты без оцоцылогграфа, ох не снять...

Батыр акомулятор. Повышайка.

Немного понятнее и много грустнее.

Короче - частота 20-50кГц, сигнал "пила", гармоник до чёрта. ФНЧ надо подбирать, как советовали.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Schrodinger_Kater пишет:

andriano пишет:

Если фильтр срезает все частоты, у него на выходе будет постоянный ноль.

Нет, будет постоянная составляющая, что была на входе (если конечно речь о НЧ фильтре).

Не будет.

Точнее, будет через бесконечное время. Может быть.

А через конечное время будет ноль или ... (далее по тексту)

Цитата:

andriano пишет:

...установленное там в процессе изготовления данного фильтра.

А это уже источник опорного напряжения, а не фильтр.

Да, но Вы почему-то называете его фильтром постоянного напряжения.

Ntrud
Offline
Зарегистрирован: 14.06.2015

   Не прошло и 10 лет и тема снова ожила.

Пост № 0 от  21.06.2011г.