Глюки с АЦП на нескольких портах

wer_wolf
Offline
Зарегистрирован: 08.08.2016

Всем доброго времени суток.

Подскажите что я делаю не так и куда мне смотреть.

Есть ардуино Nano на 328 контроллере

На порту А0 переменный резистор, одна нога на +5 вторая на GND середина на порту

На порту А4 LM328 через которую приходят данные от термопары

А1,А2 кнопки через резисторные делители.

И вот получился у меня такой глюк.

Когда вращаю ручку резистора данные которые приходят с порта LM меняются примерно на 70-80 единиц скажем когда на А0 1023 на А4 750-780 а когда на А0 0 на А4 620-650

Сначала грешил что плату не так развел, но потом решил посмотреть просто один порт и понял что это программный глюк.

Если в программе брать данные только с А4 то как не крути резистор на данные это никак не влияет, а когда пытаюсь вычитывать данные сразу с двух портов получаю что описал выше.

Даже вот в таком коде есть та же ошибка.

void loop() {
int AA= analogRead(A4);
int AB= analogRead(A0);
   Serial.print (" A0 ");
    Serial.print (AA);
    Serial.print (" A4 ");
    Serial.print (AB);
Serial.println("");
}

Заранее всем спасибо за ответы.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

у тя порты как настроены?  На ввод с подтяжкой?

rkit
Offline
Зарегистрирован: 23.11.2016

Неправильно развел. Читай даташит в разделе характеристик ацп.

wer_wolf
Offline
Зарегистрирован: 08.08.2016

DetSimen пишет:

у тя порты как настроены?  На ввод с подтяжкой?

Если честно никак не настроены. Насколько я смотрел мануалы Аналоговые порты вроде как не нужно вначале конфигурить или я не прав?

rkit пишет:

Неправильно развел. Читай даташит в разделе характеристик ацп.

А почему тогда без изменения схемы данные получаются правильными если я перестаю считывать данные с порта А0?

b707
Offline
Зарегистрирован: 26.05.2017

переменник какое сопротивление?

Bruzzer
Offline
Зарегистрирован: 17.03.2020

wer_wolf пишет:

На порту А4 LM328 через которую приходят данные от термопары

Как подключен LM328 к A4? Через резистор? Если да, то какое сопротивление?

wer_wolf
Offline
Зарегистрирован: 08.08.2016

Bruzzer пишет:

Как подключен LM328 к A4? Через резистор? Если да, то какое сопротивление?

Вот эта схема

b707 пишет:

переменник какое сопротивление?

Переменник 8 кОм

Bruzzer
Offline
Зарегистрирован: 17.03.2020

Надо уменьшать R2

Для мультиплексора АЦП рекомендуемое выходное сопротивление источника сигнала должно быть 10 КОм.

The ADC is optimized for analog signals with an output impedance of approximately 10 KOm or less. If such a
source is used, the sampling time will be negligible. If a source with higher impedance is used, the sampling
time will depend on how long time the source needs to charge the S/H capacitor, with can vary widely. The user
is recommended to only use low impedance sources with slowly varying signals, since this minimizes the
required charge transfer to the S/H capacitor.

Pyotr
Offline
Зарегистрирован: 12.03.2014

Про R2 написали.

Или так попробуй

void loop() {
analogRead(A4);	
int AA= analogRead(A4);
analogRead(A0);
int AB= analogRead(A0);
   Serial.print (" A0 ");
    Serial.print (AA);
    Serial.print (" A4 ");
    Serial.print (AB);
Serial.println("");
}

 

wer_wolf
Offline
Зарегистрирован: 08.08.2016

Pyotr пишет:

Про R2 написали.

Или так попробуй

void loop() {
analogRead(A4);	
int AA= analogRead(A4);
analogRead(A0);
int AB= analogRead(A0);
   Serial.print (" A0 ");
    Serial.print (AA);
    Serial.print (" A4 ");
    Serial.print (AB);
Serial.println("");
}

Так значение АЦП меняется от 710 до 760

rkit
Offline
Зарегистрирован: 23.11.2016

wer_wolf пишет:

А почему тогда без изменения схемы данные получаются правильными если я перестаю считывать данные с порта А0?

Потому что ты спрашиваешь вопрос не прочитав то что тебе сказали.

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

Поставь делеи по 50 мс перед считыванием портов. Посмотри как изменятся показания.

Pyotr
Offline
Зарегистрирован: 12.03.2014

