08. Gli infrarossi
Il meccanismo di funzionamento di una trasmissione ad infrarossi è abbastanza semplice; un fascio luminoso, ad elevata frequenza (38 KHz per i telecomandi tipici per la TV) viene proiettato contro un ricevente. Questo fascio luminoso non è altro che una sequenza di bit (0 e 1) che vengono codificati dal ricevente. In un telecomando ad ogni pulsante è associata una sequenza di bit. Ad esempio il pulsante on/off potrebbe essere associato alla sequenza
010101001110
Il ricevente valuterà la sequenza ricevuta e potrà svolgere la richiesta effettiva, come ad esempio accendere la TV!
Il fascio luminoso che viene inviato dal telecomando, non è possibile vederlo ad occhio nudo perché ha una frequenza troppo veloce per noi!
Tipicamente ogni produttore di dispositivi tecnologici, ha una propria codifica, come ad esempio Sony, NEC, Samsung etc..
I telecomandi IR trasmettono il segnale a infrarossi con una modulazione che va dai 33 ai 56KHz, la più diffusa è sicuramente quella a 38KHz. Questo vuol dire, semplificando, che il livello logico non è costituito da un singolo impulso di una certa durata bensì da un certo numero di transizioni alto/basso che avvengono, appunto, alla frequenza della portante (38KHz nel nostro caso). Un ricevitore demodulante presenterà in uscita non il treno di pulsazioni bensì un solo livello logico costante della durata corretta per quel treno di pulsazioni. In particolare i treni di impulsi alla frequenza portante identificano la durata di un livello logico basso, mentre le “pause” tra un treno e l’altro vengono interpretate come livello logico alto.
Codice solo per Tinkercard
#include <IRremote.h>
IRrecv irrecv(2);
decode_results r;
void setup()
{
pinMode(13, OUTPUT);
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
void dump() {
decode_results * results;
results = &r;
int count = results->rawlen;
if (results->decode_type == UNKNOWN) {
Serial.print("Unknown encoding: ");
}
else if (results->decode_type == NEC) {
Serial.print("Decoded NEC: ");
}
else if (results->decode_type == SONY) {
Serial.print("Decoded SONY: ");
}
else if (results->decode_type == RC5) {
Serial.print("Decoded RC5: ");
}
else if (results->decode_type == RC6) {
Serial.print("Decoded RC6: ");
}
else if (results->decode_type == JVC) {
Serial.print("Decoded JVC: ");
}
else if (results->decode_type == PANASONIC) {
Serial.print("Decoded Panasonic: ");
}
Serial.print(results->value, HEX);
Serial.print("(");
Serial.print(results->bits, DEC);
Serial.println(" bits)");
Serial.print("#define Something_DEC ");
Serial.println(results->value, DEC);
Serial.print("#define Something_HEX ");
Serial.println(results->value, HEX);
Serial.print("Raw (");
Serial.print(count, DEC);
Serial.print("): ");
for (int i = 0; i < count; i++) {
if ((i % 2) == 1) {
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
}
else {
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
}
Serial.print(" ");
}
Serial.println("");
}
void loop() {
if (irrecv.decode(&r)) {
dump();
irrecv.resume(); // Receive the next value
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
}
}
Codice per Arduino reale
#include <IRremote.h>
IRrecv irrecv(2);
decode_results results;
void setup()
{
pinMode(13, OUTPUT);
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
void dump(decode_results *results) {
int count = results->rawlen;
if (results->decode_type == UNKNOWN) {
Serial.print("Unknown encoding: ");
}
else if (results->decode_type == NEC) {
Serial.print("Decoded NEC: ");
}
else if (results->decode_type == SONY) {
Serial.print("Decoded SONY: ");
}
else if (results->decode_type == RC5) {
Serial.print("Decoded RC5: ");
}
else if (results->decode_type == RC6) {
Serial.print("Decoded RC6: ");
}
else if (results->decode_type == SAMSUNG) {
Serial.print("Decoded SAMSUNG: ");
}
else if (results->decode_type == JVC) {
Serial.print("Decoded JVC: ");
}
else if (results->decode_type == PANASONIC) {
Serial.print("Decoded Panasonic: ");
}
Serial.print(results->value, HEX);
Serial.print("(");
Serial.print(results->bits, DEC);
Serial.println(" bits)");
Serial.print("#define Something_DEC ");
Serial.println(results->value, DEC);
Serial.print("#define Something_HEX ");
Serial.println(results->value, HEX);
Serial.print("Raw (");
Serial.print(count, DEC);
Serial.print("): ");
for (int i = 0; i < count; i++) {
if ((i % 2) == 1) {
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
}
else {
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
}
Serial.print(" ");
}
Serial.println("");
}
void loop() {
if (irrecv.decode(&results)) {
dump(&results);
irrecv.resume(); // Receive the next value
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
}
}
Ricevitore
Codice per Tinkercard
#include <IRremote.h>
IRrecv irrecv(2);
decode_results r;
long TIMER;
int timer(long *t, long millisecondi)
{
long x;
x=millis();
if (!*t){
*t=x;
return 0;
}
else if (x-*t > millisecondi) {
*t=millis();
return 1;
}
else
return 0;
}
void setup()
{
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(8, OUTPUT);
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
void dump() {
decode_results * results;
results = &r;
int count = results->rawlen;
if (results->decode_type == UNKNOWN) {
Serial.print("Unknown encoding: ");
}
else if (results->decode_type == NEC) {
Serial.print("Decoded NEC: ");
}
else if (results->decode_type == SONY) {
Serial.print("Decoded SONY: ");
}
else if (results->decode_type == RC5) {
Serial.print("Decoded RC5: ");
}
else if (results->decode_type == RC6) {
Serial.print("Decoded RC6: ");
}
else if (results->decode_type == JVC) {
Serial.print("Decoded JVC: ");
}
else if (results->decode_type == PANASONIC) {
Serial.print("Decoded Panasonic: ");
}
Serial.print(results->value, HEX);
Serial.print("(");
Serial.print(results->bits, DEC);
Serial.println(" bits)");
Serial.print("#define Something_DEC ");
Serial.println(results->value, DEC);
Serial.print("#define Something_HEX ");
Serial.println(results->value, HEX);
Serial.print("Raw (");
Serial.print(count, DEC);
Serial.print("): ");
for (int i = 0; i < count; i++) {
if ((i % 2) == 1) {
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
}
else {
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
}
Serial.print(" ");
}
Serial.println("");
}
void loop() {
if (irrecv.decode(&r)) {
dump();
irrecv.resume(); // Receive the next value
if (r.value==16582903){
digitalWrite(13, HIGH);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(8, HIGH);
TIMER=0;
}
if (r.value==16615543){
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
digitalWrite(11, LOW);
digitalWrite(8, HIGH);
TIMER=0;
}
if (r.value==16599223){
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
digitalWrite(8, HIGH);
TIMER=0;
}
}
if (timer(&TIMER, 1500))
digitalWrite(8, LOW);
}
Telecomando
Il led blu rappresenta un led IR.
La resistenza per il led rosso è di 150 Ω.
La resistenza per il led IR è do 100 Ω.
Le resistenze per i pulsanti sono di 1K Ω.
Il led IR deve necessariamente essere collegato al pin 3.
La sequenza raw dei tasti del telecomando deve essere catturata con lo sketch precedente.
La sequenza catturata deve essere elaborata nel seguente modo:
ignorare il primo numero
eliminare il segno meno dai numeri negativi
separare i numeri con la virgola
utilizzare la sequenza per inizializzare l'array nello sketch seguente. La dimensione dell'array deve essere pari al numero di caratteri nella sequenza più uno (l'ultimo elemento dell'array sarà automaticamente impostato a zero)
#include <IRremote.h>
IRsend irsend;
unsigned int seq1[22]={900,900,1800,850,900,850,900,850,900,850,900,1750,1800,850,900,1700,900,900,1750,900,900};
unsigned int seq2[68]={4600,4350,700,1550,650,1550,650,1600,650,450,650,450,650,450,650,450,700,400,700,1550,650,1550,650,1600,650,450,650,450,650,450,700,450,650,450,650,450,650,1550,700,450,650,450,650,450,650,450,650,450,700,400,650,1600,650,450,650,1550,650,1600,650,1550,650,1550,700,1550,650,1550,650};
unsigned int seq3[68]={4600,4350,700,1550,650,1550,650,1600,650,450,650,450,650,450,650,450,700,400,700,1550,650,1550,650,1600,650,450,650,450,650,450,700,450,650,450,650,450,650,1550,700,450,650,450,650,450,650,450,650,450,700,400,650,1600,650,450,650,1550,650,1600,650,1550,650,1550,700,1550,650,1550,650};
long TIMER0;
long TIMERn;
int ultimo_rilevato1=LOW;
int ultimo_rilevato2=LOW;
int ultimo_rilevato3=LOW;
int stato=0;
int timer(long *t, long millisecondi)
{
long x;
x=millis();
if (!*t){
*t=x;
return 0;
}
else if (x-*t > millisecondi) {
*t=millis();
return 1;
}
else
return 0;
}
void setup()
{
pinMode(13, OUTPUT);
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);
Serial.begin(9600);
}
void loop()
{
//Serial.println("xxx");
if(digitalRead(8)==LOW && digitalRead(9)==LOW && digitalRead(10)==LOW ){
stato=0;
}
if (digitalRead(10)==HIGH && ultimo_rilevato1==LOW){
ultimo_rilevato1=HIGH;
stato=1;
Serial.println("tasto premuto - stato1");
}
if (digitalRead(10)==LOW)
ultimo_rilevato1=LOW;
if (digitalRead(9)==HIGH && ultimo_rilevato2==LOW){
ultimo_rilevato2=HIGH;
stato=2;
Serial.println("tasto premuto - stato2");
}
if (digitalRead(9)==LOW)
ultimo_rilevato2=LOW;
if (digitalRead(8)==HIGH && ultimo_rilevato3==LOW){
ultimo_rilevato3=HIGH;
stato=3;
Serial.println("tasto premuto - stato3");
}
if (digitalRead(8)==LOW)
ultimo_rilevato3=LOW;
if(stato==0) {
digitalWrite(13,LOW);
if (timer(&TIMER0, 5000)){
Serial.println("stato 0");
}
}
if(stato==1) {
if (timer(&TIMERn, 100)){
Serial.println("stato 1");
irsend.sendRaw(seq1,22,38);
digitalWrite(13, HIGH);
}
}
if(stato==2) {
if (timer(&TIMERn, 100)){
Serial.println("stato 2");
irsend.sendRaw(seq2,68,38);
digitalWrite(13, HIGH);
}
}
if(stato==3) {
if (timer(&TIMERn, 100)==1){
Serial.println("stato 3");
irsend.sendRaw(seq3,68,38);
digitalWrite(13, HIGH);
}
}
}
Codici per il telecomando:
// codici di Spegnimento, A/V Mute e Freeze del telecomando LIM. A cura di Gregorio, Fabio, Simone e Mariano
unsigned int seq1[68]={8900,4400,600,1600,600,1650,550,550,600,500,600,500,650,500,550,550,600,1600,600,1600,600,550, 550,1650,550,550,600,1600,600,500,650,1600,550,550,550,1650,600,1600,600,500,600,550,550,1650, 550,550,600,500,650,1600,550,550,600,500,600,1600,600,1600,650,450,600,1650,550,1650,550,550, 600};
unsigned int seq2[68]={8750,4350,550,1650,550,1600,550,550,550,550,550,550,550,550,550,550,550,1650,550,1650,500,600, 500,1650,550,550,550,1650,500,600,500,1650,550,550,550,550,550,1650,550,550,550,550,550,1600, 550,550,550,600,500,1650,550,1650,500,600,500,1650,550,1600,550,600,550,1600,550,1650,550,550, 550};
unsigned int seq3[68]={8900,4450,550,1650,550,1650,550,550,550,550,550,600,550,550,550,550,600,1600,550,1650,600,550, 550,1650,550,550,600,1600,600,550,550,1650,550,550,600,500,600,550,550,550,550,550,550,1650,550, 600,600,500,600,1600,600,1600,600,1600,600,1600,550,1650,600,550,550,1650,550,1650,550,550,550};
Sito: 7ecnologie
Sezione: 17. Robotica e domotica
Capitolo: 01. Elementi di Elettronica
Paragrafo: 03. Progetti
Sottoparagrafo: 08. Gli infrarossi
Indice dei capitoli: 00. Risorse - 01. Elementi di Elettronica - 02. Arduino - 98. Esercizi
Indice dei paragrafi: 01. Ambiente di sviluppo - 02. Elementi di programmazione - 03. Progetti - 04. Tutorial
Indice dei sottoparagrafi: 01. Led lampeggiante - 02. Pulsante di accensione led - 03. Pilotare un transistor - 04. Pilotare un relè - 05. Uso del fotoaccoppiatore - 06. Pilotare un Display a led - 07. Interruttore crepuscolare - 08. Gli infrarossi - 09. Sensore di distanza