/* --------------------- Antenna v 1.2 -----------------------------
V.1.0 Реализовано:
- Движение от стика + быстрый возврат на исходнуу позицию
- Движение с защитой выхода за пределы мак. углов
- Вывод на экран с кор. для удобства
V.1.1 Реализовано:
- Выбор угла (центр позиции)
- Запоминание угла при отключении питания
V.1.2 Реализовано:
- Запоминание фактических углов
- Плавный возврат к центру при включении и от кнопки.
- Дисплей и центровка выведены в отдельные блоки
--------------- Разработанно группой ПаялоХаб ------------------------ */
// ------------------------------ Библиотеки ------------------------
#include <I2Cdev.h> // Подключаем библиотеку
#include <Servo.h> // Подключаем библиотеку
#include <LiquidCrystal_I2C.h> // Подключаем библиотеку
#include <EEPROM.h> //Подключаем библиотеку
// ------------------------------ Управление ------------------------
LiquidCrystal_I2C lcd(0x27,16,2); // обьявляем экран
Servo myservo1; // обьявляем серво
Servo myservo2; // обьявляем серво
// ------------------------------ Переменные ------------------------
int dirX = 90; //центр 90
int dirX_center = 0; //Указатель центра
float dirX_disp = 0; //Переменная для правельного отображения угла на дисплее
int dirY = 90; //пог 65, центр 155
int dirX_Go = 0; //шаг для серво (плавность)
int dirY_Go = 0; //шаг для серво (плавность)
int x; // ось х стик
int y; // ось y стик
int val = 1; // Кнопка стика
int work = 0; // режим работы
void setup() // основной код. выполняется разово
{
pinMode(5, INPUT); // ввкл. кнопки стика
digitalWrite(5, HIGH); // уст. напряжение
lcd.init(); // вкл. экрана
lcd.backlight(); // Включаем подсветку
lcd.clear(); // Очистка экрана
lcd.setCursor(0, 0); // Позиция курсора
lcd.print("X :"); // вывод инф.
lcd.setCursor(0, 1); // Позиция курсора
lcd.print("Y :"); // вывод инф.
dirX = (EEPROM.read(2)); // Читаем с памяти dirX
dirY = (EEPROM.read(3)); // Читаем с памяти dirY
if (dirX < 0) {dirX = 90;} // Защита
if (dirX > 180) {dirX = 90;} // Защита
if (dirY < 0) {dirY = 90;} // Защита
if (dirY > 90) {dirY = 90;} // Защита
if (dirX < 90) {CenterGo1();} //Центровка
if (dirX > 90) {CenterGo2();} //Центровка
while (dirY < 90) //Центровка
{
dirY = dirY + 2; ////Центровка
oled(); // Экран
myservo2.attach(9); //Вкл. серво
myservo2.write(dirY+65); //Направляем серво
delay(150); // задержка
myservo2.detach(); // откл. сервы
}
dirY = 90; // Контроль
myservo2.attach(9); //Вкл. серво
myservo2.write(dirY+65); //Направляем серво
delay(150); // задержка
myservo2.detach(); // откл. сервы
dirX_center = dirX_center + (EEPROM.read(1)); //Читаем с памяти 2 значение
dirX_center = dirX_center + (EEPROM.read(0)*100); //Читаем с памяти 1 значение
if (dirX_center <0 and dirX_center>360){dirX_center = 0;} //Защита от ошибок
delay (3000); // Задержка
lcd.clear(); // Очистка экрана
lcd.setCursor(0, 0); // Позиция курсора
lcd.print("Center:"); // вывод инф.
}
void loop() // основной код. выполняется циклично
{
//Работа 0 - поворотный механизм выключен. Задаем центр
if (work == 0)
{
val = digitalRead(5); // состояние кнопки (0 нажата кнопка, 1 - нет)
dirX_disp = analogRead(A0); // считываем данные по x со стика
if (dirX_disp <= 123 ) {dirX_center = dirX_center - 2;} //шаг для указания центра
if (dirX_disp > 123 and dirX_disp <= 462) {dirX_center = dirX_center - 1;} //шаг для указания центра
if (dirX_disp >= 562 and dirX_disp < 900) {dirX_center = dirX_center + 1;} //шаг для указания центра
if (dirX_disp > 900) {dirX_center = dirX_center + 2;} //шаг для указания центра
if (val == 0) //Если нажата кнопка серво (возврат на начальную позицию)
{
work = 1; // сброс движения серво
lcd.clear(); // Очистка экрана
lcd.setCursor(0, 0); // Позиция курсора
lcd.print("X :"); // вывод инф.
lcd.setCursor(0, 1); // Позиция курсора
lcd.print("Y :"); // вывод инф.
if (dirX_center < 100){EEPROM.write(0, 0);} // Записываем в память 1 значение
if (dirX_center >= 300) {dirX_center = dirX_center - 300; EEPROM.write(0, 3);} //Записываем в память 1 значение
if (dirX_center >= 200) {dirX_center = dirX_center - 200; EEPROM.write(0, 2);} //Записываем в память 1 значение
if (dirX_center >= 100) {dirX_center = dirX_center - 100; EEPROM.write(0, 1);} //Записываем в память 1 значение
EEPROM.write(1, dirX_center); // Записываем в память 2 значение
dirX_center = dirX_center + (EEPROM.read(0)*100); // Читаем с памяти 1 значение
if (dirX_center <0 and dirX_center>360){dirX_center = 0;} //Защита от ошибок
}
// дисплей
if (dirX_center < 0) {dirX_center = dirX_center + 360;} // защита
if (dirX_center >= 360) {dirX_center = dirX_center - 360;} // защита
lcd.setCursor(7, 0); // Позиция курсора
if (dirX_center < 10) {lcd.print(" ");} // вывод инф.
if (dirX_center >= 10 and dirX_center < 100) {lcd.print(" ");} // вывод инф.
if (dirX_center >= 100) {lcd.print(" ");} // вывод инф.
lcd.print(dirX_center); // вывод инф.
delay(150); // задержка
}
//Работа 1 - поворотный механизм включен
if (work == 1)
{
// Данные со стика
val = digitalRead(5); // состояние кнопки (0 нажата кнопка, 1 - нет)
x = analogRead(A1); // считываем данные по x со стика
if (x <= 123 ) {dirX = dirX + 2; dirX_Go = 1;} //шаг для серво (плавность)
if (x > 123 and x <= 462) {dirX = dirX + 1; dirX_Go = 1;} //шаг для серво (плавность)
if (x >= 562 and x < 900) {dirX = dirX - 1; dirX_Go = 1;} //шаг для серво (плавность)
if (x > 900) {dirX = dirX - 2; dirX_Go = 1;} //шаг для серво (плавность)
y = analogRead(A0); // считываем данные по y со стика
if (y <= 23 ) {dirY = dirY + 2; dirY_Go = 1;} //шаг для серво (плавность)
if (y > 23 and y <= 462) {dirY = dirY + 1; dirY_Go = 1;} //шаг для серво (плавность)
if (y >= 562 and y < 1000) {dirY = dirY - 1; dirY_Go = 1;} //шаг для серво (плавность)
if (y > 1000) {dirY = dirY - 2; dirY_Go = 1;} //шаг для серво (плавность)
// защита пределов углов
if (dirX < 0) {dirX = 0; dirX_Go = 0;} // Предел угла для x
if (dirX > 180) {dirX = 180; dirX_Go = 0;} // Предел угла для x
if (dirY < 0) {dirY = 0; dirY_Go = 0;} // Предел угла для y
if (dirY > 90) {dirY = 90; dirY_Go = 0;} // Предел угла для y
EEPROM.write(2, dirX); // Записываем в память X значение
EEPROM.write(3, dirY); // Записываем в память Y значение
// Перемещение серво
if (val == 0) //Если нажата кнопка серво (возврат на начальную позицию)
{
dirX_Go = 0; // сброс движения серво
if (dirX < 90) {CenterGo1();}
if (dirX > 90) {CenterGo2();}
while (dirY < 90)
{
dirY = dirY + 2; //плавное движение
oled(); //экран
myservo2.attach(9); //Вкл. серво
myservo2.write(dirY+65); //движение серво
delay(150); // задержка
myservo2.detach(); // откл. сервы
}
dirY = 90; //контроль
myservo2.attach(9); //Вкл. серво
myservo2.write(dirY+65); //движение серво
delay(150); // задержка
myservo2.detach(); // откл. сервы
}
if (dirX_Go == 1) // Если движение серво по оси х доступно
{
myservo1.attach(8); // вкл. серво
myservo1.write(dirX); // поворот серво
dirX_Go = 0; // сброс движения серво
}
if (dirY_Go == 1) // Если движение серво по оси y доступно
{
myservo2.attach(9); // вкл. серво
myservo2.write(dirY+65); // поворот серво
dirY_Go = 0; // сброс движения серво
}
oled(); //экран
delay(150); // задержка
myservo1.detach(); // откл. сервы
myservo2.detach(); // откл. сервы
}
}
void CenterGo1 ()
{
while (dirX < 90)
{
dirX = dirX + 2; //плавное движение
oled(); //экран
myservo1.attach(8); //Вкл. серво
myservo1.write(dirX); //Направляем серво
delay(150); // задержка
myservo1.detach(); // откл. сервы
}
dirX = 90; //Контроль
myservo1.attach(8); //Вкл. серво
myservo1.write(dirX); //Направляем серво
delay(150); // задержка
myservo1.detach(); // откл. сервы
oled(); //экран
}
void CenterGo2 ()
{
while (dirX > 90)
{
dirX = dirX - 2; //плавное движение
oled(); //экран
myservo1.attach(8); //Вкл. серво
myservo1.write(dirX); //Направляем серво
delay(150); // задержка
myservo1.detach(); // откл. сервы
}
dirX = 90; //Контроль
myservo1.attach(8); //Вкл. серво
myservo1.write(dirX); //Направляем серво
delay(150); // задержка
myservo1.detach(); // откл. сервы
oled(); //экран
}
void oled ()
{
// дисплей (с кор. показаний для удобства восприятия)
dirX_disp = -1.66*(dirX-90); //Находим изменение угла
dirX_disp = dirX_center + dirX_disp; //Находим изменение угла от центра
if (dirX_disp < 0) {dirX_disp = dirX_disp + 360;} // защита
if (dirX_disp >= 360) {dirX_disp = dirX_disp - 360;} // защита
lcd.setCursor(3, 1); // Позиция курсора
if (dirX_disp < 10) {lcd.print(" ");} // вывод инф.
if (dirX_disp >= 10 and dirX_disp < 100) {lcd.print(" ");} // вывод инф.
if (dirX_disp >= 100) {lcd.print(" ");} // вывод инф.
lcd.print(dirX_disp); // вывод инф.
lcd.setCursor(3, 0); // Позиция курсора
if (((dirY-90)*-1) < 10) {lcd.print(" ");} // вывод инф.
if (((dirY-90)
-1) >= 10 and ((dirY-90)-1) < 100 ) {lcd.print(" ");} // вывод инф.
lcd.print((dirY-90)*-1); // вывод инф.
lcd.print(".00 "); // вывод инф.
}