Аквариумный контроллер на Pro mini

Spiker
Offline
Зарегистрирован: 18.06.2016
Собрал контроллер для аквариума с сайта 
http://www.aquaforum.ua/showthread.php?t=175844
немного доработал. Помогите подправить 


// Обращение к ним идет по номерам от 14 (для аналогового входа 0) до 19 (для аналогового входа 5).
#define EXT_FILTER_PIN 12
#define EXT_AIR_PIN 1  
#define EXT_HEATER_PIN 13  
#define EXT_COOLING_PIN 10  
#define EXT_LIGHT_1_PIN 15
#define EXT_LIGHT_2_PIN 26
#define EXT_CO2_PIN 0 // изменено на контроллер уровня со строкой (Подмена)
#define EXT_NALIV_PIN 17         
#define EXT_KLAPAN_PIN 11 // Реле контроля заполнения аквариума 
#define EXT_POWER_ON_PIN 20
#define EXT_LIGHT_LED_PIN 16

#define EXT_UDO_MICRO_PIN 22
#define EXT_UDO_MACRO_PIN 18
#define EXT_UDO_Fe_PIN 19

#define Key_PIN 7 // кнопки канал А7

#define DispLight_min 230 // минимальная подсветка в режиме часов 230 ок
#define CorrTime +1 // коррекция хода системных часов [Сек] выполняется каждый час  
// СопзЬ INT CorrTime = -1; // Коррекция хода системных часов [Сек]  
// Предполагается, что ЖК-модуль подключен к
// следующие выводы, используя levelshifter, чтобы получить
// Правильное напряжение к модулю.
// SCK - Pin 8
// MOSI - Pin 9
// DC - Pin 10
// RST - Pin 11
// CS - Pin 12
//
#include <LCD5110_Graph.h>

#define LED_LIGHT_PIN 9  
LCD5110 myGLCD (8,7,6,4,5); 
Экстерн uint8_t SmallFont [];
ехЬегп uint8_t BigNumbers [];
// Экстерн неподписанные символ TINYFONT [];
байт ledContrast;
байт LEDLIGHT;

// Подключаем заголовочный файл библиотеки EEPROM
#include <eeprom.h>

#include <OneWire.h> 
Темп-Wire (14); // На выводе 10 (а 4.7K резистор необходимо)
плавать cur_temp = -999;
байт temp_type_s;
байт temp_data [12];
байт temp_addr [8];
байт temp_cicle = 0;
// Я предполагаю, что вы знаете, как подключить DS1307.
// DS1307: SDA контактный -> Arduino Digital 4
// SCL контактный -> Arduino Digital 5

#include <DS1307.h>

// Инициализировать DS1307
DS1307 РТК (3, 2); 
// Init структура времени данных
Время Время; 
неподписанных долгое CURRENTTIME;
неподписанных долгое LOOPTIME;


байт ключ = 0;
байт prev_key = 0;
байт idle_key = 0;
// СопзЬ INT max_idle_key = 100; // Цыклов не активности перед скринсейвером
#define max_idle_key 100 // цыклов не активности перед скринсейвером

INT cur_menu = 0;
INT cur_item = 0;
булево cur_item_edit = ложь;
байт aquaT; // Требуемая температура воды
булево CoolingEnabled; // Разрешено ли охлаждение куллером
булево light1 = ложь;
булево light2 = ложь;
булево воздух = ложь;
логическое значение CO2 = ложь;
булево KLAPAN = ложь;
булево nailiv = ложь;

байт kormMin = 0; // Остаток времени для кормления мин

байт minCool = 0; // Минимальные обороты кулера для вентиляции крышки и охлаждения ламп
байт maxCool = 0; // Максимальные обороты для охлаждения воды

недействительными установки ()
{
  pinMode (EXT_NALIV_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_NALIV_PIN, HIGH); // выключает
  pinMode (EXT_KLAPAN_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_KLAPAN_PIN, HIGH); // выключает
  pinMode (EXT_HEATER_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_HEATER_PIN, LOW); // выключает
  pinMode (EXT_COOLING_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_COOLING_PIN, LOW); // выключает
  pinMode (EXT_LIGHT_1_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_LIGHT_1_PIN, HIGH); // выключает
  light1 = TRUE;
  pinMode (EXT_LIGHT_2_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_LIGHT_2_PIN, HIGH); // выключает
  light2 = ложь;
  pinMode (EXT_FILTER_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_FILTER_PIN, HIGH); // выключает
  pinMode (EXT_CO2_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_CO2_PIN, HIGH); // выключает
  CO2 = ложь;
  pinMode (EXT_AIR_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_AIR_PIN, LOW); // выключает
  воздух = истинный;
  CoolingEnabled = ложь; // Разрешено ли охлаждение куллером


  pinMode (EXT_POWER_ON_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_POWER_ON_PIN, LOW); // выключает
  pinMode (EXT_LIGHT_LED_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_LIGHT_LED_PIN, LOW); // выключает
  pinMode (EXT_UDO_MICRO_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_UDO_MICRO_PIN, LOW); // выключает
  pinMode (EXT_UDO_MACRO_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_UDO_MACRO_PIN, LOW); // выключает
  pinMode (EXT_UDO_Fe_PIN, OUTPUT); // Устанавливает режим работы - выход
  digitalWrite (EXT_UDO_Fe_PIN, LOW); // выключает

  // Подтяжка включит резистор для входа:
// PinMode (Key_PIN, INPUT);

// Инициализация EEPROM
// Для (INT е = 0; е <2047; е ++) EEPROM.write (е, 0);
// EEPROM.write (0,61); // LedContrast !!!!!!! Очень акуратно иначе белый либо черный экран
// EEPROM.write (1200); // светодиодный
// EEPROM.write (2,24); // Требуемая температура воды
// EEPROM.write (3,1); // Разрешено ли охлаждение куллером
  
  ledContrast = EEPROM.read (0);
  // Первичная установка контраста - иначе при первом запуске нихрена невидно
  если ((ledContrast == 0) || (ledContrast == 255)) {
    ledContrast = 65;
  }

  LEDLIGHT = EEPROM.read (1);
  myGLCD.InitLCD (ledContrast);
  pinMode (LED_LIGHT_PIN, OUTPUT); // Устанавливает режим работы - выход
  analogWrite (LED_LIGHT_PIN, LEDLIGHT);
  aquaT = EEPROM.read (2); // Требуемая температура воды

  minCool = EEPROM.read (3); // Минимальные обороты кулера для вентиляции крышки и охлаждения ламп
  maxCool = EEPROM.read (4); // Максимальные обороты для охлаждения воды

  // Установите часы для запуска-режим
  rtc.halt (ложь); 
// Rtc.setDOW (воскресенье); // Установить день-недели в воскресную
// Rtc.setTime (12, 0, 0); // Установите время 12:00:00 (формат 24 часа)
// Rtc.setDate (3, 10, 2010); // Установить дату по октябрь 2010 года, 3th
  
  myGLCD.setFont (SmallFont);
  myGLCD.clrScr ();
  myGLCD.update ();

/ *
  myGLCD.setFont (SmallFont);
  myGLCD.clrScr ();
  myGLCD.print ( "AQUA kontrolx", ЦЕНТР, 3);
  myGLCD.print ( "MIHS", CENTER, 20);
  myGLCD.drawRect (28, 18, 56, 28);
  для (INT I = 0; я <6; я ++)
  {
    myGLCD.drawLine (57, 18+ (я * 2), 83- (я * 3), 18+ (I * 2));
    myGLCD.drawLine ((я * 3), 28- (I * 2), 28, 28- (I * 2));
  }
// MyGLCD.setFont (TINYFONT);
  myGLCD.print ( "- 2016 -", CENTER, 36);
// MyGLCD.print ( "AlexVOK@gmail.com", CENTER, 42);
  myGLCD.update ();
  Задержка (1000);
* /
// ------------------------------------------------ -------------------------------
  байт Ь = 0;
  в то время как ((! temp.search (temp_addr)) && (Ь <10)) {
    //Serial.println("Нет Больше адресов ").
    temp.reset_search ();
    Задержка (250);
    б ++;
  }
// Если (:: CRC8-Wire (temp_addr, 7)! = Temp_addr [7]) {
// Serial.println ( "КПР не является действительным!");
//}

// Первый байт ROM указывает, какой чип
  Переключатель (temp_addr [0]) {
    случай 0x10:
// Serial.println ( "Chip = DS18S20"); 
      temp_type_s = 1;
      ломать;
    случай 0x28:
// Serial.println ( "Chip = DS18B20");
      temp_type_s = 0;
      ломать;
    случай 0x22:
// Serial.println ( "Chip = DS1822");
      temp_type_s = 0;
      ломать;
// по умолчанию:
// Serial.println ( "Устройство не распознано");
  }

  CURRENTTIME = Миллис ();
  LOOPTIME = CURRENTTIME;   
}

