• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопросы по analogRead

Просто читаю в течение 5 секунд analogRead(A0) значение со стационарного потенциометра с плечами 5 и 4.7Ком и вывожу в Serial каждые 10 мсек время и прочитанное значение. Рисую график (прицеплен), перехватывая данные из Putty/
Puls1_Test12.pngPuls1_Test12.png
Коричневая кривая получена первой, затем через несколько десятков секунд зеленая и с тем же запаздыванием синяя.

Почему меняется положение кривых? Плечи потенциометра 5 в с платы и земля.

Почему во всех случаях наблюдаются выбросы за рамки наблюдаемого разброса? Разброс естественнен и допустим, но выбросов хотелось бы избежать.

Попытки исправить ситуацию: перешел на внешнее питание потенциометра и исправил analogRead на analogRead(А0, INPUT_PULLUP) серая кривая на рисунке. естественный разброс несколько меньше, а выбросы заметнее. Выбросы похожи на реакцию колебательной системы на возмущение при сильном затухании.

Заметка: до изменения установки analogRead (было analogRead(А0, INPUT)) покзания мультиметра в точке измерения просаживались с 2.45 в до примерно 0.5 в. при соединении точки измерения с соответствующим пином платы.
 

enjoynering

Well-known member
используйте програмный фильтр. у меня неплохо работает простой медианный фильтр на 3 значения

Код:
/************************************************************************************/
/*
    adc_getMedianFilteredADC()

    Returns median ADC value after 3 measurements

    NOTE:
    - median filter to reduce ADC noise, see Normal/Gauss smoothing/distribution
*/
/************************************************************************************/
uint16_t adc_getMedianFilteredADC()
{
  uint16_t adcValue[3];
  uint16_t middle;

  /* read ADC */
  for (uint8_t i = 0; i < 3; i++)
  {
    adcValue[i] = analogRead(ADC_PIN);
  }

  /* find middle */
  if ((adcValue[0] <= adcValue[1]) && (adcValue[0] <= adcValue[2]))
  {
    middle = (adcValue[1] <= adcValue[2]) ? adcValue[1] : adcValue[2];
  }
  else if ((adcValue[1] <= adcValue[0]) && (adcValue[1] <= adcValue[2]))
  {
    middle = (adcValue[0] <= adcValue[2]) ? adcValue[0] : adcValue[2];
  }
  else
  {
    middle = (adcValue[0] <= adcValue[1]) ? adcValue[0] : adcValue[1];
  }

  return middle;                                 
}
 
Сходу кажется, что это выбор среднего из 3х измерений. Для пиков, которые на снимках это не поможет. Но я попробую.
С платой UNO (клон) ситуация приемлемая.Puls1_UNO-v-5-3.3.pngPuls1_UNO-v-5-3.3.png
Синяя кривая 5в платы, коричневая внешний источник, зеленая 3.3 с платы.
 
Попробовал, получилось убрать резкие выбросы. Прицеплен рисунок, зеленая по вашему. Пиков нет.
Интересно, что я много занимаясь анализом процессов, впервые столкнулся с обработкой во время измерения, для меня привычнее анализировать уже измеренное, в этом случае ваш способ не годиться, можно потерять тренд.
 

Вложения

nikolz

Well-known member
Просто читаю в течение 5 секунд analogRead(A0) значение со стационарного потенциометра с плечами 5 и 4.7Ком и вывожу в Serial каждые 10 мсек время и прочитанное значение. Рисую график (прицеплен), перехватывая данные из Putty/
Посмотреть вложение 13888Посмотреть вложение 13888
Коричневая кривая получена первой, затем через несколько десятков секунд зеленая и с тем же запаздыванием синяя.

Почему меняется положение кривых? Плечи потенциометра 5 в с платы и земля.

Почему во всех случаях наблюдаются выбросы за рамки наблюдаемого разброса? Разброс естественнен и допустим, но выбросов хотелось бы избежать.

Попытки исправить ситуацию: перешел на внешнее питание потенциометра и исправил analogRead на analogRead(А0, INPUT_PULLUP) серая кривая на рисунке. естественный разброс несколько меньше, а выбросы заметнее. Выбросы похожи на реакцию колебательной системы на возмущение при сильном затухании.

Заметка: до изменения установки analogRead (было analogRead(А0, INPUT)) покзания мультиметра в точке измерения просаживались с 2.45 в до примерно 0.5 в. при соединении точки измерения с соответствующим пином платы.
У Вас выбросы идут с интервалом 1 секунда. вот и ищите,
что у Вас включается с этим интервалом,
так как это и дает помеху.
 
Оказалось, что на плате UNO проблем до частот порядка 100Гц нет.1718354824348.png

Это выдача с паузой между 1 мсек, получается примерно 750 чтений в секунду, но если номер чтения переводить в float time, то рисунок чуть чуть хуже.
С платой ESP32 Wroom-32 (клон) все очень похоже, но наблюдаются длительные пропуски.
1718355078407.png
Во всех случаях попытка принять сигнал 50Гц 0.6 в АС
 

pvvx

Активный участник сообщества
Почему во всех случаях наблюдаются выбросы за рамки наблюдаемого разброса? Разброс естественнен и допустим, но выбросов хотелось бы избежать.
1. Потребление ESP32 во много раз больше, чем у "UNO". Для фильтрации питания требуется более сложная схема. Питание от порта USB не фильтровано.
2. При шаге измерения, близком кратности помехам (50/100Гц), обязательно будут выбросы.
3. Из-за низкого качества ADC у ESP32 его можно только условно назвать ADC.
4. Основной цикл Ардуино для ESP вызывается с неравномерным шагом. Для получения более точных временных периодов желательно использовать аппаратный таймер и отключенный WiFi.
 
Для UNO нашел полное решение. У кого не помню. Результат для синуса 50 Гц нарисован точками, чтобы было понятно, что частоту сигнала можно увеличить очень сильно. Особенность в том, что измерения выполняются по таймеру и записываются в массив, который выводится после окончания измерений. У меня остается только вопрос к ESP32, формат которого мне подходит больше.
 

Вложения

Сверху Снизу