Лазерная игрушка для кошек

  • Платформы: Iskra Neo
  • Языки программирования: Arduino (C++)
  • Тэги: Игрушка для кота, лазерная указка, котики и люди, #Структор

Что это?

Лазерная указка — пульт управления кошкой. Эта игрушка даже у самых ленивых представителей кошачьих вызывает небывалый охотничий азарт. А какие трюки проделывает питомец, в попытке схватить призрачную добычу! Давайте соберём лазерную игрушку для кошки вашими руками.

Что нам понадобится?

Как собрать?

  1. Закрепите платформу Iskra Neo на панели #структора «крепление Arduino 7×8 шипов» с помощью акриловых крепежей. Стойки закрепите на панели винтами, сверху установите платформу и зафиксируйте гайками. Это — основание корпуса.
  2. Установите Troyka Shield на плату Iskra Neo.
  3. Прикрепите боковые панели («пластины 7×5 шипов») и заднюю панель («пластина 6×5 шипов») к основанию корпуса игрушки («крепление Arduino 7×8 шипов»).
  4. Так как регулятор напряжения, установленный на плате Iskra Neo, не может выдавать ток, обеспечивающий стабильную работу сервомоторов, мы будем запитывать всю конструкцию от отдельного источника питания на 5V через клеммник. Поэтому, перед установкой лицевой панели («пластина 6×5 шипов»), с помощью бокорезов или ножа сделайте в ней отверстие для клеммника и установите его. Также отделите бокорезами секции, мешающие подключению USB-кабеля. Установите лицевую панель бокса на основание.

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

  5. С помощью проводов «папа-папа» соедините пин 5V Arduino с плюсом клеммника, а пин GND Arduino с минусом клеммника.
  6. С помощью двух панелей «крепление микросервопривода 3×4 шипа» и четырёх панелей («пластина 2×3 шипа») сделайте «домик» для микросервопривода. Данный мотор будет вращаться по оси X, назовём его «Серво-X».
  7. Возьмите качалку для микросервопривода овальной формы. Вставьте её в панель #структора «крепление качалки 2×4 шипа» и прикрутите к валу сервопривода.
  8. Используя «крепление качалки 2×4 шипа» с первого «домика», две панели «крепление микросервопривода 3×4 шипа» и две панели («пластина 2×3 шипа»), сделайте «домик» для второго микросервопривода. Этот мотор будет вращаться по оси Y, назовём его «Серво-Y».
  9. Возьмите качалку для микросервопривода овальной формы. Вставьте её в панель #структора «крепление качалки 2×4 шипа» и прикрутите к валу сервопривода.
  10. Закрепите лазерный модуль к подвижной панели верхнего сервопривода через «пластину 2×2 шипа». Мы получили двухосевой сустав из сервоприводов.
  11. Используя 3-проводной шлейф, подключите лазерный модуль к 11 цифровому пину Troyka Shield.
  12. Подключите «Серво-X» и «Серво-Y» через 3-проводные шлейфы к 4 и 6 пину Troyka Shield соответственно.
  13. В результате должна получиться такая схема:
  14. Установите верхнюю панель («пластина 7×8 шипов»), прикрепив её к боковым, передней и задней стенкам корпуса.
  15. В заключение установите сустав из сервоприводов на верхнюю панель бокса.

Алгоритм

  • Сразу после подачи питания включаем сервоприводы и лазерный модуль.
  • Передвигаем лазерный модуль с большой плавающей скоростью одновременно по двум осям в течении 10 секунд.
  • Передвигаем лазерный модуль с медленной плавающей скоростью одновременно по двум осям в течении 5 секунд.

Исходный код

kittytoy.ino
// библиотека для работы с сервоприводами
#include <Servo.h>
 
// даём разумное имя пину к которому подключён лазерный модуль
#define LASER 11
 
// даём разумное имя пинам к которым подключены сервомоторы
#define SERV_X 4
#define SERV_Y 6
 
// Ограничения углов поворота сервы-X
#define MIN_X  60
#define MAX_X  120
// Ограничения углов поворота сервы-Y
#define MIN_Y  60
#define MAX_Y  90
 
// создаём два объекта для управления сервоприводами
// 1 — для вращение влево-вправо «серво-X»
Servo myservoX;
// 2 — для вращение вверх-вниз «серво-Y»
Servo myservoY;
 
