Создание цифровых весов с HX711 и Arduino

Создание цифровых весов с HX711 и Arduino

Существует множество способов отслеживать изменения вашего веса. Вы можете получить приблизительное представление по посадке брюк или отверстию на ремне. Но любой, кто серьёзно относится к поддержанию формы, должен встать на весы, чтобы узнать правду. Так почему бы вместо покупки не собрать свои собственные?

В этом руководстве вы узнаете, как сделать цифровые весы с помощью тензодатчика, модуля усилителя HX711 и Arduino. Мы начнём с основ — как работает тензодатчик и как его калибровать для получения точных показаний. Затем рассмотрим простой пример измерения веса различных объектов. После этого мы усовершенствуем проект, добавив LCD-дисплей для отображения показаний и кнопку для тарирования весов.

Начнём!

Основы тензодатчиков

Тензодатчик — это устройство (или преобразователь, если предпочитаете технический термин), которое преобразует давление (силу) в электрический сигнал. Существует несколько типов тензодатчиков, включая тензорезисторные (наиболее распространённые), гидравлические, пневматические, пьезоэлектрические и ёмкостные.

В этом руководстве мы сосредоточимся на тензорезисторных тензодатчиках.

Создание цифровых весов с HX711 и Arduino

Как следует из названия, тензорезисторные тензодатчики используют тензорезисторы, поэтому давайте сначала разберёмся, что такое тензорезистор и как он работает.

Тензорезистор

Тензорезистор — это небольшой датчик, изготовленный из тонкой проволоки или фольги, расположенной зигзагообразно или в виде сетки. Эти датчики обычно меньше почтовой марки и выглядят примерно так:

Создание цифровых весов с HX711 и Arduino

Когда к объекту, к которому прикреплён тензорезистор, прикладывается сила, датчик слегка растягивается или сжимается. Эта деформация вызывает крошечное изменение его электрического сопротивления. Изменение сопротивления пропорционально величине приложенной силы.

Создание цифровых весов с HX711 и Arduino

Однако изменение сопротивления чрезвычайно мало. Например, тензорезистор с нормальным сопротивлением 120 Ом может изменить его лишь на около 0.12 Ом при приложении силы. Это крошечное изменение слишком мало, чтобы большинство устройств могло его обнаружить напрямую. Поэтому, чтобы использовать тензорезистор как практический инструмент, мы должны измерять чрезвычайно малые изменения сопротивления с высокой точностью.

Для этого нам понадобится другое устройство, которое может либо точно измерять сверхмалые изменения сопротивления (что может быть дорого), либо устройство, которое преобразует малое изменение сопротивления в более крупный, легко измеримый сигнал. Здесь пригодится специальная схема, называемая мостом Уитстона.

Мост Уитстона

Мост Уитстона — это электрическая схема из четырёх резисторов, расположенных в форме ромба, с известным напряжением (Vin), приложенным через мост следующим образом:

Создание цифровых весов с HX711 и Arduino

Когда все четыре резистора имеют одинаковое значение (мост сбалансирован), выходное напряжение (Vout) моста равно нулю. Но если значение хотя бы одного резистора изменится (мост разбалансирован), Vout получит результирующее изменение, которое можно измерить и которое описывается следующим уравнением с использованием закона Ома:

Создание цифровых весов с HX711 и Arduino

Как тензорезисторы используются в тензодатчиках?

В тензорезисторном тензодатчике один или несколько резисторов в мосте Уитстона заменяются реальными тензорезисторами.

В типичном балочном тензодатчике эти датчики приклеены к металлической балке. Балка часто имеет Z-образную форму.

Создание цифровых весов с HX711 и Arduino

Когда к балке прикладывается сила, она слегка изгибается. Этот изгиб вызывает растяжение двух тензорезисторов (растяжение) и сжатие двух других (сжатие).

Создание цифровых весов с HX711 и Arduino

Благодаря принципу работы моста Уитстона, такая конфигурация создаёт более сильный и чёткий сигнал от изменения сопротивления, что делает измерение силы более точным.

Подключение тензодатчика

Типичный тензодатчик имеет четыре провода — два для подачи питания (возбуждения) и два для измерения сигнала, каждый из которых соответствует точке подключения на внутреннем мосте Уитстона:

  • Excitation+ (E+ или VCC): Обычно КРАСНЫЙ — сюда подаётся положительное напряжение для питания моста.

  • Excitation- (E- или GND): Обычно ЧЁРНЫЙ или ЖЁЛТЫЙ — это заземление или подключение отрицательного напряжения.

  • Output+ (O+, S+ или A+): Обычно ЗЕЛЁНЫЙ или СИНИЙ — этот провод несёт положительный выходной сигнал моста.

  • Output- (O-, S- или A-): Обычно БЕЛЫЙ — этот провод несёт отрицательный выходной сигнал моста.