С1 нужно убрать, R2 уменьшить в 50-100 раз, поставить delay(50-500) и тогда мой пример должен работать. Да и без делей должен работать.

rkit
Offline
Зарегистрирован: 23.11.2016

Pyotr пишет:

С1 нужно убрать, R2 уменьшить в 50-100 раз, поставить delay(50-500) и тогда мой пример должен работать. Да и без делей должен работать.

Еще один не читавший ни даташита ни учебника. Вход ацп всегда фильтруется.

Pyotr
Offline
Зарегистрирован: 12.03.2014

ркит, ты конечно спец, не как я, но попробуй разобраться что происходит у ТС. Я понял его проблему, а ты?

rkit
Offline
Зарегистрирован: 23.11.2016

Не знаю уж, чего ты там понял, но советы даешь неверные.

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

Выходное сопротивление источника сигнала должно быть максимально низким. Если это достичь невозможно, то нужно ждать после переключения на канал, что бы зарядились входные ёмкости АЦП. Т.к. аналогрид не даёт возможности ждать, то делаем два раза чтение одного канала, а между ними ставим задержку, которую подбираем в зависимости от необходимой точности.

Pyotr
Offline
Зарегистрирован: 12.03.2014

rkit пишет:

Не знаю уж, чего ты там понял, но советы даешь неверные.

Сейчас по холодку мне нужно доварить металлоконструкцию. Завтра после обеда я объясню происходящее.

До завтра сможешь разобраться в вопросе и объяснить?

Коллеги, давайте послушаем что скажет rkit. 

PS. Притом, что часть ответа уже прозвучала выще.

rkit
Offline
Зарегистрирован: 23.11.2016

Можешь не торопиться, в теме уже есть правильный ответ #7. К нему нужно подкорректировать конденсатор под частоту найквиста (это к вопросу об учебнике, которого ты не читал).

Pyotr
Offline
Зарегистрирован: 12.03.2014

Скопировал вопрос ТС.

Есть ардуино Nano на 328 контроллере

На порту А0 переменный резистор, одна нога на +5 вторая на GND середина на порту

На порту А4 LM328 через которую приходят данные от термопары

А1,А2 кнопки через резисторные делители.

И вот получился у меня такой глюк.

Когда вращаю ручку резистора данные которые приходят с порта LM меняются примерно на 70-80 единиц скажем когда на А0 1023 на А4 750-780 а когда на А0 0 на А4 620-650

Сначала грешил что плату не так развел, но потом решил посмотреть просто один порт и понял что это программный глюк.

Почему так? Твой ответ: "Неправильно развел. Читай даташит в разделе характеристик ацп." Подумай и ответь. А тот учебник (где говорится о частоте Найквиста) я и правда не читал.

Гриша
Offline
Зарегистрирован: 27.04.2014

wer_wolf пишет:

Когда вращаю ручку резистора данные которые приходят с порта LM меняются примерно на 70-80 единиц скажем когда на А0 1023 на А4 750-780 а когда на А0 0 на А4 620-650

что-то где-то генерит, похоже блокировочных емкостей маловато по питанию + повесить маленькую керамику на не_инвертирующий вход усилителя. 

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

ну и  однозначно порезать R2 в плоть до 1К, там и 100 Ом должно хватить ( "противовозбудные" ) 

и где вы схему взяли? зачем там R4????? еще и такой огромный...

wer_wolf
Offline
Зарегистрирован: 08.08.2016

Гриша пишет:

и где вы схему взяли? зачем там R4????? еще и такой огромный...

Схему взял тут же в каком-то из обсуждений. Но она бродит во многих статьях только с небольшими вариациями по типу вход как и выход фильтровать конденсатором, еще есть вариант когда парралельно резистору/рам R5 и R1 (иногда вместо двух стоит один) ставят еще одну керамику.

Завтра попробую заменить R2 на 10кОм и посмотрю как обстоят дела.

Собственно я стал грешить на что, что не знаю какой-то тонкости при работе в АЦП програмно потому как если смотреть выход LM мультом или осциллографом там нет такого большого падения напряжения как фиксируется АЦП. Есть шум, но он не превышает сотых вольта как не крути резистор, примерно такой же шум показывает и ардуино пока не крутишь резистор, третья цифра в данных АЦП гуляет в пределах +/-20-30.

Поэтому и решил спросить может что не так с программной частью.

Pyotr
Offline
Зарегистрирован: 12.03.2014

