INPUT ANALOGICO: Esempio JOYSTICK

Costruire il seguente circuito (serve un JOYSTICK e un Led)

 

Ricordate di collegare il catodo (-) del diodo LED su GND e l’anodo (+) all’uscita digitale 13 (volendo possiamo omettere il led sfruttando il fatto che il PIN 13 è connesso al L-LED di Arduini. Ecco l'immagine del circuito

La lettura dei valori relativi ai due assi è di tipo analogico ed avviene attraverso i pin A0 ed A4 con il comando analogRead( pin ). Per catturare il segnale proveniente dal pulsante connesso alla leva del joystick devo utilizzare il comando digitalRead( pin ). Spostando il joystick dal punto centrale dell’asse X verso destra il suo valore varia da circa 512 a 0, spostandolo verso sinistra varia da 512 a 1023. Questo è il campo si escursione che abbiamo già incontrato parlando  dell’ADC ( convertitore analogico digitale ) di arduino a 10bit. Gli stessi valori vengono letti sul pin A4 spostando il joystick verso il basso (da 512 circa a 0) o verso l’alto (da 512 circa a 1023).

Codice Sorgente A

I pin digitali di Arduino sono per default impostati come pin di INPUT, perciò non è necessario dichiararli esplicitamente come input con il comando pinMode(). Nel caso si debba utilizzarli come pin di uscita è indispensabile impostare il pin come OUTPUT tramite il comando pinMode(pin, OUTPUT). I pin configurati come INPUT si dice che sono in uno stato di alta impedenza.

Il processore Atmega, presente sulla scheda Arduino, è dotato su ogni ingresso digitale, di una resistenza di pull-up da 20KOhm che viene abilitata via software quando imposto il PIN come INPUT. Le istruzioni sono le seguenti:

pinMode(pin, INPUT); // imposta 'pin' come input
digitalWrite(pin, HIGH); // attiva la resistenza di pull-up,

Le resistenze di pull-up vengono normalmente utilizzate per gestire degli input come ad esempio gli interruttori.

I pin configurati come OUTPUT sono detti a bassa impedenza e sono in grado di fornire 40 mA (milliampere) ad altri dospositivi o circuiti. Questa è una corrente sufficiente per accendere un LED (non dimenticate di inserire in serie una resistenza), ma non è una corrente sufficiente per pilotare la maggior parte dei relè, bobine o motori.

I cortocircuiti sui piedini di Arduino possono danneggiare o distruggere i pin di output o danneggiare l’intero chip Atmega. Quando si ha la necessità di utilizzare i pin come output per collegare dispositivi esterni è buona prassi inserire in serie al pin un resistore da 470 Ohm o 1 KOhm.

/* -----------------------------------------------------------------------------------
  Scopo del programma è leggere gli spostamenti del JOYSTICK 
----------------------------------------------------------------------------------- */  
const byte Pin_VRx = 0;    // Pin Asse Orizzontale
const byte Pin_VRy = 4;    // Pin Asse Verticale
const byte Pin_SW  = 6;    // Pin del bottone sul Joystick
const byte Pin_LED  = 13;  // Pin del LED L di Arduino

byte statoBottone; 

void setup() 
{
  // I pin di INPUT posso anche non dichiararli
  pinMode(Pin_SW, INPUT);      // Inizializzo il pin del pulsante del JOYSTICK
  digitalWrite(Pin_SW,HIGH);   // Setto la resistenza di pull-up
  pinMode(Pin_LED, OUTPUT);    // Inizializzo il pin del LED
  digitalWrite(Pin_LED,LOW);   // Spengo il LED
  Serial.begin(9600);          // Inizializzo la comunicazione seriale
}

void loop()
{
   unsigned int valueX,valueY;
   int scaleX,scaleY;
   // LETTURA PARAMETRI
   statoBottone=digitalRead(Pin_SW);  // Leggo lo stato del pulsante del joystick
   valueX = analogRead(Pin_VRx);      // Legge la posizione del joystick orizzontale
   valueY = analogRead(Pin_VRy);      // Legge la posizione del joystick verticale
   // SCALO I VALORI IN UN OPPORTUNO RANGE (utile didatticamente)
   scaleX   = map(valueX, 0, 1023, -5, 5);
   scaleY   = map(valueY, 0, 1023, -5, 5);
   // Creo le stringhe di output in 2 modi (String che char []) a scopo didattico
   char Linea2[32];
   snprintf(Linea2, 32, "Scalato(X,Y)=(%d,%d)", scaleX, scaleY);
   String Linea="(X,Y)=("+String(valueX)+","+String(valueY)+") - " + Linea2;
   Serial.println(Linea);
   if (statoBottone==LOW) // è premuto
     digitalWrite(Pin_LED,HIGH); // Accendo il LED se schiaccio il pulsante
   else
     digitalWrite(Pin_LED,LOW); // Accendo il LED se schiaccio il pulsante
}

Codice Sorgente B

Per le impostazioni delle direzioni utilizziamo questo schema:

/* -----------------------------------------------------------------------------------
  Scopo del programma è visualizzare la direzione degli spostamenti del JOYSTICK 
----------------------------------------------------------------------------------- */
#define THRESHOLD_LOW 350
#define THRESHOLD_HIGH 650

const byte Pin_VRx = 0;    // Pin inteso qui come verticale
const byte Pin_VRy = 4;    // Pin inteso qui come orizzontale
const byte Pin_SW  = 6;    // Pin del bottone sul Joystick

int x_position;
int y_position;
char Prec_x_direction = '\0'; // lettura orizzontale nel precedente loop
char Prec_y_direction = '\0'; // lettura verticale nel precedente loop
char Prec_b_state = '\0';     // stato del bottone nel precedente loop

void setup() 
{
  pinMode(Pin_SW, INPUT);      // Inizializzo il pin del pulsante del JOYSTICK
  digitalWrite(Pin_SW,HIGH);   // Setto la resistenza di pull-up
  Serial.begin(9600);
}

void loop () 
{
  char x_direction = '\0';
  char y_direction = '\0';
  char b_state = '\0';
  
  // Pin_VRx è abbinato con y e viceversa per 
  // via dell'interpretazione diversa che do ai
  // movimenti del joystick
  x_position = analogRead(Pin_VRy);
  y_position = analogRead(Pin_VRx);
  b_state=digitalRead(Pin_SW);  // Leggo lo stato del pulsante del joystick
 
  // Stabilisco la direzione e stato bottone
  if (x_position > THRESHOLD_HIGH) 
    x_direction = 'R'; // Destra
  else if (x_position < THRESHOLD_LOW)
    x_direction = 'L'; // Sinistra
  else
    x_direction = 'C'; // Riposo
  if (y_position > THRESHOLD_HIGH)
    y_direction = 'U'; // Alto
  else if (y_position < THRESHOLD_LOW)
    y_direction = 'D'; // Basso
  else
    y_direction = 'C'; // Riposo
  if (digitalRead(Pin_SW)==LOW) 
     b_state='P'; // è premuto
  else
     b_state='-';
  
  if (Prec_x_direction != x_direction || Prec_y_direction != y_direction || Prec_b_state != b_state)
      Serial.println(String(x_direction)+String(y_direction)+String(b_state));
  Prec_x_direction = x_direction;
  Prec_y_direction = y_direction;
  Prec_b_state=b_state;
  delay(50);
}

Sfruttando il codice di Arduino precedente posso far muovere una pallina in EXCEL. Per provare basta scaricare il file seguente: supporto\Arduino-JoyStick.xls