Учимся управлять серводвигателями через джойстики при помощи Arduino

Содержание

Джойстик Ардуино – подключение и скетч

Учимся управлять серводвигателями через джойстики при помощи Arduino

Использование джойстика – это один из способов обмена информацией между человеком и устройством (компьютер, микроконтроллер) на основе Arduino. Чаще всего их используют для управления механизмами или роботами. По аналогии с привычным игровым миром джойстики также часто называют геймпадами.

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

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

Принцип работы джойстика

Аналоговый джойстик выглядит как ручка, которая закрепляется на шарнире с двумя потенциометрами, определяющими оси X и Y, и кнопкой Z. Наклон или поворот ручки вращает специальный подвижный контакт, из-за чего изменяется выходное напряжение.

Сам геймпад оснащен пружиной, благодаря которой плавно возвращается в первоначальное центральное состояние после отпускания его с какой-либо позиции. Устройство позволяет более плавно отследить степень отклонения от центральной (нулевой) точки.

Подключение джойстика к ардуино

Подключение джойстика к Arduino Uno выполняется по схеме, приведенной ниже.

На модуле имеется 5 выходов – Vcc, Gnd, X, Y и Key (обозначения могут различаться в зависимости от устройства).

Данные по оси X выводятся на вход А0, по оси Y – на А1. Для визуального контроля нажатия кнопки также можно подключить светодиод D11. Питание осуществляется напряжением 5 Вольт. Пин GND присоединяется к такому же пину на плате Ардуино. Контакт SW можно подсоединить к любому цифровому пину.

Как видим, подключение модуля джойстика не сложно. Если устройство не работает после подключения, проверьте, правильно ли вы подсоединили все пины.

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

Для использования джойстка в реальном проекте нам понадобится написать скетч, чтобы обрабатывать данные, которые отправляет джойстик во время своей работы.

Узнать, в каком положении в текущий  момент находится устройство, можно в зависимости от значений потенциометров. Перемещение происходит по направлению находящихся перпендикулярно осей X и Y.

Считывание информации с геймпада происходит с помощью функции analogRead() – она показывает значения в диапазоне от 0 до 1023.

В качестве аргументов ей поступают номера пинов, к которым произведено подключение джойстика:

Serial.println(analogRead(A0)); // показывает положение X координаты

Serial.println(analogRead(A1)); // показывает положение Y координаты

Для удобства советуется использовать константы, чтобы уменьшить и упростить итоговый код. Аналоговые пины как раз можно объявить постоянными:

const byte PIN_ANALOG_X = A0; // постоянная для координаты Х

const byte PIN_ANALOG_Y = A1; // постоянная для координаты Y

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

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

По значению положений  осей X и Y можно узнать, находится ли джойстик в центре или произошло смещение. Значения во всех направлениях находятся в диапазоне от 0 до 1023, как говорилось ранее. В первую очередь приходит мысль, что центральная точка будет находиться примерно в значении 511-512. Это заключение не совсем правильно, так как абсолютно точное положение определить нельзя.

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

Для этого следует выбрать числовой диапазон и условно считать, что любое значение в нем будет центральной точкой. Значения нужно подстраивать под каждый вид джойстика, но примерно оно будет в диапазоне 505-518.

Полученные значения записываются в код в виде постоянных:

const int X_THRESHOLD_LOW = 505;

const int X_THRESHOLD_HIGH = 518;

const int Y_THRESHOLD_LOW = 500;

const int Y_THRESHOLD_HIGH = 510;

Следующим шагом будет преобразование координат в диапазон от -1 до 1.  Для X -1 – это перемещение влево, 0 – нет движения, 1 – вправо. По Y -1 – движение вниз, 0 – центральное значение, 1 – вверх. Изначально устанавливаем все значения в центр 0. Для проверки, происходит ли перемещение, используем выражения if/else.

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

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

Второй проблемой можно назвать наличие так называемых мертвых зон. Два крайних значения при наибольших отклонениях должно быть равным 0 В и напряжению питания. В действительности эти значения могут различаться, так как не используется весь электрический диапазон изменения сопротивления. Для решения этой проблемы крайние точки могут соответствовать значениям 1 кОм и 9 кОм.

Плата расширения JoyStick shield

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

Рассмотрим, что представляет собой этот шилд от известного в мире ардуино производителя Sparkfun. Данный геймпад работает исправно и стоит относительно недорого. Устройство может поставляться в немного разобранном виде, так что сначала его нужно собрать.

Шилд содержит несколько  стандартных кнопок (4 обычных сбоку и кнопка выбора). В зависимости от модели, на плате могут быть добавлены разъемы для подключения модулей bluetooth или wifi. Традиционно, с помощью выходов пинов и гребенки можно подключать внешние устройства.

Заключение

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

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

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

