Ошибка компиляции для платы ардуино uno

by Matthew Adams

Matthew is a freelancer who has produced a variety of articles on various topics related to technology. His main focus is the Windows OS and all the things… read more


Updated on January 18, 2023

  • Seeing the Error compiling for board Arduino/Genuino Uno message is not nice, but this guide should prove helpful.
  • To start the resolution of this issue, ensure that you selected the right board, and follow the next indications.
  • For more useful guides on this topic, don’t hesitate to visit our Developer Tools section.
  • To always be on top of any Arduino error message, bookmark our Arduino Errors Hub.

XINSTALL BY CLICKING THE DOWNLOAD FILE

To fix various PC problems, we recommend DriverFix:
This software will keep your drivers up and running, thus keeping you safe from common computer errors and hardware failure. Check all your drivers now in 3 easy steps:

  1. Download DriverFix (verified download file).
  2. Click Start Scan to find all problematic drivers.
  3. Click Update Drivers to get new versions and avoid system malfunctionings.
  • DriverFix has been downloaded by 0 readers this month.

The Arduboy is a small, portable game console with a similar design to the Nintendo Game Boy. It is a game console based on the Arduino board designs, which include Arduino/Genuino Uno.

Users can connect their Arduboys with Windows PCs to upload games to them with the Arduino IDE (Integrated Developer Environment) software.

However, some users have posted on the Arduboy support forum about an Error compiling for board Arduino/Genuino Uno issue.

That error arises when users try to upload a game (otherwise sketch) to the Arduboy with the Arduino IDE software. Consequently, users can’t upload games to their Arduboy when that error arises.

What can I do about the compiling for board Arduino/Genuino Uno error?

1. Make sure you’ve selected the right Arduino board

  1. The Error compiling for board Arduino/Genuino Uno issue can arise when users haven’t selected the right board design within Arduino IDE. To select the correct board, click the Tools menu in the Arduino IDE software.
  2. Then select Board to open the menu shown directly below.
    The Tools menu error compiling for board arduino/genuino uno
  3. Select Arduino/Genuino Uno if that’s not currently selected.

2. Install missing Arduboy libraries

  1. The Error compiling for board Arduino/Genuino Uno error is often due to missing Arduboy libraries needed by the games. To install missing Arduboy libraries, click the Sketch menu.
  2. Then select Include Library to open the menu in the snapshot directly below.
    The Sketch menu error compiling for board arduino/genuino uno
  3. Click Manage Libraries to open the window shown directly below.
    Library Manager error compiling for board arduino/genuino uno
  4. To search for Arduboy libraries, enter the keyword Arduboy in the search box.
  5. Make sure all the Arduboy libraries listed below are installed:
    Arduboy
    ArduboyTones
    Arduboy2
    AdruboyPlaytune
    ArdVoice 469
    ArdBitmap
    ATMlib
    FixedPointsArduino
    Arduboy-TinyFont
    U8GLIB
  6. You can install selected libraries by clicking the More info links and Install buttons for them. Select the latest versions of the libraries on their drop-down menus.
    The Install button error compiling for board arduino/genuino uno
  7. Click the Close button when you’ve installed all missing Arduboy libraries.

3. Reinstall the Adruino IDE software

  1. Some users might need to reinstall the Adruino IDE software to resolve the compiling for board Arduino/Genuino Uno error. First, open File Explorer in Windows.
  2. If you’re utilizing Arduino IDE 1.6.6 or later, open this path in Explorer: C:/Users(username)/AppData/Local /Arduino15.
  1. Users with Arduino IDE 1.6.5r5 or previous should open this folder: C:/Users (username)/AppData/Roaming/Arduino15.
  1. Select the Adruino15 folder, and press the Delete button.
  2. Next, open Run’s window by pressing the Windows key + R hotkey.
  3. Enter appwiz.cpl in the Open box, and click the OK button.
    Programs and Features window error compiling for board arduino/genuino uno
  4. Select Arduino in the Programs and Features window.
  5. Click the Uninstall option.
  6. If an uninstall prompt opens, click the Yes button on it.
  7. Restart Windows before you reinstall Arduino.
  8. Click the Windows app on the Arduino website. Then click the Just Download option.
  9. Thereafter, reinstall the Arduino IDE software. Note that you’ll also need reinstall boards with the Board Manager.

Those are three ways users can fix Error compiling for board Arduino/Genuino Uno error. With that issue fixed, you can then play Arduboy games.

newsletter icon

СОДЕРЖАНИЕ ►

  • Произошла ошибка при загрузке скетча в Ардуино
    • programmer is not responding
    • a function-definition is not allowed arduino ошибка
    • expected initializer before ‘}’ token arduino ошибка
    • ‘что-то’ was not declared in this scope arduino ошибка
    • No such file or directory arduino ошибка
  • Compilation error: Missing FQBN (Fully Qualified Board Name)

Ошибки компиляции Arduino IDE возникают при проверке или загрузке скетча в плату, если код программы содержит ошибки, компилятор не может найти библиотеки или переменные. На самом деле, сообщение об ошибке при загрузке скетча связано с невнимательностью самого программиста. Рассмотрим в этой статье все возможные ошибки компиляции для платы Ардуино UNO R3, NANO, MEGA и пути их решения.

Произошла ошибка при загрузке скетча Ардуино

Самые простые ошибки возникают у новичков, кто только начинает разбираться с языком программирования Ардуино и делает первые попытки загрузить скетч. Если вы не нашли решение своей проблемы в статье, то напишите свой вопрос в комментариях к этой записи и мы поможем решить вашу проблему с загрузкой (бесплатно!).

avrdude: stk500_recv(): programmer is not responding

Что делать в этом случае? Первым делом обратите внимание какую плату вы используете и к какому порту она подключена (смотри на скриншоте в правом нижнем углу). Необходимо сообщить Arduino IDE, какая плата используется и к какому порту она подключена. Если вы загружаете скетч в Ардуино Nano V3, но при этом в настройках указана плата Uno или Mega 2560, то вы увидите ошибку, как на скриншоте ниже.

Ошибка: programmer is not responding

Ошибка Ардуино: programmer is not responding

Такая же ошибка будет возникать, если вы не укажите порт к которому подключена плата (это может быть любой COM-порт, кроме COM1). В обоих случаях вы получите сообщение — плата не отвечает (programmer is not responding). Для исправления ошибки надо на панели инструментов Arduino IDE в меню «Сервис» выбрать нужную плату и там же, через «Сервис» → «Последовательный порт» выбрать порт «COM7».

a function-definition is not allowed here before ‘{‘ token

Это значит, что в скетче вы забыли где-то закрыть фигурную скобку. Синтаксические ошибки IDE тоже распространены и связаны они просто с невнимательностью. Такие проблемы легко решаются, так как Arduino IDE даст вам подсказку, стараясь отметить номер строки, где обнаружена ошибка. На скриншоте видно, что строка с ошибкой подсвечена, а в нижнем левом углу приложения указан номер строки.

Ошибка: a function-definition is not allowed

Ошибка: a function-definition is not allowed here before ‘{‘ token

expected initializer before ‘}’ token   expected ‘;’ before ‘}’ token

Сообщение expected initializer before ‘}’ token говорит о том, что вы, наоборот где-то забыли открыть фигурную скобку. Arduino IDE даст вам подсказку, но если скетч довольно большой, то вам придется набраться терпения, чтобы найти неточность в коде. Ошибка при компиляции программы: expected ‘;’ before ‘}’ token говорит о том, что вы забыли поставить точку с запятой в конце командной строки.

‘что-то’ was not declared in this scope

Что за ошибка? Arduino IDE обнаружила в скетче слова, не являющиеся служебными или не были объявлены, как переменные. Например, вы забыли продекларировать переменную или задали переменную ‘DATA’, а затем по невнимательности используете ‘DAT’, которая не была продекларирована. Ошибка was not declared in this scope возникает при появлении в скетче случайных или лишних символов.

Ошибка Ардуино: was not declared in this scope

Ошибка Ардуино: was not declared in this scope

Например, на скриншоте выделено, что программист забыл продекларировать переменную ‘x’, а также неправильно написал функцию ‘analogRead’. Такая ошибка может возникнуть, если вы забудете поставить комментарий, написали функцию с ошибкой и т.д. Все ошибки также будут подсвечены, а при нескольких ошибках в скетче, сначала будет предложено исправить первую ошибку, расположенную выше.