Модуль HX711

Ранее мы видели, как тензодатчик использует тензорезисторы, расположенные в мосте Уитстона, для создания напряжения, прямо связанного с величиной приложенной силы или веса. Но вот важный момент: даже после использования моста Уитстона результирующий сигнал напряжения всё ещё чрезвычайно мал — обычно всего несколько милливольт. Обычные микроконтроллеры, такие как Arduino, недостаточно чувствительны, чтобы считывать такие низковольтные сигналы напрямую.

Именно здесь пригодится HX711.

HX711 — это специализированная микросхема, разработанная специально для считывания сигналов с тензодатчиков. Её основная задача — усилить крошечный сигнал напряжения, создаваемый мостом Уитстона, а затем преобразовать усиленный аналоговый сигнал в цифровые данные с помощью встроенного 24-битного аналого-цифрового преобразователя (АЦП), чтобы микроконтроллер мог легко считывать и обрабатывать информацию.

Создание цифровых весов с HX711 и Arduino

HX711 обменивается данными с микроконтроллером через простой двухпроводный последовательный интерфейс: DATA (DOUT) и CLOCK (SCK). Микроконтроллер инициирует преобразование, переведя вывод SCK в LOW. Затем HX711 вычисляет вес и отправляет 24-битное цифровое значение на вывод DOUT, причём каждый бит выводится по нарастающему фронту SCK.

HX711 имеет два входных канала: Channel A и Channel B. Это означает, что вы можете подключить два отдельных тензодатчика, по одному на каждый канал. Вы можете установить усиление для Channel A на 64 или 128, в то время как Channel B имеет фиксированное усиление 32. В большинстве приложений с тензодатчиками используется Channel A с усилением 128 для максимальной чувствительности.

Создание цифровых весов с HX711 и Arduino

Количество тактовых импульсов на выводе SCK определяет настройку канала и усиления для следующего измерения. Например, 25 импульсов выбирают Channel A с усилением 128, 26 импульсов — Channel B с усилением 32, а 27 импульсов — Channel A с усилением 64. Однако вам не нужно управлять этими импульсами вручную; существуют библиотеки, которые делают всё это за вас с помощью простых команд.

HX711 может работать в широком диапазоне напряжений от 2.6V до 5.5V, что делает его совместимым с такими микроконтроллерами, как Arduino и Raspberry Pi. Он также потребляет очень мало энергии. В нормальном режиме потребление менее 1.5 мА, а в режиме низкого энергопотребления — всего около 1 мкА. Это делает его отличным выбором для проектов с батарейным питанием.

Распиновка модуля HX711

Давайте рассмотрим распиновку.

Создание цифровых весов с HX711 и Arduino

Выводы подключения тензодатчика

E+ обеспечивает положительное напряжение возбуждения для тензодатчика. Обычно подключается к красному проводу тензодатчика.

E- обеспечивает отрицательное напряжение возбуждения (землю) для тензодатчика. Обычно подключается к чёрному проводу тензодатчика.

A+ — это положительный дифференциальный вход Channel A, основного канала для подключения тензодатчика. Обычно подключается к белому проводу тензодатчика.

A- — это отрицательный дифференциальный вход Channel A. Обычно подключается к зелёному проводу тензодатчика. HX711 измеряет крошечную разность напряжений между A+ и A- для определения веса.

B+ — это положительный дифференциальный вход Channel B. Это вторичный канал, который может использоваться для другого тензодатчика или отдельного датчика.

B- — это отрицательный дифференциальный вход Channel B.

Выводы питания и связи

GND — это общее заземление для всей схемы, включая модуль HX711 и ваш микроконтроллер.

DT (Data) — это выходной вывод последовательных данных. Он отправляет 24-битное цифровое значение от HX711 к вашему микроконтроллеру.

SCK (Clock) — это входной вывод тактирования. Ваш микроконтроллер отправляет тактовые импульсы HX711 по этому выводу для чтения данных.

VCC — это вывод питания модуля HX711. Он принимает напряжение от 2.6V до 5.5V.

Настройка тензодатчика

Прежде чем перейти к подключению и примеру кода, важно сначала настроить тензодатчик.

