Делаем еще один джойстик (геймпад) на Arduino. Джойстик Ардуино – подключение и скетч Сервопривод и джойстик простой скетч подключение

В один прекрасный день попался мне на eBay интереснейший маленький модуль джойстика, который очень похож на используемые в контроллерах для PlayStation 2. Оказалось, что модуль очень прост в использовании с Arduino и стоит буквально несколько долларов.

Компаний-производителей джойстиков для Arduino несколько, в том числе Adafruit, Sparkfun и огромное количество китайских фирм. Радует, что принцип действия у них совершенно идентичный.

Общая информация о модуле джойстика для Arduino

На модуле 5 пинов: Vcc, Ground, X, Y, Key. Обратите внимание, что обозначения на вашем модуле могут отличаться. Это зависит от производителя. Джойстик аналоговый и обеспечивает более высокую точность, чем простые "directional" джойстики, в которых используются кнопки и механические переключатели. Кроме того, на джойстик можно нажать (на моей модели прилагать для этого приличные усилия. Возможно, он просто еще не разработан). После нажатия отработает кнопка "press to select".

Для считывания данных с пинов X/Y надо использовать аналоговые выходы на Arduino. Пин Key замыкается землей при нажатии. В противоположном случае ни в какой цепи он не участвует. Для стабильного считывания данных с пинов Key/Select, они должны подключаться к источнику питания (Vcc) через подтягивающий резистор. Номинала встроенных на Arduino резисторов для этого будет вполне достаточно.

Посмотрите видео-пример работы джойстика с Arduino:

Схема подключения джойстика к Arduino

    Arduino GND - GNG

    ARDUINO A0 - VER/Y

    Arduino A1 - HOR/X

Базовый скетч для использования джойстика с Arduino

int buttonPin = 2;

int xPosition = 0;

int yPosition = 0;

int buttonState = 0;

// инициализация обмена данными по серийному протоколу со скоростью 9600 bps:

Serial.begin(9600);

pinMode(xPin, INPUT);

pinMode(yPin, INPUT);

// активируем подтягивающий резистор на пине кнопки

pinMode(buttonPin, INPUT_PULLUP);

// Для более ранних версий Arduino (меньше 1.0.1)

// pinMode(buttonPin, INPUT);

// digitalWrite(buttonPin, HIGH);

xPosition = analogRead(xPin);

yPosition = analogRead(yPin);

buttonState = digitalRead(buttonPin);

Serial.print("X: ");

Serial.print(xPosition);

Serial.print(" | Y: ");

Serial.print(yPosition);

Serial.print(" | Button: ");

Serial.println(buttonState);

delay(100); // добавляем задержку между считыванием данных

Как уже упоминалось выше, модули джойстика производят многие. Интересное решение есть у компании Sparkfun. Они выпускают шилд Joystick Shield, о котором мы дальше и поговорим. Внешний вид джойстик шилда представлен на рисунке ниже.


Сборка джойстик шилда

Здесь стоит упомянуть, что шилд поставляется в разобранном виде. Так что придется поработать паяльником. Полная инструкция по сборке находится по этому адресу: Joystick Shield Assembly Guide . Материал от производителя на английском языке, но фотоматериалов вполне достаточно. Так что разобраться несложно.

Для чего можно использовать джойстик?

На джойстик шилде установлено четыре кнопки справа, одна кнопка непосредственно на джойстике ну и сам аналоговый джойстик. Шилд можно использовать для управления мелодией или пикселями на мониторе. Кнопки можно использовать для навигации и управления в играх.

Для дополнительной мотивации можете заценить видео ниже:

После того, как вы собрали ваш джойстик шилд, можете смело вносить изменения в скетчи для реализации ваших задач.

Как отследить текущее положение джойстика?

Положение джойстика рассчитывается в зависимости от значений двух потенциометров , которые в нем установлены. Джойстик перемещается в двух направлениях, которые обычно обозначают как X и Y. Для считывания данных с потенциометров используем функцию analogRead(), которая возвращает значение в диапазоне от 0 до 1023. Для этого надо в функцию передать номера пинов, к которым подключен джойстик. В данном примере мы подключаемся к аналоговому пину 0 для X и к аналоговому пину 1 для Y.