exit status 1 ошибка компиляции для платы Arduino

Данная ошибка возникает, если вы подключаете в скетче библиотеку, которую не установили в папку libraries. Например, не установлена библиотека ИК приемника Ардуино: fatal error: IRremote.h: No such file or directory. Как исправить ошибку? Скачайте нужную библиотеку и распакуйте архив в папку C:Program FilesArduinolibraries. Если библиотека установлена, то попробуйте скачать и заменить библиотеку на новую.

exit status 1 Ошибка компиляции для Arduino Nano

exit status 1 Ошибка компиляции для платы Arduino Nano

Довольно часто у новичков выходит exit status 1 ошибка компиляции для платы arduino uno /genuino uno. Причин данного сообщения при загрузке скетча в плату Arduino Mega или Uno может быть огромное множество. Но все их легко исправить, достаточно внимательно перепроверить код программы. Если в этом обзоре вы не нашли решение своей проблемы, то напишите свой вопрос в комментариях к этой статье.

missing fqbn (fully qualified board name)

Ошибка возникает, если не была выбрана плата. Обратите внимание, что тип платы необходимо выбрать, даже если вы не загружаете, а, например, делаете компиляцию скетча. В Arduino IDE 2 вы можете использовать меню выбора:
— список плат, которые подключены и были идентифицированы Arduino IDE.
— или выбрать плату и порт вручную, без подключения микроконтроллера.

Одна из самых неприятных ошибок — это ошибка компиляции для платы Аrduino Nano, с которой вам придется столкнуться не раз.

Содержание

  • Синтаксические ошибки
  • Ошибки компиляции плат Arduino uno
  • Ошибка exit status 1 при компиляции для плат uno, mega и nano
  • Ошибки библиотек
  • Ошибки компилятора Ардуино
  • Основные ошибки
    • Ошибка: «avrdude: stk500_recv(): programmer is not responding»
    • Ошибка: «a function-definition is not allowed here before ‘{‘ token»
    • Ошибка: «No such file or directory  /  exit status 1»
    • Ошибка: «expected initializer before ‘}’ token  /  expected ‘;’ before ‘}’ token»
    • Ошибка: «… was not declared in this scope»

Синтаксические ошибки

Ардуино – одна из наиболее комфортных сред для начинающих инженеров, в особенности программистов, ведь им не приходится проектировать свои системы управления и делать множество других действий.

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

Но и здесь не избежать множества проблем, с которыми знаком каждый программист, и одна из самых неприятных – ошибка компиляции для платы Аrduino nano, с которой вам придется столкнуться не раз. Что же эта строчка означает, какие у неё причины появления, и главное – как быстро решить данную проблему?

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

Как несложно догадаться, компиляция – приведение кода на языке Си к виду машинного (двоичного) и преобразование множественных функций в простые операции, чтобы те смогли выполняться через встроенные операнды процессора. Выглядит всё достаточно просто, но сам процесс компиляции происходит значительно сложнее, и поэтому ошибка во время проведения оной может возникать по десяткам причин.

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

Мы узнали, к чему приводит данный процесс, давайте разберёмся, как он происходит:

  1. Первое, что делает компилятор – подгружает все инклуднутые файлы, а также меняет объявленные дефайны на значения, которое для них указано. Это необходимо затем, чтобы не нужно было по нескольку раз проходиться синтаксическим парсером в пределах одного кода. Также, в зависимости от среды, компилятор может подставлять функции на место их объявления или делать это уже после прохода синтаксическим парсером. В случае с С99, используется второй вариант реализации, но это и не столь важно.
  2. Далее он проверяет первичный синтаксис. Этот процесс проводится в изначальном компилируемом файле, и своеобразный парсер ищет, были ли описаны приведенные функции ранее, подключены ли необходимые библиотеки и прочее. Также проверяется правильность приведения типов данных к определенным значениям. Не стоит забывать, что в С99 используется строгая явная типизация, и вы не можете засунуть в строку, объявленную integer, какие-то буквенные значения. Если такое замечается, сразу вылетает ошибка.
  3. В зависимости от среды разработки, иногда предоставляется возможность последний раз протестировать код, который сейчас будет компилироваться, с запуском интерпретатора соответственно.
  4. Последним идет стек из различных действий приведения функций, базовых операнд и прочего к двоичному коду, что может занять какое-то время. Также вся структура файлов переносится в исполняемые exe-шники, а затем происходит завершение компиляции.

Как можно увидеть, процесс не так прост, как его рисуют, и на любом этапе может возникнуть какая-то ошибка, которая приведет к остановке компиляции. Проблема в том, что, в отличие от первых трех этапов, баги на последнем – зачастую неявные, но всё ещё не связанные с алгоритмом и логикой программы. Соответственно, их исправление и зачистка занимают значительно больше времени.

А вот синтаксические ошибки – самая частая причина, почему на exit status 1 происходит ошибка компиляции для платы Аrduino nano. Зачастую процесс дебагинга в этом случае предельно простой.

Вам высвечивают ошибку и строчку, а также подсказку от оператора EXCEPTION, что конкретно не понравилось парсеру. Будь то запятая или не закрытые скобки функции, проблема загрузки в плату Аrduino возникнет в любом случае.

Решение предельно простое и логичное – найти и исправить непонравившийся машине синтаксис. Зачастую такие сообщения вылезают пачками, как на этапе тестирования, так и компилирования, поэтому вы можете таким образом «застопорить» разработку не один раз.

Не стоит этого страшиться – этот процесс вполне нормален. Все претензии выводятся на английском, например, часто можно увидеть такое: was not declared in this scope. Что это за ошибка arduino – на самом деле ответ уже скрыт в сообщении. Функция или переменная просто не были задекларированы в области видимости.

Ошибки компиляции плат Arduino uno

Другая частая оплошность пользователя, которая порождает вопросы вроде, что делать, если Аrduino не видит порт, заключается в том, что вы попросту забываете настроить среду разработки. IDE Ардуино создана под все виды плат, но, как мы указывали, на каждом контроллере помещается лишь ограниченное количество библиотек, и их наполнение может быть различным.

Соответственно, если в меню среды вы выбрали компиляцию не под тот МК, то вполне вероятно, что вызываемая вами функция или метод просто не будет найдена в постоянной памяти, вернув ошибку. Стандартно, в настройках указана плата Ардуино уно, поэтому не забывайте её менять. И обратная ситуация может стать причиной, по которой возникает проблема загрузки в плату на Аrduino uno.

Ошибка exit status 1 при компиляции для плат uno, mega и nano

И самое частое сообщение, для пользователей уно, которое выскакивает в среде разработки – exit 1. И оно же самое дискомфортное для отладки приложения, ведь тут необходимо учесть чуть ли не ядро системы, чтобы понять, где же кроется злополучный баг.

В документации указано, что это сообщение указывает на то, что не запускается ide Аrduino в нужной конфигурации, но на деле есть ещё десяток случаев, при которых вы увидите данное сообщение. Однако, действительно, не забывайте проверять разрядность системы, IDE и просматривать, какие библиотеки вам доступны для обращения на текущий момент.

Ошибки библиотек

Если произошла ошибка при компиляции скетча Ардуино, но не выводилось ни одно из вышеописанных сообщений, то можете смело искать баг в библиотеках МК. Это наиболее неприятное занятие для большинства программистов, ведь приходится лазить в чужом коде, но без этого никак.

Ведь банально причина может быть в устаревшем синтаксисе скачанного плагина и, чтобы он заработал, необходимо переписать его практически с нуля. Это единственный выход из сложившейся ситуации. Но бывают и более банальные ситуации, когда вы подключили библиотеку, функции из которой затем ни разу не вызвали, или просто перепутали название.

Ошибки компилятора Ардуино

Ранее упоминался финальный стек действий, при прогонке кода через компилятор, и в этот момент могут произойти наиболее страшные ошибки – баги самого IDE. Здесь конкретного решения быть не может. Вам никто не запрещает залезть в ядро системы и проверить там всё самостоятельно, но куда эффективнее будет откатиться до предыдущей версии программы или, наоборот, обновиться.

Основные ошибки

