Sei sulla pagina 1di 5

// Arduino: telecomando a infrarossi per accendere o spegnere un led

17 led telecomandato
In questo esercizio viene utilizzata una copia
del programma descritto nel precedente
esercizio 16.
Lunica differenza e che Arduino utilizza i
segnali provenienti dal telecomando per
pilotare (accendere o spegnere) un led. Piu in
dettaglio, utilizzando il telecomando
rappresentato in figura, accende il led quando
viene premuto il tasto 1 e lo spegne quando
viene premuto il tasto 2.
Nota: Questo esercizio e questa nota sono parte di una serie che vede protagonisti arduino ed
alcuni dei componenti ad esso collegabili. Per la maggior parte degli esercizi e anche disponibile
un filmato su youtube.
Esercizi facenti parte della raccolta
Filmati presenti su youtube
Informazioni su arduino e sui componenti collegabili
Breve manuale di programmazione

Materiali
1 telecomando ad infrarosssi
1 modulo ricevitore di infrarossi
1 led
1 resistenza da 220 ohm
5 cavetti

Schema

// Arduino: telecomando a infrarossi per accendere o spegnere un led

Programma
/* Per comprendere al meglio questo esercizio e' necessario comprendere prima le modalita'
di funzionamento di un telecomando o, meglio il protocollo di comunicazione dei segnali. Tutto cio'
e' spiegato, anche se non in maniera esaustiva, nelle note che accompagnano lesercizio numero
16.
Questo programma e' derivato da un programma, non professionale, esistente sul web
ed il sistema telecomando/arduino/led non sempre risponde con prontezza agli impulsi.
E possibile che tale difetto dipenda dal fatto che il momento di pressione di un tasto
non sempre coincide con il momento in cui il programma verifica l'arrivo di un blocco
di sincronismo
Per ottenere una risposta e' quindi a volte necessario premere piu' volte ed in rapida
successione un tasto, in modo da favorire la sincronizzazione tra telecomando ed apparato
ricevente
Unultima nota riguarda il telecomando illustrato nelle note descrittive. Si tratta di un prodotto di
infima qualita che spesso costringe a premere piu volte un tasto per ottenere un risultato.
Conviene in sua vece utilizzare un qualunque telecomando di casa, del quale e stata prima
rilevata la correlazione tra pulsanti e segnale inviato (utilizzando, a questo scopo, il precedente
esercizio 16). Per accendere il led bisogna premere il pulsante che invia il segnale decimale 16
mentre per spegnerlo bisoga premere il pulsante che invia il segnale decimale 17
*/
int IR_IN = 2; // inserisce 2 nella variabile IR_IN utilizzata per
// indicare la porta alla quale e' collegato il ricevitore del segnale infrarosso
int Pulse_Width = 0;
int ir_code = 0x00;
char adrL_code = 0x00;
char adrH_code = 0x00;
int lucentezza = 0;

// zona in di memorizzazione del tempo trascorso dal precedente impulso


// zona di memorizzazione del codice inviato dal telecomando
// byte in cui viene memorizzato il comando
// byte in cui viene memorizzato il comando invertito (Anti-code)
// definizione della variabile lucentezza, con valore iniziale 0

void timer1_init(void) // routine di inizializzazione delle zone di memorizzazione del tempo.