Serial.println(analogRead(0)); // отображает текущее положение X координаты

Serial.println(analogRead(1)); // отображает текущее положение Y координаты

Очень удобный подход - использование констант для значений, которые не будут меняться на протяжении работы программы. Так что в коде ниже мы объявим константы для аналоговых пинов, которые мы используем и отобразим текущее положение по Х и Y в серийном мониторе Arduino IDE:

const byte PIN_ANALOG_X = 0;

const byte PIN_ANALOG_Y = 1;

Serial.begin(9600);

Serial.print("x:");

Serial.print(" ");

Serial.print("y:");

Serial.print(" ");

Serial.println();

Как отследить текущее направление джойстика?

Очень полезный кусок кода. На основании значений положений X и Y мы можем определить, находится ли джойстик по центу или он смещен в одном из восьми направлений (вверх, вправо-вверх, вправо, вправо-вниз, вниз, влево-вниз, влево, влево-вверх).

Так как значения в каждом из направлений будет в диапазоне от 0 до 1023, можно предположить, что центр будет находиться в диапазоне 511-512. Но это не совсем так. Настолько точно текущее значение мы не получим. И если мы определим неверное значение, можем получить информацию о движении джойстика, хотя он стоял по центру и не двигался.

Для этого мы введем диапазон значений и будем считать, что любое значение в этом диапазоне будет считаться центром:

Этот диапазон не является «истиной последней инстанции». Вам надо его подстроить под ваш джойстик, так. Эти значения вводятся в код в виде констант:

Теперь мы преобразуем каждую координату из диапазона от 0 до 1023 в диапазон от -1 до 1. Для координаты Х – 1 значит перемещение влево, 0 означает отсутствие перемещения, а 1 – перемещение вправо. Для направления Y -1 означает перемещение вниз, 0 означает отсутствие перемещения, а 1 – перемещение вверх.

Мы начнем с установки значения в каждом направлении 0 («центр»). После этого мы используем выражения if/else для проверки, принимает ли значение положения в любом из направлений большее или меньшее значение чем наш диапазон:

x_direction = 0;

y_direction = 0;