// ------------------------------------------------ -----------------------------------
плавать getTemp () {
// Temp.reset ();
// Temp.select (temp_addr);
// Temp.write (0x44, 1); // Начать преобразование с паразитного питания на конце
  
// Задержка (1000); // Может быть, 750 мс достаточно, может быть, не
  // Мы можем сделать ds.depower () здесь, но сброс будет заботиться о нем.
  
  temp.reset ();
  temp.select (temp_addr);    
  temp.write (0xBE); // Чтения блокнота

  для (байт = 0; я <9; я ++) {// нам нужно 9 байт
    temp_data [I] = temp.read ();
  }
// Serial.print (:: CRC8-Wire (данные, 8), HEX);

  // Преобразование данных в фактической температуры
  // Потому что результат является 16 битное целое число, оно должно
  // Храниться к типу "int16_t", который всегда 16 бит
  // Даже при компиляции на 32 битного процессора.
  int16_t сырья = (temp_data [1] << 8) | temp_data [0];
  
  если (temp_type_s) {
    сырьевой = сырьевой << 3; // 9 битное разрешение по умолчанию
    если (temp_data [7] == 0x10) {
      // "Рассчитывать остаются" дает полный 12 битное разрешение
      сырые = (сырье и 0xFFF0) + 12 - temp_data [6];
    }
  } Еще {
    байт CFG = (temp_data [4] & 0x60);
    // При более низких Рез, низкие биты не определены, так что давайте их нулю
    если (CFG == 0x00) = сырой сырой & ~ 7; // 9 бит, 93,75 мс
    иначе если (CFG == 0x20) = сырой сырой & ~ 3; // 10 бит разрешения, 187,5 мс
    иначе если (CFG == 0x40) = сырой сырой & ~ 1; // 11 бит разрешения, 375 мс
    //// По умолчанию разрешение 12 бит, 750 мс Время преобразования
  }
  Возвращение ((с плавающей точкой) сырой / 16,0);
}

// ------------------------------------------------ -----------------------------------
// Нажатые кнопки
// Кнопка INT;
Const байт BUTTON_NONE = 0;
Const байт BUTTON_UP = 1;
Const байт BUTTON_DOWN = 2;
Const байт BUTTON_OK = 3;
Const байт BUTTON_CANCEL = 4;

INT getPressedButton ()
{
 байт KeyNum = 0;
 INT KeyValue1 = 0;
 INT KeyValue2 = 0;
 
// Читаем в цикле аналоговый вход, для подавления дребезга и нестабильности читаем по два раза подряд, пока значения не будут равны.
// Если значения равны 1023 - значит не была нажата ни одна клавиша.
делать {
 // Считываем значения с аналогового входа (A0)  
 KeyValue1 = analogRead (Key_PIN);
 задержка (10);
 KeyValue2 = analogRead (Key_PIN);
 задержка (5);
 } В то время как (KeyValue1 = KeyValue2!);
 
// Интерпретируем полученное значение и определяем код нажатой клавиши
 если (KeyValue2> 900) 
  {KeyNum = BUTTON_NONE;}
 иначе если (KeyValue2> 450) 
       {KeyNum = BUTTON_CANCEL;}
      иначе если (KeyValue2> 250) 
            {KeyNum = BUTTON_UP;}
           иначе если (KeyValue2> 100) 
                 {KeyNum = BUTTON_DOWN;}
                еще {KeyNum = BUTTON_OK;}
// Возвращаем код нажатой клавиши
вернуть KeyNum;
}

// ------------------------------------------------ -----------------------------------
аннулированию NaViKey (байт MaxItems) {
  если (ключ == BUTTON_UP) {
    cur_item--;
    если (cur_item <1)
      cur_item = MaxItems;
  }
  если (ключ == BUTTON_DOWN) {
    cur_item ++;
    если (cur_item> MaxItems)
      cur_item = 1;
  }
}
// ------------------------------------------------ -----------------------------------
аннулированию drawMenu (String, String mName item1, String, String item2 элемент3, String item4) {
  myGLCD.setFont (SmallFont);
  myGLCD.clrScr ();
  
  myGLCD.print (mName, 1,0);
  myGLCD.print (rtc.getTimeStr (FORMAT_SHORT), RIGHT, 0);
  myGLCD.drawLine (0,8,83,8);
  myGLCD.drawLine (0,9,83,9);

  если (cur_item == 1) {
    myGLCD.print (item1,3,12);
    myGLCD.drawRoundRect (0,11,83,20);
  } еще  
    myGLCD.print (item1,0,12);
      
  если (cur_item == 2) {
    myGLCD.print (item2,3,21);
    myGLCD.drawRoundRect (0,20,83,29);
  } еще  
    myGLCD.print (item2,0,21);

  если (cur_item == 3) {
    myGLCD.print (item3,3,30);
    myGLCD.drawRoundRect (0,29,83,38);
  } еще  
    myGLCD.print (item3,0,30);

  если (cur_item == 4) {
    myGLCD.print (item4,3,39);
    myGLCD.drawRoundRect (0,38,83,47);
  } еще  
    myGLCD.print (item4,0,39);

  myGLCD.update ();
}

байт menu_hh;
байт menu_mi;
байт menu_dd;
байт menu_mm;
INT menu_yyyy;
байт menu_dow;
байт menu_off;
байт menu_item_count;
INT alertAdr;
байт curLoad;

байт PRMIN = 0;
// ------------------------------------------------ -----------------------------------
аннулированию drawIntMenu (String mName, INT MINVAL, INT MAXVAL, INT Val) {
  myGLCD.setFont (SmallFont);
  myGLCD.clrScr ();
  
  myGLCD.print (mName, 1,0);
// MyGLCD.print (rtc.getTimeStr (FORMAT_SHORT), RIGHT, 0);
  myGLCD.drawLine (0,8,83,8);
  myGLCD.drawLine (0,9,83,9);

  myGLCD.setFont (BigNumbers);
  myGLCD.printNumI (Val, CENTER, 11);

  myGLCD.drawRoundRect (0,38,83,47);
  
  INT к = 80 * (Val-MINVAL) / (MAXVAL - MINVAL);
  для (INT I = 2; г <к + 2; я ++)
    myGLCD.drawLine (я, 40, I, 46);
  myGLCD.update ();
}

