Блок питания у верстака я давно хотел видеть в амперах, а не «на глаз по свисту». Шунт в минусовом проводе отдаёт до 75 мВ, и весь токоряд укладывался в пятнадцать ступенек штатного АЦП Uno: 5 В на 1024 отсчёта — шаг 4,9 мВ. О графике потребления речи не было: одна ступенька — треть ампера. Тензодатчики выглядели ещё безнадёжнее: полный мост выжимает единицы милливольт. Так я пришёл к выводу, что 10 бит — потолок не для всего, и завёл на шину отдельный чип.
ADS1115 — внешний шестнадцатибитный АЦП от Texas Instruments с I2C-интерфейсом: четыре входа A0–A3, встроенный программируемый усилитель PGA и программный диапазон от 8 до 860 выборок в секунду. Адрес 0x48, пока ножка ADDR прижата к земле; перемычки уводят чип на 0x49–0x4B. Соседние сюжеты разобраны рядом: первый урок про внешний АЦП собрал подключение целиком, а урок про дифференциальный режим — токи через шунт; здесь арифметика выбора и честные тайминги.
План такой: цена деления 10 бит против 16 и пределы усиления PGA, скорость — где 860 выборок в секунду проигрывают штатным ста микросекундам analogRead, обмен по Wire руками, и грабля питания 3,3 В, из-за которой первые эксперименты читают на входе мусор.
Цена деления: 4,9 мВ против 0,125 мВ
Арифметика простая и честная. АЦП Uno: 10 бит на диапазон 0–5 В, 5 В / 1024 ≈ 4,9 мВ на ступень. ADS1115 при GAIN_ONE держит предел ±4,096 В и отдаёт 16 бит: 4,096 В / 32768 ≈ 0,125 мВ. Разница — тридцать девять раз по цене деления, и она видна даже на глаз: шунт 75 мВ у Uno рассыпается на пятнадцать ступенек, у ADS1115 — почти на шестьсот.
Усиление переключается шестью ступенями: пределы ±6,144, ±4,096, ±2,048, ±1,024, ±0,512 и ±0,256 В. Правило выбора — предел чуть выше максимума сигнала: термопарный усилитель на 25 мВ просит самый узкий ±0,256 В с шагом 7,8 мкВ, шунт 75 мВ уживается там же, а 5-вольтовые сигналы требуют либо GAIN_TWOTHIRDS, либо делителя — предела шире ±6,144 В у чипа нет. PGA не «увеличивает» вход сверх предела, а лишь решает, какую шкалу натянуть на измеритель: промахнулись вниз — старшие ступени пропали.
Те же биты, пересчитанные в ёмкость шкалы: 16 бит — это 65536 уровней против 1024 у Uno, лесенка в шестьдесят четыре раза плотнее. Но весь выигрыш держится на пределе: узкий PGA растягивает малый сигнал на все 65536 делений, широкий оставляет его на дне, и биты сами по себе ничего не решают. Отсюда порядок действий, который сэкономил мне одну переделку корпуса: оценить максимум сигнала в вольтах, взять ближайший сверху предел и только потом считать цену деления. Шкала при этом знаковая: ±32767, и в дифференциальном режиме минус — не поломка, а честная разница, когда A1 оказался выше A0.
| Параметр | АЦП Uno | ADS1115 |
|---|---|---|
| Разрядность | 10 бит | 16 бит со знаком |
| Цена деления | 4,9 мВ на диапазоне 0-5 В | 0,125 мВ при GAIN_ONE (±4,096 В) |
| Скорость | около 100 мкс на analogRead | 1,16 мс на отсчёт при 860 выборок/с |
| Входы | A0-A5 через мультиплексор | 4 одиночных или 2 пары: A0-A1, A2-A3 |
Скорость, каналы и дифференциальная пара
Скорость — обратная сторона. analogRead на Uno тратит около 100 микросекунд: больше десяти тысяч отсчётов в секунду, если сигнал того требует. ADS1115 в максимуме даёт 860 выборок в секунду — один отсчёт каждые 1,16 мс, вдесятеро медленнее; внизу диапазона, на 8 выборках, чип копит каждый отсчёт по 125 мс, зато с максимальным подавлением шума. Для температуры, тока батареи и веса разница неважна: сигнал и так не бежит. Для формы сигнала — ток двигателя, звук — штатный АЦП честнее, и это не дефект ADS1115, а расплата за глубину разряда.
Дифференциальная пара — второй козырь. Чип меряет разницу между двумя входами, скажем A0 минус A1, и давит синфазную помеху: сигнал на шунте сидит поверх шума земли, одиночный вход смешивает их, а пара вычитает. Усиление применяется к разнице, поэтому малый сигнал занимает всю шкалу, а не дно. Каналов это стоит: четыре одиночных входа превращаются в две пары — A0–A1 и A2–A3.
Режим одиночного запуска выручает на батарейных приборах. В старший бит конфига записывается единица, чип делает одно преобразование и уходит в сон; скетч тем временем читает регистр 0x01, пока бит OS не вернётся в единицу, — это сигнал «готово». На минимуме 8 выборок в секунду преобразование тянется 125 мс, и поллить конфиг каждые 10 мс расточительно: я ставлю паузу в четверть периода, остальное довершает чтение результата. У готовых модулей есть ножка ALERT/RDY — её можно настроить стрелять по готовности или по порогу компаратора, и тогда шину до события вообще не дёргают. Для старта хватает поллинга: проводов меньше, отладка проще.
Скоростей, к слову, ровно восемь: 8, 16, 32, 64, 128, 250, 475 и 860 выборок в секунду, и это всё, что кодирует младший ниббл конфига, — промежуточных значений в даташите нет. Я живу на 128 выборках: отсчёт каждые 7,8 мс — с запасом для тока батареи, а шину дёргать можно вшестеро реже, чем на максимуме. Миф о «настройке любой частоты» разбивается об эту табличку быстро и без последствий.
#include <Wire.h> // ADS1115: ADDR на земле -> 0x48. Конфиг: непрерывно, AIN0-GND,// GAIN_ONE (+-4,096 В), 860 выборок/с. Слово конфига: 0xC2, 0xE3.const byte ADS = 0x48; void setup() { Wire.begin(); Serial.begin(9600); Wire.beginTransmission(ADS); Wire.write(0x01); // указатель на регистр конфига Wire.write(0xC2); // старт, канал AIN0-GND, GAIN_ONE, непрерывно Wire.write(0xE3); // 860 выборок/с, компаратор выключен Wire.endTransmission(); Wire.beginTransmission(ADS); Wire.write(0x00); // указатель на регистр результата Wire.endTransmission(); Serial.println("ADS1115 на 0x48: AIN0, GAIN_ONE, 860 SPS");} void loop() { delay(100); if (Wire.requestFrom(ADS, 2) != 2) { Serial.println("Чип молчит: адрес, питание, подтяжки"); return; } int hi = Wire.read(); // старший байт первым int lo = Wire.read(); int raw = (hi << 8) | lo; // 16 бит со знаком float volts = raw * 4.096 / 32768.0; // один отсчёт = 0,125 мВ Serial.print(raw); Serial.print(" отсчётов = "); Serial.print(volts, 4); Serial.println(" В");}Конфигурация уходит в регистр 0x01 двумя байтами, и слово стоит разобрать по битам. Старший байт 0xC2: бит запуска, канал AIN0 против GND (код 100), усиление GAIN_ONE (код 001), непрерывный режим. Младший 0xE3: скорость 860 выборок в секунду (код 111) и выключенный компаратор. Перед записью в указатель пишется 0x01, перед чтением результата — 0x00: тот же принцип указателя, что и у соседей по шине, — карта регистров объясняет его на общей механике.
Чтение привычное: requestFrom(0x48, 2), старший байт первым, raw = (hi << 8) | lo. Перевод: raw × 4.096 / 32768 — при GAIN_ONE один отсчёт равен 0,125 мВ. Значение знаковое: в дифференциальном режиме минус — законная часть шкалы, поэтому int, а не unsigned. Если endTransmission вернул не ноль, чип не признался в адресе — таблицу кодов держит урок про коды endTransmission, я сверяюсь с ним при каждой новой плате.
Грабля, на которой я просидел вечер: после настройки конфига я забыл переключить указатель на регистр результата и старательно читал конфигурационное слово. Число выглядело убедительно: 0xC2E3 — это 49891 отсчёта, арифметика уверенно давала 6,23 вольта на неподключённом входе, и я полчаса мерил несуществующий сигнал. Отличить можно за пять секунд: подайте на вход землю — насыщение уйдёт, а читаемый конфиг останется ровно тем, что вы сами записали в 0x01. После этого случая правило простое: настроил конфиг — первым же обменом переключи указатель на 0x00 и убедись, что число дышит.
В симуляторе ADS1115 заменён фоторезистором не случайно: движок поддерживает аналоговые входы и шину с парой готовых устройств, а идея урока — разница шкал — от этого не страдает. Одно и то же напряжение на 10-битной лестнице прыгает ступенями по 4,9 мВ, на 16-битной — шажками по 0,125 мВ: при медленно ползущем свете видно, где заканчивается грубость Uno. На живой плате к ADS1115 цепляют тот же фоторезистор через делитель — как собрать такой делитель, показал урок про фоторезисторный ночник, — и разница шкал остаётся ровно такой же.
Когда 10 бит мало, шаг измерителя толще самого сигнала. Термопара K-типа выдаёт около 41 мкВ на градус: штатные 4,9 мВ толще целых ста двадцати градусов — измерять нечем. Тензомост на весах даёт единицы милливольт на полном диапазоне: 10 бит рассыпают его на три-четыре ступени. Шунт 75 мВ мы уже считали: пятнадцать ступенек на весь ток. Никакое усреднение это не выправит — нечего усреднять.
Когда 10 бит мало: термопара, мост, шунт
Внешний АЦП исправляет именно цену деления, а не плавающее опорное напряжение: у ADS1115 опора встроенная и стабильная, что само по себе плюс против заводских 5 В Uno, гуляющих вместе с питанием. Для токов через шунт формула I = U/R и дифференциальная пара с узким пределом PGA разобраны в соседнем уроке, ссылка — в начале; мой блок питания решился шунтом на паре A0–A1 при GAIN_SIXTEEN и усреднением шестнадцати отсчётов.
Скоростной потолок при этом не обманешь: 860 выборок в секунду — и ни одного больше, что бы ни обещали маркетинговые страницы. Мне этого хватает с огромным запасом: термопара меняется секунды, ток блока питания — десятки. Как только встанет задача ловить форму сигнала, я вернусь на analogRead — или поставлю чип побыстрее, но это уже другая история и другой бюджет.
Мой водораздел простой, и вы вправе провести свой: если сигнал живёт в границах 0–5 В и прощает погрешность в две-три ступени, штатный analogRead проще, быстрее и бесплатен. Единицы и десятки милливольт — территория ADS1115, всё, что выше, — территория платы. Вторая сильная сторона, которую недооценивают, — длинные провода: термистор в теплице за пять метров кабеля ловил помеху от насоса на одиночном входе, дифференциальная пара A0–A1 с тем же делителем выпрямила картину без экрана и конденсаторов. Усреднение 8–16 отсчётов сверху — и 13–14 стабильных бит становятся нормой, о чём в даташите скромно не пишут.
- 1. Ножка ADDR прижата к GND. Какой адрес у чипа?
- 2. Цена деления при GAIN_ONE?
- 3. Сколько длится отсчёт при 860 выборок/с и как это на фоне analogRead Uno?
- 4. ESP32 питает чип от 3,3 В, на входе сигнал 5 В. Что делать?
- 5. Тензомост выдаёт единицы милливольт. Что выбрать?
- Адрес 0x48 при ADDR на земле; перемычка ADDR уводит чип на 0x49-0x4B
- GAIN_ONE: предел ±4,096 В, шаг 0,125 мВ против 4,9 мВ у АЦП Uno - в 39 раз мельче
- 860 выборок/с = 1,16 мс на отсчёт: вдесятеро медленнее 100 мкс analogRead
- Пара A0-A1 давит синфазную помеху: шунт и мост читаются чище
- Вход не выше питания: при VDD 3,3 В пятивольтовому сигналу нужен делитель
Частые вопросы по теме урока
- Ножка ADDR прижата к GND. Какой адрес у чипа?
- ADDR на земле — базовый 0x48; перемычка на VCC, SDA или SCL уводит чип на 0x49, 0x4A или 0x4B. 0x48
- Цена деления при GAIN_ONE?
- 4,096 В / 32768 ≈ 0,125 мВ. У АЦП Uno шаг 4,9 мВ — разница в 39 раз, что и составляет весь смысл внешнего чипа. 0,125 мВ
- Сколько длится отсчёт при 860 выборок/с и как это на фоне analogRead Uno?
- 860 выборок в секунду — один отсчёт каждые 1,16 мс. За скорость Uno платим глубиной разряда, и наоборот. 1,16 мс - вдесятеро медленнее 100 мкс
- ESP32 питает чип от 3,3 В, на входе сигнал 5 В. Что делать?
- Вход не должен выходить за VDD. При 3,3 В пятивольтовому сигналу нужен делитель либо питание чипа от 5 В с согласованием шины. делитель на входе: вход не выше питания
- Тензомост выдаёт единицы милливольт. Что выбрать?
- Пара давит синфазную помеху, узкий предел растягивает милливольты на всю шкалу — например ±0,256 В с шагом 7,8 мкВ. дифференциальную пару и узкий предел PGA