HX711: подключение тензодатчика и калибровка весов на Arduino
HX711 — специализированный 24-битный АЦП, который переводит микровольты тензодатчика в цифру, понятную Arduino: усиливает сигнал моста Уитстона в 128 раз и отдаёт готовые отсчёты по двум проводам. На нём строят кухонные весы, дозаторы корма, контроль затяжки крепежа и пасечные весы для ульев. Модуль стоит копейки, а вся сложность проекта сходится в одну точку — калибровку, которую мы ниже разбираем по шагам.
Скетч из статьи проверен в нашем симуляторе: рантайм исполняет begin, тару и чтение веса по-настоящему. Добавьте карточку «Тензодатчик HX711» из палитры «Макетка» или просто загрузите код, двигайте ползунок нагрузки и следите, как весы отрабатывают ноль и порог дозирования. Дальше — распиновка, четырёхшаговая калибровка, разбор скетча и честная граница между тем, что показывает браузер, и тем, что происходит на живой плате.
Почему не analogRead
Встроенный АЦП Arduino даёт 1023 деления на диапазон 0–5 В, а мост Уитстона под нагрузкой в один килограмм вырабатывает единицы милливольт — на одно деление АЦП приходится несколько граммов, и вся точность тонет в шуме. HX711 закрывает обе проблемы сразу: усиливает сигнал в 128 раз и оцифровывает его 24-битным сигма-дельта преобразователем — это 16,7 миллиона делений. Скорость скромная, 10 отсчётов в секунду (80, если замкнуть вывод RATE на землю), но для весов достаточно: платформа под грузом не дёргается. Если нужен быстрый универсальный АЦП без усиления, у нас есть разбор ADS1115 — 16 бит, восемь режимов и до 860 замеров в секунду.
Распиновка: от балки до D2 и D3
Тензодатчик — алюминиевая балка с четырьмя тензорезисторами, соединёнными в мост. У датчика четыре провода: питание моста (E+ и E−) и сигнал, снимаемый с диагонали (A+ и A−). Цвета на типовых датчиках устоялись: красный — E+, чёрный — E−, белый — A+, жёлтый или зелёный — A−. Перепутанные A+ и A− модуль не сжигают, но вес уходит в минус — лечится перестановкой проводов местами. Крепите балку жёстко: один конец на неподвижной опоре, второй принимает груз, без этого показания скачут вместе с проводами.
| Вывод HX711 | Куда подключить | Заметка |
|---|---|---|
| E+ | красный провод тензодатчика | питание моста |
| E− | чёрный провод | земля моста |
| A+ | белый провод | плюс сигнальной диагонали |
| A− | жёлтый или зелёный | минус сигнальной диагонали |
| VCC | 5 В Arduino | допустимо 2,7–5,5 В |
| GND | GND | общая земля |
| DT | D2 | данные, подойдёт любой цифровой пин |
| SCK | D3 | тактирование, второй цифровой пин |
Калибровка за четыре шага
Коэффициент масштаба у каждого экземпляра свой: он зависит и от балки, и от жёсткости сборки. Процедура на живой плате занимает пять минут. Первый шаг — пустую платформу обнуляем: set_scale(1.0), затем tare(20). Второй — кладём эталон: гирю, бутылку воды с известным объёмом, пакет сахара. Третий — читаем «сырое» значение функцией get_value(20). Четвёртый — делим отсчёты на граммы, полученный коэффициент ставим в set_scale и проверяем вторым грузом. Для типового датчика на 5 кг коэффициент лежит в районе 2000–2400. Эталон держите рядом: мост «плывёт» от температуры, и раз в пару месяцев показания стоит сверять заново.
Скетч весов с дозированием
Задача — простая весовая автоматика: обнулиться при включении, печатать вес в Serial и зажигать светодиод на D13, когда на платформе набрана целевая порция. На живой плате вместо светодиода вешают реле дозатора или зуммер — логика не меняется.
#include "HX711.h" HX711 scale; // DT -> D2, SCK -> D3const unsigned long TARGET = 250; // цель дозирования, граммовconst int PIN_LED = 13; // сигнальный светодиод «порция набрана» void setup() { Serial.begin(9600); pinMode(PIN_LED, OUTPUT); scale.begin(2, 3); // в симуляторе begin всегда успешен scale.set_scale(2280.0); // калибровочный коэффициент вашего экземпляра scale.tare(10); // 10 чтений в ноль — платформа пустая Serial.println("hx711 gotov, tara snjata");} void loop() { if (scale.is_ready()) { // на живой плате ждёт 24-битный отсчёт, тут всегда да float w = scale.get_units(3); // среднее из 3 чтений, граммы Serial.print("Ves: "); Serial.print(w); Serial.println(" g"); if (w >= TARGET) { digitalWrite(PIN_LED, HIGH); // на плате сюда — реле дозатора или зуммер Serial.println("cel dostignuta: porcija otmerena"); } else { digitalWrite(PIN_LED, LOW); } } delay(500);}Среднее из трёх чтений (get_units(3)) приглушает дрожание последней цифры: на живой плате без него строка Serial мелькает каждые полсекунды. Порог 250 граммов вынесен в константу — править одну строку проще, чем искать сравнение в теле цикла. Проверка is_ready() в симуляторе всегда отвечает «да», а на живой плате честно ждёт готовности отсчёта: при 10 отсчётах в секунду скетч без неё начнёт хватать полузаписанные данные.
Что исполняет симулятор, а что остаётся за кадром
Рантайм поддерживает begin, is_ready, wait_ready, read, read_average, get_value, get_units, tare, set_scale и set_offset — скетч выше исполняется без единой правки. Вес при этом приходит из карточки: ползунок задаёт нагрузку от 0 до 5000 граммов, и get_units возвращает именно его. Три отклонения от живой библиотеки стоит знать заранее. Первое: get_units игнорирует тару — она запоминается для read() и get_value(), тогда как на живой плате get_units вычитает тару сам; поэтому тарим с пустой платформой, как в скетче. Второе: set_scale не пересчитывает показания get_units — коэффициент нужен настоящей плате, где get_units делит сырые отсчёты на масштаб. Третье: дрейф нуля от прогрева (первые пять минут модуль стабилизируется) и шум АЦП не моделируются — браузер показывает ползунок, а не физику моста.
Частые грабли
- Первые минуты после включения показания плывут — мост и АЦП прогреваются. Дайте модулю пять-десять минут до калибровки, иначе коэффициент уедет вместе с прогревом.
- Датчик на длинном неэкранированном проводе ловит наводки: сигнал здесь милливольтовый. Кабель экранируйте и не прокладывайте рядом с силовой проводкой.
- Балка работает только в одну сторону: удар по краю или перегруз дают остаточную деформацию, после которой датчик навсегда врёт в плюс.
- Не питайте HX711 от одной линии с сервами и реле: провалы питания моста читаются как вес. Отдельный провод от 5 В и конденсатор 100 мкФ рядом с модулем.