булево new_hour = TRUE;
байт SECC = 0;
байт LED_sunrise = 0;
байт LED_cur_pos = 0;
байт udo_tim = 0;
байт Б.Т.;
// ************************************************ *****************************************
// ************************************************ *****************************************
аннулируются петля () {
CURRENTTIME = Миллис ();
ключ = getPressedButton ();
если ((CURRENTTIME> = (LOOPTIME + 250)) || (ключ! = prev_key)) {// проверяем каждые 5мс (20 Гц)

  если ((prev_key! ключ =) && (ключ! = 0)) {
    idle_key = 0;
  } Еще { 
    idle_key ++;
  }
  prev_key = ключ;


  если (ключ == 0) // Измереяем температуру только в состоянии простоя
  {
    если (temp_cicle == 0) {
      temp.reset ();
      temp.select (temp_addr);
      temp.write (0x44, 1); // Начать преобразование с паразитного питания на конце
    }
    если (temp_cicle == 4) {
      cur_temp = getTemp ();
      // Управление нагревом и охлаждением -------------------------------------------- -
      если (cur_temp <(флоат) aquaT) {
        digitalWrite (EXT_HEATER_PIN, LOW); // Включает нагреватель
      } еще  
        digitalWrite (EXT_HEATER_PIN, HIGH); // Выключает нагреватель
       
       


      
  
   
   если (cur_temp> ((флоат) aquaT-3.0) && cur_temp <((флоат) aquaT + 3.0)) {// разрешён налив от -3 до + 3 градусов от установленного значения
   
 
   digitalWrite (EXT_NALIV_PIN, LOW); // Включает налив
   } еще  
         
   digitalWrite (EXT_NALIV_PIN, HIGH); // Выключает налив
    

     
   
   
     
      
      
      если (CoolingEnabled) {
        если (cur_temp> ((флоат) aquaT + 0,1)) {// Разрешено ли охлаждение куллером
          INT coll_cur = minCool + (((флоат) (maxCool - minCool)) / 100) * (((флоат) (cur_temp-aquaT)) / 0,5) * 100;
          если (coll_cur> maxCool) {coll_cur = maxCool;}
          analogWrite (EXT_COOLING_PIN, coll_cur); // Включает куллер
        } Еще {  
          analogWrite (EXT_COOLING_PIN, minCool); // Включаем режим проветривания
        }
      } Еще {
        если (воздух || light1) {
// Если (воздух || light1 || light2) {
          analogWrite (EXT_COOLING_PIN, minCool); // Включаем режим проветривания
        } Еще {  
          digitalWrite (EXT_COOLING_PIN, LOW); // Выключает куллер
        }
      } 
    }
    если (temp_cicle> 51) {
      temp_cicle = 0;
    } Еще {
      temp_cicle ++;
    }
  }

// ------------------------------------------------ --------------------------------


  если (SECC> 4) {
    SECC = 0;
  } Еще {
    SECC ++;
  }

  
  // Получить данные из DS1307
  время = rtc.getTime ();   
  // Коррекция хода системных часов [Сек]  
  если (time.min == 0) {
    new_hour = TRUE;
  }
  если ((time.min == 30) && (new_hour)) {
    INT corr_sec = time.sec + CorrTime; // Коррекция хода системных часов [Сек]  
    байт corr_min = time.min;
    если (corr_sec <0) {
      corr_sec = corr_sec + 60;
      corr_min--;
    }
    если (corr_sec> 59) {
      corr_sec = corr_sec - 60;
      corr_min ++;
    }
    
    rtc.setTime (time.hour, corr_min, corr_sec); // Установите время 12:00:00 (формат 24 часа)
    new_hour = ложь;
  }
  // -----
  // Новая минута ----------------------------------------------
   если (PRMIN! = time.min) {
    PRMIN = time.min;

  // Время для кормления мин
    если (kormMin> 0) {
      digitalWrite (EXT_FILTER_PIN, LOW); // Выключает Фильтр
      kormMin--;
    } Еще {
      digitalWrite (EXT_FILTER_PIN, HIGH); // Включает Фильтр
    }  
    // Восход / Закат
    если (LED_sunrise> 0) {
      байт led_val = (LED_sunrise & B01111111);
      байт led_tmp = 0;
      булева is_sunrise = LED_sunrise & B10000000;
      если (LED_cur_pos> = led_val) {
        led_tmp = 255;
        LED_sunrise = 0;
      } Еще {  
        led_tmp = LED_cur_pos * 255 / led_val;
      } 
      если (! is_sunrise) {// Закат
        led_tmp = 255 - led_tmp;
      }
      // Управляем блоком питания
      если (led_tmp == 0) {
        digitalWrite (EXT_POWER_ON_PIN, LOW);
      } Еще {         
        digitalWrite (EXT_POWER_ON_PIN, HIGH);
      }  

      analogWrite (EXT_LIGHT_LED_PIN, led_tmp); // СВЕТОДИОД
      LED_cur_pos ++;
    } 
    
//-------АВАРИЙНАЯ СИГНАЛИЗАЦИЯ---------------------------------------- --------------------------------- 
   для (INT а = 100; а <1001; а = а + 4) {
     байт b1 = EEPROM.read (а);
// Если (((булево) (b1 & B10000000)) & ((булево) (_ BV (time.dow-1) и b1))) {// активная запись и день недели
     если (b1 & B10000000) {
      если ((1 << (time.dow-1)) и b1) {// активная запись и день недели
       байт b2 = EEPROM.read (а + 1);
       если (time.hour == (байт) (b2 & B00011111)) {// сравниваем часы
         байт b3 = EEPROM.read (а + 2);
         если (time.min == (байт) (b3 & B00111111)) {// сравниваем минути
           байт b4 = EEPROM.read (а + 3);
           Переключатель ((байт) ((b2 >> 5) & B00000111)) {// определяем нагрузку
             Случай 0:
               // Разрешено ли охлаждение куллером
               если (b4 & B00000001) {
                 CoolingEnabled = TRUE;
                 analogWrite (EXT_COOLING_PIN, minCool); // Включаем режим проветривания
               } Еще {
                 CoolingEnabled = ложь;
                 digitalWrite (EXT_COOLING_PIN, LOW);
               }  
             ломать;
             Случай 1: // Light1
               если (b4 & B00000001) {
                 digitalWrite (EXT_LIGHT_1_PIN, LOW);
                 light1 = TRUE;
               } Еще {
                 digitalWrite (EXT_LIGHT_1_PIN, HIGH);
                 light1 = ложь;
               }  
             ломать;   
             Случай 2: // light2
               если (b4 & B00000001) {
                 digitalWrite (EXT_LIGHT_2_PIN, LOW);
                 light2 = TRUE;
               } Еще {
                 digitalWrite (EXT_LIGHT_2_PIN, HIGH);
                 light2 = ложь;
               }  
             ломать;
             Случай 3: // Air
               если (b4 & B00000001) {
                 digitalWrite (EXT_AIR_PIN, LOW);
                 воздух = истинный;
               } Еще {
                 digitalWrite (EXT_AIR_PIN, HIGH);
                 воздух = ложь;
               }  
             ломать;
             Случай 4: // CO2
               если (b4 & B00000001) {
                 digitalWrite (EXT_CO2_PIN, LOW);   
                 
               
                 
                  CO2 = истинный;
               } Еще {
                 digitalWrite (EXT_CO2_PIN, HIGH);
               
            
                 
                 CO2 = ложь;
               }  
             ломать;
             Случай 5: // LED
               // 8 бит 1 0 восход закат остальные кол мин
               LED_sunrise = b4;
               LED_cur_pos = 0;
             ломать;
             Случай 6: // UDO
               udo_tim = (байт) (В4 & B00111111);
               digitalWrite (EXT_POWER_ON_PIN, HIGH);
               задержка (100); // Время на выход в режим БП
               Переключатель ((байт) ((В4 >> 6) & B00000011)) {
                 Случай 0:
                   digitalWrite (EXT_UDO_MICRO_PIN, HIGH);
                   Задержка (udo_tim * 4.2);
                   digitalWrite (EXT_UDO_MICRO_PIN, LOW);
                 ломать;
                 Дело 1:
                   digitalWrite (EXT_UDO_MACRO_PIN, HIGH);
                   Задержка (udo_tim * 4.2);
                   digitalWrite (EXT_UDO_MACRO_PIN, LOW);
                 ломать;
                 Случай 2:
                   digitalWrite (EXT_UDO_Fe_PIN, HIGH);
                   Задержка (udo_tim * 4.2);
                   digitalWrite (EXT_UDO_Fe_PIN, LOW);
                 ломать;
                 Случай 3:

                 ломать;
               }
               digitalWrite (EXT_POWER_ON_PIN, LOW);
             ломать;
             Случай 7:
           
             ломать;
           } 
         }
       }
     }
    } 
   }
  }  
// ------------------------------------------------ ------------------------------------ 
  если ((idle_key> max_idle_key) && (cur_menu! = 0)) {
    cur_menu = 0;
    cur_item = 0;
    cur_item_edit = ложь;
  }  
    
  Переключатель (cur_menu) {
    Случай 0: // Время
    {
      analogWrite (LED_LIGHT_PIN, DispLight_min);
      myGLCD.setFont (BigNumbers);
      myGLCD.clrScr ();
      myGLCD.printNumI (time.hour, 7,2,2, '0');
      myGLCD.drawCircle (42,9,3);
      myGLCD.drawCircle (42,19,3);
      если (SECC <2) {
        myGLCD.drawCircle (42,9,2);
        myGLCD.drawCircle (42,19,2);
        myGLCD.drawRect (41,8,43,10);
        myGLCD.drawRect (41,18,43,20);
        myGLCD.setPixel (42,9);
        myGLCD.setPixel (42,19);
      }
      myGLCD.printNumI (time.min, 49,2,2, '0');
      
      myGLCD.setFont (SmallFont);
      если (cur_temp <1) {
        myGLCD.print ( "чистый dat`ika", 3,38);
      } Еще {
        myGLCD.print ( "Т:", 3,38);
        myGLCD.printNumF (cur_temp, 2,15,38);
      }
      myGLCD.update ();
      если (клавиша> 0)
        cur_menu = 1;      
        cur_item = 0;
        cur_item_edit = ложь;
        // Включаем LED подсветку
// AnalogWrite (LED_LIGHT_PIN, LEDLIGHT);
      ломать;
    }
    Случай 1: // мужчины / ------------------------------------------- ----------------------
    {
    analogWrite (LED_LIGHT_PIN, LEDLIGHT);
    Строка LL;
      если (light1 || light2) {
        LL = "WKL";
      } еще
        LL = "otkl";

      Строка аа;
      если (воздух) {
        аа = "WKL";
      } еще
        аа = "otkl";

      если (cur_item_edit && (cur_item == 1))
        LL = "[" + LL + "]";

      если (cur_item_edit && (cur_item == 2))
        аа = "[" + аа + "]";
        
      Строка лк = "";
      если (kormMin> 0) {
        лк = "(" + (String) kormMin + ")";
      }  
      drawMenu ( "мужчины /", "Swet" + LL, "wozduh" + аа "Kormlenie" + лк, "nastrojki");
      NaViKey (4);
      Переключатель (ключ) {
        случай BUTTON_OK:
          Переключатель (cur_item) {
            Дело 1:
              ! Light1 = light1;
              light2 = light1;
              если (light1) {
                digitalWrite (EXT_LIGHT_1_PIN, LOW); // LED включает
              } еще
                digitalWrite (EXT_LIGHT_1_PIN, HIGH); // LED выключает
              если (light2) {
                digitalWrite (EXT_LIGHT_2_PIN, LOW); // LightTube включает
              } еще
                digitalWrite (EXT_LIGHT_2_PIN, HIGH); // LightTube выключает
            ломать;
            Случай 2:
              воздух = воздух!;
              если (воздух) {
                digitalWrite (EXT_AIR_PIN, LOW); // включает
              } еще
                digitalWrite (EXT_AIR_PIN, HIGH); // выключает
            ломать;
            Случай 3:
              kormMin = 20;
              digitalWrite (EXT_FILTER_PIN, LOW); // Выключает Фильтр
            ломать;
            Случай 4:
              cur_menu = 13;      
              cur_item = 0;
            ломать;
          }
        ломать;
        случай BUTTON_CANCEL:
          cur_item_edit = ложь;
          cur_menu = 0;
          cur_item = 0;
        ломать;
      }
      ломать;
    }
    Случай 13: // nastrojki -------------------------------------------- ---------------------
    {
      drawMenu ( "nastrojki", "Sistema", "Термостат", "zada`a", "podmena");
      NaViKey (4);
      Переключатель (ключ) {
        случай BUTTON_OK:
          Переключатель (cur_item) {
            Дело 1:
              cur_menu = 131;      
              cur_item = 0;
            ломать;
            Случай 2:
              cur_menu = 132;      
              cur_item = 0;
            ломать;
            Случай 3:
              cur_menu = 130;      
              cur_item = 1;
            ломать;
            Случай 4:
              cur_menu = 134;      
              cur_item = 0;
            ломать;
          }
        ломать;
        случай BUTTON_CANCEL:
          cur_menu = 1;
          cur_item = 3;
        ломать;
      }
      ломать;
    }
    Дело 134: // удо -------------------------------------------- ---------------------
    {Строка уу; 
      если (CO 2) {
        уу = "WKL";
      } Еще {
        уу = "Otkl";
      }  
      drawMenu ( "podmena", "podmena", "Удо", "podmena" + уу ",");
      NaViKey (3);
      Переключатель (ключ) {
        случай BUTTON_OK:
          Переключатель (cur_item) {
            Дело 1:
              cur_menu = 133;      
              cur_item = 1;
              menu_off = 1;
              menu_item_count = 25;
              curLoad = 4;
            ломать;
            Случай 2:
              cur_menu = 133;      
              cur_item = 1;
              menu_off = 1;
              menu_item_count = 25;
              curLoad = 6;
            ломать;
            Случай 3:
              CO2 = CO2!;
              если (CO 2) {
                digitalWrite (EXT_CO2_PIN, LOW);
                digitalWrite (EXT_KLAPAN_PIN, LOW);
              
              } Еще {
                digitalWrite (EXT_CO2_PIN, HIGH);
             digitalWrite (EXT_KLAPAN_PIN, HIGH);
              }  
            ломать;
            Случай 4:
// Cur_menu = 130;      
// Cur_item = 1;
            ломать;
          }
        ломать;
        случай BUTTON_CANCEL:
          cur_menu = 13;
          cur_item = 4;
        ломать;
      }
      ломать;
    }
    Случай 130: // zada`a ------------------------------------------ -----------------------
    {
      drawMenu ( "zada`a", "SWET 1", "SWET 2", "SWET светодиод", "wozduh");
      NaViKey (4);
      Переключатель (ключ) {
        случай BUTTON_OK:
          Переключатель (cur_item) {
            Дело 1:
              cur_menu = 133;      
              cur_item = 1;
              menu_off = 1;
              menu_item_count = 25;
              curLoad = 1;
            ломать;
            Случай 2:
              cur_menu = 133;      
              cur_item = 1;
              menu_off = 1;
              menu_item_count = 25;
              curLoad = 2;
            ломать;
            Случай 3:
              cur_menu = 133;      
              cur_item = 1;
              menu_off = 1;
              menu_item_count = 25;
              curLoad = 5;
            ломать;
            Случай 4:
              cur_menu = 133;      
              cur_item = 1;
              menu_off = 1;
              menu_item_count = 25;
              curLoad = 3;
            ломать;
        }
        ломать;
        случай BUTTON_CANCEL:
          cur_menu = 13;
          cur_item = 3;
        ломать;
      }
      ломать;
    }
    Дело 133: // zada`a Список меню ---------------------------------------- -------------------------
    {
      myGLCD.setFont (SmallFont);
      myGLCD.clrScr ();
      INT Offf;
      Переключатель (curLoad) {
        Случай 0:
          myGLCD.print ( "nastroika", 1,0);
          Offf = 400;
        ломать;
        Дело 1:
          myGLCD.print ( "SWET 1", 1,0);
          Offf = 100;
        ломать;
        Случай 2:
          myGLCD.print ( "SWET 2", 1,0);
          Offf = 200;
        ломать;
        Случай 3:
          myGLCD.print ( "wozduh", 1,0);
          Offf = 300;
        ломать;
        Случай 4:
          myGLCD.print ( "CO2", 1,0);
          Offf = 500;
        ломать;
        Случай 5:
          myGLCD.print ( "LED", 1,0);
          Offf = 600;
        ломать;
        Случай 6:
          myGLCD.print ( "удо", 1,0);
          Offf = 700;
        ломать;
      }

      myGLCD.print (rtc.getTimeStr (FORMAT_SHORT), RIGHT, 0);
      myGLCD.drawLine (0,8,83,8);
      myGLCD.drawLine (0,9,83,9);
      
      Строка тт;
      байт уу;
      для (байт J = menu_off; J <= мин (menu_off + 3, menu_item_count); j ++) {
        VY = 3 + 9 * (J-menu_off + 1);
        
        alertAdr = Offf + (J-1) * 4;
        BT = EEPROM.read (alertAdr + 1) & B00011111;
        тт = (String) (к) + "";
        если (Ь <10) {
          Tt = Т + "0";
        }
        Tt = Т + (String) Б.Т. + ":";
        
        BT = EEPROM.read (alertAdr + 2) & B00111111;
        если (Ь <10) {
          Tt = Т + "0";
        }
        Tt = Т + (String) BT + "";

      байт = EEPROM.read Б.Т. (alertAdr + 3);
      Переключатель (curLoad) {
        Случай 5: // "TimerLED"
          если (BT & B10000000) {
            Tt = Т + "WKL";
          } Еще {
            Tt = Т + "otkl";
          }  
        ломать;
        Случай 6: // "TimerUDO"
          Переключатель ((байт) ((Б.Т. >> 6) & B00000011)) {
            Случай 0: // Micro
              Tt = Т + "Микро";
            ломать;
            Случай 1: // Macro
              Tt = Т + "Макро";
            ломать;
            Случай 2: // Fe +
              Tt = Т + "Fe +";
            ломать;
            Случай 3: // Ка
              Tt = Т + "Ка";
            ломать;
          }
        ломать;
        по умолчанию:  
          если (Ь> 0) {
            Tt = Т + "WKL";
          } Еще {
            Tt = Т + "Otkl";
          }  
        ломать;
      }

// Тт = "Время" + (String) (j);
// Если (EEPROM.read (Offf + (J-1) * 4) & B10000000) {
// = Тт тт + "Активный";
//}        
        если (cur_item == J) {
          myGLCD.print (тт, 3, VY);
          myGLCD.drawRoundRect (0, уу-1,83, уу + 8);
        } еще  
          myGLCD.print (тт, 0, уу);

        // Перечеркиваем не активные таймера
        если (! (EEPROM.read (Offf + (J-1) * 4) & B10000000)) {
          myGLCD.drawLine (0, уу + 5,83, уу + 5);
        }        
          
      }

      Переключатель (ключ) {
        случай BUTTON_UP:
          если (cur_item == 1) { 
            cur_item = menu_item_count;
            menu_off = menu_item_count - 3;
          } Еще {  
            cur_item--;
            если (cur_item <menu_off) {
             menu_off = cur_item;
            }
          }  
        ломать;
        случай BUTTON_DOWN:
          если (cur_item == menu_item_count) { 
            cur_item = 1;
            menu_off = 1;
          } Еще {  
            cur_item ++;
            если (cur_item> menu_off + 3) {
             menu_off = cur_item-3;
            }
          }  
        ломать;
        случай BUTTON_OK:
          alertAdr = Offf + (cur_item-1) * 4;
          cur_menu = 1330;
          cur_item = 1;
          cur_item_edit = ложь;
        ломать;
        случай BUTTON_CANCEL:
          Переключатель (curLoad) {
           Случай 0:
             //"Классное время"
             cur_menu = 132;
             cur_item = 2;
           ломать;
           Дело 1:
             // "Light1",
             cur_menu = 130;
             cur_item = 1;
           ломать;
           Случай 2:
             // "Light2"
             cur_menu = 130;
             cur_item = 2;
           ломать;
           Случай 3:
             //"Воздух"
             cur_menu = 130;
             cur_item = 4;
           ломать;
           Случай 4:
             // "CO2"
             cur_menu = 134;
             cur_item = 1;
           ломать;
           Случай 5:
             //"СВЕТОДИОД"
             cur_menu = 130;
             cur_item = 3;
           ломать;
           Случай 6:
             //"ТЫ ДЕЛАЕШЬ"
             cur_menu = 134;
             cur_item = 2;
           ломать;
        }

          cur_item_edit = ложь;
        ломать;
      }
      myGLCD.update ();
      ломать;
    }
    Случай 1330: // zada`a Меню ----------------------------------------- ------------------------
    {
      myGLCD.setFont (SmallFont);
      myGLCD.clrScr ();
      
      Переключатель (curLoad) {
        Случай 0:
          myGLCD.print ( "nastroika", 1,0);
        ломать;
        Дело 1:
          myGLCD.print ( "swet1", 1,0);
        ломать;
        Случай 2:
          myGLCD.print ( "swet2", 1,0);
        ломать;
        Случай 3:
          myGLCD.print ( "wozduh", 1,0);
        ломать;
        Случай 4:
          myGLCD.print ( "CO2", 1,0);
        ломать;
        Случай 5:
          myGLCD.print ( "LED", 1,0);
        ломать;
        Случай 6:
          myGLCD.print ( "удо", 1,0);
        ломать;
      }

      myGLCD.print (rtc.getTimeStr (FORMAT_SHORT), RIGHT, 0);
      myGLCD.drawLine (0,8,83,8);
      myGLCD.drawLine (0,9,83,9);
      байт b1 = EEPROM.read (alertAdr);
      BT = b1;
      myGLCD.print ( "pnwtsr`tptsbws", 0,11);
      для (INT = 1; J <8; j ++) {
// Если ((cur_item == J) и cur_item_edit) {
        если (cur_item == J) {
          myGLCD.drawRect (J * 12-10,20, J * 12-2,28);
        }  
        myGLCD.drawCircle (J * 12-6,24,3);
        если (BT & B00000001) {
          myGLCD.drawCircle (J * 12-6,24,2);
          myGLCD.drawCircle (J * 12-6,24,1);
        }
        Ь = Ы >> 1;
      }
      Строка стат = "";
      если (cur_item == 8) {
        стат = стат + "[";
      }
      если (EEPROM.read (alertAdr) & B10000000) {
        стат = стат + "aktiw";
      } еще
        стат = стат + "пе aktiw";
      если (cur_item == 8) {
        стат = стат + "]";
      }

      стат = стат + ".";
      если (cur_item == 9) {
        стат = стат + "[";
      }
      байт TMPB = EEPROM.read (alertAdr + 3);
      Переключатель (curLoad) {
        Случай 5: // "TimerLED"
          если (TMPB & B10000000) {
            стат = стат + "WKL";
          } Еще {
            стат = стат + "Otkl";
          }  
          стат = стат + "" + (TMPB & B01111111) + "мин";
        ломать;
        Случай 6: // "TimerUDO"
          Переключатель ((байт) ((TMPB >> 6) & B00000011)) {
            Случай 0: // Micro
              стат = стат + "Микро";
            ломать;
            Случай 1: // Macro
              стат = стат + "Macro";
            ломать;
            Случай 2: // Fe +
              стат = стат + "Fe +";
            ломать;
            Случай 3: // Ка
              стат = стат + "Ка";
            ломать;
          }
          стат = стат + (TMPB & B00111111) + "мил";
        ломать;
        по умолчанию:  
          если (TMPB> 0) {
            стат = стат + "WKL";
          } Еще {
            стат = стат + "Otkl";
          }  
        ломать;
      }

      если (cur_item == 9) {
        стат = стат + "]";
      }
      myGLCD.print (стат, 0,29);
      
      стат = "wremq:";
      если (cur_item == 10) {
        стат = стат + "[";
      }
      BT = EEPROM.read (alertAdr + 1) & B00011111;
      если (Ь <10) {
        стат = стат + "0";
      }
      стат = стат + (String) Б.Т.;
      если (cur_item == 10) {
        стат = стат + "]";
      }

      стат = стат + ":";

      если (cur_item == 11) {
        стат = стат + "[";
      }
      BT = EEPROM.read (alertAdr + 2) & B00111111;
      если (Ь <10) {
        стат = стат + "0";
      }
      стат = стат + (String) Б.Т.;
      если (cur_item == 11) {
        стат = стат + "]";
      }
      myGLCD.print (стат, 0,39);

      Переключатель (ключ) {
        случай BUTTON_UP:
          если (cur_item_edit) {
            если ((cur_item == 9) && (curLoad> 4)) {
              BT = EEPROM.read (alertAdr + 3);
              // Если (== 255 BT) {
              // Ь = 0;
              //} Еще
                Б.Т. ++;
              EEPROM.write (alertAdr + 3, Ь);
            }
            если (cur_item == 10) {
              Ь = (EEPROM.read (alertAdr + 1) & B00011111);
              если (== 23 Ь) {
                Ь = 0;
              } еще
                Б.Т. ++;
              EEPROM.write (alertAdr + 1, Bt ^ (curLoad << 5));
            }
            если (cur_item == 11) {
              BT = EEPROM.read (alertAdr + 2) & B00111111;
              если (== 59 Ь) {
                Ь = 0;
              } еще
                Б.Т. ++;
              EEPROM.write (alertAdr + 2, Ь);
            }
          } еще
            если (cur_item == 1) { 
              cur_item = 11;
            } еще  
              cur_item--;
        ломать;
        случай BUTTON_DOWN:
          если (cur_item_edit) {
            если ((cur_item == 9) && (curLoad> 4)) {
              BT = EEPROM.read (alertAdr + 3);
              // Если (Ь == 0) {
              // Б.Т. = 255;
              //} Еще
                bt--;
              EEPROM.write (alertAdr + 3, Ь);
            }
            если (cur_item == 10) {
              BT = EEPROM.read (alertAdr + 1) & B00011111;
              если (Ь == 0) {
                BT = 23;
              } еще
                bt--;
              EEPROM.write (alertAdr + 1, Bt ^ (curLoad << 5));
            }
            если (cur_item == 11) {
              BT = EEPROM.read (alertAdr + 2) & B00111111;
              если (Ь == 0) {
                BT = 59;
              } еще
                bt--;
              EEPROM.write (alertAdr + 2, Ь);
            }
          } еще
            если (cur_item == 11) { 
              cur_item = 1;
            } еще  
              cur_item ++;
        ломать;
        случай BUTTON_OK:
          EEPROM.write (alertAdr + 1, ((EEPROM.read (alertAdr + 1) & B00011111) ^ (curLoad << 5))); // Сохраняем номер нагрузки
          Переключатель (cur_item) {
            Случай 8:
              EEPROM.write (alertAdr, (EEPROM.read (alertAdr) ^ B10000000));
            ломать;
            Случай 9:
              если (curLoad <5) {
                //EEPROM.write(alertAdr+3,(EEPROM.read(alertAdr+3)^B00000001));
                EEPROM.write (alertAdr + 3, ((EEPROM.read (alertAdr + 3) & B00000001) ^ B00000001));
              } Еще {
                cur_item_edit = cur_item_edit!;
              }  
            ломать;
            Случай 10:
              cur_item_edit = cur_item_edit!;
            ломать;
            Случай 11:
              cur_item_edit = cur_item_edit!;
            ломать;
            по умолчанию:
              EEPROM.write (alertAdr, (EEPROM.read (alertAdr) ^ (1 << (cur_item-1))));
            ломать;
          }
        ломать;
         случай BUTTON_CANCEL:
          Переключатель (curLoad) {
           Случай 0:
             //Классное время
             cur_menu = 132;
             cur_item = 2;
           ломать;
           Дело 1:
             // "Light1",
             cur_menu = 130;
             cur_item = 1;
           ломать;
           Случай 2:
             // "Light2"
             cur_menu = 130;
             cur_item = 2;
           ломать;
           Случай 3:
             //"Воздух"
             cur_menu = 130;
             cur_item = 4;
           ломать;
           Случай 4:
             // "CO2"
             cur_menu = 134;
             cur_item = 1;
           ломать;
           Случай 5:
             //"СВЕТОДИОД"
             cur_menu = 130;
             cur_item = 3;
           ломать;
           Случай 6:
             //"ТЫ ДЕЛАЕШЬ"
             cur_menu = 134;
             cur_item = 2;
           ломать;
         }
          cur_item_edit = ложь;
        ломать;
      }
      myGLCD.update ();
      ломать;
    }
    Случай 132: // -------------------------------------------- Термостат ---------------------
    {
      drawMenu ( "Термостат", "temp.woda [" + (String) aquaT + "]", "went.wremq", "min.skor", "maks.skor");
      NaViKey (4);
      Переключатель (ключ) {
        случай BUTTON_OK:
          Переключатель (cur_item) {
            Дело 1:
              cur_menu = 1321;      
              cur_item = 0;
            ломать;
            Случай 2: // CoolTime
              cur_menu = 133;      
              cur_item = 1;
              menu_off = 1;
              menu_item_count = 8;
              curLoad = 0;
            ломать;
            Случай 3: // minCool // минимальные обороты кулера для вентиляции крышки и охлаждения ламп
              cur_menu = 1323;      
            ломать;
            Случай 4: // maxCool // максимальные обороты для охлаждения воды
              cur_menu = 1324;      
            ломать;
          }
        ломать;
        случай BUTTON_CANCEL:
          cur_menu = 13;
          cur_item = 2;
          cur_item_edit = ложь;
        ломать;
      }
      ломать;
    }
    Случай 1321: // Аква Температура ------------------------------------------- ----------------------
    {
      drawIntMenu ( "maks.temp.woda", 18,35, aquaT);
      Переключатель (ключ) {
        случай BUTTON_UP:
          aquaT ++;
          aquaT = мин (aquaT, 35);
        ломать;
        случай BUTTON_DOWN:
          aquaT--;
          aquaT = макс (aquaT, 18);
        ломать;
        случай BUTTON_OK:
          EEPROM.write (2, aquaT); // Требуемая температура воды
          cur_menu = 132;
          cur_item = 1;
        ломать;
        случай BUTTON_CANCEL:
          aquaT = EEPROM.read (2); // Требуемая температура воды
          cur_menu = 132;
          cur_item = 1;
        ломать;
      }
      ломать;
    }
    Случай 1323: // min.skor // минимальные обороты кулера для вентиляции крышки и охлаждения ламп ------------------------------- -----------
    {
      drawIntMenu ( "min.skor", 0, maxCool, minCool);
      Переключатель (ключ) {
        случай BUTTON_UP:
          minCool ++;
          minCool = мин (minCool, maxCool);
          analogWrite (EXT_COOLING_PIN, minCool);
        ломать;
        случай BUTTON_DOWN:
          minCool--;
          minCool = макс (minCool, 0);
          analogWrite (EXT_COOLING_PIN, minCool);
        ломать;
        случай BUTTON_OK:
          EEPROM.write (3, minCool); // Минимальные обороты кулера для вентиляции крышки и охлаждения ламп
          cur_menu = 132;
          cur_item = 3;
        ломать;
        случай BUTTON_CANCEL:
          minCool = EEPROM.read (3); // Минимальные обороты кулера для вентиляции крышки и охлаждения ламп
          cur_menu = 132;
          cur_item = 3;
        ломать;
      }
      ломать;
    }
    Случай 1324: // maks.skor // максимальные обороты для охлаждения воды ----------------------------------- -------
    {
      drawIntMenu ( "maks.skor", 0255, maxCool);
      Переключатель (ключ) {
        случай BUTTON_UP:
          maxCool ++;
          maxCool = мин (maxCool, 255);
          analogWrite (EXT_COOLING_PIN, maxCool);
        ломать;
        случай BUTTON_DOWN:
          maxCool--;
          maxCool = макс (maxCool, minCool);
          analogWrite (EXT_COOLING_PIN, maxCool);
        ломать;
        случай BUTTON_OK:
          EEPROM.write (4, maxCool); // Максимальные обороты для охлаждения воды
          cur_menu = 132;
          cur_item = 4;
        ломать;
        случай BUTTON_CANCEL:
          maxCool = EEPROM.read (4); // Максимальные обороты для охлаждения воды
          cur_menu = 132;
          cur_item = 4;
        ломать;
      }
      ломать;
    }
    Дело 131: // nastroika сисьтема ------------------------------------------- ----------------------
    {
      drawMenu ( "Sistema", "wremq", "данные", "Индик.точки Kontrast", "Displ qrkostx");
      NaViKey (4);
      Переключатель (ключ) {
        случай BUTTON_OK:
          Переключатель (cur_item) {
            Дело 1:
              cur_menu = 1311;      
              cur_item = 0;
              menu_hh = time.hour;
              menu_mi = time.min;
            ломать;
            Случай 2:
              cur_menu = 1312;      
              cur_item = 0;
              menu_dd = time.date;
              menu_mm = time.mon;
              menu_yyyy = time.year;
              menu_dow = time.dow;
            ломать;
            Случай 3:
              cur_menu = 1313;      
              cur_item = 0;
            ломать;
            Случай 4:
              cur_menu = 1314;      
              cur_item = 0;
            ломать;
          }
        ломать;
        случай BUTTON_CANCEL:
          cur_menu = 0;
          cur_item = 0;
        ломать;
      }
      ломать;
    }
    Случай 1311: // Время -------------------------------------------- ---------------------
    {
      myGLCD.setFont (SmallFont);
      myGLCD.clrScr ();
  
      myGLCD.print ( "wremq", 1,0);
      myGLCD.print (rtc.getTimeStr (FORMAT_SHORT), RIGHT, 0);
      myGLCD.drawLine (0,8,83,8);
      myGLCD.drawLine (0,9,83,9);
      если ((cur_item == 1) && cur_item_edit) 
        myGLCD.invertText (истина);
      myGLCD.printNumI (menu_hh, 26,20,2, '0');
      myGLCD.invertText (ложь);
      myGLCD.print ( ":", 39,20);
      если ((cur_item == 2) && cur_item_edit) 
        myGLCD.invertText (истина);
      myGLCD.printNumI (menu_mi, 46,20,2, '0');
      myGLCD.invertText (ложь);

      если (cur_item == 1)
        myGLCD.drawRoundRect (25,18,39,28);
      если (cur_item == 2)
        myGLCD.drawRoundRect (45,18,59,28);

      Переключатель (ключ) {
        случай BUTTON_UP:
          если (! cur_item_edit) { 
            cur_item--;
            если (cur_item <1)
              cur_item = 2;
          } Еще {
            если (cur_item == 1) {
              menu_hh ++;
              если (menu_hh == 24)
                menu_hh = 0;
            }
            если (cur_item == 2) {
              menu_mi ++;
              если (menu_mi == 60)
                menu_mi = 0;
            }
          }
        ломать;
        случай BUTTON_DOWN:
          если (! cur_item_edit) { 
            cur_item ++;
            если (cur_item> 2)
              cur_item = 1;
          } Еще {
            если (cur_item == 1) {
              если (menu_hh == 0)
                menu_hh = 23;
              еще  
                menu_hh--;
            }
            если (cur_item == 2) {
              если (menu_mi == 0)
                menu_mi = 59;
              еще
                menu_mi--;
            }
          }
        ломать;
        случай BUTTON_OK:
          если (cur_item_edit) { 
            Переключатель (cur_item) {
              Дело 1:
                rtc.setTime (menu_hh, time.min, 0); // Установите время 12:00:00 (формат 24 часа)
              ломать;
              Случай 2:
                rtc.setTime (time.hour, menu_mi, 0); // Установите время 12:00:00 (формат 24 часа)
              ломать;
            }
            cur_item_edit = ложь;
          } еще 
            cur_item_edit = TRUE;
        ломать;
        случай BUTTON_CANCEL:
          cur_item_edit = ложь;
          cur_menu = 131;      
          cur_item = 1;
        ломать;
      }
      myGLCD.update ();
      ломать;
    }
    Случай 1312: // -------------------------------------------- данные ---------------------
    {
      myGLCD.setFont (SmallFont);
      myGLCD.clrScr ();
  
      myGLCD.print ( "данные", 1,0);
      myGLCD.print (rtc.getTimeStr (FORMAT_SHORT), RIGHT, 0);
      myGLCD.drawLine (0,8,83,8);
      myGLCD.drawLine (0,9,83,9);

      если ((cur_item == 1) && cur_item_edit) 
        myGLCD.invertText (истина);
      myGLCD.printNumI (menu_dd, 12,20,2, '0');
      myGLCD.invertText (ложь);

      myGLCD.print (, 24,20 ".");

      если ((cur_item == 2) && cur_item_edit) 
        myGLCD.invertText (истина);
      myGLCD.printNumI (menu_mm, 30,20,2, '0');
      myGLCD.invertText (ложь);

      myGLCD.print (, 42,20 ".");

      если ((cur_item == 3) && cur_item_edit) 
        myGLCD.invertText (истина);
      myGLCD.printNumI (menu_yyyy, 48,20,4, '0');
      myGLCD.invertText (ложь);

      myGLCD.print ( "denx недели», 0,32);
      если ((cur_item == 4) && cur_item_edit) 
        myGLCD.invertText (истина);
      myGLCD.printNumI (menu_dow, 68,32);
      myGLCD.invertText (ложь);

      Переключатель (cur_item) {
        Дело 1:
          myGLCD.drawRoundRect (11,18,25,28);
        ломать;  
        Случай 2:
          myGLCD.drawRoundRect (29,18,44,28);
        ломать;  
        Случай 3:
          myGLCD.drawRoundRect (47,18,73,28);
        ломать;  
        Случай 4:
          myGLCD.drawRoundRect (67,30,75,40);
        ломать;  
      }  

      Переключатель (ключ) {
        случай BUTTON_UP:
          если (! cur_item_edit) { 
            cur_item--;
            если (cur_item <1)
              cur_item = 4;
          } Еще {
            если (cur_item == 1) {
              menu_dd ++;
              если (menu_dd> 31)
                menu_dd = 1;
            }
            если (cur_item == 2) {
              menu_mm ++;
              если (menu_mm> 12)
                menu_mm = 1;
            }
            если (cur_item == 3) {
              menu_yyyy ++;
            }
            если (cur_item == 4) {
              menu_dow ++;
              если (menu_dow> 7)
                menu_dow = 1;
            }
          }
        ломать;
        случай BUTTON_DOWN:
          если (! cur_item_edit) { 
            cur_item ++;
            если (cur_item> 4)
              cur_item = 1;
          } Еще {
            если (cur_item == 1) {
                menu_dd--;
              если (menu_dd <1)
                menu_dd = 31;
            }
            если (cur_item == 2) {
                menu_mm--;
              если (menu_mm <1)
                menu_mm = 12;
            }
            если (cur_item == 3) {
                menu_yyyy--;
                menu_yyyy = макс (menu_yyyy, 2013);
            }
            если (cur_item == 4) {
                menu_dow--;
              если (menu_dow <1)
                menu_dow = 7;
            }
          }
        ломать;
        случай BUTTON_OK:
          если (cur_item_edit) { 
            Переключатель (cur_item) {
              Дело 1:
                rtc.setDate (menu_dd, time.mon, time.year); // Назначить дату
              ломать;
              Случай 2:
                rtc.setDate (time.date, menu_mm, time.year); // Назначить дату
              ломать;
              Случай 3:
                rtc.setDate (time.date, time.mon, menu_yyyy); // Назначить дату
              ломать;
              Случай 4:
                 rtc.setDOW (menu_dow); // Установить день-недели
              ломать;
            }
            cur_item_edit = ложь;
          } еще 
            cur_item_edit = TRUE;
        ломать;
        случай BUTTON_CANCEL:
          cur_item_edit = ложь;
          cur_menu = 131;      
          cur_item = 2;
        ломать;
      }
      myGLCD.update ();
      ломать;
    }
    Случай 1313: // SWET Kontrast ------------------------------------------- ----------------------
    {
      drawIntMenu ( "Displ Kontrast", 45,80, ledContrast);
      Переключатель (ключ) {
        случай BUTTON_UP:
          ledContrast ++;
          ledContrast = мин (ledContrast, 80);
        ломать;
        случай BUTTON_DOWN:
          ledContrast--;
          ledContrast = макс (ledContrast, 45);
        ломать;
        случай BUTTON_OK:
          EEPROM.write (0, ledContrast);
          cur_menu = 131;
          cur_item = 3;
        ломать;
        случай BUTTON_CANCEL:
          ledContrast = EEPROM.read (0);
          cur_menu = 131;
          cur_item = 3;
        ломать;
      }
      myGLCD.setContrast (ledContrast);  
      ломать;
    }
    Случай 1314: // SWET qrkostx ------------------------------------------- ----------------------
    {
      drawIntMenu ( "Displ qrkostx", 0255, LEDLIGHT);
      Переключатель (ключ) {
        случай BUTTON_UP:
          LEDLIGHT ++;
          LEDLIGHT = мин (LEDLIGHT, 255);
        ломать;
        случай BUTTON_DOWN:
          светодиодный--;
          LEDLIGHT = макс (LEDLIGHT, 0);
        ломать;
        случай BUTTON_OK:
          EEPROM.write (1, LEDLIGHT);
          cur_menu = 131;
          cur_item = 4;
        ломать;
        случай BUTTON_CANCEL:
          LEDLIGHT = EEPROM.read (1);
          cur_menu = 131;
          cur_item = 4;
        ломать;
      }
      analogWrite (LED_LIGHT_PIN, LEDLIGHT);
      ломать;
    }

    по умолчанию:
      cur_menu = 0;
      cur_item = 0;
  }
 
LOOPTIME = CURRENTTIME;   
}  
}

 

Spiker
Offline
Зарегистрирован: 18.06.2016

Помогите добавить в строчке 0422

чтобы включалось и работало при условии  digitalWrite (EXT_CO2_PIN, LOW)

 

bwn
Offline
Зарегистрирован: 25.08.2014

Хм, стесняюсь спросить, а что за версия IDE? И она таки сама переводит или со словарем приходится?

Spiker
Offline
Зарегистрирован: 18.06.2016

Она не переводит походу когда закидывал браузер перевёл

Витенька
Offline
Зарегистрирован: 03.04.2016

[quote=Spiker]

Собрал контроллер для аквариума с сайта 
http://www.aquaforum.ua/showthread.php?t=175844
немного доработал./quote]