// переменная для хранения положения сервопривода по шкале X
int posX = 0;
// переменная для хранения положения сервопривода по шкале Y
int posY = 0;
 
// переменная для хранения направления сервопривода по шкале X
int dirX = 0;
// переменная для хранения направления сервопривода по шкале Y
int dirY = 0;
 
// переменная для хранения времени работы программы
// после смены режима скорости вращения лазерного модуля
long previousMillis = 0;
 
void setup(void)
{
  // настраиваем пин, к которому подключён лазер в режим выхода
  pinMode(LASER, OUTPUT);
  // подключаем сервоприводы
  myservoX.attach(SERV_X);
  myservoY.attach(SERV_Y);
  // инициализируем генератор псевдослучайных чисел
  // с параметром величиной напряжения аналогового пина 0
  randomSeed(analogRead(0));
  // включаем лазерный модуль
  analogWrite(11, 50);
  // присваиваем переменной случайное значение от MIN_X до MAX_X
  posX = random(MIN_X, MAX_X);
  // присваиваем переменной случайное значение от MIN_Y до MAX_Y
  posY = random(MIN_Y, MAX_Y);
}
 
void loop(void)
{
  // проверяем не прошел ли нужный интервал времени
  while (millis() - previousMillis < 10000) {
    // перемещаем лазерный модуль в режиме 1
    servoRotation(5);
    delay(50);
  }
  //если прошел, то сохраняем текущее время
  previousMillis = millis();
 
  // проверяем не прошел ли нужный интервал времени
  while (millis() - previousMillis < 5000) {
    // перемещаем лазерный модуль в режиме 2
    servoRotation(2);
    delay(100);
  }
  //если прошел, то сохраняем текущее время
  previousMillis = millis();
}
 
// функция вращения лазерного модуля по двум осям
// принимает параметр изменение угла
void servoRotation(int i)
{
  // если направление сервы-X стремиться к увеличению угла
  // и не превысила максимально допустимый угол
  if (dirX == 0 && posX < MAX_X)
    // увеличиваем состояние сервомотора
    // на случайный угол от 0 до i
    posX = posX + random(i);
  // иначе, если направление сервы-X стремится к увеличению угла
  // и превысила или равно максимально допустимому углу
  else if (dirX == 0 && posX >= MAX_X)
    // меняем направление сервы-X
    dirX = 1;
  // иначе, если направление сервы-X стремится к уменьшению угла
  // и не превысила минимально допустимый угол
  else if (dirX == 1 && posX > MIN_X)
    // уменьшаем состояние сервомотора
    // на случайный угол от 0 до i
    posX = posX - random(i);
  // иначе, если направление сервы-X стремится к уменьшению угла
  // и превысила минимально допустимый угол
  else if (dirX == 1 && posX <= MIN_X)
    // меняем направление сервы-X
    dirX = 0;
 
  // устанавливаем заданный угол сервы-X
  myservoX.write(posX);
 
  // если направление сервы-X стремится к увеличению угла
  // и не превысила максимально допустимый угол
  if (dirY == 0 && posY < MAX_Y)
    // увеличиваем состояние сервомотора
    // на случайный угол от 0 до i
    posY = posY + random(i);
  // иначе, если направление сервы-X стремится к увеличению угла
  // и превысила или равно максимально допустимому углу
  else if (dirY == 0 && posY >= MAX_Y)
    // меняем направление сервы
    dirY = 1;
  // иначе, если направление сервы-X стремится к уменьшению угла
  // и не превысила минимально допустимый угол
  else if (dirY == 1 && posY > MIN_Y)
    // уменьшаем состояние сервомотора
    // на случайный угол от 0 до i
    posY = posY - random(i);
  // иначе, если направление сервы-X стремится к уменьшению угла
  // и превысила минимально допустимый угол
  else if (dirY == 1 && posY <= MIN_Y)
    // меняем направление сервы-Y
    dirY = 0;
 
  // устанавливаем заданный угол на сервы-Y
  myservoY.write(posY);
}

Демонстрация работы устройства

Что дальше?

Добавьте в проект Wireless Shield и Bluetooth Bee, и управляйте лазерной игрушкой с мобильного телефона. Привлеките кота звуком с помощью Зуммера (Troyka-модуль). Замените плату Iskra Neo на Arduino Yún, подключите к ней веб-камеру, и наблюдайте за тем как играет ваш питомец где бы вы ни находились.