Термопара поставила меня на место в первый же вечер. Я подключил её к A0, открыл плоттер и стал ждать плавную кривую разогрева печки. Получил лестницу: температура ползла скачками по 100 и больше градусов, и никакой плавности в помине не было. Причина элементарная, но в момент наблюдения она ощущалась как предательство железа: у ATmega328 встроенный АЦП десятибитный, то есть 1023 ступени на весь диапазон от земли до опоры. При опорных 5 В одна ступень — это 4,88 мВ. Термопара типа K живёт на 41 мкВ на градус, и мои 4,88 мВ превращаются в шаг сетки почти в 120 градусов. Я мерил температуру линейкой, у которой деления нарезаны через сотню миллиметров.
Первый тупик был мой же, и он честный: я поставил операционный усилитель с коэффициентом сто и обрадовался, что ступенька ужалась до градуса с четвертью. Обрадовался зря. Вместе с сигналом умножились шум проводов, дрейф нуля усилителя и собственные руки: кривая задрожала на пару ступеней туда-сюда, что при пересчёте снова давало те самые градусы. Усиление снаружи растит и сигнал, и мусор — пропорция не меняется. Выигрыш даёт только усилитель, встроенный в сам преобразователь, перед его входом: там шум умножается вместе с сеткой, а сетка-то мельче в десятки раз.
Такой усилитель перед АЦП носит имя PGA, программируемого усилителя, и живёт в чипе ADS1115: дельта-сигма преобразователе на 16 бит, который сидит на шине I2C и занимает одну из четырёх адресных позиций. В этом уроке разберём, когда десяти бит действительно мало и что делать с сигналом до того, как ставить внешний АЦП, как выбирается предел измерения и почему он зависит от коэффициента усиления, и как читать чип голым Wire без единой библиотеки: две записи в конфиг, пауза, два байта результата.
Когда 1023 ступени мало
Начнём с честной арифметики того, что уже есть. analogRead возвращает число от 0 до 1023, при опорных 5 В между соседними числами лежит 4,88 мВ; само преобразование занимает около 110 микросекунд, то есть за секунду можно снять тысячу отсчётов. Для потенциометра, фоторезистора или джойстика этой сетки хватает с запасом — мы крутили их в уроке про analogRead и потенциометр и не страдали. Страдать начинает слабый сигнал, у которого вся полезная амплитуда укладывается в несколько клеток такой сетки.
Три классических сигнала, которые десять бит не переваривают. Термопара: милливольты, размазанные на сотни градусов, — без мелкой сетки и усиления это просто шум с уклоном. Ток на шунте: резистор в десятую долю Ома в разрыве питания даёт 100 мВ на каждый ампер, а интересуют десятые доли ампера — то есть единицы милливольт, по клетке-полторы на измерение. NTC-термистор в узком окне, скажем от 20 до 30 градусов: весь интересующий диапазон занимает двадцать клеток, и о 0,1 градуса можно забыть. ADS1115 закрывает обе беды разом: преобразователь выдаёт 16-битное слово — до 32767 ступеней вверх от нуля в однополярном включении, — а перед входом стоит PGA, натягивающий эту сетку на выбранный вами предел. Платой служит скорость: потолок чипа — 860 отсчётов в секунду, а на самом медленном режиме, 8 отсч/с, пауза между отсчётами растягивается до 125 мс. Зависимость тут двусторонняя: чем медленнее преобразователь, тем лучше он давит шум — на 860 отсч/с дрожит последний разряд, на 8 застывают две последние цифры. Для печки и шунта медленный режим — подарок, для вибрации — приговор.
Теперь адресация. На шине чип занимает один из четырёх адресов: 0x48, 0x49, 0x4A или 0x4B, и выбирает их ножка ADDR: на земле это 0x48, на питании 0x49, на линии SDA 0x4A, на SCL 0x4B. Второй ADS1115 садится на другую позицию, и конфликта не будет; откуда вообще берутся коллизии адресов и как их разруливать, мы разбирали в уроке про конфликты адресов. Подключение стандартное: питание, SDA на A4, SCL на A5, подтяжки шины — их роль рассматривалась в уроке про устройство шины. А если чип на макетке молчит, первый инструмент всё тот же: сканер адресов за минуту покажет, виден ли модуль и на какой позиции он сидит; не виден — ищите обрыв или перепутанные SDA и SCL, а не грешите на чип.
PGA: усилитель перед преобразователем
Идея программируемого усилителя простая: вы говорите чипу, на какой диапазон натянуть его сетку, и вся точность уезжает именно туда. Пределов шесть: от ±6,144 В при коэффициенте 2/3 (это значение стоит по умолчанию) до ±0,256 В при коэффициенте 16. Шаг сетки — это предел, делённый на 32768: на широком пределе он 187,5 мкВ, на узком — 7,8125 мкВ, в 24 раза мельче. Переключение предела — три бита в конфигурационном слове, никакой обвязки и пайки, в отличие от моего операционника с руками из проводов.
Здесь две грабли, на которых я оставил время. Первая: ±6,144 В не значит, что чипу можно подавать 6 вольт. Питание модуля — 5 В, и вход нельзя заводить ниже земли или выше питания на 0,3 В — защитные диоды откроются, и начнётся греющаяся экзотика. PGA выбирает, на какой диапазон растягивается сетка, а не диапазон допустимых напряжений: пятивольтовый сигнал меряйте на пределе 6,144 В, и шаг сетки останется честные 187,5 мкВ. Вторая грабля тише: в однополярном режиме, когда измеряете вход против земли, чип отдаёт фактически 15 бит — старший знаковый разряд простаивает, потому что отрицательных значений не бывает. Все 16 бит достаются только дифференциальному включению, когда меряется разница двух входов; именно так и меряют шунты, посадив концы резистора на AIN0 и AIN1.
Битовые поля конфигурации — MUX, PGA, скорость, компаратор — собраны в одном 16-битном слове, и читать их удобнее по таблице: карта регистра ADS1115 устроена ровно как карты из урока про регистры из даташита, только плотнее — каждая четвёрка битов чего-нибудь стоит.
| Коэффициент PGA | Предел измерения | Вес одной ступени | Где пригодится |
|---|---|---|---|
| 2/3 (по умолчанию) | ±6,144 В | 187,5 мкВ | сигналы до 5 В, силовые линии |
| 1 | ±4,096 В | 125 мкВ | датчики с выходом до 4 В |
| 4 | ±1,024 В | 31,25 мкВ | NTC в узком окне температур |
| 16 | ±0,256 В | 7,8 мкВ | термопары, шунты, тензодатчики |
Диалог по Wire: config, пауза, два байта
Программисту в ADS1115 видны два регистра: 0x00 — результат последнего преобразования, 0x01 — конфигурация. Схема разговора — та же двухходовка, что разобрана в уроке про чтение регистров: пишем в 0x01 два байта конфига, ждём, пока конверсия закончится, читаем из 0x00 два байта результата, старший первым. Шестнадцать бит конфига собираются из полей: бит 15 — старт преобразования, биты 14-12 — выбор канала, биты 11-9 — коэффициент PGA, бит 8 — одиночный или непрерывный режим, биты 7-5 — скорость, младшие — компаратор. Собирать слово битами и масками — навык прямой и благодарный: четыре бита канала, три бита усиления, девять битов скорости, и всё слово готово.
Ждать окончания конверсии можно двумя способами. Ленивый — delay: при 128 отсч/с конверсия занимает около 8 мс, и девятка с запасом её накрывает. Взрослый — прочитать конфиг и посмотреть бит 15: чип сам опускает его в ноль на время работы и поднимает единицей, когда результат готов; на медленных режимах, где пауза достигает 125 мс, только этот способ и живёт, потому что delay на глазок либо спит зря, либо читает недопечённое.
Ниже — скетч, который читает канал 0 без всяких библиотек: собирает конфиг, пишет его двумя байтами, ждёт, тянет результат и печатает сырые ступени с пересчётом в милливольты. Это тот самый минимальный диалог, на котором держатся все ADS-библиотеки мира, просто без обёрток.
#include <Wire.h> // ADS1115 без библиотеки. ADDR на земле -> адрес 0x48.// Предел PGA 4,096 В (коэффициент 1), скорость 128 отсч/с, одиночный режим. const byte ADS = 0x48; // ADDR -> GNDconst byte REG_CONV = 0x00; // результат преобразованияconst byte REG_CONF = 0x01; // конфигурация // Сборка 16-битного слова: бит15 OS=1 старт, биты 14-12 MUX (канал),// биты 11-9 PGA=001 (4,096 В), бит8 одиночный, биты 7-5 DR=100 (128 SPS),// биты 1-0 компаратор выключен. Итого база 0x0383 плюс канал.unsigned int konfig(int mux) { return 0x8000 | (mux << 12) | 0x0383;} long chitat(int mux) { unsigned int konf = konfig(mux); Wire.beginTransmission(ADS); Wire.write(REG_CONF); Wire.write(konf >> 8); // старший байт уходит первым Wire.write(konf & 0xFF); Wire.endTransmission(); delay(9); // конверсия при 128 SPS занимает ~8 мс Wire.beginTransmission(ADS); Wire.write(REG_CONV); // ставим указатель на результат Wire.endTransmission(); Wire.requestFrom(ADS, 2); // читаем два байта int hi = Wire.read(); int lo = Wire.read(); return ((long)hi << 8) | lo; // слово 0..32767 (однополярный режим)} void setup() { Wire.begin(); Serial.begin(9600); Serial.println("ADS1115: AIN0 protiv GND, predel 4,096 V");} void loop() { long s = chitat(0b100); // MUX=100: AIN0 против GND Serial.print("syroe="); Serial.print(s); Serial.print(" mv="); // 125 мкВ на ступень при 4,096 В Serial.println(s * 125L / 1000L); delay(500);}Что здесь честно, а что нет. Движок не знает ни ADS1115, ни его конфигурационного регистра: панель шины пустая, а два байта «результата» рождаются из положения ручек потенциометров и печатной модели. Зато сама зависимость предел-точность видна без прикрас: перещёлкните предел кнопкой и подвигайте ручку — на 4096 мВ милливольты шагают по двенадцать с половиной, на 256 мВ — меньше милливольта на ступень. Это и есть смысл PGA: сетка одна, но натянута на разный размах.
На модуле есть ещё одна ножка, которую новички оставляют в воздухе: ALERT/RDY. Это выход открытого стока, который умеет дёргать уровень при готовности нового отсчёта или переходе компаратором заданного порога. Механика та же, что у всех прерывательных ножек I2C-чипов: вешаем на пин 2, ловим фронт, в обработчике только флаг — весь разбор в уроке про INT-прерывание от датчика.
На живой плате первый тест тот же: подайте на AIN0 землю и сравните с чтением — сырой ноль значит, что чип жив и адрес угадан. Дальше проверьте предел: при 0,256 В прикосновение пальцем к входу выйдет за сетку мгновенно. А когда дойдёте до логгера, куда такой АЦП просится сам, — помните про медленные режимы: на 8 отсч/с два последних разряда застывают, и это не поломка, а шумоподавление в действии.
- 10 бит ATmega — 1023 ступени, 4,88 мВ при 5 В: термопары, шунты и узкие окна NTC это съедают целиком
- ADS1115: 16 бит, 4 канала или 2 дифференциальных, предел PGA ±0,256…±6,144 В, скорость 8-860 отсч/с — медленнее значит тише
- Адрес выбирает ножка ADDR: GND — 0x48, VDD — 0x49, SDA — 0x4A, SCL — 0x4B
- Диалог по Wire: два байта конфига в 0x01, пауза или бит OS, два байта результата из 0x00 старшим вперёд
- В однополярном режиме реально 15 бит, полные 16 — только дифференциально; вход нельзя уводить за питание
- 1. Сколько ступеней выдаёт встроенный АЦП ATmega328?
- 2. Какой адрес получит ADS1115, если ножку ADDR посадить на линию SCL?
- 3. Что даёт предел PGA ±0,256 В?
- 4. Почему в однополярном режиме доступно фактически 15 бит, а не 16?
- 5. Как узнать, что преобразование закончилось, не глядя на часы?
Частые вопросы по теме урока
- Сколько ступеней выдаёт встроенный АЦП ATmega328?
- АЦП десятибитный: 2 в десятой степени минус единица = 1023. При опорных 5 В одна ступень — 4,88 мВ. 1023
- Какой адрес получит ADS1115, если ножку ADDR посадить на линию SCL?
- Четыре позиции раскладываются так: земля — 0x48, питание — 0x49, SDA — 0x4A, SCL — 0x4B. 0x4B
- Что даёт предел PGA ±0,256 В?
- Коэффициент 16 натягивает все 32768 ступеней на четверть вольта: вес ступени 256000/32768 = 7,8125 мкВ. самый мелкий шаг сетки — 7,8 мкВ на ступень
- Почему в однополярном режиме доступно фактически 15 бит, а не 16?
- Слово знаковое, и против GND оно всегда положительное: старший бит остаётся нулём. Полные 16 бит даёт только дифференциальное включение. старший знаковый разряд простаивает: отрицательных значений против земли не бывает
- Как узнать, что преобразование закончилось, не глядя на часы?
- Чип сам опускает бит OS на время конверсии и поднимает его по готовности — опрос этого бита работает на любой скорости вплоть до 8 отсч/с. прочитать конфиг и проверить бит 15: единица — результат готов