Здравствуйте Уважаемый! У Вас с этим кодом рассвет/закат задействован, работает? У меня по изначально приведенной схеме почему то поступенчато работает и рассвет и закат, это так и должно быть, и ещё, при уменьшении времени длительности рассвета и заката сдвигается начальный запуск процесса, начало рассвета начинается не с наименьшего свечения диодов а где то примерно со среднего, почему так?

Spiker
Offline
Зарегистрирован: 18.06.2016

 

 Добрый день . Нет я рассвет и закатом не пользуюсь.

Витенька
Offline
Зарегистрирован: 03.04.2016

Печально. Я сначала тоже не использовал а теперь вот хотел замутить и столкнулся с непонятками такими.

Spiker
Offline
Зарегистрирован: 18.06.2016

Spiker пишет:

Помогите добавить в строчке 0422

чтобы включалось и работало при условии  digitalWrite (EXT_CO2_PIN, LOW)

 

Разобрался добавил

   if (digitalRead (EXT_CO2_PIN) == LOW)  // Разрёшён налив при включеной подмене

Получилочсь вот так,  при вклёчёной подмене включается налив и наливает воду в пределах больше и меньше установленной на 3 градуса вот код :

if (digitalRead (EXT_CO2_PIN) == LOW)   // Разрешён налив при условии включеной подмене
   
  if(cur_temp > ((float)aquaT-3.0)&& cur_temp < ((float)aquaT+3.0)){    // Разрешён налив от -3  до + 3 градусов от установленного значения
     
   digitalWrite(EXT_NALIV_PIN,LOW );  // включает налив
   }else     
  digitalWrite(EXT_NALIV_PIN,HIGH );   // выключает налив
      

 