Ошибка: «avrdude: stk500_recv(): programmer is not responding»

Смотрим какая у нас плата? Какой порт используем? Сообщаем ардуино о правильной плате и порте. Возможно, что используете Nano, а указана Mega. Возможно, что указали неверный порт. Всё это приводит к сообщению: «programmer is not responding».

Решение:

В Arduino IDE в меню «Сервис» выбираем плату. В меню «Сервис → Последовательный порт» выбираем порт.

Ошибка: «a function-definition is not allowed here before ‘{‘ token»

Забыли в коде программы (скетча) закрыть фигурную скобку }.

Решение:

Обычно в Ардуино IDE строка с ошибкой подсвечивается.

Ошибка: «No such file or directory  /  exit status 1»

Подключаемая библиотека отсутствует в папке libraries.

Решение:

Скачать нужную библиотеку и скопировать её в папку программы — как пример — C:Program FilesArduinolibraries. В случае наличия библиотеки — заменить файлы в папке.

Ошибка: «expected initializer before ‘}’ token  /  expected ‘;’ before ‘}’ token»

Забыли открыть фигурную скобку {, если видим «initializer before». Ошибка «expected ‘;’ before ‘}’ token» — забыли поставить точку с запятой в конце командной строки.

Решение:

Обычно в Ардуино IDE строка с ошибкой подсвечивается.

Ошибка: «… was not declared in this scope»

Arduino IDE видит в коде выражения или символы, которые не являются служебными или не были объявлены переменными.

Решение:

Проверить код на использование неизвестных выражений или лишних символов.

17 июля 2018 в 13:23
| Обновлено 7 ноября 2020 в 01:20 (редакция)
Опубликовано:

Статьи, Arduino


#include <LCD5110_Graph.h>

// Аналоговые входы (analog pins) могут быть использованы как цифровые вход/выходы (digital pins). 
// Обращение к ним идет по номерам от 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 16
#define EXT_CO2_PIN 0  

#define EXT_POWER_ON_PIN 20
#define EXT_LIGHT_LED_PIN 11

#define EXT_UDO_MICRO_PIN 17
#define EXT_UDO_MACRO_PIN 18
#define EXT_UDO_Fe_PIN 19

#define Key_PIN 7

#define DispLight_min 253  //минимальная подсветка в режиме часов
#define CorrTime -3      // коррекция хода системных часов [Сек] выполняется каждый час  
//const int CorrTime = -23;      // коррекция хода системных часов [Сек]  
// It is assumed that the LCD module is connected to
// the following pins using a levelshifter to get the
// correct voltage to the module.
//      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); 
extern uint8_t SmallFont[];
extern uint8_t BigNumbers[];
//extern unsigned char TinyFont[];
byte ledContrast;
byte ledLight;

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

#include <OneWire.h> 
OneWire  temp(14);  // on pin 10 (a 4.7K resistor is necessary) 
float cur_temp = -999;
byte temp_type_s;
byte temp_data[12];
byte temp_addr[8];
byte temp_cicle = 0;
// I assume you know how to connect the DS1307.
// DS1307:  SDA pin   -> Arduino Digital 4
//          SCL pin   -> Arduino Digital 5

#include <DS1307.h>

// Init the DS1307
DS1307 rtc(3, 2); 
// Init a Time-data structure
Time  time; 
unsigned long currentTime;
unsigned long loopTime;


byte key = 0;
byte prev_key = 0;
byte idle_key = 0;
//const int max_idle_key = 100; //цыклов не активности перед скринсейвером
#define max_idle_key  100 //цыклов не активности перед скринсейвером

int cur_menu = 0;
int cur_item = 0;
boolean cur_item_edit = false;
byte aquaT;                   // Требуемая температура воды
boolean CoolingEnabled;             // Разрешено ли охлаждение куллером
boolean light1 = false;
boolean light2 = false;
boolean air = false;
boolean CO2 = false;
byte kormMin = 0;             // Остаток времени для кормления мин

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

void setup()
{
  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, LOW);   // выключает
  light2 = false;
  pinMode(EXT_FILTER_PIN, OUTPUT);      // устанавливает режим работы - выход
  digitalWrite(EXT_FILTER_PIN, HIGH);   // выключает
  pinMode(EXT_CO2_PIN, OUTPUT);      // устанавливает режим работы - выход
  digitalWrite(EXT_CO2_PIN, LOW);   // выключает
  CO2 = false;
  pinMode(EXT_AIR_PIN, OUTPUT);      // устанавливает режим работы - выход
  digitalWrite(EXT_AIR_PIN, HIGH);   // выключает
  air = true;
  CoolingEnabled = false;             // Разрешено ли охлаждение куллером


  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);   // выключает

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

// Init EEPROM
//  for(int e = 0; e < 2047; e++) EEPROM.write(e,0);
//  EEPROM.write(0,61);   // ledContrast  !!!!!!! Очень акуратно иначе белый либо черный экран
//  EEPROM.write(1,200);  // ledLight 
//  EEPROM.write(2,24);   // Требуемая температура воды
//  EEPROM.write(3,1);    // Разрешено ли охлаждение куллером
  
  ledContrast = EEPROM.read(0);
  // первичная установка контраста - иначе при первом запуске нихрена невидно
  if ((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);  // максимальные обороты для охлаждения воды

  // Set the clock to run-mode
  rtc.halt(false); 
//  rtc.setDOW(SUNDAY);        // Set Day-of-Week to SUNDAY
//  rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
//  rtc.setDate(3, 10, 2010);   // Set the date to October 3th, 2010 
  
  myGLCD.setFont(SmallFont);
  myGLCD.clrScr();
  myGLCD.update();
/*
  myGLCD.setFont(SmallFont);
  myGLCD.clrScr();
  myGLCD.print("AQUA controll", CENTER, 3);
  myGLCD.print("ALEX", CENTER, 20);
  myGLCD.drawRect(28, 18, 56, 28);
  for (int i=0; i<6; i++)
  {
    myGLCD.drawLine(57, 18+(i*2), 83-(i*3), 18+(i*2));
    myGLCD.drawLine((i*3), 28-(i*2), 28, 28-(i*2));
  }
//  myGLCD.setFont(TinyFont);
  myGLCD.print("(C) AlexVOK", CENTER, 36);
//  myGLCD.print("[email protected]", CENTER, 42);
  myGLCD.update();
  delay(1000);
*/
//-------------------------------------------------------------------------------
  byte b = 0;
  while ( (!temp.search(temp_addr))&&(b < 10)) {
    //Serial.println("Нет больше адресов.");
    temp.reset_search();
    delay(250);
    b++;
  }
//  if (OneWire::crc8(temp_addr, 7) != temp_addr[7]) {
//      Serial.println("CRC не является действительным!");
//  }

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

  currentTime = millis();
  loopTime = currentTime;   
}

//-----------------------------------------------------------------------------------
float getTemp(){
//  temp.reset();
//  temp.select(temp_addr);
//  temp.write(0x44, 1);        // start conversion, with parasite power on at the end
  
//  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  temp.reset();
  temp.select(temp_addr);    
  temp.write(0xBE);         // Read Scratchpad

  for (byte i = 0; i < 9; i++) {           // we need 9 bytes
    temp_data[i] = temp.read();
  }
//  Serial.print(OneWire::crc8(data, 8), HEX);

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (temp_data[1] << 8) | temp_data[0];
  
  if (temp_type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (temp_data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - temp_data[6];
    }
  } else {
    byte cfg = (temp_data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  return ((float)raw / 16.0);
}

//-----------------------------------------------------------------------------------
// Нажатые кнопки
//int button;
const byte BUTTON_NONE   = 0;
const byte BUTTON_UP     = 1;
const byte BUTTON_DOWN   = 2;
const byte BUTTON_OK     = 3;
const byte BUTTON_CANCEL = 4;

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

//-----------------------------------------------------------------------------------
void naviKey(byte maxItems){
  if(key == BUTTON_UP){
    cur_item--;
    if(cur_item < 1)
      cur_item = maxItems;
  }
  if(key == BUTTON_DOWN){
    cur_item++;
    if(cur_item > maxItems)
      cur_item = 1;
  }
}
//-----------------------------------------------------------------------------------
void drawMenu(String mName, String item1, String item2, String item3, 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);

  if(cur_item == 1){
    myGLCD.print(item1,3,12);
    myGLCD.drawRoundRect(0,11,83,20);
  }else  
    myGLCD.print(item1,0,12);
      
  if(cur_item == 2){
    myGLCD.print(item2,3,21);
    myGLCD.drawRoundRect(0,20,83,29);
  }else  
    myGLCD.print(item2,0,21);

  if(cur_item == 3){
    myGLCD.print(item3,3,30);
    myGLCD.drawRoundRect(0,29,83,38);
  }else  
    myGLCD.print(item3,0,30);

  if(cur_item == 4){
    myGLCD.print(item4,3,39);
    myGLCD.drawRoundRect(0,38,83,47);
  }else  
    myGLCD.print(item4,0,39);

  myGLCD.update();
}

byte menu_hh;
byte menu_mi;
byte menu_dd;
byte menu_mm;
int menu_yyyy;
byte menu_dow;
byte menu_off;
byte menu_item_count;
int alertAdr;
byte curLoad;

byte prMin = 0;
//-----------------------------------------------------------------------------------
void 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 k = 80*(Val-minVal)/(maxVal - minVal);
  for(int i = 2; i < k+2; i++)
    myGLCD.drawLine(i,40,i,46);
  myGLCD.update();
}