rkit, что молчишь? Ты ж крутой спец-ответь почему ТС увидел нете значения АЦП, которые ожидал.

Вот тебе последний шанс. Почти ответ. Плата УНО.
А0 подтянут к земле 1 МОм и зашунтирован 100 нФ.
На А1 подано перемычкой 3.3 В с платы УНО.
А2 подтянут к 5 В 1 МОм и зашунтирован 100 нФ.
Емкость в 100 нФ первая попавшая и значения особо не имеет.

//A0 - gnd, A1 - +3.3V, A2 - +5V
word adcPinGnd, adcPin3V, adcPin5V;

void serialPrint(){
  Serial.print(adcPinGnd); Serial.print('\t');
  Serial.print(adcPin3V); Serial.print('\t');
  Serial.println(adcPin5V);
}

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("first reading");
  adcPinGnd = analogRead(A0);
  adcPin3V = analogRead(A1);
  adcPin5V = analogRead(A2);
  serialPrint();

  for(int i=0; i<1000; i++){
    adcPinGnd = analogRead(A0);
    adcPin3V = analogRead(A1);
    adcPin5V = analogRead(A2);
  }
   Serial.println("second reading");
   serialPrint();

  for(int i=0; i<1000; i++){
    adcPinGnd = analogRead(A0);
    adcPin5V = analogRead(A2);
    adcPin3V = analogRead(A1);
  }
   Serial.println("third reading");
   serialPrint();
}

void loop() {}

Вывод отладочный:

first reading
0 675 1023
second reading
39 675 1009
third reading
26 675 982
 
Что за фигня? Почему на А0 и А2 значения уплыли?
 
wer_wolf, извините, что я в Вашей теме дискусию с ркит развел. Просто надо хама на место поставить. Его высеры надоели. Ну и Вы попробуйте сами разобраться почему такие значения получаются.
wer_wolf
Offline
Зарегистрирован: 08.08.2016

Pyotr пишет:

wer_wolf, извините, что я в Вашей теме дискусию с ркит развел. Просто надо хама на место поставить. Его высеры надоели. Ну и Вы попробуйте сами разобраться почему такие значения получаются.

Да я то что, мне еще учить далеко и долго. А вот за помощь всем спасибо, заменил 1МОм на выходе с LM на 10кОм показания почти перестали плавать при использовании переменника.

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

з.ы. Ответ на вашу задачу будет интересно услышать.

 

rkit
Offline
Зарегистрирован: 23.11.2016

Pyotr пишет:

rkit, что молчишь? Ты ж крутой спец-ответь почему ТС увидел нете значения АЦП, которые ожидал.

Еще раз, для идиотов: ответ в даташите написан. Твой ответ про "убрать конденсатор и уменьшить 1 МОм в 5 раз" - неверный.  Можешь сколько угодно хохриться, но это так. До свидания.

Pyotr
Offline
Зарегистрирован: 12.03.2014

rkit пишет:

Еще раз, для идиотов: ответ в даташите написан. Твой ответ про "убрать конденсатор и уменьшить 1 МОм в 5 раз" - неверный.  Можешь сколько угодно хохриться, но это так. До свидания.

Ясно - тему ты не осилил. 
И я говорил уменьшить резистор в 50-100 раз, а не в пять! Видеться в будущем с тобой желания нет. Прощай.

wer_wolf, смотрите что происходит в моем скетче.
При первом АЦП (строка 14) внутренний конденсатор выборки-хранения (КВХ) на 14 пФ подключается ключем к пину А0 на 12 мкс, разряжается (если был заряжен) и отключается. Пин А0 в моем случае зашунтирован конденсатором 100 нФ, много больше 14 пФ, поэтому одиночный заряд-разряд КВХ никак не повлияет на заряд 100 нФ конденсатора. Затем происходит преобразование значения напряжения на КВХ в двоичный код, который мы и получаем, вызывая функцию analogRead(A0). КВХ остается разряженным.

В строке 15 КВХ заряжается до 3.3 В и остается заряженным до 3.3 В до следующего вызова analogRead(A0) - специально не разряжается. 

В строке 16 КВХ заряжается до 5 В и остается заряженным - специально не разряжается, кроме токов утечки. 

