Joystick

Joystick
Joysticks komen van pas bij allerlei spelletjes. Met een Joystick kun je een richting aangeven (naar boven, beneden, links, rechts, of als je dat liever zegt: noord, oost, zuid, west). In werkelijkheid wordt de richting bepaalt door hoe de Joystick is aangebracht. Je kunt op de knop van de joystick drukken om een keuze te bevestigen.
Je kunt ook nagaan hoe ver de knop naar een bepaalde kant is gedrukt.

Sluit bij dit type VCC en GND maar 1 keer aan
De uitlezing van de Joystick is eenvoudig: de drukknop lees je uit als elke andere drukknop, via een digitale invoer pin; de richting via twee analoge invoer pinnen. Als we bijvoorbeeld de links-rechts beweging nemen, dan zal de analoge uitlezing 0 zijn als de knop helemaal links is, 511 in de middenstand en 1023 als de knop helemaal rechts is. Hierbij ga ik ervan uit dat je de Joystick hebt aangesloten op VCC-uitgang van je Arduino - of je een 3,3 V of een 5 V Arduino hebt maakt dan niet uit. In het voorbeeldprogramma laat ik zien hoe je alleen een waarde uitleest als de Joystick bewogen is. Dat is nog lastig, omdat je niet elke trilling wilt waarnemen. Om dit tegen te gaan heb ik een marge ingebouwd.
Voorbeeldprogramma:

#define knop 2   // Sluit de drukknop aan op pin 2,
#define vert A0  // boven-beneden op A0
#define hor  A1  // en links-rechts op A1
#define marge 20 // Marge voor de bewegingsdetectie

void setup() {
  Serial.begin(9600);
  pinMode(knop, INPUT_PULLUP);
}

int oudHorizontaal = 0, oudVerticaal = 0;
void loop() {
  int waarde = analogRead(vert);
  if ( abs(waarde - oudVerticaal) > marge ) {
    oudVerticaal = waarde;
    if (waarde > 511 + marge) {
      Serial.print( 100.0 / 512 * (waarde - 511), 0 );
      Serial.println( "% naar boven" );
    }
    else if (waarde < 511 - marge) {
      Serial.print( 100.0 / 512 * (511 - waarde), 0 );
      Serial.println( "% naar beneden" );
    }
  }
  waarde = analogRead(hor);
  if (abs(waarde - oudHorizontaal) > marge) {
    oudHorizontaal = waarde;
    if (waarde > 511 + marge) {
      Serial.print( 100.0 / 512 * (waarde - 511), 0 );
      Serial.println( "% naar links" );
    }
    else if (waarde < 511 - marge) {
      Serial.print( 100.0 / 512 * (511 - waarde), 0 );
      Serial.println( "% naar rechts" );
    }
  }
  if ( !digitalRead(knop) ) Serial.println("De knop werd ingedrukt");
  delay(200);
}

Uitvoer van het testprogramma

Joystick shield

Mijn shield
Er bestaan ook Joystick shields voor de Arduino Uno. Ze zijn er in diverse soorten, vaak met één joystick en een aantal drukschakelaars, soms ook met Bluetooth. Mijn versie heeft twee joysticks, een led en een IR sensor. Je zult zelf moeten uitzoeken hoe jouw shield is aangesloten, maar gebruikelijk is dat de X- en Y- van de eerste joystick zijn aangesloten op A0 en A1 en de X- en Y- van de tweede joystick op A2 en A3. Als je de joystick indrukt is er vaak een schakelaar, bij mij zijn die schakelaars aangesloten op D2 en D4. De led is aangesloten op D3.
Mijn shield heeft ook nog een IR sensor, zodat je elke universele infrarood afstandsbediening kunt gebruiken om signalen door te geven. Deze sensor is aangesloten op pin D7. Je kunt hem goed uitlezen met de bibliotheek IRremote.h van Shirriff e.a. die je gemakkelijk vanuit de Arduino IDE kunt installeren.
Op mijn shield zijn ook nog drie rijen van vier pinnen aanwezig: vier keer GND en vier keer VCC. De onderste rij is verbonden met (van links naar rechts: D11, D10, D9 en D5. Bij andere shields is dat wellicht anders, maar met een ohmmeter kun je er vrij gemakkelijk achterkomen met welke pinnen die dan verbonden zijn. Deze vier pinnen zijn te gebruiken voor het aansturen van motoren (via een motor driver) of servo-motoren. In het voorbeeldprogramma hieronder wordt de lichtsterkte van vier leds geregeld met de joysticks. Sluit de leds aan op de pinnen en verbind de andere kant via een weerstand van een paar honderd Ohm met GND. Als je de weerstanden weghaalt dan zullen de leds niet meteen kapot gaan, omdat ze in de neutrale positie van de joysticks de helft van de stroom krijgen.

// Joystick ingangen
const int joyX1 = A0;
const int joyY1 = A1;
const int joyX2 = A2;
const int joyY2 = A3;

// PWM-uitgangen 
const int led1 = 5;
const int led2 = 9;
const int led3 = 10;
const int led4 = 11;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
}

void loop() {
  // Joystickwaarden lezen (0–1023)
  int v1 = analogRead(joyX1);
  int v2 = analogRead(joyY1);
  int v3 = analogRead(joyX2);
  int v4 = analogRead(joyY2);

  // Omzetten naar PWM (0–255)
  int p1 = map(v1, 0, 1023, 0, 255);
  int p2 = map(v2, 0, 1023, 0, 255);
  int p3 = map(v3, 0, 1023, 0, 255);
  int p4 = map(v4, 0, 1023, 0, 255);

  // LEDs aansturen
  analogWrite(led1, p1);
  analogWrite(led2, p2);
  analogWrite(led3, p3);
  analogWrite(led4, p4);

  delay(5); // stabilisatie


Om de IR sensor te testen, of de codes te achterhalen, kun je het volgende script gebruiken:

#include <IRremote.h>

const int IR_PIN = 7;

void setup() {
  Serial.begin(9600);
  IrReceiver.begin(IR_PIN, ENABLE_LED_FEEDBACK);
  Serial.println("IR ontvanger klaar...");
}

void loop() {
  if (IrReceiver.decode()) {
    Serial.print("Ontvangen code: ");
    Serial.println(IrReceiver.decodedIRData.command, HEX);
    IrReceiver.resume(); // klaar voor volgende code
  }
}