Для электронщиков и радиолюбителей

Почему АЦП Arduino «врёт» и как получить реальную точность

Почему АЦП Arduino «врёт» и как получить реальную точность

Новички часто ожидают, что аналоговый вход Arduino будет работать как точный измерительный прибор. Подключили датчик, вызвали analogRead() — и получили точное значение напряжения. На практике всё оказывается сложнее: показания могут заметно «плавать», зависеть от источника сигнала и даже от того, какой пин вы читали перед этим.

Разберёмся, почему так происходит на примере микроконтроллера ATmega328P, который используется на плате Arduino Uno.


Как устроен АЦП в Arduino

В ATmega328P используется 10-битный последовательный АЦП (SAR — successive approximation register).

Основные параметры:

  • разрешение: 10 бит
  • диапазон: 0–1023
  • время преобразования: примерно 104 мкс
  • максимальная частота АЦП: около 200 кГц

10 бит означают, что входной диапазон напряжений делится на 1024 шага.

Если опорное напряжение 5 В:

1 шаг ≈ 4.88 мВ

Но это идеальная ситуация. На практике ошибки возникают сразу в нескольких местах.


1. Нестабильное опорное напряжение

По умолчанию Arduino использует питание платы как опорное напряжение для АЦП.

То есть:

Vref = Vcc

Если питание меняется, меняются и показания.

Типичные причины:

  • шум USB-питания
  • просадки из-за реле или моторов
  • нестабильный стабилизатор
  • нагрузка на плату

Даже изменение питания на 50–100 мВ уже даёт заметную погрешность.

Решение

Использовать внутренний опорный источник:

analogReference(INTERNAL);

В ATmega328P он равен примерно 1.1 В.

Или подключить внешний опорник к пину AREF.


2. Шум питания и цифровой части

Микроконтроллер — это шумная среда:

  • переключаются транзисторы
  • работают таймеры
  • меняются уровни GPIO
  • идёт обмен по UART и SPI

Все эти процессы создают помехи на линии питания, которые напрямую попадают в АЦП.

Особенно заметно это, когда:

  • измеряются малые напряжения
  • источник сигнала имеет высокий импеданс

Решение

Добавить фильтрацию:

  • конденсатор 100 нФ между AREF и GND
  • RC-фильтр на входе
  • отдельную аналоговую землю

3. Высокий импеданс источника сигнала

Вход АЦП подключён к внутреннему sample-and-hold конденсатору примерно 14 пФ.

Перед измерением этот конденсатор должен зарядиться до напряжения входного сигнала.

Если источник имеет высокий импеданс:

  • зарядка происходит медленно
  • результат получается заниженным

Рекомендация из datasheet:

импеданс источника ≤ 10 кОм

Решение

  • использовать буферный операционный усилитель
  • уменьшить сопротивление делителя
  • добавить конденсатор на вход

4. Переключение каналов АЦП

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

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

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

Решение

Игнорировать первый результат:

analogRead(A0);
int value = analogRead(A0);

5. Квантование и реальное разрешение

10 бит — это теоретическое разрешение.

Но реальное эффективное разрешение часто меньше из-за шума.

Обычно получается около 9–9.5 бит.

Это означает, что младшие биты могут вести себя случайно.


6. Ошибки самого АЦП

Даже в идеальных условиях есть аппаратные погрешности:

  • offset error
  • gain error
  • нелинейность
  • температурный дрейф

По datasheet:

типичная ошибка может достигать ±2 LSB.

Это нормально для встроенного АЦП микроконтроллера.


7. Как увеличить точность: oversampling

Интересный трюк — использовать передискретизацию.

Если снять несколько измерений и усреднить их, можно увеличить эффективное разрешение.

Правило:

Дополнительные битыКоличество измерений
+1 бит4
+2 бита16
+3 бита64
+4 бита256

Пример:

long sum = 0;for(int i = 0; i < 64; i++) {
sum += analogRead(A0);
}int value = sum / 64;

Это позволяет получить точность около 11–12 бит, если уровень шума достаточный.


8. Практический чек-лист точных измерений

Если нужна максимальная точность на Arduino:

  1. Использовать стабильное опорное напряжение.
  2. Поставить конденсатор 100 нФ на AREF.
  3. Делать два измерения подряд и отбрасывать первое.
  4. Использовать источник сигнала с импедансом меньше 10 кОм.
  5. Добавить RC-фильтр на входе.
  6. Усреднять несколько измерений.
  7. Разводить аналоговую и цифровую землю.

Когда встроенного АЦП недостаточно

Если требуется высокая точность (например, 14–16 бит), встроенного АЦП микроконтроллера может не хватить.

В таких случаях используют внешние преобразователи:

  • ADS1115
  • MCP3424
  • LTC2400

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


Итог

АЦП Arduino не «врёт» — он просто работает в реальных условиях, где на результат влияют:

  • опорное напряжение
  • шум питания
  • импеданс источника
  • переключение каналов
  • аппаратные ограничения

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