А вот дальше мы начинаем постоянное чтение пинов А0 и А2. КВХ примерно 10000 раз в сек подключается то к конденсатору на А0 (он разряжен), то к конденсатору на А2 (заряжен до 5 В). При этом КВХ переносит часть энергии от кондера на А2 к кондеру на А0, стремясь выровнять напряжение на них.  И если бы не было подтяжки на эти пины, то в итоге напряжения на А0 и А2 выровнялись бы и значение АЦП на этих пинах стало одинаково. Но через резисторы в 1 МОм происходит разрядка одного и зарядка другого кондера, поэтому напряжения на конденсаторах изменяются не так значительно.

Тоже самое происходит и в Вашем случае. 

Выходное сопротивление менее 10 кОм почему в даташите указано, потому что 10 кОм*14пФ дает 140 нсек, что много меньше 12 мкс. Поэтому КВХ гарантированно зарядится до напряжения источника и АЦП даст верный результат. И в этом случае неважно есть шунтирующая емкость или нет. Если на входе быстроменяющий сигнал и идет постоянная оцифровка, то емкость будет скорее мешать.

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

Ну вот объяснил насколько смог.

 

svm
Offline
Зарегистрирован: 06.11.2016

Первое-это не надо считывать подряд с двух разных аналоговых входов. АЦП и мультиплексор не идеальны и у них есть переходные процессы. В документации рекомендуют сделать несколько пустых считываний, а только потом смотреть что прилетело. Конденсатор и резистор 1 МОм в данном случае не критичны. С выхода ОУ должна приходить практически постоянка (если он не возбуждается, правильный монтаж входных цепей ОУ и питание нормальное). 

Pyotr
Offline
Зарегистрирован: 12.03.2014

svm, в некоторых моих проектах АЦП работает в непрерывном фоновом режиме-поочередно читаются четыре входа. По завершению одного преобразования вызывается прерывание и сразу запускается новое преобразование на следующем входе. Например отслеживаются два резистивных датчика положения 1 кОм и два NTC 10 кОм. Работает замечательно.

svm
Offline
Зарегистрирован: 06.11.2016

Pyotr пишет:

svm, в некоторых моих проектах АЦП работает в непрерывном фоновом режиме-поочередно читаются четыре входа. По завершению одного преобразования вызывается прерывание и сразу запускается новое преобразование на следующем входе. Например отслеживаются два резистивных датчика положения 1 кОм и два NTC 10 кОм. Работает замечательно.

И тем не менее производитель рекомендует перед чтением АЦП, хотя-бы раз произвести пустое чтение аналогового входа. Ведь АЦП - один, а к нему мультиплексором подключаются разные аналоговые входа. Хотя там что-то есть для уменьшения влияния, но идеального ничего нет, и переходные процессы существуют. Я если можно или усредняю , хотя-бы десяток измерений, а если можно , то и делеями грешу.

Гриша
Offline
Зарегистрирован: 27.04.2014

Pyotr пишет:

Например отслеживаются два резистивных датчика положения 1 кОм и два NTC 10 кОм. Работает замечательно.

не лично, а по мотивам... 

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

вообще прозвучало много полезной информации, Это если шелуху отсеять. 

"В доме есть всегда только один выход! Для того кто слепой и не видит окон и дымохода." - не помню, из какой-то книжки. это я к тому, что учитывать нужно все.

svm
Offline
Зарегистрирован: 06.11.2016

Гриша пишет:

Pyotr пишет:

Например отслеживаются два резистивных датчика положения 1 кОм и два NTC 10 кОм. Работает замечательно.

не лично, а по мотивам... 

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

Но после 1 МОм стоит конденсатор на 0,01 мкф, который по сравнению с измерительной емкостью АЦП, просто огромен. И его импеданс по сравнению с импедансом АЦП в процессе измерения - можно приравнять к "0"

Гриша
Offline
Зарегистрирован: 27.04.2014

svm пишет:

Но после 1 МОм стоит конденсатор на 0,01 мкф, который по сравнению с измерительной емкостью АЦП, просто огромен. И его импеданс по сравнению с импедансом АЦП в процессе измерения - можно приравнять к "0"

точно... теоретически...., а практически мы видим проблему, которая решилась...

wer_wolf пишет:

заменил 1МОм на выходе с LM на 10кОм показания почти перестали плавать при использовании переменника.

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

для чистоты эксперимента делать 2 изменения нельзя, поэтому и утверждать я ничего не буду. Просто есть факт.

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

svm пишет:

