Я хотел записать дрожание света на фоторезисторе: лазер мигал зеркальцем на вибрирующем корпусе насоса, и мне нужны были хотя бы двадцать тысяч замеров в секунду. Реальность: analogRead выдал свою паспортную норму — один замер около 110 микросекунд, потолок примерно девять тысяч шестьсот в секунду. На графике вместо живой дрожи стояла ровная ступенька: сигнал выше четырёх с половиной килогерц для этой скорости уже не существует, он складывается в мусор.
Первым делом я грешил на Serial: поднял скорость порта до 115200 — график стал плавнее, но потолок замеров не двинулся. Меру снял через micros(): тысяча замеров заняла 112 миллисекунд, по 112 мкс на штуку — и половина из них не печать, а само преобразование. Медлил аналого-цифровой преобразователь со своим тактом, а не монитор порта: внутри одного вызова сидят и переключение мультиплексора на нужный канал, и выборка, и сама конверсия.
Ручка управления этим тактом — регистр ADCSRA и три бита делителя ADPS2..0. В уроке: почему 16 мегагерц превращаются в 125 килогерц, сколько стоит скорость в битах точности, таблица цена-качество и практический осциллограф из Serial Plotter. Если analogRead для вас пока чёрный ящик — начните с урока про потенциометр, здесь он станет прозрачным.
Где теряется время: 16 МГц, делитель 128, 13 тактов
АЦП ATmega328P по устройству медленный: для полных десяти бит ему нужен такт от 50 до 200 кГц — это паспортный диапазон даташита. Плата из коробки делит 16 МГц на 128 (биты ADPS2..0 = 111) и получает 125 кГц — самая низкая частота из возможных, зато с максимальной точностью.
Одно преобразование стоит 13 тактов АЦП: при 125 кГц это 13 умножить на 8 мкс = 104 мкс чистой конверсии. Плюс переключение мультиплексора на входе и накладные расходы вызова — выходят те самые 110-112 мкс, что я померил micros(). В секунду набирается около 9 600 замеров, и всё это время loop() стоит и ждёт: analogRead блокирующий, никакого неблокирующего волшебства внутри нет.
Делитель меняет уравнение. Ставим 64 — такт 250 кГц, преобразование 52 мкс. Ставим 32 — 500 кГц, 26 мкс. Ставим 16 — 1 МГц, 13 мкс. Плата — точность: выше паспортных 200 кГц ядро преобразователя не успевает дожимать младшие биты, и они превращаются в шум. Тактовые регистры мы уже правили в уроке про частоту ШИМ — ADCSRA правится тем же почерком, только проще: там три бита, и они целиком про скорость АЦП.
| ADPS2..0 | Такт АЦП | Замеров в секунду | Реальная точность на практике |
|---|---|---|---|
| 111 — по умолчанию | 125 кГц | около 9 600 | полные 10 бит: младший бит стабилен, эталон |
| 110 | 250 кГц | около 19 200 | 9-10 бит: последний бит уже дрожит на единицу |
| 101 | 500 кГц | около 38 400 | примерно 8 бит: шумят два младших разряда |
| 100 | 1 МГц | около 77 000 | 7-8 бит: без усреднения сигнал в мусоре |
// Делитель живёт в младших трёх битах ADCSRA: ADPS2..0.// Маска: 7 = 128 (по умолчанию), 6 = 64, 5 = 32, 4 = 16.const int PIN_POT = A0;long summa = 0; void ustanovitDelitel(byte maska) { ADCSRA = (ADCSRA & 0xF8) | maska; // стереть старые биты, вписать новые} void setup() { Serial.begin(115200); ustanovitDelitel(7); // стартуем с эталонного 128 Serial.println("Stend: 1000 zamjerov, menyayte masku 7/6/5/4");} void loop() { unsigned long t0 = micros(); for (int i = 0; i < 1000; i = i + 1) { summa = summa + analogRead(PIN_POT); } unsigned long t1 = micros(); Serial.print("1000 zamjerov za= "); Serial.print(t1 - t0); Serial.println(" us"); delay(2000); // Поменяйте маску на 6, 5 и 4: 1000 замеров просядет // со 112 мс к 56, 28 и 14 — а дрожь младших битов вырастет.}Практика: осциллограф из Serial Plotter
Схема простая: замер и печать в loop без единого delay, плоттер из урока про Serial рисует волну в реальном времени. Но печать упирается раньше АЦП: при 115200 бод один байт уходит 86,8 мкс, строка вида v=1023 с переводом строки — семь байт, около 0,6 мс. Потолок печати — примерно 1 600 строк в секунду, и на быстром делителе именно Serial диктует темп, а не преобразователь.
Два честных способа поднять потолок. Первый: печатать каждый пятый замер — волну это не портит, если замеры идут подряд без пауз. Второй: копить серию в массив и сливать пачкой после неё — так я записывал всплески по два килогерца. Выше двух килогерц наблюдения Serial уже не отдаёт — дальше внешний АЦП или логический анализатор, о чём я говорил в уроке про внешний ADS1115 для точности, а не для скорости.
Перевод сырых значений в вольты не меняется: младший бит при 5 В — 4,88 мВ, формула — та же map из урока про потенциометр и map. Сэмплы, которые надо раздавать равномерно по времени, я держу на millis-гейте: замер каждые N миллисекунд, печать — отдельной задачей неблокирующего цикла.
Что считать шумом, а что сигналом — вопрос с числами. На делителе 128 прыжок плюс-минус единица — норма жизни десятибитного преобразователя, её не лечат. На 64 нормой становятся две единицы, на 32 — четыре-пять. Если решение у вас принимается по порогу в одну-две единицы, сначала ставьте гистерезис, а не ускоряйте АЦП: скорость дрожь не уберёт, она её усилит.
Когда ускоряться не надо: DHT22 отвечает раз в две секунды, термистору хватает раза в секунду, батарейный метеодатчик из итогового проекта раздела вообще спит. Дефолтного делителя 128 там хватает на десять проектов из десяти — я ставлю его обратно перед заливкой обычного скетча, потому что с делителем 16 неточный вольтметр никому не нужен.
Когда надо: звук (для верхней границы в четыре килогерца по Найквисту нужно минимум восемь тысяч замеров — делитель 64), вибрация, ток через шунт, где ШИМ-помеха живёт на десятках килогерц. Усреднение возвращает часть точности: четыре замера на делителе 64 со средним — почти как один замер на 128, но по времени это 4 умножить на 52 = 208 мкс против 110. Решение не бесплатное, и платить им стоит только за измерение, а не за реакцию.
И про переключение каналов — тонкость, о которой молчат в туториалах. АЦП на Uno один, а входов шесть: перед замером мультиплексор переключается на выбранный пин, и первый замер после смены канала часто врёт — конденсатор выборки ещё держит заряд предыдущего входа. Привычка простая: сменили канал — прочтите дважды, первый результат выбросьте. На шаблонах с несколькими датчиками подряд это экономит часы поиска «случайного мусора», когда один сенсор приписывает чужие значения соседу.
- 1. Сколько длится один analogRead на Uno из коробки?
- 2. За что отвечают биты ADPS2..0 в регистре ADCSRA?
- 3. Поставили делитель 16 (такт 1 МГц). Что с точностью?
- 4. Почему осциллограф из Serial Plotter упирается раньше самого АЦП?
- 5. Сигнал на быстром делителе прыгает на десяток единиц. Что сделать первым делом?
- analogRead стоит около 110 мкс при делителе 128 — примерно 9 600 замеров в секунду, и loop всё это время заблокирован
- Делитель — три бита ADPS2..0 в ADCSRA: 128 даёт 10 бит, 64 — около 19 200 зам/с, 16 — около 77 000, но точность падает до 7-8 бит
- Печать упирается раньше АЦП: 115200 бод — потолок около 1 600 строк в секунду, дальше печать каждого пятого замера или пачки из буфера
- Быстрый АЦП нужен звуку, вибрации и току; температуре и влажности хватает дефолтного делителя
- Шум на быстром делителе лечат конденсатором 100 нФ на входе, короткими проводами и усреднением; ниже 16 делитель не опускайте
Частые вопросы по теме урока
- Сколько длится один analogRead на Uno из коробки?
- 16 МГц делится на 128, получается 125 кГц; преобразование — 13 тактов АЦП, около 104 мкс, плюс переключение входа. Итог — 110-112 мкс, что подтверждает замер micros(). около 110 мкс: 13 тактов АЦП при 125 кГц плюс накладные
- За что отвечают биты ADPS2..0 в регистре ADCSRA?
- Три бита задают степень двойки для делителя частоты платы. Меньше делитель — быстрее такт АЦП — больше замеров в секунду и больше шума в младших битах. за делитель тактовой частоты АЦП: 128, 64, 32, 16 и так далее
- Поставили делитель 16 (такт 1 МГц). Что с точностью?
- Выше паспортных 200 кГц преобразователь не успевает дожимать младшие биты. На 1 МГц реальная точность — 7-8 бит; вернуть часть точности можно усреднением серии замеров. упала до 7-8 бит: младшие два-три разряда шумят без усреднения
- Почему осциллограф из Serial Plotter упирается раньше самого АЦП?
- Байт при 115200 бод идёт 86,8 мкс, строка из семи байт — около 0,6 мс. Печать диктует темп быстрее, чем АЦП, — лечится печатью каждого пятого замера или пачками из буфера. потому что при 115200 бод печать выдаёт максимум около 1 600 строк в секунду
- Сигнал на быстром делителе прыгает на десяток единиц. Что сделать первым делом?
- Конденсатор даёт выборке низкий импеданс источника, усреднение прижимает шум младших битов. Оба шага стоят копейки и возвращают часть точности, сохраняя скорость. конденсатор 100 нФ с входа на землю и усреднение четырёх-восьми замеров