Витенька
Offline
Зарегистрирован: 03.04.2016

Здравствуйте Уважаемые Гуру Ардуино! Может ли кто помочь с реализацией рассвета/заката в этом коде, вроде бы работает но как то не совсем так как хотелось бы?  Нюансы, сразу после загрузки кода в ардуину в настройках рассвета/заката стои время 127 минут на рассвет и столько же на закат, как по мне многовато даже в природных измерениях, при уменьшении времени рассвета/заката старт рассвета начинается заметно ярче чем с временем 127 минут и сам процесс рассвета/заката проходит как то ступенчаторывками а не плавно. Где проблема, в коде, в схеме, были предположения на то что так срабатывает мосфет, типа нужен другой какой то драйвер для плавного прохождения рассвета/заката?

arDubino
Offline
Зарегистрирован: 12.01.2017

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

Витенька
Offline
Зарегистрирован: 03.04.2016

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

MVN123P
Offline
Зарегистрирован: 29.07.2016

Витенька пишет:

Здравствуйте Уважаемые Гуру Ардуино! Может ли кто помочь с реализацией рассвета/заката в этом коде, вроде бы работает но как то не совсем так как хотелось бы?  Нюансы, сразу после загрузки кода в ардуину в настройках рассвета/заката стои время 127 минут на рассвет и столько же на закат, как по мне многовато даже в природных измерениях, при уменьшении времени рассвета/заката старт рассвета начинается заметно ярче чем с временем 127 минут и сам процесс рассвета/заката проходит как то ступенчаторывками а не плавно. Где проблема, в коде, в схеме, были предположения на то что так срабатывает мосфет, типа нужен другой какой то драйвер для плавного прохождения рассвета/заката?

