Умный террариум

Тема в разделе "Глядите, что я сделал", создана пользователем aleksjet, 4 дек 2012.

  1. aleksjet

    aleksjet Нуб

    Всем добрый день
    ищу тех кто может мне помочь в проекте ?
    Умный террариум
    Нужно организовать управление террариум
    А именно:
    Контроль параметров влажности и температуры
    Управление освещением по таймеру
    Возможность управлением поливом (насос для воды)
    Возможность подключения вентиляторов для проветривания
    Все эти функции хотелось бы регулировать через кнопки на устройстве

    То что у меня есть
    часы реального времени,
    ардуина уно,
    LCD 16x2,
    блок реле 4 нагрузки
    и еще разные кнопки и пр

    Буду рад услышать советы

    P.S.
    Сам в программировании ардуино мало разобрался а дома появился питомец который очень требователен к свету и температуре
     
  2. Megakoteyka

    Megakoteyka Оракул Модератор

    А с чем конкретно затык? С подключением/управлением нагрузками? С алгоритмом управления? С написанием кода?
     
  3. aleksjet

    aleksjet Нуб

    Затык в коде
    сейчас только разобрался как подключить LCD вывести параметры температуры и влажности
    а дальше не знаю как сделать меню что бы можно было выставить предельные параметры
     
  4. Megakoteyka

    Megakoteyka Оракул Модератор

    Нужно как минимум 4 кнопки: влево, вправо, прибавить значение, убавить.
    Первые две кнопки меняют значение переменной, в которой хранится номер пункта меню.
    Структура данных для каждого пункта должна содержать его название и значение.
    Вторая пара кнопок меняет значение параметра в структуре.

    Вот пример для двух первых кнопок (только листает список настроек по кругу в обе стороны:

    Код (Text):
    #include <Bounce.h>
    #include <LiquidCrystal.h>
     
    // состояние нажатой кнопки (зависит от способа подключения кнопки)
    #define BUTTON_PRESSED HIGH
     
    // количество параметров в настройках
    #define OPTIONS_COUNT 3
     
    // структура описывает параметр настроек
    typedef struct {
    int value;
    char* name;
    } OPTION;
     
    // номер текущего параметра
    int _optionIndex;
     
    // массив всех параметров
    OPTION _options[] = {
    { 10, "Option 1" },
    { 20, "Option 2" },
    { 30, "Option 3" }
    };
     
    LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
     
    // давилки дребезга для кнопок "ВЛЕВО" и "ВПРАВО"
    Bounce bouncerLeft = Bounce(3, 40);
    Bounce bouncerRight = Bounce(2, 40);
     
    // флаг "обновить дисплей"
    boolean updateDisplay = true;
     
     
    void setup()
    {
    //_options[0] = _option1;
    //_options[1] = _option2;
    //_options[2] = _option3;
    _optionIndex = 0;
     
    Serial.begin(9600);
     
    pinMode(2, INPUT);
    pinMode(3, INPUT);
     
    // init display
    lcd.begin(16, 2);
     
    UpdateDisplay();
    }
     
    void loop()
    {
    // левая кнопка
    if(bouncerLeft.update() && bouncerLeft.read() == BUTTON_PRESSED)
        ButtonHandlerL();
     
    // правая кнопка
    if(bouncerRight.update() && bouncerRight.read() == BUTTON_PRESSED)
        ButtonHandlerR();
     
    // если что-то изменилось - обновляем дисплей
    if(updateDisplay)
        UpdateDisplay();
    }
     
    void ButtonHandlerL()
    {
    _optionIndex = (_optionIndex > 0) ? _optionIndex - 1 : OPTIONS_COUNT - 1;
    updateDisplay = true;
    }
     
    void ButtonHandlerR()
    {
    _optionIndex = (_optionIndex < (OPTIONS_COUNT - 1)) ? _optionIndex + 1 : 0;
    updateDisplay = true;
    }
     
    void UpdateDisplay()
    {
    lcd.clear();
    lcd.print("ITEM: ");
    lcd.print(_options[_optionIndex].name);
     
    lcd.setCursor(0, 1);
    lcd.print("VALUE: ");
    lcd.print(_options[_optionIndex].value);
     
    updateDisplay = false;
    }
    Аналогичным способом этот пример можно расширить для второй пары кнопок.
    Неплохо еще хранить настройки в EEPROM, чтобы не терять их при потере питания.

    Помогло?
     
  5. aleksjet

    aleksjet Нуб

    спасибо попробую разобраться что к чему
    Но пока для меня это темный лес (
     
  6. Megakoteyka

    Megakoteyka Оракул Модератор

    Спрашивайте о непонятностях, расскажу подробней...
     
  7. aleksjet

    aleksjet Нуб

    Я пока мало понимаю как все это можно объединить и как должно выглядеть меню
    Могу выложить код который у меня есть и код на примере которого делал
     
  8. aleksjet

    aleksjet Нуб

    Про ером читал хотелось бы что бы данные не сносились при отключения питания ?
     
  9. Megakoteyka

    Megakoteyka Оракул Модератор

    Выкладывайте, проще будет разбираться.

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

    Часы реального времени пока отложите в сторону - они тут ни к чему, вполне хватит внутреннего таймера.
    Раз есть дисплей и кнопки - попробуйте выводить данные на дисплей и ловить нажатия кнопок (см. примеры в моем коде). Можно и реле подергать заодно, повесив на него лампочку или мультиметр для контроля.

    EEPROM штука очень простая, хороший понятный пример есть тут.
     
  10. aleksjet

    aleksjet Нуб

    Вот код к которому пытаюсь приладить кнопки что бы менять параметры контроллера без прошивки Arduino а выбирая на экране определенные параметры, а часы и ером хотел бы приладить для надежности и энергонезависимости устройства мало ли что а параметры слетят и все надо настраивать заново.
    а еще бы предусмотреть защиту если датчик отвалится что бы без датчика не включалась нагрузка, например отвалился датчик, а нагреватель включился и греет и греет, в итоге жаренный питомец.
    Код (Text):
    #include <DHT.h> // Подключаем библиотеку для работы с датчиком
    #include <DS1307.h> // Подключаем библиотеку управления модулем реального времени
    #include <LiquidCrystalExt.h> // Подключаем библиотеку управления экраном
    #include <LineDriver.h> // Далее вспомогательные библиотеки для реализации интерфейса SPI
    #include <SPI.h>
    #include <SPI_Bus.h>
    #include <Wire.h>
     
    #define DHTPIN 9 // Считывающий пин с датчика
    #define DHTTYPE DHT22 // Модель датчика
    #define tPIN 7 // Пин управления температурой
    #define hPIN 6 // Пин управления влажностью
    #define lPIN 5 // Пин управления светом
    #define sdPIN 3 // Пин управления светодиодной лентой
     
    DHT dht(DHTPIN, DHTTYPE); // Создаем объект dht
     
    int tStatus = HIGH; // определяем переменную, отвечающую за состоянеие нагревателя HIGH=выкл, LOW=вкл
    int tempDay = 28; // Желаемая дневная температура в градусах Цельсия
    int tempNight = 25; // Желаемая ночная температура в градусах Цельсия
    int hStatus = HIGH; // определяем переменную, отвечающую за состоянеие увлажнителя HIGH=выкл, LOW=вкл
    int humDay = 45; // Желаемая дневная влажность
    int humNight = 40; // Желаемая ночная влажность
     
    SPI_Bus shreg(_8bit, 10); // Подключаем сдвиговый регистр
    LiquidCrystal lcd(1, 2, 3, 4, 5, 6, &shreg, 7); // Инициализируем дисплей
     
    void setup() // инициализация основных данных
    {
    Serial.begin(9600); // Инициализируем COM-порт
    dht.begin(); // Инициализируем датчик
    pinMode(tPIN, OUTPUT); // Определяем пин для управления температурой как Вывод
    pinMode(hPIN, OUTPUT);
    pinMode(lPIN, OUTPUT);
    lcd.begin(16,2); // устанавливаем размеры экрана
    //lcd.backlight(true); // Указываем использование подсветки экрана
    }
     
    void loop() // зацикливание (код управляющей программы)
    {
    if (Serial.available() > 0) SetTime(); // Если на COM-порт поступила информация, то изменим системное время
    float h = dht.readHumidity(); // Считываем влажность
    float t = dht.readTemperature(); // Считываем температуру
    int Hour = RTC.get(DS1307_HR,true); // Получаем значение текущего часа
    int Minute = RTC.get(DS1307_MIN,false);
    int Second = RTC.get(DS1307_SEC,false);
    boolean Day = (Hour >= 8 & Hour <20); // Если текущий час находится в промежутке от 8 до 20, то действуют дневные параметры
    tStatus = (t < ((Day) ? tempDay : tempNight)) ? LOW:HIGH; // Если температура меньше желаемой, то статус обогревателя=Вкл, в противном случае Выкл
    digitalWrite(tPIN, tStatus);
    if (h < ((Day) ? humDay : humNight)) hStatus = LOW; else hStatus = HIGH; // Если влажность меньше желаемой, то статус увлажнителя=Вкл, в противном случае Выкл
    digitalWrite(hPIN, hStatus);
    digitalWrite(lPIN, (Day) ? LOW:HIGH); // Если дневное время, то включим подсветку
    switch(Hour) // в зависимости от времени меняем яркость светодиодной ленты
    {
    case 7:analogWrite(sdPIN, map(Minute, 0, 59, 0, 255)); break;
    case 20:analogWrite(sdPIN, map(Minute, 0, 59, 255, 0)); break;
    default:analogWrite(sdPIN, (Day) ? 255:0);
    }
    lcd.setCursor(1,0); // устанавливаем позицию курсора на экране (на один символ правее левого верхнего угла)
    lcd.print(t, 1); lcd.print("C "); lcd.print(h, 1); lcd.print("% "); // Выводим информацию о климате
    lcd.setCursor(4,1); // устанавливаем курсор для вывода времени
    lcd.print(addZero(Hour));lcd.print(":");lcd.print(addZero(Minute));lcd.print(":");lcd.println(addZero(Second)+ " "); // Выводим время
    lcd.setCursor(1,1);lcd.print((tStatus == LOW) ? "+":" "); // Выводим индикатор работы подогрева
    lcd.setCursor(13,1);lcd.print((hStatus == LOW) ? "+":" "); // Выводим индикатор работы увлажнения
    delay(500); // Задержка в пол секунды
    }
     
    void SetTime() // установка времени из шаблона tчч:мм
    {
    if (Serial.read() == 't') // Если первый символ t, то установим указанное время
    {
    int h = (Serial.read() - '0') * 10 + (Serial.read() - '0');
    Serial.read();
    int m = (Serial.read() - '0') * 10 + (Serial.read() - '0');
    RTC.stop();
    RTC.set(DS1307_SEC,0); //set the seconds
    RTC.set(DS1307_MIN,m); //set the minutes
    RTC.set(DS1307_HR,h); //set the hours
    RTC.start();
    }
    Serial.flush();
    }
     
    String addZero(int val)
    {
    if (val<10) return "0" + String(val);else return String(val);
    }
     
  11. aleksjet

    aleksjet Нуб

    причесав этот код понял что за что отвечает
    сейчас на экран выводится время, температура и влажность
    больше пока не разберусь ни как :)
     
  12. aleksjet

    aleksjet Нуб

    Пробовал переделать код от меги с экраном 20х3 под UNO с экраном 16х2 и еще не могу правильно подключить кнопки по этому коду
    Буду рад советам
    код выкладываю по частям
    Код (Text):
    #include <DHT.h>
    #include <DS1307.h> // Подключаем библиотеку управления модулем реального времени
    #include <LiquidCrystalExt.h> // Подключаем библиотеку управления экраном
    #include <LineDriver.h> // Далее вспомогательные библиотеки для реализации интерфейса SPI
    #include <SPI.h>
    #include <SPI_Bus.h>
    #include <Wire.h>
    #include <EEPROM.h> // Подключаем библиотеку для работы с энергонезависимой памятью
     
    #define DHTPIN 9 // Считывающий пин с датчика
    #define DHTTYPE DHT22 // Модель датчика
    #define tPIN 7 // Пин управления температурой
    #define hPIN 6 // Пин управления влажностью
    #define lPIN 8 // Пин управления светом
    #define sdPIN 5 // Пин управления светодиодной лентой
    #define switchPIN_1 4 // Кнопка №1 "MODE"
    #define switchPIN_2 3 // Кнопка №2 "+"
    #define switchPIN_3 2 // Кнопка №2 "_"
     
     
    DHT dht(DHTPIN, DHTTYPE);                   // Создаем объект dht
                               
    int tStatus = HIGH; // определяем переменную, отвечающую за состоянеие нагревателя HIGH=выкл, LOW=вкл
    int tempDay; // Декларируем переменную, которая будет хранить желаемую температуру
    int tempNight = tempDay-1; // Желаемая ночная температура в градусах Цельсия
    int hStatus = HIGH; // определяем переменную, отвечающую за состоянеие увлажнителя HIGH=выкл, LOW=вкл
    int humDay; // Декларируем переменную, которая будет хранить желаемую влажность
    int humNight = humDay+1; // Желаемая ночная влажность
    int DaySt; // Декларируем переменную, которая будет хранить желаемую времени начала дня
    int DayFin; // Декларируем переменную, которая будет хранить желаемую времени конца дня
    int LightOn; // Декларируем переменную, которая будет хранить желаемую времени начала полудня
    int LightOff; // Декларируем переменную, которая будет хранить желаемую времени конца полудня
    int edit = 0; // Переменную будем использовать для определения режима редактирования
    long last_micros = 0; // Вспомогательная переменная, используется для определения сколько микросекунд прошло после предыдущей операции
    int lastButton1 = LOW; // Предыдущее состояние кнопки №1
    int currentButton1 = LOW; // Текущее состояние кнопки №1
    int lastButton2 = LOW; // Предыдущее состояние кнопки №2
    int currentButton2 = LOW; // Текущее состояние кнопки №2
    int lastButton3 = LOW; // Предыдущее состояние кнопки №3
    int currentButton3 = LOW; // Текущее состояние кнопки №3
     
     
    SPI_Bus shreg(_8bit, 10); // Подключаем сдвиговый регистр
    LiquidCrystal lcd(1, 2, 3, 4, 5, 6, &shreg, 7); // Инициализируем дисплей
     
     
    void setup() // инициализация основных данных
    {
    Serial.begin(9600); // Инициализируем COM-порт
    dht.begin(); // Инициализируем датчик
     
     
    pinMode(tPIN, OUTPUT); // Определяем пин для управления температурой как Вывод
    pinMode(hPIN, OUTPUT);
    pinMode(lPIN, OUTPUT);
    pinMode(sdPIN, OUTPUT);
     
    tempDay = EEPROM.read(1); // Получаем параметр из первой ячейки
    if (tempDay == 255) tempDay = 26; // Если ячейка пуста, т.е. ее значение = 255, то устанавливаем параметр температуры в значение по умолчанию, вданном случае 26С.
     
    humDay = EEPROM.read(3); // Получаем параметр из 3 ячейки
     
    DaySt = EEPROM.read(9); // Получаем параметр из 9 ячейки
    if (DaySt == 255) DaySt = 8; // Если ячейка пуста, то установим параметр в 8
     
    DayFin = EEPROM.read(10); // Получаем параметр из 10 ячейки
    if (DayFin == 255) DayFin = 21; // Если ячейка пуста, то установим параметр в 21
     
    LightOn = EEPROM.read(11); // Получаем параметр из 11 ячейки
    if (LightOn == 255) LightOn = 11; // Если ячейка пуста, то установим параметр в 11
     
    LightOff = EEPROM.read(12); // Получаем параметр из 12 ячейки
    if (LightOff == 255) LightOff = 18; // Если ячейка пуста, то установим параметр в 18
     
    pinMode(switchPIN_1, INPUT); // Устанавливаем тип контакта Кнопки №1 как Вход
    pinMode(switchPIN_2, INPUT); // Устанавливаем тип контакта Кнопки №2 как Вход
    pinMode(switchPIN_3, INPUT); // Устанавливаем тип контакта Кнопки №3 как Вход
     
    lcd.begin(12,2); // устанавливаем размеры экрана
    }
     
    void loop() // зацикливание (код управляющей программы)
     
    {
     
    static unsigned long lastTime = 0; // Декларируем переменную и устанавливаем ее начальное значение в 0
    if (millis() - lastTime > 3000) // Не используем в данном случае задержку Delay, т.к. это приведет к запаздыванию нажатий кнопок
     
    {
     
    lastTime = millis();
     
    }  
     
  13. aleksjet

    aleksjet Нуб

    Код (Text):
    Switch();  
     
    if (Serial.available() > 0) SetTime(); // Если на COM-порт поступила информация, то изменим системное время
    float h = dht.readHumidity(); // Считываем влажность
    float t = dht.readTemperature(); // Считываем температуру
    int Hour = RTC.get(DS1307_HR,true); // Получаем значение текущего часа
    int Minute = RTC.get(DS1307_MIN,false);
    int Second = RTC.get(DS1307_SEC,false);
    int Date = RTC.get(DS1307_DATE,false);
    int Mon = RTC.get(DS1307_MTH,false);
    int Ye = RTC.get(DS1307_YR,false);
    boolean Day = (Hour >= DaySt & Hour <DayFin); // Если текущий час находится в промежутке от DaySt до DayFin, то действуют дневные параметры
    boolean Light = (Hour >= LightOn & Hour < LightOff); // Если текущий час находится в промежутке от LightOn до LightOff, то действуют полуденные параметры
     
    tStatus = (t < ((Day) ? tempDay : tempNight)) ? LOW:HIGH; // Если температура меньше желаемой, то статус обогревателя=Вкл, в противном случае Выкл
    digitalWrite(tPIN, tStatus);
    if (h < ((Day) ? humDay : humNight)) hStatus = LOW; else hStatus = HIGH; // Если влажность меньше желаемой, то статус увлажнителя=Вкл, в противном случае Выкл
    digitalWrite(hPIN, hStatus);
     
    digitalWrite(lPIN, (Light) ? HIGH:LOW); // Если полуденное время, то включим подсветку
    if (Hour==LightOn-1) analogWrite(sdPIN, map(Minute, 0, 59, 0, 255));
    else if (Hour==LightOff) analogWrite(sdPIN, map(Minute, 0, 59, 255, 0));
    else analogWrite(sdPIN, (Light) ? 255:0);
     
    lcd.setCursor(0,0); // устанавливаем курсор для вывода времени
    lcd.print(addZero(Hour));lcd.print(":");lcd.print(addZero(Minute));lcd.print(":");lcd.print(addZero(Second)); //Выводим время
    lcd.setCursor(0,9);lcd.print((tStatus == LOW) ? "+":" "); // Выводим индикатор работы подогрева
     
    lcd.setCursor(1,0); // устанавливаем позицию курсора на экране (на один символ правее левого нижнего угла)
    lcd.print("T:");lcd.print(t, 1); lcd.print("C ");
    lcd.setCursor(12,0);
    lcd.print("H:");lcd.print(h, 1); lcd.print("%"); // Выводим информацию о климате
     
    }
     
     
     
    void SetTime() // установка времени из шаблона tчч:мм
     
    {
     
    if (Serial.read() == 't') // Если первый символ t, то установим указанное время
     
    {
     
    int h = (Serial.read() - '0') * 10 + (Serial.read() - '0');
    Serial.read();
    int m = (Serial.read() - '0') * 10 + (Serial.read() - '0');
    Serial.read();
    int D = (Serial.read() - '0') * 10 + (Serial.read() - '0');
    Serial.read();
    int M = (Serial.read() - '0') * 10 + (Serial.read() - '0');
    Serial.read();
    int Y = (Serial.read() - '0') * 10 + (Serial.read() - '0');
     
    RTC.stop();
    RTC.set(DS1307_SEC,0); //set the seconds
    RTC.set(DS1307_MIN,m); //set the minutes
    RTC.set(DS1307_HR,h); //set the hours
    RTC.set(DS1307_DATE,D); //set the date
    RTC.set(DS1307_MTH,M); //set the month
    RTC.set(DS1307_YR,Y); //set the year
    RTC.start();
     
    }
    Serial.flush();
    }
     
    String addZero(int val)
    {
    if (val<10) return "0" + String(val);else return String(val);
    }
     
    void Switch()
     
    {
     
    if (millis() - last_micros >= 300) // Производим опрос кнопок каждую треть секунды, это необходимо, чтобы избежать повторных выполнений кода в следствие дребезга контактов
     
    {
     
    last_micros = millis();
     
    currentButton1 = digitalRead(switchPIN_1); // Считываем текущее состояние кнопки №1
    currentButton2 = digitalRead(switchPIN_2); // Считываем текущее состояние кнопки №2
    currentButton3 = digitalRead(switchPIN_3); // Считываем текущее состояние кнопки №3
     
    if (lastButton1 == LOW && currentButton1 == HIGH) // Если Кнопка №1 изменила состояние на Нажатие
     
    {
     
    long t_millis = millis(); // Фиксируем начальное время нажатие кнопки, чтобы определить, не была ли она зажата
     
    while (digitalRead(switchPIN_1) == HIGH && millis() - t_millis <= 2000 && edit==0) {} // Пока кнопка зажата не даем программе двигаться дальше
     
    if (millis() - t_millis > 2000) // Если кнопка была нажата дольше 2-х секунд, то переведем состояние в режим программирования
     
    {
     
    edit = 1;
     
    lcd.clear();lcd.setCursor(1, 1); lcd.print("TempD:"); lcd.print(tempDay); lcd.print("C");lcd.print(" edit");
     
    }
     
    // Иначе отрабатываем короткое нажатие при различных условиях
     
    else if (edit==1) { edit = 3;  lcd.clear();lcd.setCursor(1, 1); lcd.print("Humid:");lcd.print(humDay);
    lcd.print("%");lcd.print(" edit");}  // Если программа была в режиме изменения первого параметра, переведем ее на изменение 3 параметра
     
    else if (edit==8) { edit = 9; lcd.clear();lcd.setCursor(1, 1); lcd.print("DaySt:");lcd.print(DaySt); lcd.print(" edit");}//Если программа была в режиме изменения 8 параметра, переведем ее на изменение 9 параметра
     
    else if (edit==9) { edit = 10; lcd.clear();lcd.setCursor(1, 1); lcd.print("DayFin:");lcd.print(DayFin); lcd.print(" edit");}//Если программа была в режиме изменения 9 параметра, переведем ее на изменение 10 параметра
     
    else if (edit==10) { edit = 11; lcd.clear();lcd.setCursor(1, 1); lcd.print("LightOn:");lcd.print(LightOn); lcd.print("edit");}// Если программа была в режиме изменения 10 параметра, переведем ее на изменение 11 параметра
     
    else if (edit==11) { edit = 12; lcd.clear();lcd.setCursor(1, 1); lcd.print("LightOff:");lcd.print(LightOff); lcd.print("edit");}// Если программа была в режиме изменения 11 параметра, переведем ее на изменение 12 параметра
     
    else if (edit==12) // Если программа была в режиме изменения 8 параметра, переведем ее в штатный режим и сохраним параметры в энергонезависимую память
     
     
    {
     
    edit = 0;
     
    lcd.clear();
     
    EEPROM.write(1, tempDay); // Запимываем параметр температуры в 1-ю ячейку памямти
     
    EEPROM.write(3, humDay);
     
    EEPROM.write(9, DaySt);
     
    EEPROM.write(10, DayFin);
     
    EEPROM.write(11, LightOn);
     
    EEPROM.write(12, LightOff);
     
     
    }
     
    else {}; // Если программа не была в режиме редактирования, то можно выполнить тоже какое-то действие, для этого в фигурных скобках необходимо описать его функционал
     
    }
     
    if (currentButton2 == HIGH && edit != 0) // Если нажата Кнопка №2, при состоянии редактирования параметров то...
     
    {
     
    if (edit == 1) // ...если режим изменения температуры
     
    {
     
      lcd.clear();
     
          lcd.setCursor(1, 1);
     
        lcd.print("TempD:");
     
        lcd.print(tempDay);
     
        lcd.print("C +");
     
    tempDay = (tempDay == 35) ? 10:(tempDay+1);
     
    }
     
    else if (edit == 3) // ...если режим изменения влажности
     
    {
     
      lcd.clear();
     
          lcd.setCursor(1, 1);
     
        lcd.print("Humid:");
     
        lcd.print(humDay);
     
        lcd.print("% +");
     
    humDay = (humDay == 95) ? 20:(humDay+1);
     
    }
     
     
    else if (edit == 9) // ...если режим изменения DaySt
     
    {
     
      lcd.clear();
     
          lcd.setCursor(1, 1);
     
        lcd.print("DaySt:");
     
        lcd.print(DaySt);
     
        lcd.print(" + ");
     
    DaySt = (DaySt == 23) ? 0:(DaySt+1);
     
    }
     
    else if (edit == 10) // ...если режим изменения DayFin
     
    {
     
      lcd.clear();
     
          lcd.setCursor(1, 1);
     
        lcd.print("DayFin:");
     
        lcd.print(DayFin);
     
        lcd.print(" + ");
     
    DayFin = (DayFin == 23) ? 0:(DayFin+1);
     
    }
     
    else if (edit == 11) // ...если режим изменения LightOn
     
    {
     
      lcd.clear();
     
          lcd.setCursor(1, 1);
     
        lcd.print("LightOn:");
     
        lcd.print(LightOn);
     
        lcd.print(" + ");
     
    LightOn = (LightOn == 23) ? 0:(LightOn+1);
     
    }
     
    else if (edit == 12) // ...если режим изменения LightOff
     
    {
     
      lcd.clear();
     
          lcd.setCursor(1, 1);
     
        lcd.print("LightOff:");
     
        lcd.print(LightOff);
     
        lcd.print(" + ");
     
    LightOff = (LightOff == 23) ? 0:(LightOff+1);
     
    }
     
    }
     
    else if (lastButton2 == LOW && currentButton2 == HIGH) // Если было короткое нажатие на Кнопку №2 не в режиме редактирования, то можно выполнить какое либо действие, если описать его в фигурных скобках ниже
     
    {
    }
     
     
     
    if (currentButton3 == HIGH && edit != 0) // Если нажата Кнопка №3, при состоянии редактирования параметров то...
     
    {
     
    if (edit == 1) // ...если режим изменения температуры
     
    {
     
    tempDay = (tempDay == 10) ? 35:(tempDay-1);
     
    lcd.clear();
     
          lcd.setCursor(1, 1);
     
        lcd.print("TempD: ");
     
        lcd.print(tempDay);
     
        lcd.print("C -");
     
    }
     
    else if (edit == 3) // ...если режим изменения влажности
     
    {
     
    humDay = (humDay == 20) ? 95:(humDay-1);
     
    lcd.clear();
     
          lcd.setCursor(1, 1);
     
        lcd.print("Humid:");
     
        lcd.print(humDay);
     
        lcd.print("% -");
     
    }
     
     
    else if (edit == 9) // ...если режим изменения DaySt
     
    {
     
      lcd.clear();
     
          lcd.setCursor(1, 1);
     
        lcd.print("DaySt:");
     
        lcd.print(DaySt);
     
        lcd.print(" - ");
     
    DaySt = (DaySt == 0) ? 23:(DaySt-1);
     
    }
     
    else if (edit == 10) // ...если режим изменения DayFin
     
    {
     
      lcd.clear();
     
          lcd.setCursor(1, 1);
     
        lcd.print("DayFin:");
     
        lcd.print(DayFin);
     
        lcd.print(" - ");
     
    DayFin = (DayFin == 0) ? 23:(DayFin-1);
     
    }
     
    else if (edit == 11) // ...если режим изменения LightOn
     
    {
     
      lcd.clear();
     
          lcd.setCursor(1, 1);
     
        lcd.print("LightOn:");
     
        lcd.print(LightOn);
     
        lcd.print(" - ");
     
    LightOn = (LightOn == 0) ? 23:(LightOn-1);
     
    }
     
    else if (edit == 12) // ...если режим изменения LightOff
     
    {
     
      lcd.clear();
     
          lcd.setCursor(1, 1);
     
        lcd.print("LightOff:");
     
        lcd.print(LightOff);
     
        lcd.print(" - ");
     
    LightOff = (LightOff == 0) ? 23:(LightOff-1);
     
    }
     
    }
     
    else if (lastButton3 == LOW && currentButton3 == HIGH) // Если было короткое нажатие на Кнопку №3 не в режиме редактирования, то можно выполнить какое либо действие, если описать его в фигурных скобках ниже
     
    {}
     
    lastButton1 = currentButton1; // Запоминаем предыдущее значение Кнопки №1
     
    lastButton2 = currentButton2; // Запоминаем предыдущее значение Кнопки №2
     
    lastButton3 = currentButton3; // Запоминаем предыдущее значение Кнопки №23
     
    }
     
    }
     
  14. Megakoteyka

    Megakoteyka Оракул Модератор

    Вот эти статьи:
    Кнопки, PWM, функции
    Подключение текстового LCD экрана к Arduino
    смотрели? Я по ним очень быстро разобрался, все крайне доходчиво написано.
    Ваш код и схему можно немного упростить - использовать для дисплея 4 линии данных, тогда потратится 6 ножек МК и не понадобится сдвиговый регистр - для обновления картинки раз в секунду этого за глаза хватит.
     
  15. aleksjet

    aleksjet Нуб

    можно по подробней про 4 линии данных ?
     
  16. Megakoteyka

    Megakoteyka Оракул Модератор

    Отсюда: Подключение текстового LCD экрана к Arduino

    Вам как раз хватит 6 ног, т.к. читать с дисплея не надо, а обновляться он должен относительно редко, раза в секунду достаточно.
     
  17. aleksjet

    aleksjet Нуб

    Так у меня дисплей через сдвигов фей регистр подключен и использует всего 3 ноги + 2 питания
    Или можно меньше ?
     
  18. Megakoteyka

    Megakoteyka Оракул Модератор

    Можно отказаться от использования сдвигового регистра - зачем тратить лишние детали, когда они реально не нужны? Но это не принципиально, конечно же)

    Неплохо было бы считывать кнопки, используя библиотеку Bounce, она как раз предназначена для подавления дребезга. Вот так:

    Код (Text):
    #include <Bounce.h>
     
    #define BUTTON 2
    #define LED 13
     
    // время подавления дребезга - 5 мс
    Bounce bouncer = Bounce(BUTTON, 5);
     
    void setup() {
      pinMode(BUTTON, INPUT);
      pinMode(LED, OUTPUT);
    }
     
    void loop() {
     // обновляем состояние кнопки
      bouncer.update( );
     
      // читаем состояние кнопки
      int value = bouncer.read();
    }
     
  19. aleksjet

    aleksjet Нуб

    Так если делать без сдвигового регистра будет занято 6 контактов а у меня как раз он для экономии контактов
     
  20. Megakoteyka

    Megakoteyka Оракул Модератор

    А без регистра ног не хватает? Аналоговые уже использовали? Их ведь тоже можно как цифровые юзать...
    Впрочем, не забивайте этим голову, это не принципиально.

    Лучше исправьте опрос кнопок - вот это действительно важно.
    А с организацией меню удалось разобраться?