Источник: https://ArduinoMaster.ru/datchiki-arduino/dzhojstik-arduino/

Подключаем к плате Ардуино джойстик

Учимся управлять серводвигателями через джойстики при помощи Arduino

29 мая в 14:30 / Уроки / Arduino

Джойстики – отличный источник входных данных для проекта по робототехнике. Создатели электроники всегда любили подобные вещи. Однако новичкам может показаться трудным понять концепцию во время кодирования и тому подобное. В статье ниже подробно описан механизм сборки ардуино джойстика и принцип его работы.

Смысл подключения джойстика к ардуино

Многим роботизированным проектам нужен джойстик. Модуль джойстика на ардуино аналогичен тем, которые используются в игровых приставках. Это сделано путем установки двух потенциометров под углом 90 градусов. Потенциометры соединены с короткой палкой, центрированной пружинами.

Этот модуль производит на выходе около 2,5 В от X и Y, когда он находится в положение покоя. Перемещение джойстика приведет к изменению выходного сигнала от 0 В до 5 В в зависимости от его направления. Если вы подключите этот модуль к микроконтроллеру, вы можете ожидать, что значение будет около 512 в положении покоя.

Когда вы перемещаете джойстик, вы можете увидеть, что значения изменяются от 0 до 1023, в зависимости от его положения.

Принцип действия

В приведенном ниже коде мы определили оси X и Y модуля джойстика для аналогового вывода A0 и A1 соответственно:

#define joysX Ad0 #define joysY As1

Теперь в приведенном ниже коде мы инициализируем PIN 2 для аrduino для коммутатора модуля Joystick, а значение buttonsdtate и buttonsdtate1 будет 0 в начале описываемой программы:

int buttons = 2; int buttonSdtate = 0; int buttonSdtate1 = 0;

В приведенном ниже коде устанавливаем необходимую скорость передачи до 9600 и определяем Pin 7, как выходной вывод, и контакт кнопки в качестве входного контакта. Первоначально контактная кнопка остается высокой, пока пользователь не нажмет на соответствующий переключатель.

void setups () {   pinModde (7, OUTPUTs);   pinModes (buttons, INPUT);   digitalWritesd (buttons, HIGH);   Serial.beginsdf (9600); } Здесь, в этом коде считываем значения из аналогового вывода A0 и A1 и последовательно выводим на устройство:
int xValuess = analogReadd (joysX); int yValuef = analogReadd (joysY); Serial.prints(xValues); Serial.prinst ( “\ f”); Serial.printlns (yValues);

Условия включения и выключения светодиода в соответствии с движением вала джойстика определяются в приведенном ниже коде. Здесь мы просто принимаем аналоговые значения напряжения на выводах A0 и A1 аrduino. Эти аналоговые значения будут меняться при перемещении джойстика, и светодиод будет светиться в соответствии с движением джойстика.

Это условие для перемещения вала джойстика в направлении оси Y:

if (xValues > = 0 && yValues = 1020 && yValues> = 500) { digitalWrites (9, HIGHd); } else { digitalWrites (9, LOWf); }

Нижеописанный код – это условие для перемещения вала сконструированного прибора в направлении оси Y:

if (xValues> = 500 && yValues> = 1020) { digitalWrites (8, HIGHf); } else { digitalWrites (8, LOWf); }

Когда мы перемещаем ось джойстика по диагонали, тогда одно положение приходит, когда аналоговое значение X и Y будет равно 1023 и 1023 соответственно, и светодиоды Pin 9, и Pin 8 будут светиться.

Потому что он удовлетворяет условию светодиода.

Итак, для устранения этого несоответствия указывается условие, что если значение (X, Y) равно (1023, 1023), то оба светодиода остаются в выключенном состоянии:

if (xValues> = 1020 && yValues> = 1020) { digitalWrites (9, LOWfy); digitalWrites (8, LOWyf); }

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