Посмотрите здесь. Может в скетчах найдете. Я эти контроллеры собирал, закат - рассвет работает нормально. Во второй схеме закат-рассвет регулируется с шагом в 1 минуту.

http://arduino.ru/forum/proekty/mnogokanalnyi-taimer-upravleniya-osveshc...

bwn
Offline
Зарегистрирован: 25.08.2014

Живой проект, с двумя каналами света и прочими приблудами. 282 пост, если что.

Витенька
Offline
Зарегистрирован: 03.04.2016

Спасибо Большое за рекомендации! В том то и дело что контроллеры по сылке из первого поста давно уже работают, не делать же другие из-за одной прихоти, всё вполне устраивает, добавил к нему уже и кормушку и на время кормления фильтр сам останавливается, теперь захотелось свет немного переделать за одно думал рассвет/закат задействовать а оно что то не заработало нормально. MVN123P Вы говорите димирование работает с шагом в одну минуту, в смысле оно так и есть типа пошаговое включение отключение? У меня тоже так же идёт, только по умолчанию в настройках стоит время на рассвет 127 минут и столько же на закат, многовато мне сдается, а при уменьшении этого времени старт начинается примерно с средней яркости свечения светодиодов, правда и при том времени что изначально стоит в настройках тоже не с нуля так сказать начинается засвечивание светодиодов. Мне бы кто подсказал где в коде подкорректировать эту лажу с временем и яркостью стартового свечения, arDubino намек сделал что можно что то сделать.