Первое-это не надо считывать подряд с двух разных аналоговых входов. АЦП и мультиплексор не идеальны и у них есть переходные процессы. В документации рекомендуют сделать несколько пустых считываний, а только потом смотреть что прилетело. Конденсатор и резистор 1 МОм в данном случае не критичны. С выхода ОУ должна приходить практически постоянка (если он не возбуждается, правильный монтаж входных цепей ОУ и питание нормальное). 

Подскажите, где в документации сказано про пустые считывания? 2 раза прочитал мануал. Про 10к макс выходного сопротивления у сигналов нашёл. Про пустые считывания ни слова нет. Может я плохо искал? 

Pyotr
Offline
Зарегистрирован: 12.03.2014

Про источник с выходным сопротивлением в1 МОм я чисто теоритически рассуждал. Сам так никогда не делал. Больше 20-25 кОм я не имел источников. У ТС на схеме конечно 1 МОм на выходе это круто. Зачем автор схемы так сделал даже не предполагаю.

svm
Offline
Зарегистрирован: 06.11.2016

nik182 пишет:

Подскажите, где в документации сказано про пустые считывания? 2 раза прочитал мануал. Про 10к макс выходного сопротивления у сигналов нашёл. Про пустые считывания ни слова нет. Может я плохо искал? 

Недавно на ГИТХАБЕ разбирался со скетчем THC, очень хорошо закомментированным. И там встретил непонятный кусок кода (несколько пустых считываний ) и комментарий к нему. Вот кусок оттуда:

pinMode(ADJUST, INPUT);
  pinMode(PLASMA, INPUT);
  pinMode(UP, OUTPUT);
  pinMode(DOWN, OUTPUT);

  // Set the reference voltage to the external linear regulator
  // Do a few throwaway reads so the ADC stabilizes, as recommended by the docs.
  analogReference(EXTERNAL);
  analogRead(PLASMA); analogRead(PLASMA); analogRead(PLASMA); analogRead(PLASMA); analogRead(PLASMA);

  // We need to calculate how big the shift must be, for a given sample size.
  // Since we are using bitshifting instead of division, I'm using a != here,
  // so your shit will be totally broke if you don't set SAMP to a power of 2.
  while((1 << shift) != SAMP)
    shift++;

 

Гриша
Offline
Зарегистрирован: 27.04.2014

nik182 пишет:

Подскажите, где в документации сказано про пустые считывания? 2 раза прочитал мануал. Про 10к макс выходного сопротивления у сигналов нашёл. Про пустые считывания ни слова нет. Может я плохо искал? 

это не в мануале на процессор, сам не помню конкретный мануал и версию. Есть общий мануал на Атмеловские процессоры в нем... что-то типа "...для более точного измерения отбрасывать первое измерение..."

уж давно его читал, пара лет прошла, а то и более...   

UPD там еще про усреднение было и про опорное напряжение, в разделе точность измерения АЦП.

Гриша
Offline
Зарегистрирован: 27.04.2014

тут пост 20

kost82 пишет:

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

на самом деле в ДШ было написано про некое количество тактов после смены, но применительно к ардуино проще делать пустое измерение.  

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

nik182 пишет:

Подскажите, где в документации сказано про пустые считывания? 2 раза прочитал мануал. Про 10к макс выходного сопротивления у сигналов нашёл. Про пустые считывания ни слова нет. Может я плохо искал? 

В аппноуте было, Atmel AVR126: ADC of megaAVR in Single Ended Mode 

 It is recommended to discard the first conversion result (like whenever there is a 
change in ADC configuration like voltage reference / ADC channel change) 
wer_wolf
Offline
Зарегистрирован: 08.08.2016

Pyotr пишет:

Ну вот объяснил насколько смог.

Спасибо большое. Очень подробно и доступно пояснили, буквально разжевали и в рот положили. 

Гриша пишет:

для чистоты эксперимента делать 2 изменения нельзя, поэтому и утверждать я ничего не буду. Просто есть факт.

Cначала я просто заменил резистор, получилось почти, в статике температура гулает у меня +/- 2-3 градуса, при вращении резистора проседала на 3 градуса.

До замены резистора перевод переменника из одной крайней точки в другую давал сдвиг примерно на 15-20 градусов, причем разлет был стабильный. Если в одном положении резистора было скажем 28 градусов, то в другом уже 40-48 и держалось это показание стабильно, опять таки с шумом +- 2-3.

После того как разнес считывание в программе, при повороте резистора какого либо смещения показаний нет вообще.