#include "HX711.h"
#include <EEPROM.h>
// Пин подключения DT (data) к ESP32
const int LOADCELL_DT_PIN = 16;
// Пин подключения SCK (clock) к ESP32
const int LOADCELL_SCK_PIN = 4;
// Адреса в EEPROM для хранения данных
const int EEPROM_SIZE = 512; // Размер EEPROM
const int CALIBRATION_ADDR = 0; // Адрес для калибровочного коэффициента
const int TARE_ADDR = 8; // Адрес для нулевого значения (8 байт для float)
// Известный вес для калибровки (в граммах)
const float KNOWN_WEIGHT = 1000.0; // Эталонный вес 1000 грамм
// Создаем объект для работы с HX711
HX711 scale;
// Переменные для хранения калибровочных данных
float calibrationFactor = 0.0;
long tareValue = 0;
// Флаг для принудительной калибровки
bool forceCalibration = false;
void saveCalibration() {
// Сохраняем калибровочный коэффициент
EEPROM.put(CALIBRATION_ADDR, calibrationFactor);
// Сохраняем нулевое значение
EEPROM.put(TARE_ADDR, tareValue);
// Подтверждаем запись
EEPROM.commit();
Serial.println("Калибровочные данные сохранены в EEPROM");
}
bool loadCalibration() {
// Загружаем калибровочный коэффициент
EEPROM.get(CALIBRATION_ADDR, calibrationFactor);
// Загружаем нулевое значение
EEPROM.get(TARE_ADDR, tareValue);
// Проверяем, есть ли сохраненные данные (не инициализированная память)
if (isnan(calibrationFactor) || calibrationFactor < 0.1 || calibrationFactor > 10000) {
Serial.println("Сохраненные данные не найдены или некорректны");
return false;
}
Serial.println("Загружены калибровочные данные из EEPROM:");
Serial.print("Калибровочный коэффициент: ");
Serial.println(calibrationFactor, 6);
Serial.print("Нулевое значение: ");
Serial.println(tareValue);
return true;
}
void performCalibration() {
Serial.println("\n=== ЗАПУСК ПРОЦЕДУРЫ КАЛИБРОВКИ ===");
Serial.println("Убедитесь, что на датчике НЕТ груза!");
Serial.println("Калибровка начнется через 5 секунд...");
delay(5000);
// Шаг 1: Определение значения "нуля" (tare)
Serial.println("Определение нулевого значения...");
scale.tare(20); // Усредняем по 20 измерениям
tareValue = scale.get_value(10);
Serial.print("Нулевое значение: ");
Serial.println(tareValue);
Serial.println("\nТеперь поместите груз 1000 грамм на датчик.");
Serial.println("Калибровка продолжится через 10 секунд...");
delay(10000);
// Шаг 2: Измерение значения с грузом
Serial.println("Измерение значения с грузом 1000г...");
long loadedValue = 0;
const int numReadings = 20;
for (int i = 0; i < numReadings; i++) {
loadedValue += scale.read();
delay(100);
Serial.print(".");
}
Serial.println();
loadedValue = loadedValue / numReadings;
Serial.print("Значение с грузом (среднее): ");
Serial.println(loadedValue);
// Шаг 3: Расчет калибровочного коэффициента
long rawValue = loadedValue - tareValue;
calibrationFactor = rawValue / KNOWN_WEIGHT;
Serial.println("\n========== РЕЗУЛЬТАТЫ КАЛИБРОВКИ ==========");
Serial.print("Нулевое значение (tare): ");
Serial.println(tareValue);
Serial.print("Значение с грузом: ");
Serial.println(loadedValue);
Serial.print("Разница (raw value): ");
Serial.println(rawValue);
Serial.print("Калибровочный коэффициент: ");
Serial.println(calibrationFactor, 6);
Serial.println("===========================================");
// Сохраняем калибровку в EEPROM
saveCalibration();
// Применяем калибровку
scale.set_scale(calibrationFactor);
scale.set_offset(tareValue);
Serial.println("Калибровка завершена и сохранена!");
}
void setup() {
Serial.begin(115200);
Serial.println("Инициализация HX711 и ESP32...");
// Инициализация EEPROM
EEPROM.begin(EEPROM_SIZE);
// Инициализация тензодатчика
scale.begin(LOADCELL_DT_PIN, LOADCELL_SCK_PIN);
// Даем время для стабилизации датчика
delay(1000);
// Проверяем, нужно ли провести калибровку
if (forceCalibration || !loadCalibration()) {
Serial.println("Требуется калибровка!");
performCalibration();
} else {
// Применяем загруженные калибровочные данные
scale.set_scale(calibrationFactor);
scale.set_offset(tareValue);
Serial.println("Калибровочные данные загружены и применены");
}
Serial.println("\n=== Весы готовы к работе ===");
Serial.println("Текущий вес (граммы):");
}
void loop() {
// Проверяем готовность датчика
if (scale.is_ready()) {
// Читаем вес с усреднением для стабильности
float weight = scale.get_units(10);
// Форматированный вывод
Serial.print("\rВес: ");
Serial.print(weight, 2);
Serial.print(" г");
// Дополнительная информация о стабильности
if (abs(weight - 100.0) < 2.0) {
Serial.print(" ✓ (1000г)");
}
} else {
Serial.print("\rHX711 не готов...");
}
delay(200); // Обновление 5 раз в секунду
}