При использовании балочного тензодатчика его обычно устанавливают между двумя плоскими пластинами в Z-образной форме, как показано на изображении ниже. Это позволяет тензодатчику испытывать деформацию между противоположными концами при приложении веса.

Создание цифровых весов с HX711 и Arduino

Вы можете собрать эту конструкцию самостоятельно из простых материалов или приобрести набор HX711 в интернете. Эти наборы обычно включают всё необходимое: две круглые акриловые пластины, балочный тензодатчик, модуль HX711 и некоторые проставки и винты. Набор разработан для простой сборки, чтобы вы могли запустить всё в работу за несколько минут.

Подключение тензодатчика к модулю HX711 и Arduino

Начнём подключение.

Сначала возьмите тензодатчик. Большинство стандартных балочных тензодатчиков имеют провода четырёх цветов: красный, чёрный, белый и зелёный. Эти провода нужно подключить к соответствующим выводам модуля HX711.

Начните с подключения красного провода тензодатчика к выводу E+ на HX711. Затем подключите чёрный провод к выводу E-. После этого подключите белый провод к выводу A- и, наконец, зелёный провод к выводу A+. Сделав эти четыре подключения, вы закончили с соединением тензодатчик-HX711.

Теперь подключим модуль HX711 к Arduino. Начните с подключения вывода VCC на HX711 к выводу 5V на Arduino и вывода GND к выводу GND на Arduino. После этого подключите вывод DT на HX711 к выводу 2 Arduino. Наконец, подключите вывод SCK на HX711 к выводу 3 Arduino.

На изображении ниже показано, как всё подключить.

Создание цифровых весов с HX711 и Arduino

Подключение завершено! Можно переходить к загрузке кода в Arduino и начинать считывать значения с тензодатчика.

Установка библиотеки

Существует несколько библиотек для считывания измерений с тензодатчика через HX711. В этом руководстве мы используем библиотеку HX711 от Bogdan Necula. Она совместима со многими микроконтроллерами, включая ESP32, ESP8266, STM32 и Arduino.

Для установки библиотеки:

  1. Сначала откройте Arduino IDE. Затем нажмите на значок Менеджер библиотек на левой боковой панели.

  2. Введите «hx711» в поле поиска для фильтрации результатов.

  3. Найдите библиотеку «HX711 Arduino library» от Bogdan Necula.

  4. Нажмите кнопку Install для добавления её в Arduino IDE.

Создание цифровых весов с HX711 и Arduino

Калибровка тензодатчика

Каждый тензодатчик немного отличается, даже если выглядит одинаково. Это означает, что перед тем, как тензодатчик сможет давать точные показания веса, его необходимо откалибровать с помощью объекта с известным весом. Калибровка помогает Arduino понять, как необработанные числа от датчика соответствуют реальным единицам, таким как граммы или килограммы.

  1. Для начала подготовьте объект с известным весом. Например, можно использовать маленький кусок мыла весом ровно 50 граммов.

  2. Загрузите код калибровки в плату Arduino.

    #include "HX711.h"
    
    #define DT 2
    #define CLK 3
    
    HX711 scale;
    
    void setup() {
      Serial.begin(9600);
      Serial.println("HX711 calibration sketch");
    
      scale.begin(DT, CLK);
    }
    
    void loop() {
      scale.set_scale();
      Serial.println("");
      Serial.println("Remove all weight from scale");
      delay(5000);
      scale.tare();
      Serial.println("Tare done!");
    
      Serial.println("Place a known weight on the scale...");
      delay(5000);
      long reading = scale.get_units(10);
      Serial.print("Reading: ");
      Serial.println(reading);
      delay(1000);
    }
    
  3. Откройте монитор последовательного порта в Arduino IDE и убедитесь, что он настроен на скорость 9600 бод. Затем нажмите кнопку RESET на плате Arduino.

  4. Следуйте инструкциям, появляющимся в мониторе последовательного порта. Сначала уберите все предметы с тензодатчика или весов. Система автоматически выполнит «тарирование», то есть примет пустые весы за ноль. Затем поместите известный вес (например, 50-граммовый кусок мыла) на весы и дождитесь отображения значения в мониторе последовательного порта.

    Создание цифровых весов с HX711 и Arduino
  5. Рассчитайте коэффициент калибровки по формуле: Например, если показание составляет 21512, а известный вес — 50 граммов, коэффициент калибровки будет:

    Создание цифровых весов с HX711 и Arduino Создание цифровых весов с HX711 и Arduino
  6. Запишите этот коэффициент калибровки; он понадобится вам в следующем коде для получения точных измерений веса.

