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

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

- Искра нео (дорогой аналог ардуино леонардно)
- Тройка шилд
- Сервоприводы 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); }