In questa sedicesima lezione su Arduino, si parlerà di una scheda un po’ particolare, che permette di dare un tocco di originalità ai propri progetti e realizzarne nuove tipologie.
La scheda in questa si chiama Joystick Shield, in quanto permette di comandare qualsiasi cosa, come se fosse un Joystick.
Nella scheda è presente una sorta di rotella (quella in nero), che dal punto di vista circuitale non è altro che un potenziometro, ovvero un dispositivo in grado di far cambiare il proprio valore di resistenza. Ci sono altri push button, che sono A,B,C,D,E,F. Come si può notare in basso a sinistra, è possibile scegliere se alimentare la scheda con 3.3 oppure 5 [V].
Il mio consiglio è quello di utilizzare l’alimentazione più alto, in modo da avere una risoluzione migliore, per via della conversione analogica-digitale di Arduino a 10 bit (aumentando il livello 0-5 V, l’ADC lavora meglio).
La scheda va messa sopra allo stesso Arduino, cercando di far combaciare correttamente i PIN presenti.
Per capire come recuperare i valori dei vari controller presenti nella scheda, basta guardare questo documento:
I valori della X e Y vengono “inviati” sui pin analogici A0 e A1, mentre i valori digitali dei push-button A,B,C,D vengono “inviati” sui pin digitali 2-6.
I push button inviano valore 1 quando non sono premuti e il valore 0 altrimenti.
Ecco un po’ di esempi software per poter utilizzare la scheda correttamente.
Joystick Hello world !
Questo codice permette di capire in pochi minuti come poter recuperare le informazioni dalla scheda in Arduino.
/** Questo programa spiega come utilizzare il Joystick con Arduino Versione 1.0 Autore Giacomo Bellazzi */ int A = 2; int B = 3; int C = 4; int D = 5; int x = A0; int y = A1; char key[] = {'A','B','C','D'}; void setup() { Serial.begin(9600); } void loop() { keyPressed(A); keyPressed(B); keyPressed(C); keyPressed(D); joystick(); delay(100); } /* Questa funzione mostra se un pin è stato mostrato*/ void keyPressed(int index){ if(digitalRead(index)==0){ Serial.print(key[index-2]); Serial.print(" has been pressed"); Serial.print("\n"); } } /* Questa funziona mostra lo spostamendo x e y del joystick*/ void joystick(){ Serial.print("x: "); Serial.print(analogRead(x)); Serial.print(" y: "); Serial.print(analogRead(y)); Serial.print("\n"); }
Come comandare l’elicottero Syma S-107G con Arduino
Sul mercato è possibile acquistare piccoli elicotteri radio comandabili a prezzi davvero bassi. Per esempio l’elicottero Syma S-107G è facilmente acquistabili su ebay per 15 euro.
La sua autonomia è di circa 5-6 minuti e permette di controllarlo agevolmente attraverso il joystick presente nella scatola. Per chi volesse utilizzare lo stesso Arduino con la joystick shield può utilizzare questo programma.
Il joystick originale dell’elicottero utilizzare i segnali IR per poter comunicare con il dispositivo. Per tanto è necessario l’utilizzo di 3 LED ad infrarosso da collegare al PIN 12 per poter inviare correttamente la sequenza di bit di corretta.
/** Questo programa permette di utilizzare la Joystick shield per comandare l'elicottero Syma S-107G Versione 1.0 Autore Giacomo Bellazzi */ #define RED 12 // the output pin of the IR LED int A = 2; int B = 3; int C = 4; int D = 5; int x = A0; int y = A1; int throttleValue = 63; //Initial value void setup() { pinMode(RED, OUTPUT); // set IR LED (Pin 4) to Output int Channel = 0; //Channel A = 0, Channel B = 128 pinMode(A,INPUT); pinMode(B,INPUT); pinMode(C,INPUT); pinMode(D,INPUT); Serial.begin(9600); } void loop() { int Throttle, Rudder, Elevator, RudderTrim; int Channel; Throttle = throttleValue; Rudder = leftRightToPerc(analogRead(x)); Elevator = upDownToPerc(analogRead(y)); RudderTrim = 0; Serial.println(Throttle); //Serial.println(Rudder); //Serial.println(Elevator); //Transmit(0,63,50,0); Transmit(Rudder, Elevator, Throttle, RudderTrim); throttle(); } void Transmit(byte rudder, byte elevator, byte throttle, byte trim) { static byte Code[4]; byte mask = 128; //bitmask int i; Code[0] = rudder; // 0 -> 127; 63 is the midpoint. Code[1] = elevator; // 0 -> 127; 63 is the midpoint. Code[2] = throttle; // 0 -> 127; 0 is throttle off Code[3] = trim; // Haven't messed with this OutPulse(2002); // Start 38Khz pulse for 2000us (2002us is evenly divided by 26) delayMicroseconds(2000); // 2000us off. for (i = 0; i<4; i++) { // Loops through the Code[] for (mask = 128; mask > 0; mask >>=1) { // See Arduino reference for bit masking (really cool stuff!) OutPulse(312); // Sends 312 pulse each loop if(Code[i] & mask) { //If both bit positions are 1 you get 1 delayMicroseconds(688); // send 1 (700 off) } else { delayMicroseconds(288); // send 0 (300 off) } } //End mask loop } //End i loop OutPulse(312); //Send 300 microsecond Closing Pulse delay(60); } // End Transmit void OutPulse(int Pulse) { //sends 38Khz pulses over the Pulse Length int par=Pulse/26; par+=-1; for(int p = 0; p < par; p++) { //Takes about 26 microseconds per loop digitalWrite(RED, HIGH); delayMicroseconds(10); digitalWrite(RED, LOW); delayMicroseconds(10); } } //End Out int leftRightToPerc(int value){ return (int) (127-value*0.12414467); } int upDownToPerc(int value){ return (int) (127-value*0.12414467); } // Viene aumentato il valore della potenza/quota void throttle(){ if(hasBeenPressed(C)&&throttleValue!=0){ throttleValue--; } if(hasBeenPressed(A)&&throttleValue!=127){ throttleValue++; } } // Stabilisce se un push button è stato premuto boolean hasBeenPressed(int key){ if(digitalRead(key)==0){ return true; }else{ return false; } }