Поскольку выход датчика пропорционален силе, приложенной к тензодатчику, вы можете калибровать весы в любых единицах, подходящих для вашего проекта. Мы использовали граммы, но вы можете использовать фунты, килограммы или даже что-то нестандартное — например, порции корма для собак.

Также обратите внимание, что ваш коэффициент калибровки может быть как очень большим положительным, так и очень большим отрицательным числом. Всё зависит от конфигурации вашей системы весов и направления отклонения датчиков от нулевого состояния.

Пример 1 — Измерение веса

После вычисления коэффициента калибровки для вашей конфигурации тензодатчика вы готовы использовать его для взвешивания реальных объектов.

Для этого скопируйте приведённый код в Arduino IDE. Перед загрузкой в плату Arduino убедитесь, что вы обновили calibration_factor в коде, чтобы он соответствовал значению, полученному при калибровке.

#include "HX711.h"

#define DT 2
#define CLK 3

#define calibration_factor 430.24  //This value is obtained using the Calibration sketch

HX711 scale;

void setup() {
  Serial.begin(9600);
  Serial.println("HX711 scale demo");

  scale.begin(DT, CLK);

  scale.set_scale(calibration_factor);
  scale.tare();  //Assuming there is no weight on the scale at start up, reset the scale to 0
}

void loop() {
  Serial.print("Reading: ");
  Serial.print(scale.get_units(), 1);
  Serial.print(" gm");
  Serial.println();

  delay(1000);
}

После загрузки кода откройте монитор последовательного порта в Arduino IDE и установите скорость 9600 бод.

Убедитесь, что весы полностью пусты в начале. Это позволит коду автоматически выполнить тарирование. Как только начнутся показания, аккуратно поместите известный вес (например, 50-граммовый кусок мыла) на весы. Наблюдайте за показаниями в мониторе последовательного порта.

Создание цифровых весов с HX711 и Arduino

Если отображаемое значение не совпадает с известным весом, может потребоваться повторить процесс калибровки для получения более точного коэффициента.

Теперь, когда настройка завершена, вы можете попробовать размещать различные объекты на весах и наблюдать их вес в реальном времени.

Объяснение кода

Мы начинаем скетч с подключения библиотеки HX711. Эта библиотека предоставляет все необходимые функции для работы с модулем HX711.

#include "HX711.h"

Затем мы определяем два вывода Arduino, подключённых к выводам DT (данные) и CLK (тактирование) модуля HX711.

#define DT 2
#define CLK 3

Далее мы определяем переменную calibration_factor. Это число, найденное при калибровке, которое сообщает Arduino, как преобразовывать необработанные значения датчика в читаемые единицы веса, например граммы. Обязательно замените значение-заглушку в коде на ваш реальный коэффициент калибровки.

#define calibration_factor 430.24

После этого мы создаём экземпляр класса HX711 под именем scale.

HX711 scale;

Внутри функции setup() мы сначала инициализируем последовательную связь, чтобы видеть вывод в мониторе последовательного порта. Затем инициализируем весы, вызывая метод begin() и передавая номера выводов. Мы используем метод set_scale() для применения коэффициента калибровки, чтобы датчик знал, как преобразовывать показания. Сразу после этого мы используем метод tare() для сброса весов на ноль, предполагая, что при запуске программы на них нет веса.

void setup() {
  Serial.begin(9600);
  Serial.println("HX711 scale demo");

  scale.begin(DT, CLK);

  scale.set_scale(calibration_factor);
  scale.tare();  //Assuming there is no weight on the scale at start up, reset the scale to 0
}

После завершения настройки весы готовы к измерению. В функции loop() мы непрерывно вызываем метод get_units() для получения показаний веса. Результат отображается в мониторе последовательного порта раз в секунду.

void loop() {
  Serial.print("Reading: ");
  Serial.print(scale.get_units(), 1);
  Serial.print(" gm");
  Serial.println();

  delay(1000);
}

Пример 2 — Создание простых цифровых весов

В предыдущем примере мы использовали монитор последовательного порта для отображения показаний веса. Теперь давайте пойдём дальше и создадим простые цифровые весы, которые показывают данные на I2C LCD-дисплее и включают кнопку для тарирования весов при необходимости.

Если вы ранее не работали с I2C LCD-дисплеем, рекомендуем ознакомиться с этим полезным руководством:

