В этой статье мы рассмотрим создание автоматической кормушки для животных на основе платы Arduino, которая автоматически будет выдавать еду вашим домашним питомцам по расписанию. В составе этого устройства присутствует микросхема часов реального времени DS3231 RTC (Real Time Clock), с помощью которой устанавливаются дата и время для нашей кормушки. Таким образом, с помощью микросхемы часов реального времени и платы Arduino можно составить расписание, по которому вашим домашним животным будет автоматически выдаваться пища.
Для отображения времени и других статусных сообщений устройства используется ЖК дисплей 16х2. Для привода в действие механизма кормушки используется сервомотор. Клавиатура (клавишная панель) 4х4 используется для выставления времени, в которое нужно кормить животных. Количество выдаваемой кормушкой пищи можно регулировать с помощью угла поворота сервомотора, поэтому ее можно использовать для кормления различных домашних животных – собаки, кошки, птицы и т.д.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- Клавиатура (клавишная панель) 4х4 (купить на AliExpress).
- Модуль часов реального времени DS3231 (RTC DS3231 module) (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- Кнопка.
- Сервомотор (купить на AliExpress).
- Резисторы (купить на AliExpress).
- Соединительные провода.
- Макетная плата
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Работа схемы
Схема автоматической кормушки для животных на основе платы Arduino представлена на следующем рисунке.
Для получения информации о времени и дате в схеме используется микросхема часов реального времени (RTC Module). Клавиатура 4х4 вместе с ЖК дисплеем используются для установки времени кормления. Также ЖК дисплей используется для отображения времени и даты.
Внешний вид собранного устройства на макетной плате у нас получился следующий:
3D модель механических частей кормушки
Мы для изготовления механических частей кормушки использовали 3D принтер, но если у вас его нет, то, мы думаем, для вас не составит особого труда изготовить их из подручных средств.
А если у вас есть 3D принтер, то скачать дизайн механических частей нашей кормушки вы можете по этой ссылке. Материал, использованный для изготовления кормушки, называется PLA. Все 4 части кормушки показаны на следующем рисунке:
Соберите все 4 части в единое целое и подсоедините к ним сервомотор как показано на следующем рисунке.
Также вы можете скачать STL файлы для печати этих частей кормушки на 3D принтере.
Модуль часов реального времени (RTC Module) DS3231
Модуль часов реального времени DS3231 используется в большом числе различных радиоэлектронных проектов для хранения информации о времени и дате. Модуль имеет свою собственную небольшую батарейку (на фото ниже) поэтому может хранить информацию о времени и дате даже когда питание основного устройства отключено. Достаточно один раз в модуле установить дату и время и они будут храниться в нем до тер пока не исчерпается заряд батарейки.
Соответственно, информация о времени кормления животных берется из данного модуля – как только наступает время кормления сервомотор открывает задвижку контейнера и еда поступает животным.
Примечание: перед началом использования модуля DS3231 вам необходимо установить в нем правильные дату и время. Более подробно о работе с данным модулем вы можете прочитать в статье про часы реального времени на основе Arduino.
Объяснение кода программы для Arduino
Полный код программы приведен в конце статьи, здесь же рассмотрим его наиболее важные фрагменты.
Для работы с сервомотором и ЖК дисплеем в Arduino IDE есть встроенные библиотеки, но для взаимодействия с модулем DS3231 и клавиатурой 4х4 необходимо скачать дополнительные библиотеки. Их можно скачать по следующим ссылкам:
Сначала в программе нам необходимо подключить библиотеки, которые мы будем использовать для работы.
1 2 3 4 |
#include <DS3231.h> // для работы с часами реального времени #include <Servo.h> // для работы с сервомотором #include <LiquidCrystal.h> // для работы с ЖК дисплеем #include <Keypad.h> // для работы с клавиатурой |
В следующем фрагменте мы зададим карту клавиш нашей клавиатуры и сообщим плате Arduino к каким ее контактам подключены контакты клавиатуры.
1 2 3 4 5 6 7 8 |
char keys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; byte rowPins[ROWS] = { 2, 3, 4, 5 }; byte colPins[COLS] = { 6, 7, 8, 9 }; |
Далее создадим объект клавиатуры чтобы потом дальше работать с ней в программе. Более подробно о работе с подобной клавиатурой можно прочитать в статье про подключение клавиатуры 4х4 к плате Arduino.
1 |
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); |
Инициализируем контакты A4 и A5 платы Arduino – к ним подключены контакты SCL и SDA модуля DS3231. Также инициализируем контакты для подключения ЖК дисплея и сервомотора.
1 2 3 |
DS3231 rtc(A4, A5); Servo servo_test; //создаем объект сервомотора LiquidCrystal lcd(A0, A1, A2, 11, 12, 13); // контакты Arduino, к которым подключен ЖК дисплей |
В следующем фрагменте кода мы объявим переменные с t1 по t6, массив r[6], а также логическую переменную feed.
1 2 3 4 |
int t1, t2, t3, t4, t5, t6; boolean feed = true; char key; int r[6]; |
Далее, в функции setup() мы зададим режим работы для контактов и включим в работу используемые в схеме устройства.
1 2 3 4 5 6 7 8 9 10 11 |
void setup() { servo_test.attach(10); // к этому контакту подключен сервомотор rtc.begin(); lcd.begin(16,2); servo_test.write(55); Serial.begin(9600); pinMode(A0, OUTPUT); pinMode(A1, OUTPUT); pinMode(A2, OUTPUT); } |
Далее в функции loop() мы должны непрерывно проверять состояние контактов и в зависимости от этого выполнять необходимые действия. При нажатии кнопки необходимо начать процедуру установки времени. Затем сравнивается реальное время со временем кормления, введенным пользователем. Если они совпадают, то дается команда сервомотору повернуть ось на 100 градусов чтобы открыть кормушку и затем через 0,4 секунды снова ее закрыть.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
void loop() { lcd.setCursor(0,0); int buttonPress; buttonPress = digitalRead(A3); if (buttonPress==1) setFeedingTime(); lcd.print("Time: "); String t = ""; t = rtc.getTimeStr(); t1 = t.charAt(0)-48; t2 = t.charAt(1)-48; t3 = t.charAt(3)-48; t4 = t.charAt(4)-48; t5 = t.charAt(6)-48; t6 = t.charAt(7)-48; lcd.print(rtc.getTimeStr()); lcd.setCursor(0,1); lcd.print("Date: "); lcd.print(rtc.getDateStr()); if (t1==r[0] && t2==r[1] && t3==r[2] && t4==r[3]&& t5<1 && t6<3 && feed==true) { servo_test.write(100); //повернуть ось сервомотора на 100 градусов delay(400); servo_test.write(55); feed=false; } } |
В функции void setFeedingTime() производится установка времени кормления, чтобы после этого сохранить введенное время необходимо нажать ‘D’. Когда реальное время будет соответствовать сохраненному дается команда сервомотору на открытие кормушки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
void setFeedingTime() { feed = true; int i=0; lcd.clear(); lcd.setCursor(0,0); lcd.print("Set feeding Time"); lcd.clear(); lcd.print("HH:MM"); lcd.setCursor(0,1); while(1){ key = kpd.getKey(); char j; if(key!=NO_KEY){ lcd.setCursor(j,1); lcd.print(key); r[i] = key-48; i++; j++; if (j==2) { lcd.print(":"); j++; } delay(500); } if (key == 'D') {key=0; break; } } } |
Тестирование работы кормушки
После загрузки кода программы в плату Arduino Uno текущее время и дата начнут показываться на экране ЖК дисплея 16х2. При нажатии кнопки система попросит ввести вас время кормления – вы можете сделать это с помощью клавиатуры 4х4. Введенное время отобразится на дисплее, после этого вы должны нажать клавишу ‘D’ на клавиатуре чтобы сохранить его. Когда текущее и сохранённое время будут совпадать, дается команда сервомотору на поворот с его начальной позиции 55⁰ в позицию 100⁰ и после небольшой задержки возврат в начальную позицию – поскольку ось сервомотора соединена с задвижкой контейнера, то вследствие этого происходит открытие кормушки и последующее ее закрытие. Более подробно все эти процессы показаны на видео, приведенном в конце статьи.
Исходный код программы
В коде программы вы можете изменить угол поворота сервомотора и время, после которого он будет возвращаться в начальное положение – в зависимости от вида животного, которое вы собираетесь кормить с помощью данной кормушки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
#include <DS3231.h> #include <Servo.h> #include <LiquidCrystal.h> #include <Keypad.h> const byte ROWS = 4; // 4 строки const byte COLS = 4; // 4 столбца // задаем карту расположения клавиш клавиатуры char keys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; // Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins. byte rowPins[ROWS] = { 2, 3, 4, 5 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins. byte colPins[COLS] = { 6, 7, 8, 9 }; // создаем объект клавиатуры Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); DS3231 rtc(A4, A5); Servo servo_test; // даем имя используемому сервомотору LiquidCrystal lcd(A0, A1, A2, 11, 12, 13); // контакты, к которым подключен ЖК дисплей //int angle = 0; // int potentio = A0; // initialize the A0analog pin for potentiometer int t1, t2, t3, t4, t5, t6; boolean feed = true; // условие для срабатывания кормушки char key; int r[6]; void setup() { servo_test.attach(10); // к этому контакту подключен сервомотор rtc.begin(); lcd.begin(16,2); servo_test.write(55); Serial.begin(9600); pinMode(A0, OUTPUT); pinMode(A1, OUTPUT); pinMode(A2, OUTPUT); } void loop() { lcd.setCursor(0,0); int buttonPress; buttonPress = digitalRead(A3); if (buttonPress==1) setFeedingTime(); //Serial.println(buttonPress); lcd.print("Time: "); String t = ""; t = rtc.getTimeStr(); t1 = t.charAt(0)-48; t2 = t.charAt(1)-48; t3 = t.charAt(3)-48; t4 = t.charAt(4)-48; t5 = t.charAt(6)-48; t6 = t.charAt(7)-48; lcd.print(rtc.getTimeStr()); lcd.setCursor(0,1); lcd.print("Date: "); lcd.print(rtc.getDateStr()); if (t1==r[0] && t2==r[1] && t3==r[2] && t4==r[3]&& t5<1 && t6<3 && feed==true) { servo_test.write(100); //повернуть сервомотор на угол 100 градусов delay(400); servo_test.write(55); feed=false; } } void setFeedingTime() { feed = true; int i=0; lcd.clear(); lcd.setCursor(0,0); lcd.print("Set feeding Time"); lcd.clear(); lcd.print("HH:MM"); lcd.setCursor(0,1); while(1){ key = kpd.getKey(); char j; if(key!=NO_KEY){ lcd.setCursor(j,1); lcd.print(key); r[i] = key-48; i++; j++; if (j==2) { lcd.print(":"); j++; } delay(500); } if (key == 'D') {key=0; break; } } } |