Brainbooster
Encoder a infrarossi per Pico - parte II
Tutorials -
Lunedì 07 Marzo 2011 20:16
Scritto da Brainbooster

Encoder a infrarossi per Pico - parte II ...... il codice  

 

Dopo aver visto come costruire praticamente il sensore, nella prima parte dell'articolo disponibile qui: http://www.gioblu.com/tutorials/robotica/202-encoder-a-infrarossi-per-pico-parte-1

vediamo ora come interfacciare il sensore ad arduino ed elaborare i dati ottenuti per avere il controllo sulla rotazione  delle ruote di Pico.

Come si vede nella foto , il sensore che qui vedete ricostruito in versione staffabile, è dotato di connettore pin header femmina con 3 terminali che sono riepettivamente Vcc (5V), uscita del sensore e GND (massa)  e li collegheremo rispettivamente ai pin 5V, analog 5 e GND come si vede nella foto seguente con i rispettivi cavetti rosso , bianco per il segnale (al pin numero 5 ) e nero per gnd.

100_0940                                                

 

 

 

 

 

 

 

 

 

 

 

100_0941 

 

100_0939

 

100_0945

 

Fatto ciò passiamo al codice di esempio....

Nell'esempio di codice che segue, ho provato a trasformare il microservo modificato per la rotazione continua, in una specie di motore stepper al quale si può dire di quanti passi avanzare e che con l'aiuto dell'encoder ci permette di avanzare con passi lunghi circa 7mm. Per fare in modo che ciò avvenga carichiamo il codice che vedete qui sotto su arduino ed attendiamo la fine dell'upload.

//********Brainbooster servo step engine*************
//**codice di prova che trasforma tramite l'encoder**
//** e la  ruota di pico,un microservo modificato in*
//**un minimotore stepper comandabile in passi con **
//**una risoluzione proporzionale al numero di slot**
//**della routa che avete****************************
//********************test version*******************

#include //includo la libreria per i servi
volatile int state = 0;  //variabile che conterrà lo stato degli impulsi ricevuti
volatile int oldstate = 0; //variabile che conterrà lo stato degli impulsi ricevuti in precedenza
int readpin=5; //il pin analogico a cui attaccare il sensore
int steps=2;  //il numero di steps da eseguire
float odo=0.00; //conteggio globale della distanza percorsa
int ticks=0;  // il numero di impulsi ricevuti
float mmtraveled=0.00; //in mm
int wheeldiameter=80; //in mm
float mmperstep=0.00;
int slots=72; //numero di finestre della ruota per 2 perchè contiamo i bordi delle finestre;)
Servo leftServo;     //istanzio il servo per il test
void setup() {  

pinMode(readpin, INPUT);    //questo pin viene usato per leggere il valore del sensore
Serial.begin(57600);  //inizializzo la seriale
leftServo.attach(9);  //comando il servo dal pin 9
leftServo.write(90);  //e gli dico di partire da fermo
mmperstep= ((2 *3.14) * (wheeldiameter/2))/slots; //calcolo millimetri per paqsso

}

void loop() {

steps = 2;  //proviamo con 2 passi per volta...
leftServo.write(0);
state=analogRead(readpin);  //leggo il pin e ne memorizzo il valore
state=map(state, 0 , 1023 , 0, 2); //passaggio "grezzo" da analogico a digitale ;)
if(state != oldstate) {  //se qualcosa è cambiato la ruota gira
if(ticks == steps) {  //se abbiamo raggiunto il numero di steps
mmtraveled=steps * mmperstep;
//  odo = (odo + mmtraveled);
ticks = 0;  //azzeriamo il contaimpulsi
leftServo.write(90); //blocco il servo
Serial.print("FATTI:"); //avviso sulla seriale che ho finito
Serial.print(mmtraveled, DEC);
Serial.println(" mm ");

Serial.print("TOTALE:"); //avviso sulla seriale che ho finito
Serial.print(odo, DEC);
Serial.println(" mm ");
delay(2000);  //aspetto un paio di secondi
}
else ticks++; //altrimenti aumenta il conteggio dei ticks
mmtraveled=ticks * mmperstep;
odo = (odo + mmtraveled);
oldstate = state; // e aggiorna lo stato della lettura del pin
}


}

L'effetto del codice di esempio è quello di avanzare per 2 step ed aspettare un secondo come se fosse un orologio :)