if (x_position > X_THRESHOLD_HIGH) {

x_direction = 1;

} else if (x_position

x_direction = -1;

if (y_position > Y_THRESHOLD_HIGH) {

y_direction = 1;

} else if (y_position

y_direction = -1;

В Arduino IDE есть функция map(), которую, теоретически могли бы использовать вместо if/else, но в данном случае метод усложняется из-за вопросов центрирования, так что применять здесь map мы не будем.

В примере, который представлен ниже, вы увидите, что в дальнейшем if/else используются для отображения направления – вы можете спокойно изменить этот пример под ваши задачи:

const byte PIN_ANALOG_X = 0;

const byte PIN_ANALOG_Y = 1;

const int X_THRESHOLD_LOW = 505;

const int X_THRESHOLD_HIGH = 515;

const int Y_THRESHOLD_LOW = 500;

const int Y_THRESHOLD_HIGH = 510;

int x_direction;

int y_direction;

Serial.begin(9600);

x_direction = 0;

y_direction = 0;

x_position = analogRead(PIN_ANALOG_X);

y_position = analogRead(PIN_ANALOG_Y);

if (x_position > X_THRESHOLD_HIGH) {

x_direction = 1;

} else if (x_position

x_direction = -1;

if (y_position > Y_THRESHOLD_HIGH) {

y_direction = 1;

} else if (y_position

y_direction = -1;

if (x_direction == -1) {

if (y_direction == -1) {

Serial.println("left-down");

Serial.println("left");

// y_direction == 1

Serial.println("left-up");

} else if (x_direction == 0) {

if (y_direction == -1) {

Serial.println("down");

} else if (y_direction == 0) {

Serial.println("centered");

// y_direction == 1

Serial.println("up");

// x_direction == 1

if (y_direction == -1) {

Serial.println("right-down");

} else if (y_direction == 0) {

Serial.println("right");

// y_direction == 1

Serial.println("right-up");

Как настроить Arduino для отслеживания состояния кнопки (нажата ли она)?

Перед тем как узнать, нажата ли кнопка на джойстик шилде, вам надо настроить Arduino на узнавание кнопок. Как это не удивительно, это реализуется в теле функции setup()!

Сначала мы определяем константы для пинов Arduino, которые связаны с кнопками:

// Выбор кнопки, которая срабатывает при нажатии джойстика

const byte PIN_BUTTON_UP = 4;

Если вы до этого когда-то использовали кнопки с Arduino, вы могли заметить, что для определения напряжения при нажатой кнопке, надо использовать резистор . Для уменьшения количества деталей, джойстик шилд спроектирован таким образом, что резисторы не нужны. Вы можете спросить себя: «Если для кнопок нужны резисторы, почему шилд работает без них?». Вы просто не учли, что на Arduino есть встроенные резисторы. Можно просто их активировать и использовать с нашим шилдом!

Для задействования этих встроенных подтягивающих резисторов надо установить пин в режим INPUT, а после уже активировать с помощью следующих строк:

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

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

pinMode(PIN_BUTTON_RIGHT, INPUT);

digitalWrite(PIN_BUTTON_RIGHT, HIGH);

Как узнать, когда была нажата кнопка на джойстик шилде?

После одоления предыдущих пунктов, можно определять, нажата ли кнопка с помощью функции digitalRead(). Когда считываемое значение будет LOW, кнопка нажата, а когда значение равно HIGH, кнопка не нажата.

if (digitalRead(PIN_BUTTON_LEFT) == LOW) {

// Кнопка нажата

// Кнопка не нажата

Следующий пример отобразит состояние каждой кнопки и значения с джойстика в серийном мониторе Arduino IDE:

const byte PIN_BUTTON_SELECT = 2;

const byte PIN_BUTTON_RIGHT = 3;

const byte PIN_BUTTON_UP = 4;

const byte PIN_BUTTON_DOWN = 5;

const byte PIN_BUTTON_LEFT = 6;

const byte PIN_ANALOG_X = 0;

const byte PIN_ANALOG_Y = 1;

Serial.begin(9600);

pinMode(PIN_BUTTON_RIGHT, INPUT);

digitalWrite(PIN_BUTTON_RIGHT, HIGH);

pinMode(PIN_BUTTON_LEFT, INPUT);

digitalWrite(PIN_BUTTON_LEFT, HIGH);

pinMode(PIN_BUTTON_UP, INPUT);

digitalWrite(PIN_BUTTON_UP, HIGH);

pinMode(PIN_BUTTON_DOWN, INPUT);

digitalWrite(PIN_BUTTON_DOWN, HIGH);

pinMode(PIN_BUTTON_SELECT, INPUT);

digitalWrite(PIN_BUTTON_SELECT, HIGH);

Serial.print("l:");

Serial.print(digitalRead(PIN_BUTTON_LEFT));

Serial.print(" ");

Serial.print("r:");

Serial.print(digitalRead(PIN_BUTTON_RIGHT));

Serial.print(" ");

Serial.print("u:");

Serial.print(digitalRead(PIN_BUTTON_UP));

Serial.print(" ");

Serial.print("d:");

Serial.print(digitalRead(PIN_BUTTON_DOWN));

Serial.print(" ");

Serial.print("x:");

Serial.print(analogRead(PIN_ANALOG_X));

Serial.print(" ");

Serial.print("y:");

Serial.print(analogRead(PIN_ANALOG_Y));

Serial.print(" ");

Serial.print("s:");

Serial.print(digitalRead(PIN_BUTTON_SELECT));

Serial.print(" ");

Serial.println();

Оставляйте Ваши комментарии, вопросы и делитесь личным опытом ниже. В дискуссии часто рождаются новые идеи и проекты!

Является модулем ввода данных. С его помощью можно управлять роботами, манипуляторами, станками, различными моделями (машинки, танки, самолёты, вертолёты, квадрокоптеры, лодки и т.д.), а также использовать для создания игровых приставок, выбора пунктов меню на дисплеях и индикаторах, ввода значений, и т.д. Джойстик можно не только перемещать по осям X и Y, но и нажимать на него.

Видео:

Спецификация:

  • Напряжение питания: 5 В / 3,3 В (оба напряжения входят в диапазон допустимых значений).
  • Потребляемый ток: < 10 мА
  • Габариты: 30x30 мм

Все модули линейки "Trema" выполнены в одном формате

Подключение:

  • Выводы «X» и «Y» модуля подключается к любым аналоговым входам Arduino . Значения, считываемые с этих выводов, растут при перемещении джойстика слева на право и снизу вверх.
  • Вывод «K» является цифровым и подключается к любому выводу Arduino . В обычном состоянии на нём уровень логического «0», а при нажатии на джойстик, он меняется на логическую «1».
  • Выводы «V» и «G» являются выводами питания.

Модуль удобно подключать 3 способами, в зависимости от ситуации:

Способ - 1: Используя проводной шлейф и Piranha UNO

Используя провода «Папа - Мама », подключаем напрямую к контроллеру Piranha UNO


Способ - 2: Используя Trema Set Shield

Модуль можно подключить к любому из аналоговых входов Trema Set Shield.


Способ - 3: Используя проводной шлейф и Shield

Используя 5-и проводной шлейф, к Trema Shield, Trema-Power Shield, Motor Shield, Trema Shield NANO и тд.


Питание:

Входное напряжение 5 В или 3,3 В постоянного тока, подаётся на выводы Vcc (V) и GND (G).

Подробнее о модуле:

Данные модуля считываются с двух потенциометров и тактовой кнопки, механически связанных с рычагом джойстика. Кнопка подключена в разрыв питания Vcc и выхода «K», который прижат к GND через резистор. Следовательно, на выходе «K» может устанавливаться только два состояния: логический «0» (кнопка отпущена) или «1» (кнопка нажата). Выводы координат «X» и «Y» являются аналоговыми выходами модуля, они подключены к потенциометрам так, что напряжение снимаемое между этими выводами и GND растет при перемещении джойстика слева на право и снизу вверх.

Примеры:

Определение положения джойстика и включение светодиода по нажатию кнопки

const int8_t Xaxis = A0; // Определяем номер вывода, к которому подключен контакт оси Х джойстика const int8_t Yaxis = A1; // Определяем номер вывода, к которому подключен контакт оси У джойстика const int8_t Button = 2; // Определяем номер вывода, к которому подключен контакт кнопки джойстика const int8_t LED = 7; // Определяем номер вывода, к которому подключен светодиод uint16_t XborderMIN = 505; // Задаём границу значений, НИЖЕ которой будет считаться, что джойстик отклонён по оси Х влево uint16_t XborderMAX = 515; // Задаём границу значений, ВЫШЕ которой будет считаться, что джойстик отклонён по оси Х вправо uint16_t YborderMIN = 505; // Задаём границу значений, НИЖЕ которой будет считаться, что джойстик отклонён по оси У вниз uint16_t YborderMAX = 515; // Задаём границу значений, ВЫШЕ которой будет считаться, что джойстик отклонён по оси У вверх uint16_t Xvol = 0, Yvol = 0; // Задаём переменные, которые будут принимать значения, считанные с осей джойстика void setup() { Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта pinMode(LED, OUTPUT); // Настраиваем вывод LED на работу в режиме выхода pinMode(Button, INPUT); // Настраиваем вывод Button на работу в режиме входа } void loop() { Xvol = analogRead(Xaxis); // Считываем значения оси Х Yvol = analogRead(Yaxis); // Считываем значения оси У if (Xvol < XborderMIN) { // Проверяем, полученное значение Х меньше нижней границы центрального положения или нет. Если да, то if (Yvol < YborderMIN) { // проверяем, полученное значение У меньше нижней границы центрального положения или нет. Если да, то Serial.println("Left-Down"); // значит джойстик находится в положении ВЛЕВО-ВНИЗ } else if (Yvol > YborderMAX) { // Если же полученное значение У больше верхней границы центрального положения, то Serial.println("Left-Up"); // значит джойстик находится в положении ВЛЕВО-ВВЕРХ } else { Serial.println("Left"); // Если же полученное значение У входит в границы центрального положения по оси У, значит джойстик отклонён ВЛЕВО } } else if (Xvol > XborderMAX) { // Проверяем, полученное значение Х больше верхней границы центрального положения или нет. Если да, то if (Yvol < YborderMIN) { // проверяем, полученное значение У меньше нижней границы центрального положения или нет. Если да, то Serial.println("Right-Down"); // значит джойстик находится в положении ВПРАВО-ВНИЗ } else if (Yvol > YborderMAX) { // Если же полученное значение У больше верхней границы центрального положения, то Serial.println("Right-Up"); // значит джойстик находится в положении ВПРАВО-ВВЕРХ } else { Serial.println("Right"); // Если же полученное значение У входит в границы центрального положения по оси У, значит джойстик отклонён ВПРАВО } } else { // Если полученное значение Х входит в границы центрального положения по оси Х, значит if (Yvol < YborderMIN) { // проверяем, полученное значение У меньше нижней границы центрального положения или нет. Если да, то Serial.println("Down"); // значит джойстик находится в положении ВНИЗ } else if (Yvol > YborderMAX) { // Если же полученное значение У больше верхней границы центрального положения, то Serial.println("Up"); // значит джойстик находится в положении ВВЕРХ } else { Serial.println("Center"); // Если же полученное значение У входит в границы центрального положения по оси У, значит джойстик находится в центре. } } if (digitalRead(Button)) { // Проверяем, нажата ли кнопка delay(1); // Если кнопка была нажата, то подавляем дребезг digitalWrite(LED, !digitalRead(LED)); // и меняем состояние на выходе светодиода Serial.println("Button click!"); // Выводим текст о том, что кнопка была нажата while (digitalRead(Button)) {} // Если кнопка удерживается, то ничего не делаем delay(10); // Если кнопка отпускается, то подавляем дребезг } }

В мониторе последовательного порта вы увидите.

Завалялась у меня arduino nano (качественный китайский клон от RobotDyn). А тут на днях так же из Китая пришли сервомотор и манипулятор, а так же нашлось время, чтобы немного разобраться с этим. Итак, цель у меня была простая: соединить arduino nano, сервомотор и джойстик, и заставить сервомотор поворачиваться при повороте джойстика. В практических целях это можно использовать, например, для управления поворотом камеры.

Как оказалось, это не так уж и сложно. Схема подключения следующая:

1. Подключение Arduino и сервомотора:

  • коричневый (на моем сервомоторе) провод - земля (gnd);
  • красный провод - 5v;
  • оранжевый провод - 8 пин.

2. Подключение Arduino и джойстика:

  • gnd - gnd;
  • 5v - 5v (я подключил к 3.3v);
  • VRX (сигнал для координат по оси X) - A1;
  • VRY (сигнал для координат по оси Y) - A0;
  • SW (режим кнопки - нажата или отпущена) - 2 пин.

Соединяем все наши чуда китайского производства, подключаем arduino к компьютеру, открываем Arduino IDE, заливаем скетч, указанный ниже. После загрузки скетча можно двигать манипулятором в стороны, сервомотор будет поворачиваться .

#include //Библиотека для работы с сервомотором int xPin = A1; //А1 - аналоговый сигнал Х координат джойстика int yPin = A0; //А0 - аналоговый сигнал У координат джойстика int buttonPin = 2; // Пин для режима кнопки (нажата или отпущена) int xPosition = 0; // переменная для хранения текущей позиции джойстика по оси X int yPosition = 0; // переменная для хранения текущей позиции джойстика по оси Y int buttonState = 0; //текущее состояние кнопки (нажата) int servoPin = 8; // пин для сигналов с сервомотора Servo servo; // переменная типа Servo int angle = 90; //стартовый угол поворота сервомотора int currentXpos = 0; //Текущая позиция X void setup() { pinMode(xPin, INPUT); // Сигнал с xPin определяем как входной сигнал pinMode(yPin, INPUT); // Сигнал с yPin определяем как входной сигнал pinMode(buttonPin, INPUT_PULLUP); // активируем подтягивающий резистор на пине кнопки servo.attach(servoPin); // присоединяем пин servo.write(angle); // Поворачиваем сервомотор на 90 градусов } void loop() { xPosition = analogRead(xPin); // читаем значение xPin yPosition = analogRead(yPin); // читаем значение yPin buttonState = digitalRead(buttonPin); // читаем "состояние" кнопки //если значение xPosition больше 360 if(xPosition > 360) { angle = angle-10; // уменьшаем угол поворота на 10 градусов // если угол меньше 0 if(angle < 0) { angle = 0; //устанавливаем значение угла 0 градусов } } //если xPosition меньше 300 if(xPosition < 300) { angle = angle+10; // увеличиваем угол поворота сервомотора на 10 градусов //если угол поворота больше 180 градусов if(angle > 180) { angle = 180; //устанавливаем значение угла в 180 градусов } } // если нажата кнопка джойстика if(buttonState == 0) { angle = 90; //устанавливаем угол в 90 градусов } servo.write(angle); // поворачиваем сервомотор на нужный угол delay(50); // добавляем задержку между считыванием данных }

При подключении джойстика к питанию 3.3V значение по умолчанию для X и Y позиций было 330 (при подключении к 5V значения могут быть другие), для проверки значений текущих показаний и я взял отклонение от начального значения в 30 единиц.

Отследить значения аналоговых сигналов можно с помощью монитора серийного порта (открыть его можно так: инструменты -> монитор порта или CTRL + SHIFT + M). Для этого в функции setup() необходимо написать следующее:

Serial.begin(9600); // инициализация обмена данными по серийному протоколу со скоростью 9600 bps

В функции loop() написать следующее:

Serial.print("X: "); Serial.print(xPosition); Serial.print(" | Y: "); Serial.print(yPosition); Serial.print(" | Button: "); Serial.println(buttonState);

Вот видео того, что получилось:

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

Новые статьи


Простая реализация текстового поля с выпадающими подсказками (аналогично поиску у Яндекс и Google) при вводе текста на языке C# WPF. Реализация пользовательского элемента управления в C#/

Для плат Arduino существуют модули аналоговых джойстиков. Как правило, имеющие ось X, Y и кнопку - ось Z. Джойстик позволяет более плавно и точно отслеживать степень отклонения от нулевой точки. А помимо удобства по сравнению с кнопками, это позволяет реализовывать более совершенные интерфейсы. К примеру, при изменении какого-либо значения в меню, можно написать программу таким образом, что чем сильнее отклонена ось джойстика, тем быстрее изменяется значение переменной. Например, нам необходимо изменить значение от 0 до 2000 с шагом в 1. Представьте, сколько раз вам потребовалось бы нажимать кнопку или писать специальный алгоритм, скажем при длительности нажатия больше 3 сек прибавлять изменять шаг на 10 или 100. А при использовании джойстика это можно реализовать намного проще.

Средняя цена на подобные модули колеблется в районе 1-2$ за модуль (с бесплатной доставкой в Россию). Поиск модулей в магазине AliExpress

Сами модули выглядят примерно так:

Не пугайтесь количеством выводов, это сделано для универсальности и удобства подключения. Контакты Vcc и GND между всеми тремя группами контактов соединены. Т.о. для подключения нужно 5 проводов: ось X, ось Y, кнопка Z, питание V cc и общий GND. Джойстики пассивные модули и не потребляют какую-либо энергию от платы Arduino. Питание V cc необходимо только для подтягивающих резисторов. Бывают модули без подтягивающих резисторов, в таком случае, необходимо вывод подключения кнопки подтянуть к +V cc через резистор 1-10 кОм.

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

В программе, работать с джойстиком также очень просто:

#define axis_X 0 // Ось Х подключена к Analog 0 #define axis_Y 1 // Ось Y подключена к Analog 1 #define axis_Z 2 // Ось Z (кнопка джойстика) подключена к Digital 2 int value_X, value_Y, value_Z = 0; // Переменные для хранения значений осей void setup() { pinMode(axis_Z, INPUT); // Задаем как вход Serial.begin(9600); } void loop() { value_X = analogRead(axis_X); // Считываем аналоговое значение оси Х Serial.print("X:"); Serial.print(value_X, DEC); // Выводим значение в Serial Monitor value_Y = analogRead(axis_Y); // Считываем аналоговое значение оси Y Serial.print(" | Y:"); Serial.print(value_Y, DEC); // Выводим значение в Serial Monitor value_Z = digitalRead(axis_Z); // Считываем цифровое значение оси Z (кнопка) value_Z = value_Z ^ 1; // Инвертируем значение Serial.print(" | Z: "); Serial.println(value_Z, DEC); // Выводим значение в Serial Monitor delay(250); // Задержка 250 мс }

Как видно выше, в начале мы определяем входные пины для осей (define), а потом в главном цикле считываем значения с пинов и выводим их в Serial Monitor. И видим следующую картину:

Как видите все довольно просто. И напоследок напишем небольшую программу, целью которой будет изменять значение переменной, в зависимости от отклонения джойстика по оси Y от нулевой точки. А при нажатии на кнопку джойстика, переменная будет обнуляться.

#define axis_Y 1 // Ось Y подключена к Analog 1 #define axis_Z 2 // Ось Z (кнопка джойстика) подключена к Digital 2 int value, value_Y, value_Z = 0; // Переменные для хранения значений осей void setup() { pinMode(axis_Z, INPUT); // Задаем как вход Serial.begin(9600); } void loop() { value_Y = analogRead(axis_Y); // Считываем аналоговое значение оси Y if(value_Y >= 0 && value_Y < 100) value = value - 10; if(value_Y > 100 && value_Y < 300) value = value - 5; if(value_Y > 300 && value_Y < 520) value = value - 1; if(value_Y > 535 && value_Y < 700) value = value + 1; if(value_Y > 700 && value_Y < 900) value = value + 5; if(value_Y > 900) value = value + 10; value_Z = digitalRead(axis_Z); // Считываем цифровое значение оси Z (кнопка) if(value_Z == 0) value = 0; // Сброс значения Serial.println(value, DEC); // Выводим значение в Serial Monitor delay(500); // Задержка }

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

Что нам потребуется

  1. Соединительные провода;

Исходный код

#include
int joyX=0;
int angl=0;
Servo myservo;
void setup()
{
myservo.attach(9);
pinMode(joyX,INPUT);
Serial.begin(9600);
}
void loop()
{
int val = (analogRead(joyX)/64)-8;
if (val > 0) {
angl=angl+abs(val);
}
else {
if (val < 0) {
angl=angl-abs(val);}
}
if (angl < 0) angl = 0;
if (angl > 180) angl = 180;
Serial.print("Power: ");
Serial.println(val);
Serial.print("Angle: ");
Serial.println(angl);
myservo.write(angl);
int spd = 500;
if (val != 0) {
spd = 600/abs(val);
}
Serial.print("Speed: ");
Serial.println(spd);
Serial.println("-----------");
delay(spd);
}

Как это работает

Управлять сервоприводом оказалось просто (с использованием библиотеки). Мы просто вызываем функцию write и значение угла поворота в градусах. А вот само значение угла мы будем изменять динамически с помощью джойстика.

В цикле считывается значение с аналогового входа (изменяется от 0 до 1023 в зависимости от положения джойстика), я делю это значение, чтобы уменьшить шаг на 64 и вычитаю 8, чтобы усреднить. Теперь мы будем иметь значение от 7 до -8. Затем на это значение я изменяю переменную, хранящую угол поворота. Также изменяю задержку в зависимости от этого значения. Чем больше отклонение, тем меньше задержка (быстрее происходит вращение).

  1. С Arduino берём +5 В на одну сторону бредборда (красный првоод);
  2. Чёрный провод идёт с GND на другую сторону бредборда;
  3. Сигнальный пин – девятый, зелёный провод, идёт на сервомотор (жёлтый шлейф);
  4. Так же на аналоговый вход a0 подаётся синий провод от джойстика (пин S-X);
  5. С джойстика VCC стороны X идёт красным проводом на +5 В бредборда;
  6. С джойстика GND стороны X идёт белым проводом на GND общее бредборда;
  7. Ну и соответственно белый провод GND бредборда в чёрный шлейф сервомотора;
  8. Оранжевый провод +5 В бредборда в красный шлейф сервомотора;

Что получилось