Для всех любителей рыбок, представляем устройство способное помочь Вам в заботе о морских обитателях. Самодельная автоматическая кормушка не затратит много хлопот в ее установке, а так же не придется тратиться на дорогие кормушки. Самодельность заключается в том, чтобы небольшой цилиндр закрепить на ось сервопривода. Например пластиковый стакан, в котором необходимо проделать дырки под Ваш корм.
Описание работы:
Для начала работы подключите питание к Arduino. На дисплее Вы увидите время в верхнем ряду. В среднем ряду - 4 квадрата внутри которых в зависимости от вашей платы Arduino, появятся либо прочерки либо цифры. 4 квадрата - это возможность 4 раза задать время кормления рыбок. При наступлении этого времени, произойдет кормление рыбок. Нижний ряд - это количество поворотов сервопривода. Для настройки устройства, нажмите любую кнопку. Начнет мигать значение часов в верхнем ряду. Для регулирования параметра "Часы" нажимайте кнопки: синюю или зеленую. При нажатии синей кнопки значение часов будет уменьшаться, при нажатии зеленой кнопки значение часов будет увеличиваться. Для перехода к настройкам следующего параметра, необходимо подождать 3 секунды. По истечению трех секунд параметр "Часы" перестанет мигать, и начнет мигать параметры "Минуты". Для регулирования минут, нажимайте так же синюю либо зеленую кнопку для уменьшения, либо увеличения минут. И для перехода к следующему параметру так же необходимо подождать три секунды и так далее. Время кормления рыбок задается только часами, следовательно в квадратах для задания времени кормления рыбок, в каждом из квадратов задается диапазон от 0 до 23 и прочерк, если вы хотите отключить одну из позиции. Последний ряд регулируется в диапазоне от 1 до 10. То есть при повороте сервопривода, будет поворачиваться стакан на 180 градусов, создаст небольшую тряску, в виде быстрого поворота стакана на небольшие углы и вернется в исходное положение. Количество поворотов стакана на небольшие углы и регулирует нижний ряд на дисплее. Таким образом происходит регулирование порций для рыбок. При нажатии кнопок, горят светодиоды внутри кнопок. При наступлении времени кормления рыбок светодиоды в кнопках будут тоже индицировать. Попеременно мигать.
Нам понадобится:
- Arduino Uno х 1шт.
- Trema Set Shield х 1шт.
- Trema OLED-дисплей 128x64 х 1шт.
- Trema-модуль кнопка со светодиодом, синяя х 1шт.
- Trema-модуль кнопка со светодиодом, зеленая х 1шт.
- Trema-модуль часы реального времени, RTC х 1шт.
- Штыревой соединитель х 1шт.
- Сервопривод х 1шт.
Для реализации проекта нам необходимо установить следующие библиотеки:
- iarduino_OLED - графическая библиотека для работы с Trema OLED дисплеями.
- Библиотека iarduino_RTC для работы с Trema-модуль часами реального времени, RTC.
- Библиотека Servo для работы с сервоприводами (библиотека входит в стандартный набор Arduino IDE).
- Библиотека EEPROM - для работы с энергонезависимой памятью EEPROM (библиотека входит в стандартный набор Arduino IDE).
О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki - Установка библиотек в Arduino IDE.
Схема сборки:
- Устанавливаем Trema Set Shield в Arduino Uno.
- Устанавливаем Trema OLED-дисплей 128x64 в 3 посадочную площадку, в верхнюю I2C колодку.
- Устанавливаем Trema-модуль часы реального времени, RTC в 5 посадочную площадку, в верхнюю I2C колодку.
- Устанавливаем Trema-модуль синюю кнопку со светодиодом в 4 посадочную площадку.
- Устанавливаем Trema-модуль зеленую кнопку со светодиодом в 6 посадочную площадку.
- Устанавливаем Сервопривод в 1 посадочную площадку, воспользуясь Штыревым соединителем.
- Полученный результат представлен на рисунке ниже.
- На ось сервопривода закрепить стакан с дырками и закрыть стакан крышкой, как показано на рисунке ниже.
В Верхней части стакана необходимо сделать отверстия, чтобы при повороте сервопривода на 180 градусов, корм высыпался через отверстия. Стакан можно использовать любой для Вашего удобства в зависимости от количества корма. Хоть пластиковый из под сметаны с готовой крышкой, хоть стакан для лекарств из аптеки.
Код программы:
#include <EEPROM.h> // Подключаем библиотеку EEPROM. // #include <Servo.h> // Подключаем библиотеку Servo. Servo servo; // Объявляем объект для работы с сервоприводом. // #include <Wire.h> // Подключаем библиотеку для работы с аппаратной шиной I2C, до подключения библиотек iarduino_RTC и iarduino_OLED. #include <iarduino_RTC.h> // Подключаем библиотеку. iarduino_RTC time(RTC_DS3231); // Объявляем объект time для модуля на базе чипа DS3231. // #include <iarduino_OLED.h> // Подключаем библиотеку iarduino_OLED. iarduino_OLED myOLED(0x3C); // Объявляем объект myOLED, указывая адрес дисплея на шине I2C: 0x3C. extern const uint8_t MediumFont[]; // Подключаем шрифт MediumFontRus. extern const uint8_t SmallFont[]; // Подключаем шрифт MediumFontRus. // const uint8_t pinLedBlue = A2; // Создаем массив констант с № входов к которым подключены светодиоды. const uint8_t pinLedGreen = 5; // Создаем массив констант с № входов к которым подключены светодиоды. // const uint8_t pinKeyBlue = 2; // Создаем массив констант с № входов к которым подключены кнопки. const uint8_t pinKeyGreen = A3; // Создаем массив констант с № входов к которым подключены кнопки. // const uint8_t pinServo = 6; // Определяем № вывода к которому подключён сервопривод. // const uint8_t deg = 30; // Угол отклонения кормушки. const uint16_t del = 400; // Задержка между отклонениями кормушки. // int menu; // Переменная события. int minut; // Переменная минут. int hour; // Переменная часов. int minutPrev; // Переменная предыдущих минут. int i; // Переменная количества счета. int k; // Переменная количества счета. // long prevMicros; // Предыдущая переменная значений счетчика. long prevMicros2; // Вторая предыдущая переменная значений счетчика. bool counter; // Переменная события разрешает/запрещает событие каждые пол секунды. // long microsBlue; // Предыдущее значений счетчика для синей кнопки. long microsGreen; // Предыдущее значений счетчика для зеленой кнопки. // int serv = 10; // Переменная уровня тряски. // int times; // Переменная времени выхода из подпрограммы. int prevTimes; // Переменная предыдущего значения времени выхода из под программы. // int A = 20; // Начальная Y-координата центрального ряда. int mTmAlarm[5]; // Массив значений времени, когда кормить рыбок. uint8_t mCrdTmAlarm[5] = {37,A,A+24,A+24*2,A+24*3}; // Массив координат центрального ряда. // int O = 10; // Начальная Y-координата нижнего ряда. const int massOscill[11] = {50,O,O+11,O+11*2,O+11*3,O+11*4,O+11*5,O+11*6,O+11*7,O+11*8,O+11*9}; // Массив координат нижнего ряда. // void Return(); // Функция переход из одного события в другое. void Check(); // Функция проверки диапазонов. void ChangeTime(); // Функция изменения параметров. Увеличение/уменьшение. void Alert(); // Функция тряски кормушки для рыбок. // void ShowTime(); // Функция вывода на экран времени. void ShowHour(); // Функция вывода на экран часов. void ShowMinut(); // Функция вывода на экран минут. void ShowSec(); // Функция вывода на экран секунда. void ShowAlarm(); // Функция вывода на экран времени кормить рыбок. void ShowServo(); // Функция вывода на экран количества тряски кормушки для рыбок. // void setup() // { // pinMode(pinLedBlue,OUTPUT); // Переводим выводы pinLedBlue в режим выхода. digitalWrite(pinLedBlue,LOW); // Выключаем светодиоды. pinMode(pinKeyBlue,INPUT); // Переводим выводы pinKeyBlue в режим входа. // pinMode(pinLedGreen,OUTPUT); // Переводим выводы pinLedGreen в режим выхода. digitalWrite(pinLedGreen,LOW); // Выключаем светодиоды. pinMode(pinKeyGreen,INPUT); // Переводим выводы pinKeyGreen в режим входа. // servo.attach(pinServo); // Присоединяем сервопривод к выводу pinServo. // myOLED.begin(); // Инициируем работу с дисплеем. myOLED.autoUpdate(false); // Запрещаем автоматический вывод данных. time.begin(); // Инициируем RTC модуль. // menu = 1; // Разрешаем переход к событию 1. servo.write(0); // Устанавливаем сервопривод в 0 градусов. // for(int i = 1; i <= 4; i++) // В цикле считываем время кормления рыбок из памяти EEPROM. { // mTmAlarm[i] = EEPROM.read(i); // Считываем время кормления рыбок из памяти EEPROM. if (mTmAlarm[i] > 23 || mTmAlarm[i] < 0) {mTmAlarm[i] = 24;} // Если значение не в диапазоне от 0 до 23, то присваиваем значение 24. } // serv = EEPROM.read(5); // Считываем количество тряски из памяти EEPROM. if (serv > 10 || serv < 1) {serv = 9;} // Проверяем на диапазон от 1 до 10, если нет то присваиваем значение 9. } // // void loop() // { // if (micros() - microsBlue > 500000) {digitalWrite(pinLedBlue,LOW);} // Каждые пол секунды мигаем значением часов. if (micros() - microsGreen > 500000){digitalWrite(pinLedGreen,LOW);} // Каждые пол секунды мигаем значением часов. // switch(menu) // Выбор события. { // case 1: // Событие 1. // Прорисовываем двоеточия между часами и минутами. if (micros() - prevMicros > 500000) // Каждые пол секунды мигаем двоеточием. { // prevMicros = micros(); // Сохраняем предыдущее значение таймера. counter=!counter; // Изменяем переменную события вывода значений на индикатор. if (!counter) // Если переменная события false. { // myOLED.drawLine(65, 9, 65, 11, 0); // Гасим линию. myOLED.drawLine(65, 16, 65, 18, 0); // Гасим линию. myOLED.drawLine(64, 10, 66, 10, 0); // Гасим линию. myOLED.drawLine(64, 17, 66, 17, 0); // Гасим линию. } // else // Если переменная события true. { // myOLED.drawLine(65, 9, 65, 11, 1); // Прорисовываем линию. myOLED.drawLine(65, 16, 65, 18, 1); // Прорисовываем линию. myOLED.drawLine(64, 10, 66, 10, 1); // Прорисовываем линию. myOLED.drawLine(64, 17, 66, 17, 1); // Прорисовываем линию. } // } // // myOLED.setFont(MediumFont); // Указываем шрифт Medium который требуется использовать для вывода цифр и текста. time.gettime(); // Читаем время, обновляя значения всех переменных. hour = time.Hours; // Сохраняем значение часов. minut = time.minutes; // Сохраняем значение минут. ShowTime(); // Функция вывода на экран времени. // for(int i = 1; i <= 4; i++) // В цикле проверяем совпадение текущего времени и времени кормления рыбок. {if(mTmAlarm[i] == hour && minut == 0 && time.seconds == 0){Alert();}} // Если время кормления рыбок совпадает с текущем временем, то переходим к функции тряски кормушки. // myOLED.setFont(SmallFont); // Указываем шрифт Small который требуется использовать для вывода цифр и текста. for(int i = 1; i <= 4; i++) // В цикле формируем центральный ряд параметров. { // if (mTmAlarm[i]>=0 && mTmAlarm[i]<10) // Если количество времени от 0 до 9. { // myOLED.print(F("0"), mCrdTmAlarm[i], mCrdTmAlarm[0]); // Добавляем спереди ноль, выводя его на дисплей. myOLED.print(mTmAlarm[i], mCrdTmAlarm[i]+6, mCrdTmAlarm[0]); // Выводим переменную значения времени кормления рыбок. } // else{myOLED.print(mTmAlarm[i], mCrdTmAlarm[i], mCrdTmAlarm[0]);} // Иначе выводим переменную значения времени кормления рыбок без нуля. myOLED.drawRect(mCrdTmAlarm[i]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[i]+14, mCrdTmAlarm[0]+2, false, 1); // Выводим на экран рамки для значений времени кормления рыбок. } // // for(int i = 1; i <= 4; i++) // В цикле сравниваем переменные времени кормления рыбок с числом 24 и 0. { // if (mTmAlarm[i] == 24 || mTmAlarm[i] == -1) // Если переменные времени кормления рыбок равны 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[i]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[i]+13, mCrdTmAlarm[0]+1, true, 0); // Гасим квадрат. myOLED.drawLine(23+24*(i-1), 33, 29+24*(i-1), 33, 1); // Прорисовываем линию. } // } // // myOLED.drawRect(O-3, massOscill[0]-3, O+109, massOscill[0]+7, false, 1); // Выводим рамку нижнего ряда. for(int i = 1; i <= serv; i++) // В цикле формируем уровень тряски кормушки. { // myOLED.drawRect(massOscill[i], massOscill[0], massOscill[i]+7, massOscill[0]+4, true, 1); // Выводим уровень тряски кормушки в виде прямоугольников. } // // myOLED.update(); // Обновляем информацию на дисплее. if(digitalRead(pinKeyBlue)) {digitalWrite(pinLedBlue,HIGH); microsBlue = micros();} // Если нажата синяя кнопка, то включаем ее светодиод, считываем значения счетчика. if(digitalRead(pinKeyGreen)){digitalWrite(pinLedGreen,HIGH); microsGreen = micros();} // Если нажата зеленая кнопка, то включаем ее светодиод, считываем значения счетчика. if(digitalRead(pinKeyBlue) || digitalRead(pinKeyGreen)) {menu = 2;} // Если нажата кнопка, то разрешаем переход к событию 2, сбрасываем секунды. break; // Выходим из оператора case. // case 2: // Событие 2. delay(200); // Задержка 200 мс. menu = 3; // Разрешаем переход к событию 3. break; // Выходим из оператора case. // case 3: // Событие 2. myOLED.setFont(MediumFont); // Указываем шрифт Medium который требуется использовать для вывода цифр и текста. if (micros() - prevMicros > 500000) // Каждые пол секунды мигаем значением часов. { // prevMicros = micros(); // Сохраняем предыдущее значение таймера. counter=!counter; // Изменяем переменную события вывода значений на индикатор. if (!counter) // Если переменная события false. { // myOLED.drawRect(39,5,60,20, true, 0); // Гасим значение на индикаторе. } // else // Если переменная события true. { // ShowTime(); // Выводим на экран значения часов. } // } // myOLED.update(); // Обновляем информацию на дисплее. ChangeTime(); // Функция изменения параметров. Увеличение/уменьшение. time.settime(-1, -1, hour); // Присваиваем значение часов датчику реального времени. times = hour; // Присваиваем значение часов переменной времени выхода из подпрограммы. Return(); // Функция переход из одного события в другое. break; // Выходим из оператора case. // case 4: // Событие 3. ShowHour(); // Выводим на экран значения часов. myOLED.setFont(MediumFont); // Указываем шрифт Medium который требуется использовать для вывода цифр и текста. if (micros() - prevMicros > 500000) // Каждые пол секунды мигаем значением минут. { // prevMicros = micros(); // Сохраняем предыдущее значение таймера. counter=!counter; // Изменяем переменную события вывода значений на индикатор. if (!counter) // Если переменная события false. { // myOLED.drawRect(67,5,92,20, true, 0); // Гасим значение на индикаторе. } // else // Если переменная события true. { // ShowMinut(); // Выводим на экран значения минут. } // } // myOLED.update(); // Обновляем информацию на дисплее. ChangeTime(); // Функция изменения параметров. Увеличение/уменьшение. time.settime(0, minut, -1); // Присваиваем значение минут датчику реального времени. times = minut; // Присваиваем значение минут переменной времени выхода из подпрограммы. Return(); // Функция переход из одного события в другое. break; // Выходим из оператора case. // case 5: // Событие 5. ShowMinut(); // Выводим на экран значения минут. menu = 6; // Разрешаем переход к событию 6. break; // Выходим из оператора case. // case 6: // Событие 6. myOLED.setFont(SmallFont); // Указываем шрифт Small который требуется использовать для вывода цифр и текста. if (micros() - prevMicros > 500000) // Каждые пол секунды мигаем рамкой первого значения времени кормления рыбок. { // prevMicros = micros(); // Сохраняем предыдущее значение таймера. counter=!counter; // Изменяем переменную события вывода значений на индикатор. if (!counter) // Если переменная события false. { // myOLED.drawRect(mCrdTmAlarm[1]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[1]+14, mCrdTmAlarm[0]+2, false, 1); // Выводим рамку первого значения времени кормления рыбок на индикатор. } // else // Если переменная события true. { // myOLED.drawRect(mCrdTmAlarm[1]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[1]+14, mCrdTmAlarm[0]+2, false, 0); // Гасим румку первого значения времени кормления рыбок на индикаторе. } // } // myOLED.update(); // Обновляем информацию на дисплее. ChangeTime(); // Функция изменения параметров. Увеличение/уменьшение. times = mTmAlarm[1]; // Присваиваем первое значение времени кормления рыбок переменной времени выхода из подпрограммы. Return(); // Функция переход из одного события в другое. if(menu != 6){EEPROM.write(1, mTmAlarm[1]);} // Если изменилась переменная события, то записываем в память EEPROM время первого кормления рыбок. break; // Выходим из оператора case. // case 7: // myOLED.drawRect(mCrdTmAlarm[1]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[1]+14, mCrdTmAlarm[0]+2, false, 1); // Выводим румку первого значения времени кормления рыбок на индикатор. myOLED.setFont(SmallFont); // Указываем шрифт Small который требуется использовать для вывода цифр и текста. if (micros() - prevMicros > 500000) // Каждые пол секунды мигаем рамкой второго значения времени кормления рыбок. { // prevMicros = micros(); // Сохраняем предыдущее значение таймера. counter=!counter; // Изменяем переменную события вывода значений на индикатор. if (!counter) // Если переменная события false. { // myOLED.drawRect(mCrdTmAlarm[2]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[2]+14, mCrdTmAlarm[0]+2, false, 1); // Выводим румку второго значения времени кормления рыбок на индикатор. } // else // Если переменная события true. { // myOLED.drawRect(mCrdTmAlarm[2]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[2]+14, mCrdTmAlarm[0]+2, false, 0); // Гасим румку второго значения времени кормления рыбок на индикаторе. } // } // myOLED.update(); // Обновляем информацию на дисплее. ChangeTime(); // Функция изменения параметров. Увеличение/уменьшение. times = mTmAlarm[2]; // Присваиваем второе значение времени кормления рыбок переменной времени выхода из подпрограммы. Return(); // Функция переход из одного события в другое. if(menu != 7){EEPROM.write(2, mTmAlarm[2]);} // Если изменилась переменная события, то записываем в память EEPROM время второго кормления рыбок. break; // Выходим из оператора case. // case 8: // Событие 8. myOLED.drawRect(mCrdTmAlarm[2]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[2]+14, mCrdTmAlarm[0]+2, false, 1); // Выводим румку второго значения времени кормления рыбок на индикатор. myOLED.setFont(SmallFont); // Указываем шрифт Small который требуется использовать для вывода цифр и текста. if (micros() - prevMicros > 500000) // Каждые пол секунды мигаем рамкой третьего значения времени кормления рыбок. { // prevMicros = micros(); // Сохраняем предыдущее значение таймера. counter=!counter; // Изменяем переменную события вывода значений на индикатор. if (!counter) // Если переменная события false. { // myOLED.drawRect(mCrdTmAlarm[3]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[3]+14, mCrdTmAlarm[0]+2, false, 1); // Выводим румку третьего значения времени кормления рыбок на индикатор. } // else // Если переменная события true. { // myOLED.drawRect(mCrdTmAlarm[3]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[3]+14, mCrdTmAlarm[0]+2, false, 0); // Гасим румку третьего значения времени кормления рыбок на индикаторе. } // } // myOLED.update(); // Обновляем информацию на дисплее. ChangeTime(); // Функция изменения параметров. Увеличение/уменьшение. times = mTmAlarm[3]; // Присваиваем третье значение времени кормления рыбок переменной времени выхода из подпрограммы. Return(); // Функция переход из одного события в другое. if(menu != 8){EEPROM.write(3, mTmAlarm[3]);} // Если изменилась переменная события, то записываем в память EEPROM время третьего кормления рыбок. break; // Выходим из оператора case. // case 9: // Событие 9. myOLED.drawRect(mCrdTmAlarm[3]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[3]+14, mCrdTmAlarm[0]+2, false, 1); // Выводим румку третьего значения времени кормления рыбок на индикатор. myOLED.setFont(SmallFont); // Указываем шрифт Small который требуется использовать для вывода цифр и текста. if (micros() - prevMicros > 500000) // Каждые пол секунды мигаем рамкой четвертого значения времени кормления рыбок. { // prevMicros = micros(); // Сохраняем предыдущее значение таймера. counter=!counter; // Изменяем переменную события вывода значений на индикатор. if (!counter) // Если переменная события false. { // myOLED.drawRect(mCrdTmAlarm[4]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[4]+14, mCrdTmAlarm[0]+2, false, 1); // Выводим румку четвертого значения времени кормления рыбок на индикатор. } // else // Если переменная события true. { // myOLED.drawRect(mCrdTmAlarm[4]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[4]+14, mCrdTmAlarm[0]+2, false, 0); // Гасим румку четвертого значения времени кормления рыбок на индикаторе. } // } // myOLED.update(); // Обновляем информацию на дисплее. ChangeTime(); // Функция изменения параметров. Увеличение/уменьшение. times = mTmAlarm[4]; // Присваиваем четвертое значение времени кормления рыбок переменной времени выхода из подпрограммы. Return(); // Функция переход из одного события в другое. if(menu != 9){EEPROM.write(4, mTmAlarm[4]);} // Если изменилась переменная события, то записываем в память EEPROM время четвертого кормления рыбок. break; // Выходим из оператора case. // case 10: // Событие 10. myOLED.drawRect(mCrdTmAlarm[4]-2, mCrdTmAlarm[0]-10, mCrdTmAlarm[4]+14, mCrdTmAlarm[0]+2, false, 1); // Выводим рамку четвертого значения времени кормления рыбок на индикатор. menu = 11; // Разрешаем переход к событию 11. break; // Выходим из оператора case. // case 11: // Событие 11. if (micros() - prevMicros > 500000) // Каждые пол секунды мигаем рамкой уровня тряски кормушки. { // prevMicros = micros(); // Сохраняем предыдущее значение таймера. counter=!counter; // Изменяем переменную события вывода значений на индикатор. if (!counter) // Если переменная события false. { // myOLED.drawRect(O-3, massOscill[0]-3, O+109, massOscill[0]+7, false, 1); // Выводим рамку уровня тряски кормушки. } // else // Если переменная события true. { // myOLED.drawRect(O-3, massOscill[0]-3, O+109, massOscill[0]+7, false, 0); // Гасим рамку уровня тряски кормушки. } // } // ChangeTime(); // Функция изменения параметров. Увеличение/уменьшение. ShowServo(); // Функция вывода на экран количества тряски кормушки для рыбок. times = serv; // Присваиваем значение уровня тряски кормушки переменной времени выхода из подпрограммы. Return(); // Функция переход из одного события в другое. myOLED.update(); // Обновляем информацию на дисплее. if(menu != 11){EEPROM.write(5, serv);} // Если изменилась переменная события, то записываем в память EEPROM количество тряски. break; // Выходим из оператора case. } // } // // void Return() // Функция переход из одного события в другое. { // if (prevTimes == times) // Если нынешнее значение времени равно предыдущему значению. { // if (micros() - prevMicros2 > 100000) // Каждые 100 мс увеличиваем переменную счета. { // prevMicros2 = micros(); // Сохраняем предыдущее значение таймера. k++; // Увеличиваем переменную счета. } // } // else {k = 0;} // Иначе обнуляем переменную счета. if (k > 30) // Если переменная счета больше 30. { // menu++; k = 0; prevTimes = 0; // Увеличиваем переменную события. Сбрасываем переменную предыдущего значения времени выхода из подпрограммы. if (menu == 12){menu = 1;} // Если событие равно 12, то разрешаем переход к событию 1. } // prevTimes = times; // Сохраняем текущее значение времени выхода из подпрограммы. } // // void Check() // Функция проверки диапазонов. { // if (minut > 59){minut = 0; } // Если минуты больше 59, то обнуляем минуты. if (minut < 0) {minut = 59;} // Если минуты меньше 00, то устанавливаем 59 минут. if (hour > 23) {hour = 0; } // Если часы больше 23, то обнуляем часы. if (hour < 0) {hour = 23;} // Если часы меньше 00, то устанавливаем 23 часа. // if (mTmAlarm[1] > 24){mTmAlarm[1] = 0; } // Если переменная первого значения времени кормления рыбок больше 23, то обнуляем переменную. if (mTmAlarm[1] < -1){mTmAlarm[1] = 23;} // Если переменная первого значения времени кормления рыбок меньше 00, присваиваем ей 23. if (mTmAlarm[2] > 24){mTmAlarm[2] = 0; } // Если переменная второго значения времени кормления рыбок больше 23, то обнуляем переменную. if (mTmAlarm[2] < -1){mTmAlarm[2] = 23;} // Если переменная второго значения времени кормления рыбок меньше 00, присваиваем ей 23. if (mTmAlarm[3] > 24){mTmAlarm[3] = 0; } // Если переменная третьего значения времени кормления рыбок больше 23, то обнуляем переменную. if (mTmAlarm[3] < -1){mTmAlarm[3] = 23;} // Если переменная третьего значения времени кормления рыбок меньше 00, присваиваем ей 23. if (mTmAlarm[4] > 24){mTmAlarm[4] = 0; } // Если переменная четвертого значения времени кормления рыбок больше 23, то обнуляем переменную. if (mTmAlarm[4] < -1){mTmAlarm[4] = 23;} // Если переменная четвертого значения времени кормления рыбок меньше 00, присваиваем ей 23. // if (serv > 10) {serv = 10;} // Если переменная уровня тряски кормушки больше 10, присваиваем ей 10. if (serv < 1) {serv = 1;} // Если переменная уровня тряски кормушки меньше 1, присваиваем ей 1. } // // void ChangeTime() // Функция изменения параметров. Увеличение/уменьшение. { // if(digitalRead(pinKeyBlue)) // Проверка нажатия синей кнопки. { // if(digitalRead(pinKeyBlue)) {digitalWrite(pinLedBlue,HIGH); microsBlue = micros();} // Если нажата синяя кнопка, то включаем ее светодиод, считываем значения счетчика. while(digitalRead(pinKeyBlue)) // Цикл слежения нажатой синей кнопки. { // delay(10); // Ждём пока мы её не отпустим. if(i<100){i++;} // Если переменная счета меньше 100, то увеличиваем переменную счета. else // Если переменная счета больше 100. { // delay(50); // Задержка 50 мс. if(menu==3) {hour--; Check(); ShowHour(); myOLED.update();} // Если Событие 3, то уменьшаем часы, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение, обновляем информацию на дисплее. if(menu==4) {minut--; Check(); ShowMinut(); myOLED.update();} // Если Событие 4, то уменьшаем минуты, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение, обновляем информацию на дисплее. // if(menu==6) {mTmAlarm[1]--; Check(); ShowAlarm(); // Если Событие 6, то увеличиваем переменную первого значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[1] == 24 || mTmAlarm[1] == -1) // Если переменная первого значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[1]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[1]+13, mCrdTmAlarm[0]+1, true, 0);// Гасим квадрат. myOLED.drawLine(23, 33, 29, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. if(menu==7) {mTmAlarm[2]--; Check(); ShowAlarm(); // Если Событие 7, то увеличиваем переменную второго значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[2] == 24 || mTmAlarm[2] == -1) // Если переменная второго значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[2]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[2]+13, mCrdTmAlarm[0]+1, true, 0);// Гасим квадрат. myOLED.drawLine(47, 33, 53, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. if(menu==8) {mTmAlarm[3]--; Check(); ShowAlarm(); // Если Событие 8, то увеличиваем переменную первого значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[3] == 24 || mTmAlarm[3] == -1) // Если переменная первого значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[3]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[3]+13, mCrdTmAlarm[0]+1, true, 0);// Гасим квадрат. myOLED.drawLine(71, 33, 77, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. if(menu==9) {mTmAlarm[4]--; Check(); ShowAlarm(); // Если Событие 6, то увеличиваем переменную первого значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[4] == 24 || mTmAlarm[4] == -1) // Если переменная первого значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[4]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[4]+13, mCrdTmAlarm[0]+1, true, 0);// Гасим квадрат. myOLED.drawLine(95, 33, 101, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. // if(menu==11){serv--; Check(); ShowServo(); myOLED.update();} // Если Событие 11, то уменьшаем переменную уровня тряски кормушки, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение, обновляем информацию на дисплее. } // } // if (i < 70) // Если переменная счета меньше 70. { // if(menu==3) {hour--; Check(); ShowHour(); myOLED.update();} // Если Событие 3, то уменьшаем часы, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение, обновляем информацию на дисплее. if(menu==4) {minut--; Check(); ShowMinut(); myOLED.update();} // Если Событие 4, то уменьшаем минуты, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение, обновляем информацию на дисплее. // if(menu==6) {mTmAlarm[1]--; Check(); ShowAlarm(); // Если Событие 6, то увеличиваем переменную первого значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[1] == 24 || mTmAlarm[1] == -1) // Если переменная первого значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[1]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[1]+13, mCrdTmAlarm[0]+1, true, 0); // Гасим квадрат. myOLED.drawLine(23, 33, 29, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. if(menu==7) {mTmAlarm[2]--; Check(); ShowAlarm(); // Если Событие 7, то увеличиваем переменную второго значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[2] == 24 || mTmAlarm[2] == -1) // Если переменная второго значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[2]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[2]+13, mCrdTmAlarm[0]+1, true, 0); // Гасим квадрат. myOLED.drawLine(47, 33, 53, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. if(menu==8) {mTmAlarm[3]--; Check(); ShowAlarm(); // Если Событие 8, то увеличиваем переменную первого значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[3] == 24 || mTmAlarm[3] == -1) // Если переменная первого значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[3]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[3]+13, mCrdTmAlarm[0]+1, true, 0); // Гасим квадрат. myOLED.drawLine(71, 33, 77, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. if(menu==9) {mTmAlarm[4]--; Check(); ShowAlarm(); // Если Событие 6, то увеличиваем переменную первого значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[4] == 24 || mTmAlarm[4] == -1) // Если переменная первого значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[4]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[4]+13, mCrdTmAlarm[0]+1, true, 0); // Гасим квадрат. myOLED.drawLine(95, 33, 101, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. // if(menu==11){serv--; Check(); ShowServo(); myOLED.update();} // Если Событие 11, то уменьшаем переменную уровня тряски кормушки, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение, обновляем информацию на дисплее. } // i = 0; // Обнуляем переменную счета. } // // if(digitalRead(pinKeyGreen)) // Проверка нажатия зеленой кнопки. { // if(digitalRead(pinKeyGreen)){digitalWrite(pinLedGreen,HIGH); microsGreen = micros();} // Если нажата зеленая кнопка, то включаем ее светодиод, считываем значения счетчика. while(digitalRead(pinKeyGreen)) // Цикл слежения нажатой зеленой кнопки. { // delay(10); // Ждём пока мы её не отпустим. if(i<100){i++;} // Если переменная счета меньше 100, то увеличиваем переменную счета. else // Если переменная счета больше 100. { // delay(50); // Задержка 50 мс. if(menu==3) {hour++; Check(); ShowHour(); myOLED.update();} // Если Событие 3, то увеличиваем часы, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение, обновляем информацию на дисплее. if(menu==4) {minut++; Check(); ShowMinut(); myOLED.update();} // Если Событие 4, то увеличиваем минуты, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение, обновляем информацию на дисплее. // if(menu==6) {mTmAlarm[1]++; Check(); ShowAlarm(); // Если Событие 6, то увеличиваем переменную первого значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[1] == 24 || mTmAlarm[1] == -1) // Если переменная первого значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[1]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[1]+13, mCrdTmAlarm[0]+1, true, 0);// Гасим квадрат. myOLED.drawLine(23, 33, 29, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. if(menu==7) {mTmAlarm[2]++; Check(); ShowAlarm(); // Если Событие 7, то увеличиваем переменную второго значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[2] == 24 || mTmAlarm[2] == -1) // Если переменная второго значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[2]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[2]+13, mCrdTmAlarm[0]+1, true, 0);// Гасим квадрат. myOLED.drawLine(47, 33, 53, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. if(menu==8) {mTmAlarm[3]++; Check(); ShowAlarm(); // Если Событие 8, то увеличиваем переменную первого значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[3] == 24 || mTmAlarm[3] == -1) // Если переменная первого значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[3]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[3]+13, mCrdTmAlarm[0]+1, true, 0);// Гасим квадрат. myOLED.drawLine(71, 33, 77, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. if(menu==9) {mTmAlarm[4]++; Check(); ShowAlarm(); // Если Событие 6, то увеличиваем переменную первого значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[4] == 24 || mTmAlarm[4] == -1) // Если переменная первого значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[4]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[4]+13, mCrdTmAlarm[0]+1, true, 0);// Гасим квадрат. myOLED.drawLine(95, 33, 101, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. // if(menu==11){serv++; Check(); ShowServo(); myOLED.update();} // Если Событие 11, то увеличиваем переменную уровня тряски кормушки, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение, обновляем информацию на дисплее. } // } // if (i < 70) // Если переменная счета меньше 70. { // if(menu==3) {hour++; Check(); ShowHour(); myOLED.update();} // Если Событие 3, то увеличиваем часы, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение, обновляем информацию на дисплее. if(menu==4) {minut++; Check(); ShowMinut(); myOLED.update();} // Если Событие 4, то увеличиваем минуты, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение, обновляем информацию на дисплее. // if(menu==6) {mTmAlarm[1]++; Check(); ShowAlarm(); // Если Событие 6, то увеличиваем переменную первого значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[1] == 24 || mTmAlarm[1] == -1) // Если переменная первого значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[1]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[1]+13, mCrdTmAlarm[0]+1, true, 0); // Гасим квадрат. myOLED.drawLine(23, 33, 29, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. if(menu==7) {mTmAlarm[2]++; Check(); ShowAlarm(); // Если Событие 7, то увеличиваем переменную второго значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[2] == 24 || mTmAlarm[2] == -1) // Если переменная второго значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[2]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[2]+13, mCrdTmAlarm[0]+1, true, 0); // Гасим квадрат. myOLED.drawLine(47, 33, 53, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. if(menu==8) {mTmAlarm[3]++; Check(); ShowAlarm(); // Если Событие 8, то увеличиваем переменную первого значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[3] == 24 || mTmAlarm[3] == -1) // Если переменная первого значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[3]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[3]+13, mCrdTmAlarm[0]+1, true, 0); // Гасим квадрат. myOLED.drawLine(71, 33, 77, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. if(menu==9) {mTmAlarm[4]++; Check(); ShowAlarm(); // Если Событие 6, то увеличиваем переменную первого значения времени кормления рыбок, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение. if (mTmAlarm[4] == 24 || mTmAlarm[4] == -1) // Если переменная первого значения времени кормления рыбок равна 24 или 0, то ставим прочерк. { // myOLED.drawRect(mCrdTmAlarm[4]-1, mCrdTmAlarm[0]-9, mCrdTmAlarm[4]+13, mCrdTmAlarm[0]+1, true, 0); // Гасим квадрат. myOLED.drawLine(95, 33, 101, 33, 1); // Прорисовываем линию. } // myOLED.update();} // Обновляем информацию на дисплее. // if(menu==11){serv++; Check(); ShowServo(); myOLED.update();} // Если Событие 11, то увеличиваем переменную уровня тряски кормушки, проверяем переменную на выход за пределы диапазона, выводим на дисплей значение, обновляем информацию на дисплее. } // i = 0; // Обнуляем переменную счета. } // } // // void ShowServo() // Функция вывода на экран количества тряски кормушки для рыбок. { // for(int i = serv; i <= 10; i++) // В цикле формируем пустые ячейки уровня тряски. {myOLED.drawRect(massOscill[i], massOscill[0], massOscill[i]+7, massOscill[0]+4, true, 0);} // Гасим ячейки уровня тряски. // for(int i = 1; i <= serv; i++) // В цикле формируем ячейки уровня тряски. {myOLED.drawRect(massOscill[i], massOscill[0], massOscill[i]+7, massOscill[0]+4, true, 1);} // Выводим ячейки уровня тряски. } // // void ShowAlarm() // Функция вывода на экран времени кормить рыбок. { // if (mTmAlarm[menu-5]>=0 && mTmAlarm[menu-5]<10) // Если количество времени от 0 до 9. { // myOLED.print(F("0"), mCrdTmAlarm[menu-5], mCrdTmAlarm[0]); // Добавляем спереди ноль, выводя его на дисплей. myOLED.print(mTmAlarm[menu-5], mCrdTmAlarm[menu-5]+6, mCrdTmAlarm[0]); // Выводим переменную значения времени кормления рыбок. } // else{myOLED.print(mTmAlarm[menu-5], mCrdTmAlarm[menu-5], mCrdTmAlarm[0]);} // Иначе выводим переменную значения времени кормления рыбок без нуля. } // // void ShowHour() // Функция показа часов. { // if (hour>=0 && hour<10) // Если количество часов от 0 до 9. { // myOLED.print(F("0"), 38, 20); // Добавляем спереди ноль, выводя его на дисплей. myOLED.print(hour, 50, 20); // Выводим часы. } // else{myOLED.print(hour, 38, 20);} // Иначе выводим часы без нуля. } // // void ShowMinut() // Функция показа минут. { // if (minut>=0 && minut<10) // Если количество минут от 0 до 9. { // myOLED.print(F("0"), 69, 20); // Добавляем спереди ноль, выводя его на дисплей. myOLED.print(minut, 81, 20); // Выводим минуты. } // else{myOLED.print(minut, 69, 20);} // Иначе выводим минуты без нуля. } // // void ShowTime() // Функция показа всего времени. { // if (hour>=0 && hour<10) // Если количество часов от 0 до 9. { // myOLED.print(F("0"), 38, 20); // Добавляем спереди ноль, выводя его на дисплей. myOLED.print(hour, 50, 20); // Выводим часы. } // else{myOLED.print(hour, 38, 20);} // Иначе выводим часы без нуля. // if (minut>=0 && minut<10) // Если количество минут от 0 до 9. { // myOLED.print(F("0"), 69, 20); // Добавляем спереди ноль, выводя его на дисплей. myOLED.print(minut, 81, 20); // Выводим минуты. } // else{myOLED.print(minut, 69, 20);} // Иначе выводим минуты без нуля. } // // void Alert() // Функция тряски кормушки для рыбок. { // servo.write(180); // Устанавливаем сервопривод на 180 градусов. delay(del); // Задержка. for(int i = 1; i <= serv; i++) // Повторяем столько раз сколько задан уровень тряски. От 1 до 10. { // digitalWrite(pinLedBlue,HIGH); // Включаем синей светодиод. servo.write(180 - deg); // Устанавливаем сервопривод на заданный угол. delay(del); // Задержка. digitalWrite(pinLedBlue,LOW); // Выключаем синей светодиод. // digitalWrite(pinLedGreen,HIGH); // Включаем зеленый светодиод. servo.write(180); // Устанавливаем сервопривод на 180 градусов. delay(del); // Задержка. digitalWrite(pinLedGreen,LOW); // Выключаем зеленый светодиод. } // servo.write(0); // Устанавливаем сервопривод в 0 градусов. } //
Особенности:
Для удобства в программе предусмотрены константы для регулирования угла отклонения сервопривода "deg" и задержки между тряской стакана "del". Регулируются в начале скетча. По умолчанию угол отклонения равен 30 градусов, а задержка 400 мс. Прежде чем полноценно использовать устройство поэкспериментируйте с этими значениями, чтобы настроить оптимальную подачу корма Вашим рыбкам.
Алгоритм работы:
В начале скетча (до кода seup) выполняются следующие действия:
- Подключаем стандартную библиотеку EEPROM.h для работы с памятью EEPROM.
- Подключаем библиотеку Servo, для работы с Сервоприводом.
- Объявляем объект servo.
- Подключаем библиотеку iarduino_RTC для работы с Trema-модуль часами реального времени, RTC.
- Объявляем объект time для модуля на базе чипа DS3231.
- Подключаем библиотеку iarduino_4LED для работы с Trema-модуль Четырехразрядным LED индикатором.
- Объявляем объект dispLED, с указанием выводов дисплея.
- Подключаем шрифты
- Объявляем функции, переменный и константы задействованные в скетче.
В коде setup выполняются следующие действия:
- Переводим выводы pinKeyGreen для зеленой кнопки и pinKeyRed для красной кнопки в режим выхода.
- Переводим выводы pinKeyGreen для зеленой кнопки и pinKeyBlue для cbytq кнопки в режим входа, а выводы pinLedGreen и pinLedBlue для светодиодов кнопок в режим выхода.
- Гасим все светодиоды.
- Присоединяем сервопривод к выводу pinServo.
- Инициируем OLED дисплей и запрещаем автоматический вывод данных.
- Инициируем RTC модуль.
- Выбираем событие 1. Устанавливаем сервопривод в 0 градусов. Считываем из памяти EEPROM значение времени кормления рыбок и количество тряски.
В коде loop выполняются следующие действия:
- Через каждые пол секунды, после нажатие кнопки, выключаем светодиод.
- Событие 1.
- Каждые пол секунды мигаем двоеточием между часами и минутами.
- Считываем время, выводим его на дисплей.
- Сравниваем текущее время и время кормления рыбок. При совпадении запускаем сервопривод с помощью функции "Alert()".
- Выводим на дисплей центральный ряд параметров времени кормления рыбок.
- Выводим на дисплей нижний ряд параметра количества тряски стакана.
- Ожидаем нажатие одной из кнопок. При нажатии разрешаем переход к событию 2 и включаем светодиод нажатой клавиши.
- Событие 2.
- Задержка для подавления дребезга кнопки и разрешаем переход к событию 3.
- Событие 3.
- Каждые пол секунды мигаем параметром "Часы". С помощью функции "ChangeTime()" изменяем значение параметра. Устанавливаем значение в датчик реального времени и разрешаем переход к следующему событию с помощью функции "Return()".
- Событие 4.
- Каждые пол секунды мигаем параметром "Минуты". С помощью функции "ChangeTime()" изменяем значение параметра. Устанавливаем значение в датчик реального времени и разрешаем переход к следующему событию с помощью функции "Return()". Настройка секунд происходит в этом событии автоматически, как только перестают мигать минуты, то есть прошло 3 секунды, при переходе к следующему событию, секунды устанавливаются в ноль.
- Событие 5. Выводим минуты на дисплей. и разрешаем переход к событию 6.
- Событие 6 - 9. Каждые пол секунды мигаем рамкой параметра "Время кормления рыбок" в зависимости от события. В событии 6 настраиваем первый параметр, в событии 7 настраиваем второй параметр, в событии 8 настраиваем третий параметр, в событии 9 настраиваем 4 параметр. С помощью функции "ChangeTime()" изменяем значение параметров, а так же возможность установить прочерк, что соответствует отключению времени кормления рыбок. Разрешаем переход к следующему событию с помощью функции "Return()" и сохраняем значение в память EEPROM.
- Событие 10.
- Отрисовываем рамку последнего параметра центрального ряда и разрешаем переход к событию 11.
- Событие 11.
- Кадые пол секунды мигаем рамкой нижнего ряда. С помощью функции "ChangeTime()" изменяем значение параметра. Выводим на дисплей полученный результат. Разрешаем переход к следующему событию с помощью функции "Return()" и сохраняем значение в память EEPROM.
- Функция "Return()". В ней отслеживаем изменение параметров. Если изменялись параметры обнуляем счетчик. Если не изменялись, то ждем три секунды и разрешаем переход к следующему событию. Если события закончились, то разрешаем переход к событию 1.
- Функция "ChangeTime()". В ней при разовом нажатии или удержании синей кнопки уменьшается параметр в зависимости от события. При разовом нажатии или удержании зеленой кнопки увеличивается параметр в зависимости от события.
- Функции "Check()" проверяет параметр на выход из диапазона. Если выходит, то присваиваем противоположное значение.
- Функции "ShowServo()", "ShowAlarm()", "ShowHour()", "ShowMinut()", "ShowTime()" выводят на дисплей параметры.
- Функция "Alert()" поворачивает сервопривод на 180 градусов, затем крутит сервопривод на небольшой угол в зависимости от количества тряски и возвращает сервопривод в исходное положение.
Ссылки:
- Библиотека iarduino_OLED;
- Библиотека iarduino_RTC.
- Wiki - Установка библиотек в Arduino IDE;
- Wiki - OLED экран 128×64 / 0,96”;
- Wiki - описание, подключение Trema-модуль кнопки со светодиодом и ее управление.
- Wiki - описание, подключение Trema-модуль часов реального времени, RTC и их управление.
Обсуждение