Подключение I2C LCD-дисплея к Arduino
Подключение I2C LCD к Arduino

Схема подключения

Подключение в этом примере в основном такое же, как и раньше, но с несколькими дополнениями. На этот раз мы добавляем I2C LCD и кнопку.

Начните с подключения I2C LCD к Arduino. Подключите вывод VCC LCD к выходу 5V на Arduino, а вывод GND — к земле Arduino. Затем подключите вывод SDA LCD к A4 на Arduino и вывод SCL к A5. На платах Arduino с разводкой R3 вы также можете найти SDA и SCL с отдельными маркировками рядом с выводом AREF — оба варианта подойдут.

Далее подключите кнопку. Одна ножка кнопки должна идти к GND, а другая — к цифровому выводу 4 на Arduino.

Эта схема показывает, как именно подключить всё:

Создание цифровых весов с HX711 и Arduino

Код Arduino

Вот скетч Arduino.

#include "HX711.h"
#include <LiquidCrystal_I2C.h>

#define DT 2
#define CLK 3
#define buttonPin 4
#define calibration_factor 430.24  //This value is obtained using the Calibration sketch

LiquidCrystal_I2C lcd(0x3F, 16, 2);
HX711 scale;

float reading;
float lastReading = -999;     // Initialize to a value that won't match first reading
unsigned long lastEvent = 0;  // For button debouncing
bool lastButtonState = HIGH;  // Previous button state (HIGH when using INPUT_PULLUP)

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);

  lcd.init();
  lcd.clear();
  lcd.backlight();

  // Display title
  lcd.setCursor(0, 0);
  lcd.print("Digital Scale");

  // Initialize scale
  scale.begin(DT, CLK);
  scale.set_scale(calibration_factor);
  scale.tare();  // Reset scale to 0 at startup

  // Initial weight display
  lcd.setCursor(0, 1);
  lcd.print("Weight: 0g   ");
}

void loop() {
  // Read current button state
  bool currentButtonState = digitalRead(buttonPin);

  // Check for button press with debouncing
  if (lastButtonState == HIGH && currentButtonState == LOW) {
    // Button was just pressed (falling edge)
    if (millis() - lastEvent > 50) {  // 50ms debounce delay
      Serial.println("Tare!");
      scale.tare();

      // Clear weight display and show "Taring..."
      lcd.setCursor(0, 1);
      lcd.print("Taring...       ");
      delay(500);  // Brief pause to show tare message

      lastReading = -999;  // Force display update after tare
    }
    lastEvent = millis();
  }

  // Update last button state
  lastButtonState = currentButtonState;

  // Read weight
  reading = round(scale.get_units());

  // Only update display if reading has changed significantly (reduce flicker)
  if (abs(reading - lastReading) > 0.01) {  // 0.01g threshold
    lcd.setCursor(0, 1);
    lcd.print("Weight: ");
    lcd.print(reading, 0);  // Display with 2 decimal places
    lcd.print("g    ");     // Extra spaces to clear previous longer values

    // Also print to serial for debugging
    Serial.print("Weight: ");
    Serial.print(reading, 2);
    Serial.println("g");

    lastReading = reading;
  }

  delay(100);  // Small delay to prevent overwhelming the display and serial
}

Демонстрация

После загрузки кода в Arduino вы готовы к использованию цифровых весов. Когда вы поместите объект на тензодатчик, вес отобразится на I2C LCD-экране. Если вы хотите сбросить весы на ноль — например, при смене контейнера или снятии всего веса — просто нажмите кнопку, и весы выполнят тарирование.

Для теста я взвесил свои наручные часы на этих цифровых весах, а затем проверил те же часы на обычных кухонных весах. Результаты совпали идеально, что показывает, что эта конструкция одновременно точна и надёжна.

Создание цифровых весов с HX711 и Arduino

Объяснение кода

Код аналогичен предыдущему примеру, но на этот раз мы добавляем поддержку I2C LCD-дисплея и кнопки.

В начале скетча мы подключаем две библиотеки: HX711.h для связи с модулем HX711 и LiquidCrystal_I2C.h для управления I2C LCD-экраном.

#include "HX711.h"
#include <LiquidCrystal_I2C.h>

Затем мы определяем выводы модуля HX711: DT подключён к цифровому выводу 2, а CLK — к выводу 3, как и раньше. Далее определяем buttonPin и назначаем ему цифровой вывод 4, к которому подключена кнопка. Затем устанавливаем calibration_factor — значение, найденное при калибровке.

