Всем добрый день. Не могу понять в чем причина. Написал код, все работало, но я использовал DELAY для пауз. Обратился к ИИ для оптимизации, вроде как он скорректировал поставил millis, где были несоответствия я доделал... В общем программа работает так как я это задумал. Но в одном месте, после выключения помпы, мне нужна пауза порядка 1 минуты. И вот тут засада. Если я ставлю 30сек. то программа работает идеально. Если ставлю 40сек, то программа работает, все изменяется, на дисплее данные выводятся, но помпа больше не включается...
Где порылась ошибка не пойму! Просьба подсказать, если кто то найдет причину. Код прикрепляю. Спасибо. Строки с данным параметром задержки я выделил.
Где порылась ошибка не пойму! Просьба подсказать, если кто то найдет причину. Код прикрепляю. Спасибо. Строки с данным параметром задержки я выделил.
не работает millis , больше 30 сек.:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// === Конфигурация === // дисплей подключается А4 и А5 по стандарту
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
#define OLED_ADDR 0x3C
// Пин датчика влажности
#define SENSOR_PIN A0
#define AirValue 680 // Значение сухого датчика
#define WaterValue 365 // Значение мокрого датчика
// Пин переменного резистора
#define THRESHOLD_PIN A1
// Пин светодиодов
#define LED_GREEN 2 // Нормальная влажность
#define LED_BLUE 3 // Высокая влажность
#define LED_YELLOW 4 // Низкая влажность желтый или красный диод можно поставить
// Пин управления насосом
#define MOTOR_PIN 11
// Пин кнопки настройки
#define KEY_PIN 6
#define KEY_GR 5 // земля (минус) для кнопки
// Время работы насоса (в секундах)
#define PUMP_TIME 5
#define WAIT_AFTER_PUMP 30 // Пауза после полива (секунд)
int thresholdValue = 20; // значение влажности по умолчанию в процентах
// Переменные для управления насосом
enum PumpState { IDLE, PUMPING, COOLDOWN };
PumpState pumpState = IDLE;
unsigned long pumpTimer = 0;
Adafruit_SSD1306 display(OLED_WIDTH, OLED_HEIGHT, &Wire, -1);
void setup() {
// Инициализация дисплея
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
while (1); // Останов если дисплей не найден
}
// Настройка дисплея
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.clearDisplay();
// Приветственное сообщение
display.setCursor(45, 20);
display.println("ORION");
display.setCursor(10, 30);
display.println("*****************");
display.display();
delay(2000);
// Инициализация пинов
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
pinMode(LED_YELLOW, OUTPUT);
pinMode(MOTOR_PIN, OUTPUT);
pinMode(KEY_PIN, INPUT_PULLUP);
pinMode(KEY_GR, OUTPUT);
digitalWrite(KEY_GR, LOW);
// Выключаем все светодиоды и насос
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_BLUE, LOW);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(MOTOR_PIN, LOW);
thresholdValue = thresholdValue * 11;
}
void handlePump(int sensorPercent, int thresholdPercent) {
switch (pumpState) {
case IDLE:
// Проверяем нужно ли включать насос
if (sensorPercent < thresholdPercent && digitalRead(KEY_PIN) == HIGH) {
digitalWrite(MOTOR_PIN, HIGH);
pumpState = PUMPING;
pumpTimer = millis();
}
break;
case PUMPING:
// Проверяем не пора ли выключить насос
if (millis() - pumpTimer >= PUMP_TIME * 1000) {
digitalWrite(MOTOR_PIN, LOW);
pumpState = COOLDOWN;
pumpTimer = millis();
}
break;
case COOLDOWN:
// Ждем окончания паузы
if (millis() - pumpTimer >= WAIT_AFTER_PUMP * 1000) {
pumpState = IDLE;
pumpTimer = millis(); // ← ДОБАВИТЬ! Это улучшает читаемость и надёжность
}
break;
}
}
void loop() {
// Считываем данные с датчиков
int sensorValue = analogRead(SENSOR_PIN);
if (digitalRead(KEY_PIN) == LOW) { // если не нажата кнопка то не считываем установки.
thresholdValue = analogRead(THRESHOLD_PIN); // защита от случайного поворота настроек во время использования.
}
// Преобразуем в проценты
int sensorPercent = constrain(map(sensorValue, AirValue, WaterValue, 0, 100), 0, 100);
int thresholdPercent = constrain(map(thresholdValue, 0, 1020, 0, 100), 0, 100); // задаем нужный диапазон настройки влажности 20-80% или ...
// Рассчитываем разницу
int difference = sensorPercent - thresholdPercent;
// Управление светодиодами
digitalWrite(LED_GREEN, (abs(difference) <= 10) ? HIGH : LOW);
digitalWrite(LED_BLUE, (difference >= 10) ? HIGH : LOW);
digitalWrite(LED_YELLOW, (difference <= -1) ? HIGH : LOW);
// Управление насосом
handlePump(sensorPercent, thresholdPercent);
// Отображение на дисплее
display.clearDisplay();
// Текущая влажность
display.setCursor(10, 20);
display.print("Real: ");
display.print(sensorPercent);
display.print("%");
// Установленная влажность
display.setCursor(10, 38);
display.print("Set: ");
display.print(thresholdPercent);
display.print("%");
// Прогресс-бар
int barWidth = map(sensorValue, AirValue, WaterValue, 0, OLED_WIDTH - 20);
display.drawRect(10, 0, OLED_WIDTH - 20, 10, SSD1306_WHITE);
display.fillRect(10, 0, barWidth, 10, SSD1306_WHITE);
// Состояние насоса
display.setCursor(10, 54);
display.print("Pump: ");
switch (pumpState) {
case IDLE: display.print("OFF"); break;
case PUMPING: display.print("PUMPING"); break;
case COOLDOWN: display.print("OFF"); break;
}
display.display();
delay(500); // Задержка между измерениями
}
Изменено: