some fixes
This commit is contained in:
@@ -50,7 +50,7 @@ W = 100 × (m1 - m0) / (m0 - m)
|
||||
### Удержание кнопки (4-6 секунд)
|
||||
Автоматическое тарирование (обнуление весов)
|
||||
|
||||
### Удержание кнопки (8-10 секунд)
|
||||
### Удержание кнопки (8+ секунд)
|
||||
Калибровка с эталонным грузом 100г
|
||||
|
||||
## Режим нагрева
|
||||
|
||||
117
grunt_stand.ino
117
grunt_stand.ino
@@ -57,14 +57,13 @@ const unsigned long HEAT_DURATION = 900000; // 15 минут = 900000 мс
|
||||
bool heating_active = false;
|
||||
|
||||
// Циклический нагрев
|
||||
const unsigned long HEAT_ON_TIME = 30000; // 30 секунд нагрева
|
||||
const unsigned long HEAT_OFF_TIME = 20000; // 20 секунд паузы
|
||||
const unsigned long HEAT_ON_TIME = 20000; // 15 секунд нагрева
|
||||
const unsigned long HEAT_OFF_TIME = 30000; // 30 секунд паузы
|
||||
unsigned long last_cycle_change = 0; // Время последнего переключения
|
||||
bool heat_cycle_on = false; // Текущее состояние цикла (вкл/выкл)
|
||||
|
||||
// Для постоянного расчета W с фильтрацией
|
||||
float current_W = 0.0; // Текущее значение влажности (сырое)
|
||||
float filtered_W = 0.0; // Отфильтрованное значение W для отображения
|
||||
// Для расчета W (без фильтрации)
|
||||
float current_W = 0.0; // Текущее значение влажности
|
||||
float max_W = 0.0; // Максимальное значение W за время нагрева
|
||||
unsigned long last_W_update = 0;
|
||||
const unsigned long W_UPDATE_INTERVAL = 500; // Обновлять W каждые 500 мс
|
||||
@@ -357,12 +356,23 @@ void loop() {
|
||||
|
||||
// Обновляем W каждые W_UPDATE_INTERVAL мс
|
||||
if (millis() - last_W_update > W_UPDATE_INTERVAL) {
|
||||
current_W = calculateW(); // Вычисляем сырое значение W
|
||||
filtered_W = w_filter.update(current_W); // Фильтруем для отображения
|
||||
current_W = calculateW(); // Вычисляем W напрямую (без фильтра)
|
||||
|
||||
// DEBUG: выводим все значения для диагностики
|
||||
Serial.print("m=");
|
||||
Serial.print(m, 4);
|
||||
Serial.print(" m1=");
|
||||
Serial.print(m1, 4);
|
||||
Serial.print(" m0=");
|
||||
Serial.print(m0, 4);
|
||||
Serial.print(" W=");
|
||||
Serial.print(current_W, 4);
|
||||
Serial.print(" max_W=");
|
||||
Serial.println(max_W, 4);
|
||||
|
||||
// Обновляем максимальное значение W
|
||||
if (filtered_W > max_W) {
|
||||
max_W = filtered_W;
|
||||
if (current_W > max_W) {
|
||||
max_W = current_W;
|
||||
}
|
||||
|
||||
last_W_update = millis();
|
||||
@@ -467,7 +477,7 @@ void updateDisplay() {
|
||||
heat_cycle_on = true;
|
||||
last_cycle_change = millis();
|
||||
last_W_update = millis();
|
||||
w_filter.reset(); // Сбрасываем фильтр W при начале нагрева
|
||||
// Фильтр W удалён - используем прямое значение
|
||||
max_W = 0.0; // Сбрасываем максимальное W
|
||||
digitalWrite(HEAT_PIN, HIGH);
|
||||
break;
|
||||
@@ -529,8 +539,8 @@ void handleButton() {
|
||||
// Тарирование 4-6 секунд
|
||||
performTaring();
|
||||
}
|
||||
else if (press_duration >= MIN_CAL_TIME && press_duration <= MAX_CAL_TIME) {
|
||||
// Калибровка 8-10 секунд
|
||||
else if (press_duration >= MIN_CAL_TIME) {
|
||||
// Калибровка 8+ секунд
|
||||
performCalibration();
|
||||
}
|
||||
else if (press_duration < 1000) {
|
||||
@@ -605,21 +615,38 @@ void displayHeating() {
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print(line1);
|
||||
|
||||
// Вторая строка: только максимальный W
|
||||
// Вторая строка: масса (слева) и W (справа)
|
||||
char line2[17];
|
||||
char m_buf[6];
|
||||
char w_buf[6];
|
||||
char mass_buf[7];
|
||||
|
||||
// Форматируем максимальный W
|
||||
if (max_W >= 100) {
|
||||
strcpy(m_buf, ">99");
|
||||
strcpy(w_buf, ">99");
|
||||
} else {
|
||||
dtostrf(max_W, 5, 1, m_buf);
|
||||
dtostrf(max_W, 4, 1, w_buf);
|
||||
}
|
||||
|
||||
// Формат: "Wmax: XX.X%"
|
||||
snprintf(line2, sizeof(line2), "W:%s%%", m_buf);
|
||||
// Форматируем массу m0 (показываем когда индуктор выключен)
|
||||
if (!heat_cycle_on) {
|
||||
// Индуктор выключен - показываем текущую массу
|
||||
if (m0 >= 100.0) {
|
||||
strcpy(mass_buf, ">99g");
|
||||
} else if (m0 <= -10.0) {
|
||||
strcpy(mass_buf, "<-9g");
|
||||
} else {
|
||||
dtostrf(m0, 5, 2, mass_buf);
|
||||
strcat(mass_buf, "g");
|
||||
}
|
||||
// Формат: "XX.XXg W:XX.X%"
|
||||
snprintf(line2, sizeof(line2), "%-8s %s%%", mass_buf, w_buf);
|
||||
} else {
|
||||
// Индуктор включен - показываем только W по центру
|
||||
snprintf(line2, sizeof(line2), " * %s%%", w_buf);
|
||||
}
|
||||
|
||||
printCentered(1, line2);
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(line2);
|
||||
}
|
||||
|
||||
void displayHeatingComplete() {
|
||||
@@ -683,7 +710,6 @@ void performTaring() {
|
||||
scale.tare();
|
||||
median_filter.reset();
|
||||
display_filter.setImmediate(0.0);
|
||||
w_filter.reset();
|
||||
|
||||
// Если был режим нагрева - выходим из него
|
||||
if (heating_active) {
|
||||
@@ -708,6 +734,10 @@ void performCalibration() {
|
||||
}
|
||||
|
||||
void calibrationProcedure() {
|
||||
Serial.println("=== CALIBRATION START ===");
|
||||
Serial.print("Old calibration_factor: ");
|
||||
Serial.println(calibration_factor, 6);
|
||||
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print("Calibration ");
|
||||
@@ -717,9 +747,11 @@ void calibrationProcedure() {
|
||||
digitalWrite(HEAT_PIN, LOW);
|
||||
heating_active = false;
|
||||
heat_cycle_on = false;
|
||||
Serial.println("Heating was active, turned off");
|
||||
}
|
||||
|
||||
// Шаг 1: Clear platform
|
||||
Serial.println("Step 1: Waiting for empty platform...");
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("Clear platform ");
|
||||
|
||||
@@ -733,14 +765,22 @@ void calibrationProcedure() {
|
||||
delay(100);
|
||||
|
||||
// Сообщение о тарировании
|
||||
Serial.println("Step 2: Taring...");
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("Taring... ");
|
||||
|
||||
// ВАЖНО: Устанавливаем scale=1.0 ПЕРЕД тарированием,
|
||||
// чтобы получать сырые значения и избежать зацикливания калибровки
|
||||
scale.set_scale(1.0);
|
||||
Serial.println("Scale set to 1.0 for raw measurements");
|
||||
|
||||
// Тарируем весы (устанавливаем ноль)
|
||||
delay(500); // Даем время на стабилизацию
|
||||
scale.tare();
|
||||
Serial.println("Tare complete");
|
||||
|
||||
// Шаг 2: Set 100g
|
||||
Serial.println("Step 3: Waiting for 100g weight...");
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("Set 100g ");
|
||||
|
||||
@@ -754,29 +794,47 @@ void calibrationProcedure() {
|
||||
delay(100);
|
||||
|
||||
// Сообщение о сохранении результатов 100г
|
||||
Serial.println("Step 4: Measuring 100g raw values (15 samples)...");
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("saving results ");
|
||||
|
||||
// Измеряем среднее значение 100г (15 измерений)
|
||||
// Измеряем среднее СЫРОЕ значение 100г (15 измерений)
|
||||
// scale=1.0, поэтому get_units() возвращает сырые значения
|
||||
delay(1000); // Даем время на стабилизацию
|
||||
float weight_sum = 0;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
float reading = scale.get_units(1);
|
||||
float reading = scale.get_units(1); // При scale=1.0 это сырое значение
|
||||
weight_sum += reading;
|
||||
Serial.print(" Raw sample ");
|
||||
Serial.print(i + 1);
|
||||
Serial.print(": ");
|
||||
Serial.println(reading, 2);
|
||||
delay(100);
|
||||
}
|
||||
float weight_average = weight_sum / 15;
|
||||
|
||||
Serial.print("Raw weight sum: ");
|
||||
Serial.println(weight_sum, 2);
|
||||
Serial.print("Raw weight average: ");
|
||||
Serial.println(weight_average, 2);
|
||||
Serial.print("CALIBRATION_WEIGHT: ");
|
||||
Serial.println(CALIBRATION_WEIGHT, 2);
|
||||
|
||||
// Вычисляем коэффициент калибровки
|
||||
// После tare() шкала обнулена, поэтому weight_average - это разница веса напрямую
|
||||
// Проверяем, что груз действительно поставлен (вес больше 10 единиц)
|
||||
if (abs(weight_average) > 10) {
|
||||
// scale=1.0 и tare() выполнен, поэтому weight_average - это СЫРОЕ значение АЦП
|
||||
// new_factor = raw_value / known_weight
|
||||
// Проверяем, что груз поставлен (сырое значение больше 1000 единиц АЦП)
|
||||
if (abs(weight_average) > 1000) {
|
||||
calibration_factor = weight_average / CALIBRATION_WEIGHT;
|
||||
|
||||
Serial.print("New calibration_factor: ");
|
||||
Serial.println(calibration_factor, 6);
|
||||
|
||||
// Проверяем, что коэффициент положительный
|
||||
if (calibration_factor <= 0) {
|
||||
// Ошибка: отрицательный или нулевой коэффициент - неправильная калибровка
|
||||
// (датчик подключен неправильно или вес убрали вместо добавления)
|
||||
Serial.println("ERROR: calibration_factor <= 0!");
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print("Calibration ");
|
||||
@@ -786,11 +844,14 @@ void calibrationProcedure() {
|
||||
} else {
|
||||
// Сохраняем коэффициент в EEPROM
|
||||
saveCalibrationToEEPROM(calibration_factor);
|
||||
Serial.println("Calibration factor saved to EEPROM");
|
||||
|
||||
// Устанавливаем новый коэффициент
|
||||
scale.set_scale(calibration_factor);
|
||||
Serial.println("Scale updated with new factor");
|
||||
|
||||
// Сообщение об успешной калибровке
|
||||
Serial.println("=== CALIBRATION OK ===");
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print("Calibration ");
|
||||
@@ -800,6 +861,11 @@ void calibrationProcedure() {
|
||||
}
|
||||
} else {
|
||||
// Сообщение о неудачной калибровке (груз не поставлен или слишком легкий)
|
||||
Serial.print("ERROR: abs(raw_weight_average) = ");
|
||||
Serial.print(abs(weight_average), 2);
|
||||
Serial.println(" <= 1000, raw ADC value too low!");
|
||||
Serial.println("Check: is 100g weight placed? Is HX711 connected?");
|
||||
Serial.println("=== CALIBRATION FAILED ===");
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print("Calibration ");
|
||||
@@ -813,4 +879,5 @@ void calibrationProcedure() {
|
||||
// Возврат в режим READY
|
||||
current_state = STATE_READY;
|
||||
need_display_clear = true;
|
||||
Serial.println("Returned to READY state");
|
||||
}
|
||||
Reference in New Issue
Block a user