#define DT 2
#define CLK 3
#define buttonPin 4
#define calibration_factor 430.24  //This value is obtained using the Calibration sketch

После этого мы создаём два важных объекта. Первый — lcd, экземпляр класса LiquidCrystal_I2C, который будет использоваться для вывода данных на LCD-экран. Адрес 0x3F — распространённый I2C-адрес для этих дисплеев, а 16 и 2 означают, что дисплей имеет 16 столбцов и 2 строки. Второй объект — scale, наш экземпляр HX711.

LiquidCrystal_I2C lcd(0x3F, 16, 2);
HX711 scale;

Мы также создаём несколько вспомогательных переменных. reading будет хранить текущее показание веса. lastReading инициализируется значением, далёким от нормальных показаний, чтобы оно не совпало с первым реальным значением при сравнении. Мы также настраиваем lastEvent и lastButtonState для устранения дребезга кнопки.

float reading;
float lastReading = -999;     // Initialize to a value that won't match first reading
unsigned long lastEvent = 0;  // For button debouncing
bool lastButtonState = HIGH;  // Previous button state (HIGH when using INPUT_PULLUP)

В функции setup() мы начинаем последовательную связь на скорости 9600 бод, чтобы видеть вывод в мониторе последовательного порта. Настраиваем вывод кнопки как INPUT_PULLUP, что означает, что кнопка нормально в HIGH и переходит в LOW при нажатии.

Serial.begin(9600);
pinMode(buttonPin, INPUT_PULLUP);

Затем инициализируем LCD-экран с помощью lcd.init(), очищаем его и включаем подсветку. Выводим заголовок «Digital Scale» на первой строке. Далее инициализируем весы HX711, устанавливаем коэффициент калибровки и вызываем scale.tare() для сброса на 0 при запуске. На второй строке LCD отображаем «Weight: 0g» как начальное показание.

lcd.init();
lcd.clear();
lcd.backlight();

// Display title
lcd.setCursor(0, 0);
lcd.print("Digital Scale");

// Initialize scale
scale.begin(DT, CLK);
scale.set_scale(calibration_factor);
scale.tare();  // Reset scale to 0 at startup

// Initial weight display
lcd.setCursor(0, 1);
lcd.print("Weight: 0g   ");

В функции loop() мы сначала проверяем текущее состояние кнопки. Затем проверяем, была ли кнопка только что нажата. Если кнопка нажата и прошло более 50 миллисекунд с последнего нажатия, мы выполняем операцию тарирования.

При тарировании мы выводим «Tare!» в монитор последовательного порта и вызываем scale.tare() для сброса показаний на ноль. На LCD-экране мы кратко показываем «Taring…», чтобы пользователь знал, что происходит. Затем принудительно обновляем дисплей, сбрасывая lastReading.

// Read current button state
bool currentButtonState = digitalRead(buttonPin);

// Check for button press with debouncing
if (lastButtonState == HIGH && currentButtonState == LOW) {
  // Button was just pressed (falling edge)
  if (millis() - lastEvent > 50) {  // 50ms debounce delay
    Serial.println("Tare!");
    scale.tare();

    // Clear weight display and show "Taring..."
    lcd.setCursor(0, 1);
    lcd.print("Taring...       ");
    delay(500);  // Brief pause to show tare message

    lastReading = -999;  // Force display update after tare
  }
  lastEvent = millis();
}

// Update last button state
lastButtonState = currentButtonState;

После логики кнопки мы считываем текущий вес с помощью scale.get_units() и округляем результат. Чтобы избежать мерцания на LCD, мы обновляем экран только если новое показание значительно отличается от предыдущего. Если вес изменился, обновляем LCD-дисплей новым значением и выводим его в монитор последовательного порта.

// Read weight
reading = round(scale.get_units());

// Only update display if reading has changed significantly (reduce flicker)
if (abs(reading - lastReading) > 0.01) {  // 0.01g threshold
  lcd.setCursor(0, 1);
  lcd.print("Weight: ");
  lcd.print(reading, 0);  // Display with 2 decimal places
  lcd.print("g    ");     // Extra spaces to clear previous longer values

  // Also print to serial for debugging
  Serial.print("Weight: ");
  Serial.print(reading, 2);
  Serial.println("g");

  lastReading = reading;
}

В конце добавляем небольшую задержку, чтобы экран и монитор последовательного порта не обновлялись слишком быстро.

delay(100);  // Small delay to prevent overwhelming the display and serial