Рейтинг@Mail.ru
Аналоговый джойстик
Аналоговый джойстик

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

3 комментарии Arduino
Print Friendly, PDF & Email
Существует большое разнообразие способов передачи информации от человека микроконтроллеру или компьютеру, и один из них - это использование джойстика. Давайте посмотрим как подключить к Arduino аналоговый джойстик с двумя осями и кнопкой.
Инструкция по подключению аналогового джойстика к Arduino

Для проекта нам понадобится:

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

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

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

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

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

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

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

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

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

Аналоговый джойстик, подключённый к 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 с аналогового джойстика, выведенные в монитор последовательного порта
Значения 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
Подключение 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 <= 255; i++) {
      if (isLedOn()) { break; } // при нажатии кнопки выходим из цикла
      analogWrite(pinRed, i); // работает канал RED
      analogWrite(pinGreen, 0);
      analogWrite(pinBlue, 0);  
      delay(5);
    }
    for (int i=0; i <= 255; i++) {
      if (isLedOn()) { break; } // при нажатии кнопки выходим из цикла
      analogWrite(pinRed, 0);
      analogWrite(pinGreen, 0);
      analogWrite(pinBlue, i);  // работает канал BLUE
      delay(5);
    }
    for (int i=0; i <= 255; i++) {
      if (isLedOn()) { break; } // при нажатии кнопки выходим из цикла
      analogWrite(pinRed, 0);
      analogWrite(pinGreen, i); // работает канал GREEN
      analogWrite(pinBlue, 0);  
      delay(5);
    }
}

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

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

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

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

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

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

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

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

Последнее изменениеСреда, 10 Январь 2024 18:52 Прочитано 54099 раз

Поблагодарить автора:

Поделиться

Print Friendly, PDF & Email

3 комментарии

  • Павел
    Павел 02.10.2018 17:42 Комментировать

    В первом примере ошибка:
    void setup() {
    pinMode(ledPin, OUTPUT);

    На встроенном светодиоде OUTPUT вместо INPUT

  • aave111
    aave111 03.10.2018 20:00 Комментировать

    Спасибо, поправил.

  • Владимир
    Владимир 26.09.2023 07:02 Комментировать

    Доброго времени суток! Подскажите пожалуйста, как написать скетч, чтобы подключить две оси x и две оси y?!
    Допустим на игровом контроллере по одной оси x и y, для министика , а у датчиков TLE5010 две другие оси?! Как должен выглядеть скетч в таком случае?!

Оставить комментарий