Smoothing: сглаживание показаний аналогового входа
Учимся сглаживать шумные показания аналогового датчика с помощью скользящего среднего и массива на Arduino.
Этот скетч многократно считывает значения с аналогового входа, вычисляет скользящее среднее и выводит результат в монитор порта. Подход особенно полезен, когда датчик даёт нестабильные или «прыгающие» показания — например, потенциометр с изношенным контактом, датчик освещённости при мерцающем свете или любой аналоговый сенсор с высоким уровнем шума. Заодно пример наглядно показывает, как использовать arrays для хранения серии измерений.
Как работает сглаживание
Идея проста: вместо того чтобы брать одно «сырое» значение с analogRead(), мы храним последние N измерений в массиве и каждый раз вычисляем их среднее. Это называется скользящим средним (running average). Чем больше N, тем плавнее результат, но тем медленнее он реагирует на резкие изменения — здесь важно найти баланс под конкретную задачу.
Необходимые компоненты
- Arduino Board
- Потенциометр 10 кОм
Схема подключения

Один крайний вывод потенциометра подключите к 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