Кошачьая лазерная указка

Публикация 24.02.2017

Лучший друг любого кота - яркий луч. Такой проворной добычи зверь еще не встречал. Скачет неутомимо по потолку и стенам и никак его не поймать. Ах как жалко, что этот дружок появляется только в компании с этим человеком. Это мы сегодня исправим!

Кошачьая лазерная указка

Шерстяной друг больше не будет скучать весь день. Мы сделаем ему автоматическую лазерную указку, которая будет гонять его до седьмого пота.

Использовать для сборки будем юыстросборные компоненты лентяя:

Кошачьая лазерная указка
  • Искра нео (дорогой аналог ардуино леонардно)
  • Тройка шилд
  • Сервоприводы FS90 2 шт.
  • Блок питания от телефона
  • Разъем питания 2,1 мм
  • Лазерный диод
  • Шлейфы и провода
  • Структор
  • Нейлоновые винты М3×8 4 шт.
  • Нейлоновые стойки «мама-папа» М3×8 4 шт.
  • Нейлоновые гайки М3 4 шт.

Начнем сборку с основания корпуса. Возьмем панельку структора, на ней закрепим нашу Arduino с помощью специальных крепежей из комплекта структора. Сверху воткнем тройка шилд.

Кошачьая лазерная указка

Сделаем стенки из структора по размерам нашей платы.

Кошачьая лазерная указка

Штатный стабилизатор питания плохо держит нагрузку от сервомоторов и сильно греется. Что бы этого избежать мы сделаем отдельное питание сервомоторов с помощью клеммика. В структоре прорежем отверстия под него.

Кошачьая лазерная указка

Подведем питание от клеммика к gnd/5v arduino. Тем самым мы будем запитывать ее в обход штатного стабилизатора напряжения.

Кошачьая лазерная указка

Теперь из структора нужно собрать панель крепления для серводвигателя горизонтальной оси.

Кошачьая лазерная указка

Чем хорош структор, так это тем, что в нем всегда есть большое разнообразие прорезей под разные крепления. Вот к примеру под качалку сервомотора тоже есть. Используем ее.

Кошачьая лазерная указка

Включаем весь наш творческий потенциал и собираем площадку для сервы вертикальной оси. Закрепляем ее на качалке горизонтальной оси. Ну вот, уже почти все готово!

Кошачьая лазерная указкаКошачьая лазерная указка

Остается просунуть лазерный модуль в отверстие структора. Он входит плотно. Для надежности можно использовать термоклей.

Кошачьая лазерная указка

Соблюдая полярность подключим лазерный диод к тройка шилду на 11 пин.

Кошачьая лазерная указка

Сервомотор горизонтальной оси мы подключим к пину 4. Вертикальный к пину 6.

Кошачьая лазерная указка

Ну вот мы собрали всю механику. Блеск нашего инженерного гения должен поражать всех вокруг!

Кошачьая лазерная указкаКошачьая лазерная указкаКошачьая лазерная указка

Принцип работы программы будет такой:

  • Двигаем оба сервомотора с переменной скоростью в течении 10 сек.
  • Двигаем оба сервомотора с переменной скоростью в течении 5 секунд.

Пример скетча будет такой:

// библиотека для работы с сервоприводами
#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);
}
* комментарии публикуются после модерации
Нет комментариев