boolean  new_hour = true;
byte secc = 0;
byte LED_sunrise = 0;
byte LED_cur_pos = 0;
byte udo_tim = 0;
byte bt;
//*****************************************************************************************
//*****************************************************************************************
void loop() {
currentTime = millis();
key = getPressedButton();
if((currentTime >= (loopTime + 250))||(key != prev_key)){ // проверяем каждые 5мс (20 Гц)

  if((prev_key != key)&&(key != 0)){
    idle_key = 0;
  }else{ 
    idle_key++;
  }
  prev_key = key;


  if (key == 0) // Измереяем температуру только в состоянии простоя
  {
    if(temp_cicle == 0){
      temp.reset();
      temp.select(temp_addr);
      temp.write(0x44, 1);        // start conversion, with parasite power on at the end
    }
    if(temp_cicle == 4){
      cur_temp = getTemp();
      // Управление нагревом и охлаждением ----------------------------------------------
      if(cur_temp < (float)aquaT){
        digitalWrite(EXT_HEATER_PIN, HIGH);   // включает нагреватель
      }else  
        digitalWrite(EXT_HEATER_PIN, LOW);   // выключает  нагреватель
        
      if (CoolingEnabled) {
        if(cur_temp > ((float)aquaT+0.1)){               // Разрешено ли охлаждение куллером
          int coll_cur = minCool+(((float)(maxCool - minCool))/100)*(((float)(cur_temp-aquaT))/0.5)*100;
          if (coll_cur > maxCool) { coll_cur = maxCool;}
          analogWrite(EXT_COOLING_PIN, coll_cur);   // включает куллер
        }else{  
          analogWrite(EXT_COOLING_PIN, minCool);   // включаем режим проветривания
        }
      }else{
        if (air||light1){
//        if (air||light1||light2){
          analogWrite(EXT_COOLING_PIN, minCool);   // включаем режим проветривания
        }else{  
          digitalWrite(EXT_COOLING_PIN, LOW);   // выключает  куллер
        }
      } 
    }
    if(temp_cicle > 51){
      temp_cicle = 0;
    }else{
      temp_cicle++;
    }
  }

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


  if(secc > 4){
    secc = 0;
  }else{
    secc++;
  }

  
  // Get data from the DS1307
  time = rtc.getTime();   
  // коррекция хода системных часов [Сек]  
  if (time.min == 0){
    new_hour = true;
  }
  if ((time.min == 30)&&(new_hour)){
    int corr_sec = time.sec + CorrTime;    // коррекция хода системных часов [Сек]  
    byte corr_min = time.min;
    if (corr_sec < 0){
      corr_sec = corr_sec + 60;
      corr_min--;
    }
    if (corr_sec > 59){
      corr_sec = corr_sec - 60;
      corr_min++;
    }
    
    rtc.setTime(time.hour, corr_min, corr_sec);     // Set the time to 12:00:00 (24hr format)
    new_hour = false;
  }
  //-----
  // Новая минута ----------------------------------------------
   if(prMin != time.min){
    prMin = time.min;

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

      analogWrite(EXT_LIGHT_LED_PIN, led_tmp);   // LED
      LED_cur_pos++;
    } 
    
//-------ALARM------------------------------------------------------------------------- 
   for(int a = 100; a < 1001; a = a + 4){
     byte b1 = EEPROM.read(a);
//     if(((boolean)(b1&B10000000))&((boolean)(_BV(time.dow-1)&b1))){  // активная запись и день недели
     if(b1&B10000000){
      if((1<<(time.dow-1))&b1){  // активная запись и день недели
       byte b2 = EEPROM.read(a+1);
       if(time.hour == (byte)(b2&B00011111)){        // сравниваем часы
         byte b3 = EEPROM.read(a+2);
         if(time.min == (byte)(b3&B00111111)){        // сравниваем минути
           byte b4 = EEPROM.read(a+3);
           switch((byte)((b2>>5)&B00000111)){         // определяем нагрузку
             case 0:
               // Разрешено ли охлаждение куллером
               if (b4&B00000001){
                 CoolingEnabled = true;
                 analogWrite(EXT_COOLING_PIN, minCool);   // включаем режим проветривания
               }else{
                 CoolingEnabled = false;
                 digitalWrite(EXT_COOLING_PIN, LOW);
               }  
             break;
             case 1:  // Light1
               if (b4&B00000001){
                 digitalWrite(EXT_LIGHT_1_PIN, HIGH);
                 light1 = true;
               }else{
                 digitalWrite(EXT_LIGHT_1_PIN, LOW);
                 light1 = false;
               }  
             break;   
             case 2:  // Light2
               if (b4&B00000001){
                 digitalWrite(EXT_LIGHT_2_PIN, HIGH);
                 light2 = true;
               }else{
                 digitalWrite(EXT_LIGHT_2_PIN, LOW);
                 light2 = false;
               }  
             break;
             case 3:  // Air
               if (b4&B00000001){
                 digitalWrite(EXT_AIR_PIN, HIGH);
                 air = true;
               }else{
                 digitalWrite(EXT_AIR_PIN, LOW);
                 air = false;
               }  
             break;
             case 4:  // CO2
               if (b4&B00000001){
                 digitalWrite(EXT_CO2_PIN, HIGH);
                 CO2 = true;
               }else{
                 digitalWrite(EXT_CO2_PIN, LOW);
                 CO2 = false;
               }  
             break;
             case 5:  //LED
               // 8 бит 1 восход 0 закат остальные кол мин
               LED_sunrise = b4;
               LED_cur_pos = 0;
             break;
//             case 6:  // UDO
//               udo_tim = (byte)(b4&B00111111);
//               digitalWrite(EXT_POWER_ON_PIN, HIGH);
//               delay(100);  //Время на выход в режим БП
//               switch((byte)((b4>>6)&B00000011)){
//                 case 0:
//                   digitalWrite(EXT_UDO_MICRO_PIN, HIGH);
//                   delay(udo_tim*4.2);
//                   digitalWrite(EXT_UDO_MICRO_PIN, LOW);
//                 break;
//                 case 1:
//                   digitalWrite(EXT_UDO_MACRO_PIN, HIGH);
//                   delay(udo_tim*4.2);
//                   digitalWrite(EXT_UDO_MACRO_PIN, LOW);
//                 break;
//                 case 2:
//                   digitalWrite(EXT_UDO_Fe_PIN, HIGH);
//                   delay(udo_tim*4.2);
//                   digitalWrite(EXT_UDO_Fe_PIN, LOW);
//                 break;
//                 case 3:
//
//                 break;
//               }
//               digitalWrite(EXT_POWER_ON_PIN, LOW);
//             break;
             case 7:
           
             break;
           } 
         }
       }
     }
    } 
   }
  }  
//------------------------------------------------------------------------------------ 
  if((idle_key > max_idle_key)&&(cur_menu != 0)){
    cur_menu = 0;
    cur_item = 0;
    cur_item_edit = false;
  }  
    
  switch(cur_menu){
    case 0: // Time
    {
      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);
      if(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);
      if(cur_temp < 1){
        myGLCD.print("T: Error",3,38);
      }else{
        myGLCD.print("T:",3,38);
        myGLCD.printNumF(cur_temp,2,15,38);
      }
      myGLCD.update();
      if(key > 0)
        cur_menu = 1;      
        cur_item = 0;
        cur_item_edit = false;
        // Включаем подсветку LED
//        analogWrite(LED_LIGHT_PIN,ledLight);
      break;
    }
    case 1: // Main -----------------------------------------------------------------
    {
    analogWrite(LED_LIGHT_PIN,ledLight);
    String ll;
      if(light1||light2){
        ll = "On";
      }else
        ll ="Off";

      String aa;
      if(air){
        aa = "On";
      }else
        aa ="Off";

      if(cur_item_edit&&(cur_item == 1))
        ll = "["+ll+"]";

      if(cur_item_edit&&(cur_item == 2))
        aa = "["+aa+"]";
        
      String lk = "";
      if(kormMin > 0){
        lk = " ("+(String)kormMin+")";
      }  
      drawMenu("Main","Light "+ll,"Air "+aa,"Kormlenie"+lk,"Settings");
      naviKey(4);
      switch(key){
        case BUTTON_OK:
          switch(cur_item){
            case 1:
              light1 = !light1;
              light2 = light1;
              if(light1){
                digitalWrite(EXT_LIGHT_1_PIN, HIGH);  // включает LED
              }else
                digitalWrite(EXT_LIGHT_1_PIN, LOW);   // выключает LED
              if(light2){
                digitalWrite(EXT_LIGHT_2_PIN, HIGH); // включает lightTUBE
              }else
                digitalWrite(EXT_LIGHT_2_PIN, LOW);  // выключает lightTUBE
            break;
            case 2:
              air = !air;
              if(air){
                digitalWrite(EXT_AIR_PIN, HIGH);  // включает
              }else
                digitalWrite(EXT_AIR_PIN, LOW);   // выключает
            break;
            case 3:
              kormMin = 20;
              digitalWrite(EXT_FILTER_PIN, LOW);   // выключает Фильтр
            break;
            case 4:
              cur_menu = 13;      
              cur_item = 0;
            break;
          }
        break;
        case BUTTON_CANCEL:
          cur_item_edit = false;
          cur_menu = 0;
          cur_item = 0;
        break;
      }
      break;
    }
    case 13: // Settings -----------------------------------------------------------------
    {
      drawMenu("Settings", "System","Termostat","Tasker","Tasker");
      naviKey(4);
      switch(key){
        case BUTTON_OK:
          switch(cur_item){
            case 1:
              cur_menu = 131;      
              cur_item = 0;
            break;
            case 2:
              cur_menu = 132;      
              cur_item = 0;
            break;
            case 3:
              cur_menu = 130;      
              cur_item = 1;
            break;
            case 4:
              cur_menu = 130;      // 134 UDO
              cur_item = 0;
            break;
          }
        break;
        case BUTTON_CANCEL:
          cur_menu = 1;
          cur_item = 3;
        break;
      }
      break;
    }
//    case 134: // UDO -----------------------------------------------------------------
//    { String uu; 
//      if (CO2){
//        uu = "On";
//      }else{
//        uu = "Off";
//      }  
//      drawMenu("UDO", "CO2", "UDO","CO2 "+uu,"");
//      naviKey(3);
//      switch(key){
//        case BUTTON_OK:
//          switch(cur_item){
//            case 1:
//              cur_menu = 133;      
//              cur_item = 1;
//              menu_off = 1;
//              menu_item_count = 25;
//              curLoad = 4;
//            break;
//            case 2:
//              cur_menu = 133;      
//              cur_item = 1;
//              menu_off = 1;
//              menu_item_count = 25;
//              curLoad = 6;
//            break;
//            case 3:
//              CO2 = !CO2;
//              if (CO2){
//                digitalWrite(EXT_CO2_PIN, HIGH);
//              }else{
//                digitalWrite(EXT_CO2_PIN, LOW);
//              }  
//            break;
//            case 4:
////              cur_menu = 130;      
////              cur_item = 1;
//            break;
//          }
//        break;
//        case BUTTON_CANCEL:
//          cur_menu = 13;
//          cur_item = 4;
//        break;
//      }
//      break;
//    }
    case 130: // Tasker -----------------------------------------------------------------
    {
      drawMenu("Tasker","Light 1","Light 2","LED","Air");
      naviKey(4);
      switch(key){
        case BUTTON_OK:
          switch(cur_item){
            case 1:
              cur_menu = 133;      
              cur_item = 1;
              menu_off = 1;
              menu_item_count = 25;
              curLoad = 1;
            break;
            case 2:
              cur_menu = 133;      
              cur_item = 1;
              menu_off = 1;
              menu_item_count = 25;
              curLoad = 2;
            break;
            case 3:
              cur_menu = 133;      
              cur_item = 1;
              menu_off = 1;
              menu_item_count = 25;
              curLoad = 5;
            break;
            case 4:
              cur_menu = 133;      
              cur_item = 1;
              menu_off = 1;
              menu_item_count = 25;
              curLoad = 3;
            break;
        }
        break;
        case BUTTON_CANCEL:
          cur_menu = 13;
          cur_item = 3;
        break;
      }
      break;
    }
    case 133: // Tasker Menu List -----------------------------------------------------------------
    {
      myGLCD.setFont(SmallFont);
      myGLCD.clrScr();
      int offf;
      switch(curLoad){
        case 0:
          myGLCD.print("CoolTime",1,0);
          offf = 400;
        break;
        case 1:
          myGLCD.print("Light 1",1,0);
          offf = 100;
        break;
        case 2:
          myGLCD.print("Light 2",1,0);
          offf = 200;
        break;
        case 3:
          myGLCD.print("Air",1,0);
          offf = 300;
        break;
        case 4:
          myGLCD.print("CO2",1,0);
          offf = 500;
        break;
        case 5:
          myGLCD.print("LED",1,0);
          offf = 600;
        break;
        case 6:
          myGLCD.print("UDO",1,0);
          offf = 700;
        break;
      }

      myGLCD.print(rtc.getTimeStr(FORMAT_SHORT),RIGHT,0);
      myGLCD.drawLine(0,8,83,8);
      myGLCD.drawLine(0,9,83,9);
      
      String tt;
      byte vy;
      for(byte j = menu_off; j <= min(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;
        tt = (String)(j) + " ";
        if(bt < 10){
          tt = tt + "0";
        }
        tt = tt + (String)bt + ":";
        
        bt = EEPROM.read(alertAdr+2)&B00111111;
        if(bt < 10){
          tt = tt + "0";
        }
        tt = tt + (String)bt + " ";

      byte bt = EEPROM.read(alertAdr+3);
      switch(curLoad){
        case 5: // "TimerLED"
          if (bt&B10000000){
            tt = tt + "On";
          }else{
            tt = tt + "Off";
          }  
        break;
        case 6:  //  "TimerUDO"
          switch((byte)((bt>>6)&B00000011)){
            case 0: // Micro
              tt = tt + "Micro";
            break;
            case 1: // Macro
              tt = tt + "Macro";
            break;
            case 2: // Fe+
              tt = tt + "Fe+";
            break;
            case 3: // Ka
              tt = tt + "Ka";
            break;
          }
        break;
        default:  
          if(bt > 0){
            tt = tt + "On";
          }else{
            tt = tt + "Off";
          }  
        break;
      }

//        tt = "Time "+(String)(j);
//        if(EEPROM.read(offf+(j-1)*4)&B10000000){
//          tt = tt+" Active";
//        }        
        if(cur_item == j){
          myGLCD.print(tt,3,vy);
          myGLCD.drawRoundRect(0,vy-1,83,vy+8);
        }else  
          myGLCD.print(tt,0,vy);

        // перечеркиваем не активные таймера
        if(!(EEPROM.read(offf+(j-1)*4)&B10000000)){
          myGLCD.drawLine(0,vy+5,83,vy+5);
        }        
          
      }

      switch(key){
        case BUTTON_UP:
          if(cur_item == 1){ 
            cur_item = menu_item_count;
            menu_off = menu_item_count - 3;
          }else{  
            cur_item--;
            if(cur_item < menu_off){
             menu_off = cur_item;
            }
          }  
        break;
        case BUTTON_DOWN:
          if(cur_item == menu_item_count){ 
            cur_item = 1;
            menu_off = 1;
          }else{  
            cur_item++;
            if(cur_item > menu_off+3){
             menu_off = cur_item-3;
            }
          }  
        break;
        case BUTTON_OK:
          alertAdr = offf+(cur_item-1)*4;
          cur_menu = 1330;
          cur_item = 1;
          cur_item_edit = false;
        break;
        case BUTTON_CANCEL:
          switch(curLoad){
           case 0:
             //"CoolTime"
             cur_menu = 132;
             cur_item = 2;
           break;
           case 1:
             //"Light1",
             cur_menu = 130;
             cur_item = 1;
           break;
           case 2:
             //"Light2"
             cur_menu = 130;
             cur_item = 2;
           break;
           case 3:
             //"Air"
             cur_menu = 130;
             cur_item = 4;
           break;
           case 4:
             //"CO2"
             cur_menu = 134;
             cur_item = 1;
           break;
           case 5:
             //"LED"
             cur_menu = 130;
             cur_item = 3;
           break;
           case 6:
             //"UDO"
             cur_menu = 134;
             cur_item = 2;
           break;
        }

          cur_item_edit = false;
        break;
      }
      myGLCD.update();
      break;
    }
    case 1330: // Tasker Menu -----------------------------------------------------------------
    {
      myGLCD.setFont(SmallFont);
      myGLCD.clrScr();
      
      switch(curLoad){
        case 0:
          myGLCD.print("CoolTime",1,0);
        break;
        case 1:
          myGLCD.print("Light1",1,0);
        break;
        case 2:
          myGLCD.print("Light2",1,0);
        break;
        case 3:
          myGLCD.print("Air",1,0);
        break;
        case 4:
          myGLCD.print("CO2",1,0);
        break;
        case 5:
          myGLCD.print("LED",1,0);
        break;
        case 6:
          myGLCD.print("UDO",1,0);
        break;
      }

      myGLCD.print(rtc.getTimeStr(FORMAT_SHORT),RIGHT,0);
      myGLCD.drawLine(0,8,83,8);
      myGLCD.drawLine(0,9,83,9);
      byte b1 = EEPROM.read(alertAdr);
      bt = b1;
      myGLCD.print("MoTuWeThFrSaSu",0,11);
      for(int j = 1; j < 8; j++){
//        if((cur_item == j)&cur_item_edit){
        if(cur_item == j){
          myGLCD.drawRect(j*12-10,20,j*12-2,28);
        }  
        myGLCD.drawCircle(j*12-6,24,3);
        if(bt&B00000001){
          myGLCD.drawCircle(j*12-6,24,2);
          myGLCD.drawCircle(j*12-6,24,1);
        }
        bt = bt >> 1;
      }
      String stat = "";
      if(cur_item == 8){
        stat = stat + "[";
      }
      if(EEPROM.read(alertAdr)&B10000000){
        stat = stat + "Act";
      }else
        stat = stat + "Pas";
      if(cur_item == 8){
        stat = stat + "]";
      }

      stat = stat + ".";
      if(cur_item == 9){
        stat = stat + "[";
      }
      byte tmpb = EEPROM.read(alertAdr+3);
      switch(curLoad){
        case 5: // "TimerLED"
          if (tmpb&B10000000){
            stat = stat + "On";
          }else{
            stat = stat + "Off";
          }  
          stat = stat + " " + (tmpb&B01111111)+"min";
        break;
        case 6:  //  "TimerUDO"
          switch((byte)((tmpb>>6)&B00000011)){
            case 0: // Micro
              stat = stat + "Micro";
            break;
            case 1: // Macro
              stat = stat + "Macro";
            break;
            case 2: // Fe+
              stat = stat + "Fe+";
            break;
            case 3: // Ka
              stat = stat + "Ka";
            break;
          }
          stat = stat + (tmpb&B00111111)+"mil";
        break;
        default:  
          if(tmpb > 0){
            stat = stat + "On";
          }else{
            stat = stat + "Off";
          }  
        break;
      }

      if(cur_item == 9){
        stat = stat + "]";
      }
      myGLCD.print(stat,0,29);
      
      stat = "Time: ";
      if(cur_item == 10){
        stat = stat + "[";
      }
      bt = EEPROM.read(alertAdr+1)&B00011111;
      if(bt < 10){
        stat = stat + "0";
      }
      stat = stat + (String)bt;
      if(cur_item == 10){
        stat = stat + "]";
      }

      stat = stat + ":";

      if(cur_item == 11){
        stat = stat + "[";
      }
      bt = EEPROM.read(alertAdr+2)&B00111111;
      if(bt < 10){
        stat = stat + "0";
      }
      stat = stat + (String)bt;
      if(cur_item == 11){
        stat = stat + "]";
      }
      myGLCD.print(stat,0,39);

      switch(key){
        case BUTTON_UP:
          if(cur_item_edit){
            if((cur_item == 9)&&(curLoad > 4)){
              bt = EEPROM.read(alertAdr+3);
              //if(bt == 255){
              //  bt = 0;
              //}else
                bt++;
              EEPROM.write(alertAdr+3,bt);
            }
            if(cur_item == 10){
              bt = (EEPROM.read(alertAdr+1)&B00011111);
              if(bt == 23){
                bt = 0;
              }else
                bt++;
              EEPROM.write(alertAdr+1,bt^(curLoad<<5));
            }
            if(cur_item == 11){
              bt = EEPROM.read(alertAdr+2)&B00111111;
              if(bt == 59){
                bt = 0;
              }else
                bt++;
              EEPROM.write(alertAdr+2,bt);
            }
          }else
            if(cur_item == 1){ 
              cur_item = 11;
            }else  
              cur_item--;
        break;
        case BUTTON_DOWN:
          if(cur_item_edit){
            if((cur_item == 9)&&(curLoad > 4)){
              bt = EEPROM.read(alertAdr+3);
              //if(bt == 0){
              //  bt = 255;
              //}else
                bt--;
              EEPROM.write(alertAdr+3,bt);
            }
            if(cur_item == 10){
              bt = EEPROM.read(alertAdr+1)&B00011111;
              if(bt == 0){
                bt = 23;
              }else
                bt--;
              EEPROM.write(alertAdr+1,bt^(curLoad<<5));
            }
            if(cur_item == 11){
              bt = EEPROM.read(alertAdr+2)&B00111111;
              if(bt == 0){
                bt = 59;
              }else
                bt--;
              EEPROM.write(alertAdr+2,bt);
            }
          }else
            if(cur_item == 11){ 
              cur_item = 1;
            }else  
              cur_item++;
        break;
        case BUTTON_OK:
          EEPROM.write(alertAdr+1,((EEPROM.read(alertAdr+1)&B00011111)^(curLoad<<5))); // сохраняем номер нагрузки 
          switch(cur_item){
            case 8:
              EEPROM.write(alertAdr,(EEPROM.read(alertAdr)^B10000000));
            break;
            case 9:
              if(curLoad < 5){
                //EEPROM.write(alertAdr+3,(EEPROM.read(alertAdr+3)^B00000001));
                EEPROM.write(alertAdr+3,((EEPROM.read(alertAdr+3)&B00000001)^B00000001));
              }else{
                cur_item_edit = !cur_item_edit;
              }  
            break;
            case 10:
              cur_item_edit = !cur_item_edit;
            break;
            case 11:
              cur_item_edit = !cur_item_edit;
            break;
            default:
              EEPROM.write(alertAdr,(EEPROM.read(alertAdr)^(1<<(cur_item-1))));
            break;
          }
        break;
         case BUTTON_CANCEL:
          switch(curLoad){
           case 0:
             //CoolTime
             cur_menu = 132;
             cur_item = 2;
           break;
           case 1:
             //"Light1",
             cur_menu = 130;
             cur_item = 1;
           break;
           case 2:
             //"Light2"
             cur_menu = 130;
             cur_item = 2;
           break;
           case 3:
             //"Air"
             cur_menu = 130;
             cur_item = 4;
           break;
           case 4:
             //"CO2"
             cur_menu = 134;
             cur_item = 1;
           break;
           case 5:
             //"LED"
             cur_menu = 130;
             cur_item = 3;
           break;
           case 6:
             //"UDO"
             cur_menu = 134;
             cur_item = 2;
           break;
         }
          cur_item_edit = false;
        break;
      }
      myGLCD.update();
      break;
    }
    case 132: // Termostat -----------------------------------------------------------------
    {
      drawMenu("Termostat", "Aqua T ["+(String)aquaT+"]","CoolTime","minCool","maxCool");
      naviKey(4);
      switch(key){
        case BUTTON_OK:
          switch(cur_item){
            case 1:
              cur_menu = 1321;      
              cur_item = 0;
            break;
            case 2:  //CoolTime
              cur_menu = 133;      
              cur_item = 1;
              menu_off = 1;
              menu_item_count = 8;
              curLoad = 0;
            break;
            case 3:  //minCool // минимальные обороты кулера для вентиляции крышки и охлаждения ламп
              cur_menu = 1323;      
            break;
            case 4:  //maxCool // максимальные обороты для охлаждения воды
              cur_menu = 1324;      
            break;
          }
        break;
        case BUTTON_CANCEL:
          cur_menu = 13;
          cur_item = 2;
          cur_item_edit = false;
        break;
      }
      break;
    }
    case 1321: // Aqua Temperature -----------------------------------------------------------------
    {
      drawIntMenu("Aqua Temperat",18,35,aquaT);
      switch(key){
        case BUTTON_UP:
          aquaT++;
          aquaT = min(aquaT, 35);
        break;
        case BUTTON_DOWN:
          aquaT--;
          aquaT = max(aquaT, 18);
        break;
        case BUTTON_OK:
          EEPROM.write(2,aquaT);                   // Требуемая температура воды
          cur_menu = 132;
          cur_item = 1;
        break;
        case BUTTON_CANCEL:
          aquaT = EEPROM.read(2);                   // Требуемая температура воды
          cur_menu = 132;
          cur_item = 1;
        break;
      }
      break;
    }
    case 1323: // minCool // минимальные обороты кулера для вентиляции крышки и охлаждения ламп ------------------------------------------
    {
      drawIntMenu("minCool",0,maxCool,minCool);
      switch(key){
        case BUTTON_UP:
          minCool++;
          minCool = min(minCool, maxCool);
          analogWrite(EXT_COOLING_PIN, minCool);
        break;
        case BUTTON_DOWN:
          minCool--;
          minCool = max(minCool, 0);
          analogWrite(EXT_COOLING_PIN, minCool);
        break;
        case BUTTON_OK:
          EEPROM.write(3,minCool);                   // минимальные обороты кулера для вентиляции крышки и охлаждения ламп
          cur_menu = 132;
          cur_item = 3;
        break;
        case BUTTON_CANCEL:
          minCool = EEPROM.read(3);                   // минимальные обороты кулера для вентиляции крышки и охлаждения ламп
          cur_menu = 132;
          cur_item = 3;
        break;
      }
      break;
    }
    case 1324: // maxCool // максимальные обороты для охлаждения воды ------------------------------------------
    {
      drawIntMenu("maxCool",0,255,maxCool);
      switch(key){
        case BUTTON_UP:
          maxCool++;
          maxCool = min(maxCool, 255);
          analogWrite(EXT_COOLING_PIN, maxCool);
        break;
        case BUTTON_DOWN:
          maxCool--;
          maxCool = max(maxCool, minCool);
          analogWrite(EXT_COOLING_PIN, maxCool);
        break;
        case BUTTON_OK:
          EEPROM.write(4,maxCool);                   // максимальные обороты для охлаждения воды
          cur_menu = 132;
          cur_item = 4;
        break;
        case BUTTON_CANCEL:
          maxCool = EEPROM.read(4);                   // максимальные обороты для охлаждения воды
          cur_menu = 132;
          cur_item = 4;
        break;
      }
      break;
    }
    case 131: // System -----------------------------------------------------------------
    {
      drawMenu("System", "Time","Date","LED Contrast","LED Light");
      naviKey(4);
      switch(key){
        case BUTTON_OK:
          switch(cur_item){
            case 1:
              cur_menu = 1311;      
              cur_item = 0;
              menu_hh = time.hour;
              menu_mi = time.min;
            break;
            case 2:
              cur_menu = 1312;      
              cur_item = 0;
              menu_dd = time.date;
              menu_mm = time.mon;
              menu_yyyy = time.year;
              menu_dow = time.dow;
            break;
            case 3:
              cur_menu = 1313;      
              cur_item = 0;
            break;
            case 4:
              cur_menu = 1314;      
              cur_item = 0;
            break;
          }
        break;
        case BUTTON_CANCEL:
          cur_menu = 0;
          cur_item = 0;
        break;
      }
      break;
    }
    case 1311: // Time -----------------------------------------------------------------
    {
      myGLCD.setFont(SmallFont);
      myGLCD.clrScr();
  
      myGLCD.print("Time",1,0);
      myGLCD.print(rtc.getTimeStr(FORMAT_SHORT),RIGHT,0);
      myGLCD.drawLine(0,8,83,8);
      myGLCD.drawLine(0,9,83,9);
      if((cur_item == 1)&&cur_item_edit) 
        myGLCD.invertText(true);
      myGLCD.printNumI(menu_hh,26,20,2,'0');
      myGLCD.invertText(false);
      myGLCD.print(":",39,20);
      if((cur_item == 2)&&cur_item_edit) 
        myGLCD.invertText(true);
      myGLCD.printNumI(menu_mi,46,20,2,'0');
      myGLCD.invertText(false);

      if(cur_item == 1)
        myGLCD.drawRoundRect(25,18,39,28);
      if(cur_item == 2)
        myGLCD.drawRoundRect(45,18,59,28);

      switch(key){
        case BUTTON_UP:
          if(!cur_item_edit){ 
            cur_item--;
            if(cur_item < 1)
              cur_item = 2;
          }else{
            if(cur_item == 1){
              menu_hh++;
              if(menu_hh == 24)
                menu_hh = 0;
            }
            if(cur_item == 2){
              menu_mi++;
              if(menu_mi == 60)
                menu_mi = 0;
            }
          }
        break;
        case BUTTON_DOWN:
          if(!cur_item_edit){ 
            cur_item++;
            if(cur_item > 2)
              cur_item = 1;
          }else{
            if(cur_item == 1){
              if(menu_hh == 0)
                menu_hh = 23;
              else  
                menu_hh--;
            }
            if(cur_item == 2){
              if(menu_mi == 0)
                menu_mi = 59;
              else
                menu_mi--;
            }
          }
        break;
        case BUTTON_OK:
          if(cur_item_edit){ 
            switch(cur_item){
              case 1:
                rtc.setTime(menu_hh, time.min, 0);     // Set the time to 12:00:00 (24hr format)
              break;
              case 2:
                rtc.setTime(time.hour, menu_mi, 0);     // Set the time to 12:00:00 (24hr format)
              break;
            }
            cur_item_edit = false;
          }else 
            cur_item_edit = true;
        break;
        case BUTTON_CANCEL:
          cur_item_edit = false;
          cur_menu = 131;      
          cur_item = 1;
        break;
      }
      myGLCD.update();
      break;
    }
    case 1312: // Date -----------------------------------------------------------------
    {
      myGLCD.setFont(SmallFont);
      myGLCD.clrScr();
  
      myGLCD.print("Date",1,0);
      myGLCD.print(rtc.getTimeStr(FORMAT_SHORT),RIGHT,0);
      myGLCD.drawLine(0,8,83,8);
      myGLCD.drawLine(0,9,83,9);

      if((cur_item == 1)&&cur_item_edit) 
        myGLCD.invertText(true);
      myGLCD.printNumI(menu_dd,12,20,2,'0');
      myGLCD.invertText(false);

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

      if((cur_item == 2)&&cur_item_edit) 
        myGLCD.invertText(true);
      myGLCD.printNumI(menu_mm,30,20,2,'0');
      myGLCD.invertText(false);

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

      if((cur_item == 3)&&cur_item_edit) 
        myGLCD.invertText(true);
      myGLCD.printNumI(menu_yyyy,48,20,4,'0');
      myGLCD.invertText(false);

      myGLCD.print("Day of week",0,32);
      if((cur_item == 4)&&cur_item_edit) 
        myGLCD.invertText(true);
      myGLCD.printNumI(menu_dow,68,32);
      myGLCD.invertText(false);

      switch(cur_item){
        case 1:
          myGLCD.drawRoundRect(11,18,25,28);
        break;  
        case 2:
          myGLCD.drawRoundRect(29,18,44,28);
        break;  
        case 3:
          myGLCD.drawRoundRect(47,18,73,28);
        break;  
        case 4:
          myGLCD.drawRoundRect(67,30,75,40);
        break;  
      }  

      switch(key){
        case BUTTON_UP:
          if(!cur_item_edit){ 
            cur_item--;
            if(cur_item < 1)
              cur_item = 4;
          }else{
            if(cur_item == 1){
              menu_dd++;
              if(menu_dd > 31)
                menu_dd = 1;
            }
            if(cur_item == 2){
              menu_mm++;
              if(menu_mm > 12)
                menu_mm = 1;
            }
            if(cur_item == 3){
              menu_yyyy++;
            }
            if(cur_item == 4){
              menu_dow++;
              if(menu_dow > 7)
                menu_dow = 1;
            }
          }
        break;
        case BUTTON_DOWN:
          if(!cur_item_edit){ 
            cur_item++;
            if(cur_item > 4)
              cur_item = 1;
          }else{
            if(cur_item == 1){
                menu_dd--;
              if(menu_dd < 1)
                menu_dd = 31;
            }
            if(cur_item == 2){
                menu_mm--;
              if(menu_mm < 1)
                menu_mm = 12;
            }
            if(cur_item == 3){
                menu_yyyy--;
                menu_yyyy = max(menu_yyyy,2013);
            }
            if(cur_item == 4){
                menu_dow--;
              if(menu_dow < 1)
                menu_dow = 7;
            }
          }
        break;
        case BUTTON_OK:
          if(cur_item_edit){ 
            switch(cur_item){
              case 1:
                rtc.setDate(menu_dd, time.mon, time.year);   // Set the date
              break;
              case 2:
                rtc.setDate(time.date, menu_mm, time.year);   // Set the date
              break;
              case 3:
                rtc.setDate(time.date, time.mon, menu_yyyy);   // Set the date
              break;
              case 4:
                 rtc.setDOW(menu_dow);     // Set Day-of-Week 
              break;
            }
            cur_item_edit = false;
          }else 
            cur_item_edit = true;
        break;
        case BUTTON_CANCEL:
          cur_item_edit = false;
          cur_menu = 131;      
          cur_item = 2;
        break;
      }
      myGLCD.update();
      break;
    }
    case 1313: // LED Contrast -----------------------------------------------------------------
    {
      drawIntMenu("LED Contrast",45,80,ledContrast);
      switch(key){
        case BUTTON_UP:
          ledContrast++;
          ledContrast = min(ledContrast, 80);
        break;
        case BUTTON_DOWN:
          ledContrast--;
          ledContrast = max(ledContrast, 45);
        break;
        case BUTTON_OK:
          EEPROM.write(0,ledContrast);
          cur_menu = 131;
          cur_item = 3;
        break;
        case BUTTON_CANCEL:
          ledContrast = EEPROM.read(0);
          cur_menu = 131;
          cur_item = 3;
        break;
      }
      myGLCD.setContrast(ledContrast);  
      break;
    }
    case 1314: // LED Light -----------------------------------------------------------------
    {
      drawIntMenu("LED Light",0,255,ledLight);
      switch(key){
        case BUTTON_UP:
          ledLight++;
          ledLight = min(ledLight, 255);
        break;
        case BUTTON_DOWN:
          ledLight--;
          ledLight = max(ledLight, 0);
        break;
        case BUTTON_OK:
          EEPROM.write(1,ledLight);
          cur_menu = 131;
          cur_item = 4;
        break;
        case BUTTON_CANCEL:
          ledLight = EEPROM.read(1);
          cur_menu = 131;
          cur_item = 4;
        break;
      }
      analogWrite(LED_LIGHT_PIN,ledLight);
      break;
    }

    default:
      cur_menu = 0;
      cur_item = 0;
  }
 
loopTime = currentTime;   
}  
}