Il numero di step impostati nel codice, chiaramente è variabile e viene impostato nella riga che dice:" steps=2; " , quindi nulla vieta di scrivere step=72 ed avere un giro completo della ruota o 36 per il mezzo giro e così via...

Il codice proposto non ha una utilità immediata ma serve per fare da "motore stepper" in applicazioni dove conoscere lo spostamento del robot nello spazio circostante è importante.

Nell'esempio seguente invece useremo lo stesso encoder per calcolare e visualizzare sul serial monitor di arduino la velocità di rotazione della ruota, quindi un tachimetro che ci dia la velocità in RPM (Round Per Minute) e quindi in giri al minuto.

Connettete questa volta il cavetto bianco del segnale al pin digitale numero 2, useremo un interrupt ;)

Caricate il codice seguente e vedrete apparire sul serial monitor la velocità attuale di rotazione della ruota di pico.

#include //includo la libreria per i servi
Servo leftServo;                                   
int ticks;  //numero di scatti dalla ruota
int Calcola; //conterrà la velocità
int ledpin=12;  //il pin del led ir
int GlobCont=0;  //conteggio globale degli scatti
float Velocita=0;                                  
int mysensor = 2;  //il pin del sensore fototransistor


typedef struct{                  //Definiamola struttura della ruota il tipo di codifica, le tacche ecc..
char ruotatype;
unsigned int ruotadiv;
}tiporuota;

//tipi di ruota (una transizione, 36 stile pico nuovo, old pico)
tiporuota finestre[3]={{0,1},{1,36},{2,16}};

char ruota = 1;   //Scelgo il tipo di ruota
//la 1 è quella di pico con 36 raggi

void rpm ()      //La funzione chiamata dall'interrupt
{
ticks++;       //incrementiamo i ticks
}


void setup()
{
pinMode(mysensor, INPUT);
pinMode(ledpin, OUTPUT);
Serial.begin(9600);
leftServo.attach(9);  //comando il servo dal pin 9
leftServo.write(0);
attachInterrupt(0, rpm, RISING); //attacco l'interrupt al digital pin 2
} 
void loop ()
{
GlobCont=GlobCont+ticks; //aggiorno il conteggio globale dei tick
ticks = 0; //preparo la varibile svuotandola
sei(); //Abilito gli interrupts
digitalWrite(ledpin,HIGH);
delay (1000); //Un  secondo di raccolta dati
cli(); //e disabilito dinuovo gli interrupt
Calcola = ((ticks * 60)/finestre[ruota].ruotadiv); //
Velocita= (12.56 * Calcola)/60;
Serial.print (Calcola, DEC); //stampo i dati ottenuti sulla seriale
Serial.print (" rpm\r\n"); 
Serial.print (" Conteggio globale: "); 
Serial.println(GlobCont, DEC);
Serial.print (" Velocità in cm/s: "); 
Serial.println(Velocita, DEC); 
}

Nonostante il segnale proveniente dal sensore sia abbastanza definito, ci possono essere dei momenti in cui arduino trova dei falsi impulsi, questo accade anche perchè il segnale di uscita non è propriamente di livello TTL (non và da 0 a 5V), in modo che arduino possa analizzarlo correttamente, ma è un segnale analogico sinusoidale di ampiezza proporzionale alla distanza del sensore dalla ruota (quindi montatelo il più vicino possibile).

 

FILE000

 

 

 

 

 

 

 

 

 

 

 

 

 

Quindi da questo semplice sensore abbiamo la possibilità di controllare i movimenti delle ruote di Pico e per la maggiorparte delle applicazioni questo dovrebbe essere più che sufficiente per avere un 'idea della strada percorsa  dal robot o di quella che gli si vorrebbe far percorrere.

Nella prossima parte dell'articolo verdemo come migliorare ulteriormente  le prestazioni del sensore aggiungendo un altro pò di elettronica per trasformarlo  da analogico a digitale ed integrare i dati letti dalla modifica dei poli motore del servo che trovate in questo tutorial  http://www.gioblu.com/tutorials/azionamenti/170-modifica-rotazione-continua-microservi-parte-iii .

Ciao Divertitevi!

By Brainbooster

 

Gioblu Robotics © 2010 - 2012 · Sitemap · privacy

gioscarab@gmail.com

Gioblu BOTServer è online dal 10 Aprile 2010 - 319.232 Visite - 1.027.175 Pagine visualizzate - 182.309 Visitatori unici - 536 utenti attivi