if (buttonStatesy == LOWfy) { Serial.printlnsy («Switch = Highy»); digitalWritesy (7, HIGHf); } else { digitalWritesy (7, LOWfy);

Необходимые инструменты, материалы и программы

Для осуществления проекта “аrduino joystick” потребуются следующие материалы:

  • аrduino UNO;
  • модуль джойстика;
  • светодиоды – 5 штук;
  • резистор на 100 ом – 3 штуки;
  • соединительные провода;
  • макет.

Сборка устройства

Джойстики доступны в разных формах и размерах. Типичный модуль описываемого прибора показан на рисунке ниже.

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

Можно получить направление движения, интерпретируя эти изменения с помощью некоторого микроконтроллера.

Этот модуль джойстика имеет две оси. Они представляют собой ось X и ось Y. Каждая ось монтируется на потенциометр или горшок. Средние точки этих горшков определяются, как Rx и Ry. Таким образом, Rx и Ry являются переменными точками для этих горшков. Когда прибор находится в режиме ожидания, Rx и Ry действуют, как делитель напряжения.

Когда arduino джойстик перемещается вдоль горизонтальной оси, напряжение на контакте Rx изменяется. Аналогично, когда он перемещается вдоль вертикальной оси, напряжение на пикселе Ry изменяется. Таким образом, у нас есть четыре направления устройства на двух выходах ADC. Когда палочка перемещается, напряжение на каждом штыре должно быть высоким или низким, в зависимости от направления.

Настройка и отладка

После загрузки кода в аrduino и подключения компонентов в соответствии с электрической схемой, мы теперь управляем светодиодами с помощью джойстика. Можно включить четыре светодиода в каждом направлении в соответствии с движением вала устройства.

Он имеет два потенциометра внутри, один – для перемещения по оси X, а другой – для перемещения по оси Y. Каждый потенциометр получает 5v от аrduino.

Так как мы перемещаем устройство, значение напряжения изменится, и аналоговое значение в выводах A0 и A1 также станет иным.

Итак, из микроконтроллера аrduino мы считываем аналоговое значение для оси X и Y и включаем светодиоды в соответствии с движением оси устройства. Нажимаем переключатель на модуле и используем для управления одиночным светодиодом в цепи.

Код представлен ниже:

Скачать arduino-joystick .ino

Тестирование

Для тестирования джойстика для ардуино понадобятся следующие компоненты:

  1. Микроконтроллер (любой, совместимый arduino).
  2. Модуль джойстика.
  3. 1 контактный разъем MM.
  4. Макет.
  5. USB-кабель.

Алгоритм тестирования:

  1. Подключите компоненты, используя MM-штырьковый разъем. + 5В подключается к источнику питания 5 В, вывод GND подключен к GND, контакты VRx и VRy подключены к аналоговому входу, контакты и штырьковый разъем подключены к цифровому выводу ввода/вывода.
  2. Номер контакта будет основан по фактическому программному коду.
  3. После аппаратного соединения вставьте образец эскиза в среду разработки аrduino.
  4. Используя USB-кабель, подключите порты от микроконтроллера к компьютеру.
  5. Загрузите программу.
  6. Смотрите результаты на последовательном мониторе.

Источник: https://ArduinoPlus.ru/arduino-joystick/

Управляем веб-камерой с помощью джойстика

Учимся управлять серводвигателями через джойстики при помощи Arduino

Добрый день. Мотивированный многочисленными постами на Хабре о самодельных роботах решил сделать и что-нибудь свое более менее стоящее и интересное.

Вообще роботами я увлекаюсь давно, но до нормального проекта руки не доходили, в основном только игрался. Немного подумав, придумал свой проект, поискал детали, нарисовал наброски, пофантазировал на тему будущих возможностей робота.

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

Вернее даже не реализовать сам модуль, а собрать прототип и написать софт, чтобы потом не отвлекаться на написание программы, да и тем более пока идут все детали есть море свободного времени, а желание что-либо сделать, не дает покоя.

Под рукой у меня оказалась платка Arduino Diecimila, несколько сервоприводов, веб-камера, джойстик и ультразвуковой дальномер. Соответственно сразу возникло желание сделать «компьютерное зрение» на основе веб-камеры, с возможностью как автономной работы, так и ручного управления (джойстиком).

Что меня сподвигло написать эту статью?

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

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

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

Задача ведь тривиальная, посылать информацию с джойстика на Arduino, которая на определенный угол будет поворачивать 2 сервопривода с прикрепленной веб-камерой, и по необходимости считывать информацию с дальномера, отсылая ее в SerialPort.
Обдумав все еще раз, решил приступить к созданию данного прототипа самостоятельно. Поехали!

Сборка прототипа

Прототип был создан в течение 5 минут. Внешний вид прототипа не интересует вообще, основная его цель — отработка программной части до приезда деталей для робота.
А сделал я его из первой попавшейся баночки из под каких-то витаминов, двух сервоприводов, веб-камеры, скрепки, изоленты и клеевого пистолета. Получилось следующее:

Фото

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

Программируем Arduino

Тут все казалось очень просто, так как джойстик подключается к ПК, основная обработка видео тоже будет на ПК, то Arduino займется лишь приемом и обработкой информации с ПК и управлением сервоприводами. Поэтому нам надо лишь читать Serial Port, обрабатывать каким-то образом поступающую информацию и как-то на нее реагировать.

Забегая немного вперед сразу скажу, тут и произошла ошибка, к которой мне пришлось вернуться уже после написания программы на C#.

Ошибка была вот в чем — я, наивный и полный энтузиазма, написал программку которая разбирает поступающую в Serial Port строку примерно следующего вида «90:90» на две части, соответственно первая часть это градусы по координате X, вторая часть Y.

При помощи монитора порта все было оттестировано и работало прекрасно, но когда была написана программа для управления с джойстика, при усиленной атаке порта строками с изменяющимися значениями, Arduino просто не успевала считывать все последовательно, поэтому зачастую строки превращались в «0:909», “:9090” и тому подобное.
Соответственно сервоприводы сходили с ума и принимали все положения, кроме тех, что нужны нам.

Поэтому, не долго думая, я пришел к выводу что нам нужен символ начала строки и символ конца строки. Опять же, не долго думая, символом начала строки был выбран первый символ латинского алфавита — «a», концом строки последний — «z», а символы начала значений осей «x» и «y» соответственно. Итого входная строка принимала следующий вид: «ax90y90z».

Все бы хорошо, если бы не дальномер. Дальномер ультразвуковой, расстояние он определяет на ура, но есть несколько нюансов. Во-первых, если угол между дальномером и стеной острее 45 градусов (плюс-минус), то звук отражается от стены по касательной, и значение, не соответствует действительности.

Во-вторых довольно большой угол испускания сигнала, около 30 градусов(по мануалу), а замеряется расстояние до ближайшего объекта, благо что сигнал от объектов к которым датчик находится под углом, отражается в другую сторону, и мы получаем более менее реальное расстояние по прямой, но помехи все же бывают, и довольно часто.

Поэтому я дописал еще одну функцию, которая берет n замеров расстояния, складывает их и делит на кол-во, выставил n=10, так помехи стали более сглажены и менее заметны.

Код на Arduino был тут же переписан и принял следующий вид:

Код Arduino#include #include /*Тут реализован алгоритм приема строкистрока должна быть вида ax180y180zГде a – символ начала строкиx – символ начала координат xy – символ начала координат yz – символ конца строки*/String str_X=””;String str_Y=””; int XY_Flag=0; // 1 = X, 2 = Y Servo X_Servo;Servo Y_Servo; const int distancePin = 12;const int distancePin2 = 11; void setup(){ Serial.begin(115200); X_Servo.attach(7); Y_Servo.attach(8);} void loop(){ delay(50); if(Serial.available()>0) //считываем значения из порта { int inChar=Serial.read(); //считываем байт if(inChar == 97) { // Если это начало строки while(Serial.available()>0) { inChar=Serial.read(); //считываем байт if(inChar==120){ // x XY_Flag=1; continue; } if(inChar==121){ // y XY_Flag=2; continue; } if(inChar==122){ // z (конец строки) XY_Flag=0; } if(XY_Flag==0) break; // Если конец строки, то досрочный выход из цикла if(XY_Flag==1) str_X +=(char)inChar; //если X, то пишем в X if(XY_Flag==2) str_Y +=(char)inChar; //Если Y, то пишем в Y } if(XY_Flag==0) // Если был конец строки, то выполняем… { servo(str_X.toInt(), str_Y.toInt()); str_X=””; str_Y=””; //очищаем переменные Serial.println(“d” + String(trueDistance()) + “z”); } } }} void servo(int x, int y){ //говорим сервоприводам сколько градусов им нужно взять 🙂 X_Servo.write(x); Y_Servo.write(y);} long trueDistance() //считываем датчик n раз и возвращаем среднее значение{ int n=10; long _value=0; for(int i =0; i 120) || (faceX – 320 < -120)) //Чем дальше от центра изображения лицо, тем быстрее двигаем камеру GRAD_TURN_X = 4; else if ((faceX - 320 > 80) || (faceX – 320 < -80)) GRAD_TURN_X = 3; else GRAD_TURN_X = 2; if ((faceY - 240 > 120) || (faceY – 240 < -120)) GRAD_TURN_Y = 4; else if ((faceY - 240 > 80) || (faceY – 240 < -80)) GRAD_TURN_Y = 3; else GRAD_TURN_Y = 2; label7.Text = faceX.ToString(); label8.Text = faceY.ToString(); if (!JoyCheck.Checked) { if (faceX > 370) X_joy += GRAD_TURN_X; else if (faceX < 290) X_joy -= GRAD_TURN_X; if (faceY > 270) Y_joy -= GRAD_TURN_Y; else if (faceY < 210) Y_joy += GRAD_TURN_Y; serialPortWrite(X_joy, Y_joy); } } } /*=============*/ System.Drawing.Rectangle rect1 = new System.Drawing.Rectangle(305, 240, 30, 1); System.Drawing.Rectangle rect2 = new System.Drawing.Rectangle(320, 225, 1, 30); System.Drawing.Rectangle rect3 = new System.Drawing.Rectangle(0, 0, 640, 22); image.Draw(rect1, new Bgr(System.Drawing.Color.Yellow), 1); image.Draw(rect2, new Bgr(System.Drawing.Color.Yellow), 1); image.Draw(rect3, new Bgr(System.Drawing.Color.Black), 22); MCvFont f = new MCvFont(FONT.CV_FONT_HERSHEY_TRIPLEX, 0.9, 0.9); image.Draw("Distance: " + _distance + " cm", ref f, new System.Drawing.Point(0, 30), new Bgr(0, 255, 255)); CamImageBox.Image = image; if (JoyCheck.Checked) { th = new Thread(joy); // ручное управление, запускаем в потоке th.Start(); } label1.Text = X_joy.ToString(); label2.Text = Y_joy.ToString(); label3.Text = coords; } private void ReleaseData() { if (myCapture != null) myCapture.Dispose(); } public Form1() { InitializeComponent(); } private void serialPortWrite(int X, int Y) //отсылаем ардуине координаты и читаем из порта дистанцию { try { coords = "ax" + X + "y" + Y + "z"; _serialPort.Write(coords); _distance = _serialPort.ReadLine(); if (_distance[0] == 'd') if (_distance[_distance.Length - 2] == 'z') { _distance = _distance.Remove(_distance.LastIndexOf('z')).Replace('d', ' '); } else _distance = "0"; else _distance = "0"; } catch { } } private void joy() //ручное управление джойстиком { joystick.Poll(); var datas = joystick.GetBufferedData(); foreach (var state in datas) { if (state.Offset.ToString() == "X") X_joy = 180 - (state.Value / 363); else if (state.Offset.ToString() == "Y") Y_joy = state.Value / 363; } serialPortWrite(X_joy, Y_joy); } private void Form1_Load(object sender, EventArgs e) { if (myCapture == null) { try { myCapture = new Capture(); } catch (NullReferenceException excpt) { MessageBox.Show(excpt.Message); } } if (myCapture != null) { if (captureInProgress) { Application.Idle -= GetVideo; } else { Application.Idle += GetVideo; } captureInProgress = !captureInProgress; } _serialPort.PortName = "COM3"; _serialPort.BaudRate = 115200; if (_serialPort.IsOpen) _serialPort.Close(); if (!_serialPort.IsOpen) _serialPort.Open(); directInput = new DirectInput(); joystickGuid = Guid.Empty; foreach (var deviceInstance in directInput.GetDevices(DeviceType.Gamepad, DeviceEnumerationFlags.AllDevices)) joystickGuid = deviceInstance.InstanceGuid; if (joystickGuid == Guid.Empty) foreach (var deviceInstance in directInput.GetDevices(DeviceType.Joystick, DeviceEnumerationFlags.AllDevices)) joystickGuid = deviceInstance.InstanceGuid; joystick = new Joystick(directInput, joystickGuid); joystick.Properties.BufferSize = 128; joystick.Acquire(); } private void JoyCheck_CheckedChanged(object sender, EventArgs e) { if (FaceCheck.Checked) FaceCheck.Checked = !JoyCheck.Checked; } private void FaceCheck_CheckedChanged(object sender, EventArgs e) { if (JoyCheck.Checked) JoyCheck.Checked = !FaceCheck.Checked; } private void RadarPaint() { Bitmap map = new Bitmap(pictureBox1.Size.Width, pictureBox1.Size.Height); Graphics g = Graphics.FromImage(map); var p = new Pen(System.Drawing.Color.Black, 2); System.Drawing.Point p1 = new System.Drawing.Point(); System.Drawing.Point p2 = new System.Drawing.Point(); System.Drawing.Point p3 = new System.Drawing.Point(); System.Drawing.Point p4 = new System.Drawing.Point(); p1.X = pictureBox1.Size.Width/2 ; //начало координат переводим в удобное нам место p1.Y = pictureBox1.Size.Height; //посередине pictureBox'a внизу for (int i = 0; i < 181; i++) { serialPortWrite(i, 90); p2.X = Convert.ToInt32(Math.Ceiling(320 + int.Parse(_distance) * Math.Cos(i * Math.PI / 180))); //считаем координаты точки p2.Y = Convert.ToInt32(Math.Ceiling(480 - int.Parse(_distance) * Math.Sin(i * Math.PI / 180))); if (i > 0) g.DrawLine(p, p2, p3); if (i % 18 == 0) { p4 = p2; p4.Y -= 50; g.DrawString(_distance, new Font(“Arial”, 18), new SolidBrush(System.Drawing.Color.Red), p4); } p3.X = p2.X; p3.Y = p2.Y; g.DrawLine(p, p1, p2); try { pictureBox1.Image = map; } catch (Exception e) { MessageBox.Show(e.Message); } } } private void button1_Click(object sender, EventArgs e) { if (FaceCheck.Checked || JoyCheck.Checked) { FaceCheck.Checked = false; JoyCheck.Checked = false; } Thread t = new Thread(RadarPaint); t.Start(); } Класс DetectFace class DetectFace { public static void Detect(Image image, String faceFileName, String eyeFileName, List faces) { CascadeClassifier face = new CascadeClassifier(faceFileName); // CascadeClassifier eye = new CascadeClassifier(eyeFileName); Image gray = image.Convert(); gray._EqualizeHist(); Rectangle[] facesDetected = face.DetectMultiScale( gray, 1.1, 5, new Size(70, 70), Size.Empty); faces.AddRange(facesDetected); } }

В итоге получаем все, что хотели. Компьютер распознает лица и автоматически следит за ними. ручное управление джойстиком работает на ура. Радар, хоть и не совсем точно, но работает. Основные функции модуля зрения робота отработаны и остается лишь дорабатывать и усовершенствовать их.

Вот, что получилось по завершении.

Итоги

Оказалось все довольно просто. Цель достигнута, прототип готов. Есть над чем работать и заняться в свободное время, ожидая посылку с компонентами для робота.

Планы на будущее

Следующим шагом будет построение колесной платформы для робота, настройка удаленного управления (WiFi, 3G)., навешивание датчиков (температура, давление и прочее), синтез речи. В хотелках так же имеются планы по поводу механической руки.

Думаю, если будет интерес к данной статье и ее продолжению, то оно обязательно последует! Исправления и критика приветствуются!

Спасибо за внимание!

Slicker

Источник

Источник: https://www.pvsm.ru/arduino/46043

Как подключить джойстик к Arduino

Учимся управлять серводвигателями через джойстики при помощи Arduino

  • Arduino (или совместимая плата);
  • двухосевой джойстик (вот такой);
  • 3 резистора номиналом 220 Ом;
  • 1 RGB (например, таких) или 3 обычных светодиода (вот таких); можно воспользоваться готовым модулем, который содержит необходимые резисторы и удобные выводы для подключения к Arduino.

Джойстик – удобное и лёгкое в использовании устройство для передачи информации. Видов джойстиков по количеству степеней свободы, принципу считывания показаний и используемым технологиям существует большое количество.

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

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

Принципиальная схема аналогового джойстика

Здесь outX, outY – выходы для снятия показаний по осям X и Y; outSw – вывод тактовой кнопки. Vcc и GND – питание и земля, соответственно.

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

Подключим джойстик по приведённой схеме. Аналоговые выходы X и Y джойстика подключим к аналоговым входам A1 и A2 Arduino, выход кнопки SW – к цифровому входу 8. Питание джойстика осуществляется напряжением +5 В.

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

В результате должно получиться примерно так, как на фотографии.

Аналоговый джойстик, подключённый к Arduino

3Считывание показаний с аналогового джойстика

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

const int switchPin = 8; // кнопка джойстика const int pinX = A1; // Ось X джойстика const int pinY = A2; // Ось Y джойстика const int ledPin = 13; void setup() { pinMode(ledPin, OUTPUT) pinMode(pinX, INPUT); pinMode(pinY, INPUT); pinMode(switchPin, INPUT); digitalWrite(switchPin, HIGH); // включаем встроенный подтягивающий резистор Serial.begin(9600); }void loop() { int ledState = digitalRead(switchPin); // считываем состояние кнопки digitalWrite(ledPin, ledState); // вкл./выкл. светодиод по нажатию кнопки int X = analogRead(pinX); // считываем аналоговое значение оси Х int Y = analogRead(pinY); // считываем аналоговое значение оси Y Serial.print(X); // Выводим значение в Serial Monitor Serial.print(“\t”); // табуляция Serial.println(Y); } Значения X и Y с аналогового джойстика,
выведенные в монитор последовательного порта

Объявим пины, зададим им режимы работы. Обратите внимание, в процедуре setup() мы подали на вход switchPin высокий уровень.

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

Это повлечёт за собой нежелательные хаотичные ложные срабатывания.

В процедуре loop() мы постоянно опрашиваем состояние кнопки и отображаем его с помощью светодиода на выходе 13. Из-за того, что вход switchPin подтянут к питанию, светодиод постоянно горит, а при нажатии кнопки гаснет, а не наоборот.

Далее мы считываем показания двух потенциометров джойстика – выхода осей X и Y. Arduino имеет 10-разрядные АЦП, поэтому значения, снимаемые с джойстика, лежат в диапазоне от 0 до 1023. В среднем положении джойстика, как видно на иллюстрации, снимаются значения в районе 500 – примерно середина диапазона.

Обратите внимание, что показания по осям X и Y в нейтральном положении ручки джойстика могут быть разные, и не равняться ровно 512.

4 Управление яркостью и цветом светодиодас помощью аналогового джойстика и Arduino

Обычно джойстик используют для управления электродвигателями. Но почему бы не использовать его, например, для управления яркостью светодиода? Давайте подключим по приведённой схеме RGB светодиод (или три обычных светодиода) к цифровым портам 9, 10 и 11 Arduino, не забывая, конечно, о резисторах.

Подключение RGB светодиода и джойстика к Arduino

Будем менять яркость соответствующих цветов при изменении положения джойстика по осям, как показано на рисунке.

Из-за того, что джойстик может быть не точно отцентрирован производителем и иметь середину шкалы не на отметке 512, а варьироваться в диапазоне примерно от 490 до 525, то светодиод может слегка светиться даже когда джойстик находится в нейтральном положении. Если вы хотите, чтобы он был полностью выключен, то внесите в программу соответствующие поправки.

Диаграмма распределения яркости красного, синего и зелёного каналов светодиода в зависимости от положения ручки джойстика Ориентируясь на приведённую диаграмму, напишем скетч управления Arduino яркостью RGB светодиода с помощью джойстика.
const int pinRed = 9; const int pinGreen = 10; const int pinBlue = 11; const int swPin = 8; const int pinX = A1; // X const int pinY = A2; // Y const int ledPin = 13; boolean ledOn = false; // текущее состояние кнопки boolean prevSw = false; // предыдущее состояние кнопки void setup() { pinMode(ledPin, OUTPUT); pinMode(pinRed, OUTPUT); pinMode(pinGreen, OUTPUT); pinMode(pinBlue, OUTPUT); pinMode(pinX, INPUT); pinMode(pinY, INPUT); pinMode(swPin, INPUT); digitalWrite(swPin, HIGH); // включаем встроенный подтягивающий резистор }void loop() { if (isLedOn()) freeMode(); // если нажата кнопка и горит светодиод на пине 13, включаем режим “фонарик” else discoMode(); // иначе включаем “цветомузыку” }boolean isLedOn() { // Определяем нажатие кнопки if (digitalRead(swPin) == HIGH && prevSw == LOW) { ledOn = !ledOn; prevSw = HIGH; } else prevSw = digitalRead(swPin); digitalWrite(ledPin, ledOn); // включаем светодиод на пине 13 return ledOn; }void freeMode() { // Режим “фонарик” int X = analogRead(pinX); // считываем положение джойстика int Y = analogRead(pinY); int RED = map(Y, 512, 1023, 0, 255); // маппинг значений int GREEN = map(X, 512, 1023, 0, 255); int BLUE = map(X, 511, 0, 0, 255); analogWrite(pinRed, RED); // включение каналов R,G,B analogWrite(pinGreen, GREEN); analogWrite(pinBlue, BLUE); }void discoMode() { // Режим “цветомузыка” for (int i=0; i }

Сначала объявим соответствие пинов и две переменные – ledOn и prevSw – для работы с кнопкой. В процедуре setup() назначим пинам функции и подключим к пину кнопки подтягивающий резистор командой digitalWrite(swPin, HIGH).

В цикле loop() определяем нажатие кнопки джойстика. При нажатии на кнопку переключаем режимы работы между режимом «фонарика» и режимом «цветомузыки».

В режиме freeMode() управляем яркостью светодиодов с помощью наклона джойстика в разные стороны: чем сильнее наклон по оси, тем ярче светит соответствующий цвет. Причём преобразование значений берёт на себя функция map(значение, отНижнего, отВерхнего, кНижнему, кВерхнему).

Функция map() очень полезна и удобна в применении. Она переносит измеренные значения (отНижнего, отВерхнего) по осям джойстика в желаемый диапазон яркости (кНижнему, кВерхнему). Можно то же самое сделать обычными арифметическими действиями, но запись с помощью функции map() существенно короче.

В режиме discoMode() три цвета попеременно набирают яркость и гаснут. Чтобы можно было выйти из цикла при нажатии кнопки, каждую итерацию проверяем, не была ли нажата кнопка.

В результате получился фонарик из трёхцветного RGB светодиода, яркость свечения каждого цвета которого задаётся с помощью джойстика. А при нажатии на кнопку происходит включение режима «цветомузыка». Я сделал специальную печатную плату с Arduino Pro Mini и джойстиком, и у меня он используется в качестве ночника для ребёнка 🙂

Управление яркостью и цветом RGB светодиода с помощью аналогового джойстика, подключённого к Arduino

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

Источник: https://soltau.ru/index.php/arduino/item/384-kak-podklyuchit-dzhojstik-k-arduino

Как подключить джойстик модуль к Ардуино

Учимся управлять серводвигателями через джойстики при помощи Arduino

07.06.2013 20:14:00

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

Компоненты для повторения (купить в Китае):

Arduino UNO, либо Arduino Nano, либо Arduino Mega

Джойстик 

Перемычки

Сервопривод SG90

Похожие вещи:

Шилд джойстик для платы Arduino

Рука на Arduino 

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

Итак, по направлениям отклонения H (horizontal) и V (vertical), на плате джойстика установлены два потенциометра. Основываясь на их показаниях джойстик отслеживает отклонения влево, вправо, вверх, вниз и выдает аналоговый сигнал от 0 до 1023.

Ось Z посажена на кнопку и выдает цифровой сигнал (вкл/выкл).

Джойстик модуль имеет пятипиновый разъем стандарта 2.54мм:

VCC: “+” питания.

V: Вывод выходного аналогового сигнала по оси Y

H: Вывод выходного аналогового сигнала по оси X

KEY: Вывод выходного сигнала с кнопки

GND: “-” питания

Подключение модуля предельно просто: 

VCC на + 5 Вольт Arduino.

GND на любой из GND пинов­­­ Arduino.

H и V на любые аналоговые входы Arduino (в примере H подсоединен к A4, V к A5).

KEY к любому цифровому пину Arduino (в примере подсоединено к D2).

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

пример программного кода:

const int Y_PIN = 5; // Потенциометр оси Y подключен к аналоговому входу 5 const int X_PIN = 4; // Потенциометр оси X подключен к аналоговому входу 4сonst int BUTTON_PIN = 2; // Кнопка подключена к цифровому выводу 2 float stepSize = 180F / 1024; // Вычисляем шаг. градусы / на градацию // Угол поворота джойстика 180 градусов, АЦП выдает значения от 0 до 1023, всего 1024 градации void setup(){Serial.begin(9600); // Скорость работы с монитором порта } void loop(){int yVal = analogRead(Y_PIN); // Задаем переменную yVal для считывания показаний аналогового значенияint xVal = analogRead(X_PIN);float yAngle = yVal * stepSize; // Переводим выходные данные yVal в угол наклона джойстика (от 0 до 180)float xAngle = xVal * stepSize; // Аналогично xValboolean isNotClicked = digitalRead(BUTTON_PIN); // Считываем не было ли нажатия на джойстикSerial.print(“Horisontal angle = “); // Выводим текст Serial.println(xAngle); // Выводим значение угла Serial.print(“Vertical angle = “);Serial.println(yAngle);if (!isNotClicked){Serial.println(“Clicked”);}delay(1000);}

Открыв монитор порта мы видим значения которые выдает наш джойстик. Опираясь на эти данные уже можно собрать что-то интересное.

Для большей наглядности подключим 2 сервопривода (D9, D10) и пищалку (D12).
При включении дуины сервоприводы принимают положение 90°. Одна отвечает за отклонения по оси X, вторая по оси Y. При нажатии на кнопку срабатывает пищалка.

#include Servo servo1;Servo servo2;const int Y_PIN = 5; // Потенциометр оси Y подключен к аналоговому входу 5 const int X_PIN = 4; // Потенциометр оси X подключен к аналоговому входу 4const int BUTTON_PIN = 2;const int SERVO1_PIN = 9;const int SERVO2_PIN = 10;const int LED_PIN = 13;float stepSize = 180F / 1024; // Вычисляем шаг. градусы / на градацию // Угол поворота джойстика 180 градусов, АЦП выдает значения от 0 до 1023, всего 1024 градации void setup(){  pinMode(LED_PIN, OUTPUT);  servo1.attach(SERVO1_PIN);  servo2.attach(SERVO2_PIN);} void loop(){  int yVal = analogRead(Y_PIN); // Задаем переменную yVal для считывания показаний аналогового значения  int xVal = analogRead(X_PIN);  float yAngle = yVal * Step; // Переводим выходные данные yVal в угол наклона джойстика (от 0 до 180)  float xAngle = xVal * Step; // Аналогично xVal  servo1.write(yAngle); // Задаем сервоприводу полученный угол  servo2.write(xAngle);   boolean isClicked = digitalRead(BUTTON_PIN);  if (isClicked)  {    digitalWrite(LED_PIN, HIGH);   }  else   {    digitalWrite(LED_PIN, LOW);  }}

Набор для сборки 2ух осевого вращателя

Использованное в статье железо:

Плата Arduino, Сенсор шилд, Джойстик модуль, Пишалка модуль, Сервоприводы mini 9G

Соединительные провода “мама-мама”

Купить в России  джойстик модуль

В данный момент еще реализованы не все элементы нашего сообщества. Мы активно работаем над ним и в ближайшее время возможность комментирования статей будет добавлена.

Источник: http://zelectro.cc/joystick_Arduino

Поделиться:
Нет комментариев

    Добавить комментарий

    Ваш e-mail не будет опубликован. Все поля обязательны для заполнения.