Кот + Arduino =?

Что может быть общего между двумя этими объектами? 64a8711642917e73db54d773e3bb772f.jpg Идея Однажды я задумал приучить кота к унитазу, с целью избавиться от неприятного запаха, исходящего от его лотка. Но приучить его ходить — это одно, а вот спускать за собой — задача почти невыполнимая. Поэтому я решил возложить это на электронные плечи, в роли которых выступает Arduino Nano.Сценарий задумывался такой: Котэ (тот, что на первой картинке) через минидверцу в двери санузла попадает внутрь, заставляя сработать датчик открытия, делает свои дела сколько ему угодно, и выходит. После второго срабатывания датчика включается вытяжка, спускается вода в унитазе и распыляется освежитель.

Оборудование и тесты К плате были подключены сервомашинка Towerpro MG996R, Z-Wave реле Fibaro FGS221 и кнопка со светодиодом. Кнопку добавил в качестве бонуса параллельно реле и вывел ее на стену.4732c91364fd4fc52f613ed257f8461e.jpg По факту сервомашинка питается от БП 5V 2A. От него же запитана плата по USB.

Схема подключения и код:

d0090c2966279fad3a5176870d5b4037.jpg Код для Arduino #include // подключаем библиотеку Servo

Servo flush; // создаем объект для управления сервой

const int buttonPin = 2; // номер пина кнопки const int led = 4; // номер пина светодиода

int buttonState = 0; // переменная для чтения статуса кнопки int flag = 0; // флаг по умолчанию сброшен unsigned long holdTime = 0; // время начала события unsigned long blinkTime = 0; // время начала события unsigned long loadTime = 0; // время начала события

void setup () { pinMode (led, OUTPUT); // задаем пин светодиода как выход pinMode (buttonPin, INPUT); // задаем пин кнопки как вход flush.attach (3, 8, 140); // привязываем серву к пину 3 и задаем мин/макс угол flush.write (8); // поворачиваем серву в положение по умолчанию }

void loop (){ buttonState = digitalRead (buttonPin); // проверяем положение кнопки

if (buttonState == LOW && flag == 0) { // если кнопка не нажата и флаг не установлен flush.write (8); // поворачиваем серву в положение по умолчанию digitalWrite (led, LOW); // включаем светодиод } if (buttonState == HIGH && flag == 0) { // если кнопка нажата и флаг не установлен delay (100); // защита от дребезга контактов кнопки flush.write (140); // поворачиваем серву на заданный угол flag = 1; // устанавливаем флаг holdTime = millis (); // включаем таймер удержания кнопки } if (buttonState == HIGH && flag == 1 && millis ()-holdTime > 200) { // если кнопка была нажата более X мс flag = 0; // сбрасываем флаг blinkTime = millis (); // включаем таймер мигания светодиода do { digitalWrite (led, LOW); // выключаем светодиод delay (200); digitalWrite (led, HIGH); // включаем светодиод delay (200); } while (millis ()-blinkTime < 5000); // мигаем светодиодом X мс flush.write(8); // поворачиваем серву в положение по умолчанию loadTime = millis(); // включаем таймер ожидания наполнения бачка do { digitalWrite(led, LOW); // выключаем светодиод delay(200); digitalWrite(led, HIGH); // включаем светодиод delay(200); } while (millis()-loadTime < 54000); // мигаем светодиодом X мс (время полного наполнения бачка) } if (buttonState == LOW && flag == 1 && millis()-holdTime <= 200) { // если кнопка была нажата менее X мс flag = 0; // сбрасываем флаг blinkTime = millis(); // включаем таймер мигания светодиода do { digitalWrite(led, LOW); // выключаем светодиод delay(200); digitalWrite(led, HIGH); // включаем светодиод delay(200); } while (millis()-blinkTime < 2000); // мигаем светодиодом X мс flush.write(8); // поворачиваем серву в положение по умолчанию loadTime = millis(); // включаем таймер ожидания наполнения бачка do { digitalWrite(led, LOW); // выключаем светодиод delay(200); digitalWrite(led, HIGH); // включаем светодиод delay(200); } while (millis()-loadTime < 30000); // мигаем светодиодом X мс } } Видео первой версии алгоритма с Z-Wave [embedded content]

Эта версия отличается от финальной только задержкой перед возможностью повторного нажатия кнопки [embedded content]

Задержка равна периоду полной перезарядки бачка водой. Реализация Так как во время ремонта была установлена инсталляция от Geberit, то подключение тяги не составило большого труда. Сервомашинка поставлена враспор между бачком и алюминиевым профилем, прикручена и залита термоклеем. В качестве тяги был использован тросик с зажимами, который пропущен через отверстие в бачке. Гибкая тяга нужна была, чтобы не потерять возможность спуска воды кнопкой на бачке.b0860cbf983f48275d78bc1b5015ddc9.jpg Электронная часть размещена в распаячных коробках за инсталляцией.

a2dc1ab74decab6e272361d66d5da324.jpg Ручное управление может осуществляться как кнопкой, так и через приложение для Fibaro HomeCenter.

c2dbb26fac30e2eafe9537582af0ad1b.jpg Используется два режима спуска:

При коротком нажатии (<200 мс) спускается половина воды. При удержании кнопки более 200 мс, бачок опустошается целиком. Z-Wave реле настроено на второй режим.Демонстрация работы устройства [embedded content]

Задержка срабатывания вызвана тем, что приложение работало в режиме удаленного доступа через сервера fibaro. Заключение К сожалению, котэ на видео не будет, так как он съехал, а желание реализовать задуманное у меня осталось.Ну и бонусом :) [embedded content]

© Habrahabr.ru