// il trascorrere del tempo e' automaticamente gestito dal sistema che registra in TCNT1 un
// valore corrispondente al tempo trascorso dall'ultimo azzeramento
{
TCCR1A = 0X00;
TCCR1B = 0X05; // modulatore del tempo; con il valore 5, TCNT1 si incrementa di 15625 unita di
// tempo ad ogni secondo
TCCR1C = 0X00;
TCNT1 = 0X00; // timer, con TTCCR1B = 5 incrementa di 15625 unita' ad ogni secondo
// fino ad un massimo di circa 65000, poi si azzera e ricominicia
TIMSK1 = 0X00;
}
char logic_value() /*routine di ricezione del comando. Restituisce il valore 0 (0,56 microsecondi
dal precedente impulso, corrispondente al valore 0) oppure 1 (1,7 micorsecondi dal
precedente impulso, corrispondente al valore 1) oppure -1 nessun tasto premuto o segnale
non riconosciuto */
{
TCNT1 = 0X00;
while(!(digitalRead(IR_IN))); // inizio attesa dell'impulso

// Arduino: telecomando a infrarossi per accendere o spegnere un led


Pulse_Width=TCNT1;
TCNT1=0;
if(Pulse_Width>=7&&Pulse_Width<=10) // 0,56 microsecondi
{
while(digitalRead(IR_IN)); // quando riceve un impulso
Pulse_Width=TCNT1;
//memorizza il tempo trascorso dal precedente impulso
TCNT1=0;
if(Pulse_Width>=7&&Pulse_Width<=10) // 0.56 microsecondi
return 0;
else if(Pulse_Width>=25&&Pulse_Width<=27) // 1.7 microsecondi
return 1;
}
return -1;
}
void pulse_deal() // routine di ricezione e memorizzazione dei 4 bytes di indirizzo e comando
{
int i;
int j;
ir_code=0x00;
// azzera l'area di memorizzazione del comando
adrL_code=0x00; // azzera l'area di memorizzazione dell'indirizzo
adrH_code=0x00; // azzera l'area di memorizzazione dell'indirizzo inverso
// Le prossime istruzioni analizzano i valori trasmessi dal telecomando, Questa routine
// compila, bit per bit, i 4 bytes in cui viene memorizzato il comando (due bytes di indirizzo
// e due bytes di comando)
for(i = 0 ; i < 16; i++) // memorizza i 16 bit dei due bytes di comando
{
if(logic_value() == 1) // se la routine di ricezione restituisce il valore 1
ir_code |= (1<<i); // Salva il bit del comando
}
for(i = 0 ; i < 8; i++) // memorizza gli 8 bit del byte di indirizzo
{
if(logic_value() == 1)
adrL_code |= (1<<i); // salva il bit dell'indirizzo
}
for(j = 0 ; j < 8; j++) // memorizza gli 8 bit del byte del comando inverso
{
if(logic_value() == 1)
adrH_code |= (1<<j); // Salva il bit dell'indirizzo inverso
}
}
void remote_decode(void) // routine di ricezione e interpretazione degli impulsi
{
TCNT1=0X00;
while(digitalRead(IR_IN)) // esegue la routine quando riceve un impulso
{
if(TCNT1>=1563) // se se sono trascorsi piu' di 100 microsecondi dal precedente
// impulso significa che il telecomando non era in uso e quindi azzera le zone di
// memorizzazione dei codici e torna alla routine chiamante
{
ir_code=0x00ff; // inserisce il valore FF nel comando (0x00ff corrisponde al
// tasto "spento" del telecomando)
adrL_code=0x00; // azzera il byte di indirizzo
adrH_code=0x00; // azzera il byte di indirizzo inverso
return;

// Arduino: telecomando a infrarossi per accendere o spegnere un led


}
}
// Se la durata non e' superiore a 100 microsecondi significa che il telecomando e' in uso
// e quindi si predispone a ricevere una sequenza di impulsi
TCNT1=0X00;
while(!(digitalRead(IR_IN))); // se non c'e' impulso verifica il tempo trascorso dal
// precedente impulso
Pulse_Width=TCNT1;
TCNT1=0;
if(Pulse_Width>=140&&Pulse_Width<=141) // 9 microsecondi. Se sono trascorsi 9 microsecondi
// significa che e' arrivato il primo segnale di sincronismo
{
while(digitalRead(IR_IN)); // verifica se dopo il primo blocco di sincronismo sono trascorsi
// 4,5 microsecondi, (secondo blocco di sincronismo)
Pulse_Width=TCNT1;
TCNT1=0;
if(Pulse_Width>=68&&Pulse_Width<=72) // 4.5ms
{
pulse_deal(); // Se e' arrivato anche il secondo blocco di sincronismo lancia la routine
// di ricezione e memorizzazione dei comandi
return;
}
else if(Pulse_Width>=34&&Pulse_Width<=36) //2.25ms
{
while(!(digitalRead(IR_IN))); // Low attesa
Pulse_Width=TCNT1;
TCNT1=0;
if(Pulse_Width>=7&&Pulse_Width<=10) //0,56 microsecondi
{
return;
}
}
}
}
void remote_deal(void) // routine di esecuzione delle funzioni richieste dal telecomando
// (accensione e spegnimento del led)
{
if (adrL_code == 16) // il valore decimale 16 corrisponde al valore esadecimale 10
// ed al tasto "1" del telecomando
{
lucentezza = 255;
analogWrite (9, lucentezza);
}
if (adrL_code == 17) // il valore decimale 17 corrisponde al valore esadecimale 11
// ed al tasto "2" del telecomando
{
lucentezza = 0;
analogWrite (9, lucentezza);
}
if (adrL_code == 8) // il valore decimale 8 corrisponde al valore esadecimale 8
// ed al tasto "freccia bassa" del telecomando
{
if (lucentezza == 0)
{

// Arduino: telecomando a infrarossi per accendere o spegnere un led


lucentezza = 5;
}
lucentezza = lucentezza -5;
analogWrite (9, lucentezza);
}
if (adrL_code == 10) // il valore decimale 10 corrisponde al valore esadecimale A
// ed al tasto "freccia alta" del telecomando
{
if (lucentezza == 255)
{
lucentezza = 250;
}
lucentezza = lucentezza +5;
analogWrite (9, lucentezza);
}
}
void setup()
{
pinMode (9, OUTPUT); // definisce come porta di uscita la porta 9, alla quale e' collegato il led
pinMode(IR_IN,INPUT); // definisce come porta di ingresso la porta IR_IN (la porta 2),
// alla quale e' collegato il ricevitore infrarossi,
}
void loop()
{
timer1_init();
//inizializza le zone di gestione del tempo
{
remote_decode(); // lancia la routine di ricezione e decodifica dei segnali
remote_deal();
// lancia la routine di esecuzione delle funzioni richieste dal telecomando
}
}