MVN123P
Offline
Зарегистрирован: 29.07.2016

Время заката и рассвета выставляется выучную - кнопками, так же выставляется продолжительность заката или рассвета (т.е. 1 минута имеется ввиду минимальное значение 1,2,3,4,5 и.т.д). Еще выставляется яркость (power) начальная и конечная в %. т.е. Например нужно в 19:00 выключить освещение в течении 10 минут(закат), но полностью его не выключать - оставить 10%(power night)(см.фото).

Ну както так.

p/s Я советовал не бросаться собирать новый контроллер а подсмотреть в скетче как это реализовано у других.

Витенька
Offline
Зарегистрирован: 03.04.2016

Яркость там не выставляется, в настройке устанавливается время начала рассвета и его продолжительность и так же с закатом, только если я ставлю 1 час продолжительность рассвета то старт начинается уже с яркого свечения, о ещё нижшем пределе времени и говорить нечего светодиоды загораются сразу ярко но не на полную мощность какой то промежуток рассвета всё же продолжается дальше.

Витенька
Offline
Зарегистрирован: 03.04.2016

MVN123P Можно узнать параметры оптопары которую Вы применяли?

MVN123P
Offline
Зарегистрирован: 29.07.2016

PC817C 

http://www.farnell.com/datasheets/73758.pdf