Синтаксические ошибки

Первые ошибки, которые определяются отладчиком – это синтаксические ошибки. Их же легче всего исправить. Неправильный синтаксис в Arduino IDE выделяется строкой, в которой допущена неточность. Нужно разобраться – это ошибка в написании служебного слова, случайно удалена важная функция, не хватает закрывающейся скобки или неправильно отделены комментарии.

Для определения ошибки внимательно просмотрите строку-подсказку и внесите необходимые изменения. Ниже мы приведем примеры наиболее часто встречающихся синтаксических ошибок компиляции кода:

  • Ошибка “expected initializer before ‘}’ token” говорит о том, что случайно удалена или не открыта фигурная скобка.
  • Ошибка “a function-definition is not allowed here before ‘{‘ token” – аналогичная предыдущей и указывает на отсутствие открывающейся скобки, например, открывающих скобок в скетче только 11, а закрывающих 12.
  • Уведомление об ошибке “undefined reference to “setup” получите в случае переименования или удаления функции “setup”.
  • Ошибка “undefined reference to “loop” – возникает в случае удаления функции loop. Без команд этой функции компилятор запустить программу не сможет. Для устранения надо вернуть каждую из команд на нужное место в скетче.
  • Ошибка “… was not declared in this scope” обозначает, что в программном коде обнаружены слова, которые написаны с ошибкой (например, которые обозначают какую-то функцию) или найдены необъявленные переменные, методы. Подобная ошибка возникает также в случае случайного удаления значка комментариев и текст, который не должен восприниматься как программа, читается IDE.

Ошибки компиляции и их решения, для плат Arduino, синтаксические ошибки картинка

Ошибки библиотек

Большое количество ошибок возникает на уровне подключения библиотек или неправильного их функционирования. Наиболее известные:

  • “fatal error: … No such file or directory”. Такое сообщение вы получите, если необходимую в скетче библиотеку вы не записали в папку libraries. Сообщение об ошибке в одном из подключенных файлов может означать, что вы используете библиотеку с ошибками или библиотеки не совместимы. Решение – обратиться к разработчику библиотеки или еще раз проверить правильность написанной вами структуры.
  • “redefinition of void setup” – сообщение возникает, если автор библиотеки объявил функции, которые используются и в вашем коде. Чтобы исправить – переименуйте свои методы или в библиотеке.

Ошибки компилятора

Нестабильность в работе самого компилятора тоже могут возникать при отладке программы. Вариантов выхода из данной ситуации может быть несколько, например, установить последнюю версию компилятора. Иногда решением может быть наоборот, возвращение до более старой версии. Тогда используемая библиотека может работать корректно.

Ошибки компиляции при работе с разными платами — Uno, Mega и Nano

В Arduino можно писать программы под разные варианты микроконтроллеров. По умолчанию в меню выбрана плата Arduino/Genuino Uno. Если забудете о том что нужно указать нужную плату – в вашем коде будут ссылки на методы или переменные, не описанные в конфигурации “по умолчанию”.

Вы получите ошибку при компиляции “programmer is not responding”. Чтобы исправить ее – проверьте правильность написания кода в части выбора портов и вида платы. Для этого в Ардуино IDE в меню «Сервис» выберите плату. Аналогично укажите порт в меню “Сервис” – пункт «Последовательный порт».

Ошибка exit status 1

В среде разработки такое сообщение можно увидеть во многих случаях. И хотя в документации данная ошибка указывается как причина невозможности запуска IDE Аrduino в нужной конфигурации, на самом деле причины могут быть и другие. Для того, чтобы найти место, где скрывается эта ошибка можно “перелопатить” действительно много. Но все же стоит сначала проверить разрядность системы и доступные библиотеки.

Ошибки компиляции и их решения, для плат Arduino, Ошибка exit status 1

Обновления и исправления касательно версий инструкции и ПО

Понравилась статья? Поделить с друзьями:
  • Ошибка компиляции для платы wemos d1 r2 mini
  • Ошибка компиляции для платы nodemcu
  • Ошибка компиляции для платы lgt8f328p lqfp32 minievb
  • Ошибка компиляции для платы lgt8f328
  • Ошибка компиляции для платы generic stm32f103c series