Главная chevron_right Уроки chevron_right Встроенные примеры chevron_right Аналоговые примеры chevron_right Smoothing: сглаживание показаний аналогового входа

Smoothing: сглаживание показаний аналогового входа

Учимся сглаживать шумные показания аналогового датчика с помощью скользящего среднего и массива на Arduino.

Этот скетч многократно считывает значения с аналогового входа, вычисляет скользящее среднее и выводит результат в монитор порта. Подход особенно полезен, когда датчик даёт нестабильные или «прыгающие» показания — например, потенциометр с изношенным контактом, датчик освещённости при мерцающем свете или любой аналоговый сенсор с высоким уровнем шума. Заодно пример наглядно показывает, как использовать arrays для хранения серии измерений.

Как работает сглаживание

Идея проста: вместо того чтобы брать одно «сырое» значение с analogRead(), мы храним последние N измерений в массиве и каждый раз вычисляем их среднее. Это называется скользящим средним (running average). Чем больше N, тем плавнее результат, но тем медленнее он реагирует на резкие изменения — здесь важно найти баланс под конкретную задачу.

Необходимые компоненты

Схема подключения

Один крайний вывод потенциометра подключите к 5V, средний (ползунок) — к аналоговому входу A0, второй крайний — к GND.

Принципиальная схема

На схеме: POTENTIOMETER (потенциометр) подключён к аналоговому входу A0 платы Arduino UNO. Крайние выводы идут на 5V и GND, средний — на A0.

Код

Скетч последовательно записывает 10 показаний аналогового датчика в arrays — по одному за итерацию. При каждом новом значении пересчитывается сумма всех элементов массива, которая делится на их количество — получается текущее среднее. Поскольку среднее обновляется при каждом новом измерении, а не раз в 10 итераций, задержка в отклике минимальна.

Чтобы сделать сглаживание более агрессивным, увеличьте значение numReadings: чем оно больше, тем «тяжелее» фильтр и тем меньше шума попадёт в итоговый результат. Типичные значения — от 5 до 50 в зависимости от частоты опроса датчика и допустимой задержки.

Практические замечания

  • Выбор размера массива. Значение 10 — хороший старт. Если датчик обновляется 100 раз в секунду, массив из 10 элементов даёт среднее за последние 100 мс. При 50 элементах — за 500 мс. Слишком большой массив сделает систему «вялой» и медленно реагирующей на реальные изменения.
  • Место в памяти. Каждый элемент массива типа int занимает 2 байта. Массив из 10 элементов — 20 байт. На Arduino UNO всего 2 КБ SRAM, поэтому не увлекайтесь большими массивами.
  • Круговой буфер. В скетче используется классическая техника кольцевого (циклического) буфера: индекс записи доходит до конца массива и возвращается к началу, перезаписывая старые значения. Это позволяет обойтись без сдвига элементов и работает очень быстро.

Типичные ошибки

  • Не инициализирован массив. Если не заполнить массив нулями перед началом работы, первые несколько средних значений будут некорректными. В скетче это решено через инициализацию в setup().
  • Переполнение суммы. Если датчик возвращает значения близкие к 1023 и массив большой, сумма может превысить диапазон типа int. В таких случаях используйте long для переменной суммы.
  • Слишком частый вывод в Serial. Serial.println() в быстром цикле без задержки может замедлить весь скетч. Добавьте небольшую паузу или выводите данные раз в несколько итераций.

Как проверить результат

Откройте Монитор порта (или Serial Plotter) в Arduino IDE. Медленно вращайте ручку потенциометра — вы увидите плавно изменяющееся значение без резких скачков. Если резко повернуть ручку до упора, значение будет нарастать постепенно, «догоняя» новое положение — это и есть эффект сглаживания.

Дополнительные материалы

Больше базовых уроков вы найдёте в разделе built-in examples.

Также рекомендуем изучить language reference — подробный справочник по языку программирования Arduino.

Последнее обновление: 29.07.2015, SM