Автоматическая кормушка для рыб

Проекты на Arduino и Slot Shield

Аквариум с рыбками прекрасно успокаивает нервы после тяжёлого рабочего дня. За его обитателями можно наблюдать часами напролёт. Но что делать, если хочется уехать отпуск или на дачу. Везти аквариум с собой — нелепая идея. Конечно можно попросить кого-нибудь из знакомых регулярно кормить рыбок, но лучше воспользоваться инженерными навыками и собрать простую автоматическую кормушку на Arduino.

Устройство будет трясти пакетиком с кормом точно по расписанию. За точность часов отвечает модуль RTC, а время кормления задаётся с помощью четырёхкнопочной клавиатуры и цифрового дисплея.

Что потребуется

Видеоинструкция

Как собрать

Установите Troyka Slot Shield на Iskra Neo

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

Переверните Quad Display на 180 градусов и вставьте в центральный и правый слоты нижнего ряда.

Поверните четырёхкнопочную клавиатуру на 90 градусов против часовой стрелки и вставьте в правый верхний слот.

Подключите сервопривод трёхпроводным шлейфом через штырьковые соединители к пину 11.

Скетч

Прошейте контроллер скетчем через Arduino IDE.

fish-fider.ino
// библиотека для работы I²C
#include <Wire.h>
// библиотека для работы с часами реального времени
#include "TroykaRTC.h"
// библиотека для работы с сервоприводами
#include <Servo.h>
// библиотека для работы с дисплеем
#include <QuadDisplay2.h>
// библиотека для работы с кнопками
#include "TroykaButton.h"
 
// пин с сервоприводом
#define SERVO_PIN     11
// пины к которым подключены кнопки
#define BUTTON_PIN_1  0
#define BUTTON_PIN_2  1
#define BUTTON_PIN_3  4
#define BUTTON_PIN_4  5
// период блокировки включения подачи еды в мс
#define TIME_BLOCK    60000
// создаём объект для работы с часами реального времени
RTC clock;
// создаём объект для управления сервоприводом
Servo myservo;
// создаём объект класса QuadDisplay и передаём номер пина CS
QuadDisplay qd(10);
 
// создаём объект для работы с кнопкой
TroykaButton button1(BUTTON_PIN_1);
TroykaButton button2(BUTTON_PIN_2);
TroykaButton button3(BUTTON_PIN_3);
TroykaButton button4(BUTTON_PIN_4);
 
// переменные для хранения времени кормления
// по умолчанию время кормёжки «12:30»
int hourAlarm = 12;
int minuteAlarm = 30;
// состояние кормушки (текущее время / установка времени кормления)
bool state = true;
// переменная для хранения текущего времени
unsigned long ms = 0;
 
void setup()
{
  Serial.begin(9600);
  // инициализация дисплея
  qd.begin();
  // инициализация часов
  clock.begin();
  // метод установки времени и даты в модуль вручную
  // clock.set(10,25,45,27,07,2005,THURSDAY);
  // метод установки времени и даты автоматически при компиляции
  clock.set(__TIMESTAMP__);
  // инициализация кнопок
  button1.begin();
  button2.begin();
  button3.begin();
  button4.begin();
  // запоминаем текущее время
  ms = millis();
}
 
void loop()
{
  // считывание данных с кнопок
  button1.read();
  button2.read();
  button3.read();
  button4.read();
  // запрашиваем данные с часов
  clock.read();
  // считываем показания часов и минут в переменные
  int hour = clock.getHour();
  int minute = clock.getMinute();
  // если кнопка «1» длительно зажата  
  if (button1.isHold()) {
    // меняем состояние кормушки
    state = !state;
    // в зависимости от текущего состояние кормушки
    if (!state) {
      qd.displayDigits(QD_F, QD_O, QD_O, QD_d);
    } else {
      qd.displayDigits(QD_t, QD_I, QD_S, QD_H);
    }
    // ждём пару секунд
    delay(2000);
  }
 
  // в зависимости от текущего режима работы кормушки
  // «текущее время / время кормления»
  // если режим «текущее время»
  if (state) {
    // в зависимости от состояние кнопок
    // увеличиваем / уменьшаем часы и минуты
    if (button1.justReleased()) {
      Serial.println("1");
      clock.setHour(hour + 1);
    } else if (button2.justReleased()) {
      Serial.println("2");
      clock.setHour(hour - 1);
    } else if (button3.justReleased()) {
      Serial.println("3");
      clock.setMinute(minute - 1);
    } else if (button4.justReleased()) {
      Serial.println("4");
      clock.setMinute(minute + 1);
    }
    // выводим время на дисплей
    qd.displayScore(hour, minute, true);  
  } else {
    // если режим «время кормления»
    // в зависимости от состояние кнопок
    // увеличиваем / уменьшаем часы и минуты
    if (button1.justReleased()) {
      Serial.println("5");
      hourAlarm++;
    } else if (button2.justReleased()) {
      Serial.println("6");
      hourAlarm--;
    } else if (button3.justReleased()) {
      Serial.println("7");
      minuteAlarm--;
    } else if (button4.justReleased()) {
      Serial.println("8");
      minuteAlarm++;
    }
    parsingFoodTime();
    // выводим время кормления на дисплей
    qd.displayScore(hourAlarm, minuteAlarm);
  }
  // если пришло время кормёжки
  if (hour == hourAlarm && minute == minuteAlarm && millis() - ms > TIME_BLOCK) {
    Serial.println("Go Feed");
    // включаем подачу еды
    goFeed();
    // запоминаем текущее время
    ms = millis();
  }
}
 
// функция включения сервопривода
void goFeed() {
  // подключаем сервопривод
  myservo.attach(SERVO_PIN);
  for (int i = 0; i < 10; i++){
    myservo.write(50);
    delay(200);
    myservo.write(80);
    delay(200);
  }
}
 
// функция парсинга времени
void parsingFoodTime() {
  if (hourAlarm > 23) {
    hourAlarm = 0;
  } else if (hourAlarm < 0) {
    hourAlarm = 23;
  }
 
  if (minuteAlarm > 59) {
    minuteAlarm = 0;
  } else if (minuteAlarm < 0) {
    minuteAlarm = 59;
  }
}

Что дальше?

Хотите собрать другой девайс? Выберите своё будущее устройство из списка проектов на Slot Shield.

Часто задаваемые вопросы

Где скачать необходимые библиотеки и как их установить?
У моего модуля QuadDisplay всего три ноги и расположены они слева. Можно ли использовать его в этом проекте?

Да, модуль можно использовать, но скетч, библиотеки и схема сборки отличаются. Мы работаем над второй версией программы для старых дисплеев и скоро выложим её на этой странице.