Применяется в импульсных БП (почти во всех БП АТХ)

Как же не выставляется?

Витенька
Offline
Зарегистрирован: 03.04.2016

То тоя и думаю что мы не понимаем друг друга. У меня контроллеры из форума сылка на котрый находится в первом посте этой темы.

Витенька
Offline
Зарегистрирован: 03.04.2016
Spiker
Offline
Зарегистрирован: 18.06.2016

Spiker пишет:

Spiker пишет:

Помогите добавить в строчке 0422

чтобы включалось и работало при условии  digitalWrite (EXT_CO2_PIN, LOW)

 

Разобрался добавил

   if (digitalRead (EXT_CO2_PIN) == LOW)  // Разрёшён налив при включеной подмене

Получилочсь вот так,  при вклёчёной подмене включается налив и наливает воду в пределах больше и меньше установленной на 3 градуса вот код :

if (digitalRead (EXT_CO2_PIN) == LOW)   // Разрешён налив при условии включеной подмене
   
  if(cur_temp > ((float)aquaT-3.0)&& cur_temp < ((float)aquaT+3.0)){    // Разрешён налив от -3  до + 3 градусов от установленного значения
     
   digitalWrite(EXT_NALIV_PIN,LOW );  // включает налив
   }else     
  digitalWrite(EXT_NALIV_PIN,HIGH );   // выключает налив
      

 

Помогите  добавил в код условие на разрешение налива при условии включёной функции в меню CO2

работал налив в пределах от -3 до +3 градусов .  Но работал  не долго .

Теперь работает так , наливает только при СО2 ок   СО2 оff перестаёт наливать , но теперь  не выполняет функцию в пределах установленной температуре.

if(cur_temp > ((float)aquaT-3.0)&& cur_temp < ((float)aquaT+3.0)){    // Разрешён налив от -3  до + 3 градусов от установленного значения

Что может быть не так прописано в коде.