Tutorial Arduino – IR con TSOP31238

Dopo l’articolo di Massimo sul TSOP1738 mi sono così incuriosito all’argomento che ho voluto fare qualche test ed ho tentato di acquistare il medesimo ricevitore IR a 38Hz, mio malgrado non sono riuscito a procurarmene uno ed ho dovuto optare per il TSOP31238 il cui datasheet lo puoi trovare a questo link.

TSOP31238

Come puoi vedere nel datasheet i piedini sono:

  1. GND o negativo
  2. Vs o positivo
  3. OUT o segnale

Lo schema di collegamento è molto semplice, è sufficente collegare una resistenza da 100Ω tra il terminale positivo e l’alimentazione.

Per fare qualche prova puoi collegare il terminale 3 del TSOP31238 ( o segnale) al pin 11 di Arduino ed alimentarlo attraverso i 5v dell’Arduino stesso.

Per i test puoi utilizzare la libreria IRremote.h rilasciata sotto licenza creative.
ATTENZIONE: la libreria IRremote.h è veramente fantastica ma presenta un limite, sono decodificati solo alcuni telecomandi (Sony, NEC, RC5, e RC6 ) se come me hai a disposizione un telecomando della Samsung qualsiasi segnale inviato dal telecomando sarà visto come 0.

Per nostra fortuna “Ken Shirriff’s” ha realilzzato uno sketch di decodifica utilizzando la suddetta libreria che consente di mappare il tuo telecomando.
Il codice è presente sul suo blog, io lo riporto per poterne analizzare il funzionamento, il codice completo è il seguente:

/*
 * IRhashdecode - decode an arbitrary IR code.
 * Instead of decoding using a standard encoding scheme
 * (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.
 *
 * An IR detector/demodulator must be connected to the input
 * RECV_PIN.
 * This uses the IRremote library:
 * http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
 *
 * The algorithm: look at the sequence of MARK signals,
 * and see if each one is shorter (0), the same length (1),
 * or longer (2) than the previous.
 * Do the same with the SPACE signals.
 * Hszh the resulting sequence of 0's,
 * 1's, and 2's to a 32-bit value.
 * This will give a unique value for each
 * different code (probably), for most code systems.
 *
 * You're better off using real decoding than this technique,
 * but this is
 * useful if you don't have a decoding algorithm.
 *
 * Copyright 2010 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  irrecv.enableIRIn(); // Start the receiver
  Serial.begin(9600);
}

// Compare two tick values, returning
// 0 if newval is shorter,
// 1 if newval is equal, and 2 if newval is longer
// Use a tolerance of 20%
int compare(unsigned int oldval, unsigned int newval) {
  if (newval < oldval * .8) {
    return 0;
  }
  else if (oldval < newval * .8) {
    return 2;
  }
  else {
    return 1;
  }
}

// Use FNV hash algorithm:
// http://isthe.com/chongo/tech/comp/fnv/#FNV-param
#define FNV_PRIME_32 16777619
#define FNV_BASIS_32 2166136261

/* Converts the raw code values into a 32-bit hash code.
 * Hopefully this code is unique for each button.
 */
unsigned long decodeHash(decode_results *results) {
  unsigned long hash = FNV_BASIS_32;
  for (int i = 1; i+2 < results->rawlen; i++) {
    int value =  compare(results->rawbuf[i], results->rawbuf[i+2]);
    // Add value into the hash
    hash = (hash * FNV_PRIME_32) ^ value;
  }
  return hash;
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.print("'real' decode: ");
    Serial.print(results.value, HEX);
    Serial.print(", hash decode: ");
    Serial.println(decodeHash(&results), HEX);
    irrecv.resume(); // Resume decoding (necessary!)
  }
}

#define LEDPIN 13
void blink() {
  digitalWrite(LEDPIN, HIGH);
  delay(200);
  digitalWrite(LEDPIN, LOW);
  delay(200);
}  

// Blink the LED the number of times indicated
// by the Philips remote control
// Replace loop() with this for the blinking LED example.
void blink_example_loop() {
  if (irrecv.decode(&results)) {
    unsigned long hash = decodeHash(&results);
    switch (hash) {
    case 0x322ddc47: // 0 (10)
      blink(); // fallthrough
    case 0xdb78c103: // 9
      blink();
    case 0xab57dd3b: // 8
      blink();
    case 0x715cc13f: // 7
      blink();
    case 0xdc685a5f: // 6
      blink();
    case 0x85b33f1b: // 5
      blink();
    case 0x4ff51b3f: // 4
      blink();
    case 0x15f9ff43: // 3
      blink();
    case 0x2e81ea9b: // 2
      blink();
    case 0x260a8662: // 1
      blink();
      break;
    default:
      Serial.print("Unknown ");
      Serial.println(hash, HEX);
    }
    irrecv.resume(); // Resume decoding (necessary!)
  }
}

Le prime righe includono la libreria IRremote.h e imposta il pin 11 di Arduino come il pin su cui arriverà il segnale PWM del ricevitore, inizializza l’oggetto irrecv e imposta la decodifica dei segnali assegnandoli alla variabile result:

#include <IRremote.h>

int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

Le righe seguenti si riferiscono alla funzione setup() che oramai conosci benissimo, se hai seguito gli altri mei tutorial su Arduino, e che in questo pde si occupa diabilitare la ricezione del segnale attraverso l’oggetto irrecv e inizializza la comunicazione seriale a 9600, questa comunicazione ti serve per conoscere i codici decodificati del tuo telecomendo non standard:

void setup()
{
  irrecv.enableIRIn(); // Start the receiver
  Serial.begin(9600);
}

La funzione loop, anche questa nota, ad ogni ciclo Arduino verifica che la variabile result contenga un codice decodificabile con il metodo decode dell’oggetto irrecve in caso di esito positivo scrive nel canale seriale una riga del tipo:

‘real’ decode: [valore in result], hash decode: [valore decodificato]

per ottenere il valore decodificato utilizza la funzione decodeHash che si appoggia alla funzione compare per confrontare due valori successivi del segnale captato con una tolleranza del 20% tra i due, questa comparazione avviene tra due buffer successivi captati dal nostro sensore ed è importante in quanto i segnali emessi da un telecomando non sono mai univoci per ciascuna pressione di un tasto, sono più simili ad un treno di segnali tutti uguali che partono dal telecomando e sono catturati dal TSOP31238

void loop() {
  if (irrecv.decode(&results)) {
    Serial.print("'real' decode: ");
    Serial.print(results.value, HEX);
    Serial.print(", hash decode: ");
    Serial.println(decodeHash(&results), HEX);
    irrecv.resume(); // Resume decoding (necessary!)
  }
}

Grazie a questa funzione è possibile leggere nel monitor seriale dell’IDE la corrispondenza, decodificata in Hesadecimale (HEX), del bottone premuto sul telecomando.

Puoi fare il seguente esercizio:  carica il file .pde su Arduino e punta il telecomando verso il ricevitore e premi in sequenza i bottoni 0,1,2,3,4,5,6,7,8,9 ad ogni pressione vedrai comparire una riga del tipo:

‘real’ decode: unknown, hash decode:B9F56762

che ti indica il mancato riconoscimento del codice inviato e l’hash decode del segnale ricevuto.

Puoi sostituire ciascuno dei segnali decodificati alla pressione di un tasto sul telecomando con quelli presenti nella funzione blink_example_loop() ciascuno nel corrispettivo case e rinominiamo l’attuale funzione loop() in _loop() e la blink_example_loop() in loop(), come riportato di seguito:

void _loop() {
  if (irrecv.decode(&results)) {
    Serial.print("'real' decode: ");
    Serial.print(results.value, HEX);
    Serial.print(", hash decode: ");
    Serial.println(decodeHash(&results), HEX);
    irrecv.resume(); // Resume decoding (necessary!)
  }
}

#define LEDPIN 13
void blink() {
  digitalWrite(LEDPIN, HIGH);
  delay(200);
  digitalWrite(LEDPIN, LOW);
  delay(200);
}  

void loop() {
  if (irrecv.decode(&results)) {
    unsigned long hash = decodeHash(&results);
    switch (hash) {
    case 0xB9F56762: // 0 (10)
      blink(); // fallthrough
    case 0x........: // 9
      blink();
    case 0x........: // 8
      blink();
    case 0x........: // 7
      blink();
    case 0x........: // 6
      blink();
    case 0x........: // 5
      blink();
    case 0x........: // 4
      blink();
    case 0x........: // 3
      blink();
    case 0x........: // 2
      blink();
    case 0x........: // 1
      blink();
      break;
    default:
      Serial.print("Unknown ");
      Serial.println(hash, HEX);
    }
    irrecv.resume(); // Resume decoding (necessary!)
  }

Se ricarichi il programma sulla scheda Arduino e premi un numero sul telecomando da 1 a 9 vedrai lampeggiare il led collegato al pin 13 di un numero pari al numero premuto sul telecomendo + uno (es.: premendo il tasto 3 vedrai lampeggiare il led 4 volte).

Ovviamente se utilizzi un telecomando di quelli conosciuti (es.. Sony, Nec, RC5 o RC6) è tutto più semplice e non è necessario decodificare i segnali del telecomando come hash degli stessi, la libreria IRremote provvede in autonomia a fornire un valore pari al numero del tasto premuto sul telecomando.

Buon divertimento

  • Questo sito ed i suoi contenuti è fornito "così com'è" e Mauro Alfieri non rilascia alcuna dichiarazione o garanzia di alcun tipo, esplicita o implicita, riguardo alla completezza, accuratezza, affidabilità, idoneità o disponibilità del sito o delle informazioni, prodotti, servizi o grafiche correlate contenute sul sito per qualsiasi scopo.
  • Ti chiedo di leggere e rispettare il regolamento del sito prima di utilizzarlo
  • Ti chiedo di leggere i Termini e Condizioni d'uso del sito prima di utilizzarlo
  • In qualità di Affiliato Amazon io ricevo un guadagno dagli acquisti idonei qualora siano presenti link al suddetto sito.

Permalink link a questo articolo: https://www.mauroalfieri.it/elettronica/tutorial-arduino-ir-con-tsop31238.html

49 commenti

2 ping

Vai al modulo dei commenti

    • Massimo il 20 Agosto 2011 alle 20:42
    • Rispondi

    Ciao Mauro, complimenti per il tutorial molto chiaro e completo : )))

    • Matteo il 7 Giugno 2012 alle 18:06
    • Rispondi

    Ciao Mauro,io ti ho già contattato su Facebook e mi hai detto di scriverti il mio problema sul blog.Lo posto qui

    sto progettando di comandare il mio robot tramite un telecomando infrarossi,che invierà il suo segnale al sensore collegato all’arduino,per farlo muovere avanti,indietro etc.
    il modulo infrarossi è questo:
    http://www.robotstore.it/product/278…nfrarossa.html
    però ho un problema con il programma che gestisce tutto ciò che è questo:
    #include
    #include

    char comando, vel;
    int velocita=255,temp;
    int RECV_PIN = 1;

    IRrecv irrecv(RECV_PIN);
    void setup(){
    Serial.begin(9600);
    irrecv.enableIRIn(); // Start the receiver

    }

    void loop(){
    temp= analogRead(RECV_PIN);
    switch(temp){
    case 1: go(); break;
    case 2: stop(); break;
    case 3: back(); break;
    case 4: right(); break;
    case 5: left(); break;
    case 6: delay(500);
    vel=Serial.read();
    if(vel==’1′) velocita=100;
    else if(vel==’2′) velocita=180;
    else if(vel==’3′) velocita=255;
    if(vel) Serial.println(“Velocita’ modificata”);
    break;
    }
    }

    void go(){
    //Motore sinistro
    digitalWrite(7,HIGH);
    analogWrite(6,velocita);
    //Motore destro
    digitalWrite(4,HIGH);
    analogWrite(5,velocita);
    }
    void stop(){
    //Motore sinistro
    digitalWrite(7,LOW);
    analogWrite(6,0);
    //Motore destro
    digitalWrite(4,HIGH);
    analogWrite(5,0);
    }
    void back(){
    //Motore sinistro
    digitalWrite(7,HIGH);
    analogWrite(6,velocita);
    //Motore destro
    digitalWrite(4,LOW);
    analogWrite(5,velocita);
    }
    void right(){
    //Motore sinistro
    digitalWrite(7,LOW);
    analogWrite(6,velocita);
    //Motore destro
    digitalWrite(4,LOW);
    analogWrite(5,velocita);
    }
    void left(){
    //Motore sinistro
    digitalWrite(7,HIGH);
    analogWrite(6,velocita);
    }

    di sicuro il programma ha qualcosa di sbagliato o mancante,ma non riesco nemmeno a compilarlo perchè mi da degli errori che se non ho capito male riguardano le librerie IRremote del sensore.
    In fase di compilazione gli errori sono questi:

    In file included from provainfra.cpp:2:
    C:\hteo\arduino-1.0.1\libraries\IRremote/IRremoteInt.h:87: error: ‘uint8_t’ does not name a type
    C:\hteo\arduino-1.0.1\libraries\IRremote/IRremoteInt.h:88: error: ‘uint8_t’ does not name a type
    C:\hteo\arduino-1.0.1\libraries\IRremote/IRremoteInt.h:89: error: ‘uint8_t’ does not name a type
    C:\hteo\arduino-1.0.1\libraries\IRremote/IRremoteInt.h:92: error: ‘uint8_t’ does not name a type

    Sapete dirmi cosa vogliono dire?Ovviamente la libreria IRRemote l’ho già inserita nella cartella libraries dell’IDE arduino
    Grazie

    1. Probabilmente facendo copia e incolla nel commento le prime due righe hanno perso le due classi che includi, puoi dirmi cosa stai includendo?

      Mauro

    • Matteo il 8 Giugno 2012 alle 09:16
    • Rispondi

    Includo le librerie IRRemote.h e IRRemoteInt.h

    1. Ho meso il tuo sketch nel compilatore e corretto i nomi delle librerie che includi:

      IRremote.h invece di IRRemote.h
      IRremoteInt.h invece di IRRemoteInt.h

      a parte qualche errore con le ” e gli ‘ che penso siano divuti al copia e incolla dal browser compila senza problemi.

      Fammi sapere se correggendo questa cosa compila 🙂

      Mauro

    • Matteo il 8 Giugno 2012 alle 16:51
    • Rispondi

    Non cambia nulla.Comunque avevo già messo i nomi delle librerie giuste,sono io che quando me lo hai chiesto ho scritto sbagliato.Compilando mi da quegli errori.Possibile sia colpa dell’IDE Arduino?

    1. Che versione dell’IDE utilizzi?

    • Matteo il 8 Giugno 2012 alle 19:43
    • Rispondi

    1.0.1 ma anche con la 1.0 è uguale.

    1. Ho cercato su Google l’errore che ti si verifica trovando come primi link un tuo post su Robot-Italy e come secondo questo:
      http://arduino.cc/forum/index.php?action=printpage;topic=96719.0

      In cui c’è la soluzione al problema.
      La modifica di cui parla io l’avevo già fatta e suggerita in un commento ad un altro utente per questo a me compila senza difficoltà.

      Mauro

    • Matteo il 9 Giugno 2012 alle 18:53
    • Rispondi

    Ok adesso compila e il mio robottino è comandato via infrarossi,il problema è che i tasti non corrispondono ai movimenti che voglio fargli impartire.come faccio a vedere ogni singolo tasto del mio telecomando a che codice corrisponde per modificare i case dello switch?

    1. Nell’articolo:
      https://www.mauroalfieri.it/elettronica/tutorial-arduino-ir-con-tsop31238.html
      c’è una funzione loop che serve proprio a mostrarti i codici del tuo telecomando sul monitor seriale.
      L’ho aggiunta perchè i pulsanti e i codici dei vari telecomandi possono non combaciare.

      Mauro

    • Matteo il 11 Giugno 2012 alle 18:15
    • Rispondi

    Ho ancora problemi.Ho integrato la codifica con il mio programma,però nel serial monitor non mi compare nulla e soprattutto non succede nulla,credo perchè non riconosco i case:

    #include
    #include

    #define FNV_PRIME_32 16777619
    #define FNV_BASIS_32 2166136261

    char comando, vel;
    int velocita=255,temp;
    int RECV_PIN = 1;
    decode_results results;
    IRrecv irrecv(RECV_PIN);

    void setup(){
    Serial.begin(9600);
    irrecv.enableIRIn(); // Start the receiver

    }
    int compare(unsigned int oldval, unsigned int newval) {
    if (newval < oldval * .8) {
    return 0;
    }
    else if (oldval < newval * .8) {
    return 2;
    }
    else {
    return 1;
    }
    }
    unsigned long decodeHash(decode_results *results) {
    unsigned long hash = FNV_BASIS_32;
    for (int i = 1; i+2 rawlen; i++) {
    int value = compare(results->rawbuf[i], results->rawbuf[i+2]);
    // Add value into the hash
    hash = (hash * FNV_PRIME_32) ^ value;
    }
    return hash;
    }
    void loop() {
    if (irrecv.decode(&results)) {
    Serial.print(“‘real’ decode: “);
    Serial.print(results.value, HEX);
    Serial.print(“, hash decode: “);
    Serial.println(decodeHash(&results), HEX);
    irrecv.resume(); // Resume decoding (necessary!)
    }
    }
    void sens(){
    //temp= analogRead(RECV_PIN);
    if (irrecv.decode(&results)) {
    unsigned long hash = decodeHash(&results);
    switch(hash){
    case 0x260a8662: go(); break;
    case 0x2e81ea9b: stop(); break;
    case 0x15f9ff43: back(); break;
    case 0x4ff51b3f: right(); break;
    case 0x85b33f1b: left(); break;
    case 0xdc685a5f: delay(500);
    vel=Serial.read();
    if(vel==’1′) velocita=100;
    else if(vel==’2′) velocita=180;
    else if(vel==’3′) velocita=255;
    if(vel) Serial.println(“Velocita’ modificata”);
    break;
    default:
    Serial.print(“Unknown “);
    Serial.println(hash, HEX);
    }
    irrecv.resume(); // Resume decoding (necessary!)
    }
    }
    void go(){
    //Motore sinistro
    digitalWrite(7,HIGH);
    analogWrite(6,velocita);
    //Motore destro
    digitalWrite(4,HIGH);
    analogWrite(5,velocita);
    }
    void stop(){
    //Motore sinistro
    digitalWrite(7,LOW);
    analogWrite(6,0);
    //Motore destro
    digitalWrite(4,HIGH);
    analogWrite(5,0);
    }
    void back(){
    //Motore sinistro
    digitalWrite(7,HIGH);
    analogWrite(6,velocita);
    //Motore destro
    digitalWrite(4,LOW);
    analogWrite(5,velocita);
    }
    void right(){
    //Motore sinistro
    digitalWrite(7,LOW);
    analogWrite(6,velocita);
    //Motore destro
    digitalWrite(4,LOW);
    analogWrite(5,velocita);
    }
    void left(){
    //Motore sinistro
    digitalWrite(7,HIGH);
    analogWrite(6,velocita);
    }

      • Matteo il 11 Giugno 2012 alle 18:16
      • Rispondi

      le include sono le solite 🙂

      1. Avevo immaginato 🙂

    1. Non può dipendere dalla conoscenza dei codici, la loop() è scritta proprio per rilevare tali codici.

      Inserisci una linea tipo Serial.print(“prova seriale”); prima dell’if in modo da verificare che il monitor seriale e la comunicazione funzioni.

      Poi prova a verificare che il sensore funzioni con altri telecomandi.

      Mauro

        • Matteo il 12 Giugno 2012 alle 18:25
        • Rispondi

        Il monitor seriale non risponde…nulla

        1. Ciao Matteo,
          sembra che il tuo ploblema sia di comunicazione seriale:
          prova questo sketch:

          void setup()
          {
          Serial.begin( 9600 );
          }

          void loop()
          {
          Serial.println(“Test”);
          delay( 1000 );
          }

          Dovrebbe scrivere nel monitor seriale la parola Test ogni secondo.

          Mauro

            • Matteo il 14 Giugno 2012 alle 17:46

            Il tuo sketch funziona 🙂

          1. Ciao Matteo,
            sono contento.
            Passo 2: copia tutta l’inizializzazione dallo sketch del tutorial, e scrivi nella loop solo:

            Serial.prinln( irrecv.decode(&results) );
            delay (1000);

            Poi prova a premere il pulsante del telecomando difronte al sensore.
            Da qui in poi:
            se vedi codici ti invito a rileggere i tutorial sull’IR con tanto di spiegazione passo passo per capire dove sia il tuo errore;
            se non vedi nulla il problema potrebbe essere di natura elettrica: sensore non funzionante, telecomando non funzionante, sensore e telecomando non compatibili, ecc..

            Ovviamente io sono sempre quì per dati delle dritte, ti invito solo a provare provare provare senza arrenderti davanti alle difficoltà tutti le incontriamo ma la buona volontà e la tenacia premiano sempre.

            Mauro

            • Matteo il 15 Giugno 2012 alle 18:20

            io ho cambiato il codice così:
            #include
            #include

            #define FNV_PRIME_32 16777619
            #define FNV_BASIS_32 2166136261

            char comando, vel;
            int velocita=255,temp;
            int RECV_PIN = 1;
            decode_results results;
            IRrecv irrecv(RECV_PIN);

            void setup(){
            Serial.begin(9600);
            irrecv.enableIRIn(); // Start the receiver

            }
            int compare(unsigned int oldval, unsigned int newval) {
            if (newval < oldval * .8) {
            return 0;
            }
            else if (oldval < newval * .8) {
            return 2;
            }
            else {
            return 1;
            }
            }
            unsigned long decodeHash(decode_results *results) {
            unsigned long hash = FNV_BASIS_32;
            for (int i = 1; i+2 rawlen; i++) {
            int value = compare(results->rawbuf[i], results->rawbuf[i+2]);
            // Add value into the hash
            hash = (hash * FNV_PRIME_32) ^ value;
            }
            return hash;
            }
            void loop() {
            /*if (irrecv.decode(&results)) {
            Serial.print(“‘real’ decode: “);
            Serial.print(results.value, HEX);
            Serial.print(“, hash decode: “);
            Serial.println(decodeHash(&results), HEX);
            irrecv.resume(); // Resume decoding (necessary!)
            }*/
            Serial.println( irrecv.decode(&results) );
            delay (1000);
            }
            /*void sens(){
            //temp= analogRead(RECV_PIN);
            Serial.print(“prova seriale”);
            if (irrecv.decode(&results)) {
            unsigned long hash = decodeHash(&results);
            switch(hash){
            case 0x260a8662: go(); break;
            case 0x2e81ea9b: stop(); break;
            case 0x15f9ff43: back(); break;
            case 0x4ff51b3f: right(); break;
            case 0x85b33f1b: left(); break;
            case 0xdc685a5f: delay(500);
            vel=Serial.read();
            if(vel==’1′) velocita=100;
            else if(vel==’2′) velocita=180;
            else if(vel==’3′) velocita=255;
            if(vel) Serial.println(“Velocita’ modificata”);
            break;
            default:
            Serial.print(“Unknown “);
            Serial.println(hash, HEX);
            }
            irrecv.resume(); // Resume decoding (necessary!)
            }
            }
            void go(){
            //Motore sinistro
            digitalWrite(7,HIGH);
            analogWrite(6,velocita);
            //Motore destro
            digitalWrite(4,HIGH);
            analogWrite(5,velocita);
            }
            void stop(){
            //Motore sinistro
            digitalWrite(7,LOW);
            analogWrite(6,0);
            //Motore destro
            digitalWrite(4,HIGH);
            analogWrite(5,0);
            }
            void back(){
            //Motore sinistro
            digitalWrite(7,HIGH);
            analogWrite(6,velocita);
            //Motore destro
            digitalWrite(4,LOW);
            analogWrite(5,velocita);
            }
            void right(){
            //Motore sinistro
            digitalWrite(7,LOW);
            analogWrite(6,velocita);
            //Motore destro
            digitalWrite(4,LOW);
            analogWrite(5,velocita);
            }
            void left(){
            //Motore sinistro
            digitalWrite(7,HIGH);
            analogWrite(6,velocita);
            }*/

            mettendo a commento le parti che per adesso non servivano.caricando il programma senza fare nulla nel monitor seriale per i primi due secondi sono usciti 0 e poi tutti 1 ogni secondo.

          2. Ciao Matteo,
            ottima notizia, il valore 0 lo avrai avuto fino a che lo sketch non ha finito la fase di setup,
            appena ha iniziato a rilevare il segnale IR la funzione irrecv.decode(&results) restituisce correttamente 1, se interrompi la pressione del pulsante sul telecomando vedrai nuovamente 0.

            Elimina le due linee Serial.println( .. ) e delay(…) e decommenta le altre linee nella loop().

            Rieseguendo lo script dovresti vedere i valori di decode del tuo telecomando.

            Mauro

            • Matteo il 16 Giugno 2012 alle 17:54

            No aspetta…i due zero e poi tutto 1 li vedo nel monitor seriale ma senza fare nulla.continua a farmi vedere 1 ogni secondo senza che faccia nulla col telecomando e se schiaccio qualche tasto non succede nulla.e poi se cancello la println e il delay sono al punto di partenza 🙁

          3. Scusa non avevo compreso, il problema potrebbe essere il sensore o come lo hai collegato, prova a consultare il datasheet del sensore per capire se hai collegato i pin in modo errato se così non è prova un’altro sensore.

            Mauro

    • drummo il 4 Settembre 2012 alle 17:41
    • Rispondi

    Ciao e Complimenti per le ottime guide !!
    proprio ieri ho ricevuto a casa arduino è ho scelto di seguire i tuoi tutorial, facendo il semplice copia ed incolla del codice da te postato il compilatore mi restituisce:…

    IRremote:25: error: ‘decode_results’ was not declared in this scope
    IRremote:25: error: ‘results’ was not declared in this scope
    IRremote:30: error: ‘IRrecv’ does not name a type
    IRremote:31: error: ‘decode_results’ does not name a type
    IRremote.cpp: In function ‘void setup()’:
    IRremote:35: error: ‘irrecv’ was not declared in this scope
    IRremote.cpp: At global scope:
    IRremote:63: error: redefinition of ‘long unsigned int decodeHash’
    IRremote:25: error: ‘long unsigned int decodeHash’ previously defined here
    IRremote:63: error: ‘decode_results’ was not declared in this scope
    IRremote:63: error: ‘results’ was not declared in this scope

    come risolvo ???
    ciao e grazie

    1. Ciao Drummo,
      ad occhio sembra che manchino un po di righe di codice, controlla quello che hai incollato e di avere tutte le librerie necessarie.
      Se sei all’inizio ti consiglio di iniziare con tutorial semplici che trovi nella pagina https://www.mauroalfieri.it/corso-arduino.

      Mauro

    • Carmelo il 14 Novembre 2012 alle 17:57
    • Rispondi

    ciao Mauro,
    anche io ho lo stesso problema di Drummo. Come è possibile risolverlo?
    Ho controllato e non manca nessuna riga di codice

    1. Ciao Carmelo,
      suggerisco la stessa cosa detta a Drummo, devi avere la libreria IRremote installata, nell’articolo c’è scritto dove prenderla.
      Considera anche questo sketch è stato scritto per l’IDE 0022 al tempo l’unico disponibile, potrebbe essere necessario modificare la libreria o lo sketch per adattarlo all’IDE che stai utilizzando.

      Mauro

    • Carmelo il 15 Novembre 2012 alle 11:03
    • Rispondi

    Grazie per la risposta Mauro, con la libreria è tutto ok. Non riesco a capire dove sia il problema.
    L’IDE da me utilizzato è l’IDE 1.0.1

    1. Ciao Carmelo,
      come ti dicevo l’IDE per cui è stata scritta la libreria è lo 0022, se lo provi con questa versione dell’IDE vedrai che non da quegli errori.
      Ho verificato sul sito dell’autore: http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html e trovi delle indicazioni per lIDE 1.0 non so se ne pubblicherà per l’IDE 1.0.1 ma puoi sempre scriverle tu e condividerle sul sito ufficiale o sul blog.

      Mauro

    • Carmelo il 15 Novembre 2012 alle 13:14
    • Rispondi

    Sono riuscito a risolvere, non viene generato più il messaggio di errore. Ho scaricato un’altra libreria IR remote dal sito di Ken Shirriff (per chi avesse lo stesso problema, la trova sotto il nome di Arduino IRremote master, basta poi seguire le istruzioni che si trovano sul sito), ho sostituito la vecchia ed ora è tutto ok.
    Dimenticavo, complimenti per il sito Mauro, mi è stato e mi sarà di grande aiuto, sono ancora all’inizio con Arduino, seguendo le tue istruzioni sto imparando in modo più rapido di quanto mi aspettassi.

    1. Ciao Carmelo,
      sono contento che tu abbia risolto il problema e che abbia condiviso con tutti noi la soluzione.
      Se vorrai pubblicare i tuoi progetti il mio blog è a disposizione di tutti i makers.

      Mauro

    • francesco il 2 Febbraio 2013 alle 18:13
    • Rispondi

    Ciao Mauro.
    Ho un TSOP1738.
    Mi spieghi in dettaglio come si fa a installare IRremote.h nella cartella “Libraries” di Arduino ?
    Ho provato a scaricarla dal sito ” github.com/shirriff/Arduino-IRremote”, ma non ci sono riuscito.
    Puoi aiutarmi ? Grazie. Francesco

    1. Ciao Francesco,
      se quello che hai scaricato è un file .zip devi decomprimerlo, ti crea una directory tipo: Arduino-IRremote.
      Rinomina la directory in IRremote.
      Copiala sotto la directory Arduino/libraries, la dovresti trovare dove hai installato L’IDE di Arduino.

      Avvia l’IDE Arduino e troverai la libreria installata.

      Mauro

    • Rosario il 4 Marzo 2013 alle 12:25
    • Rispondi

    Ciao Mauro… Ho un problema con questo esperimento.. Premetto che uso un ricevitore infrarossi a 30 Hz, ma non penso che sia rilevante. Il mio led fa una luce molto fioca, quasi invisibile. Perchè? Non riesco a spiegarmelo..!

    1. Ciao Rosario,
      per il led fioco prova ad aggiungere nella setup() le linee:

      pinMode( LEDPIN,OUTPUT );
      digitalWrite( LEDPIN,LOW );

      per il ricevitore sono certo che la libreria funziona con questo tipo di ricevitore perchè è stata scritta appositamente, non sono sicuro che possa funzionare anche per ricevitori di tipo differente, dovresti provare a leggere la documentazione dell’autore, di solito nei commenti della libreria stessa.

      Mauro

    • Rosario il 5 Marzo 2013 alle 21:32
    • Rispondi

    Ah giusto… Grazie! Altra domanda… Quando spengo e riaccendo arduino mi succede che il led non funziona. Dopo vari tentativi sono riuscito a capire che il ricevitore il vero problema; infatti si attiva solo se sottoposto a una “brusca” variazione di corrente, per cui ho inserito un condensatore in parallelo con il ricevitore.. Perchè è necessaria una cosa del genere? Tra l’altro nel datasheet del mio ricevitore IR (TSOP31230) non ho letto nulla a riguardo…

    1. Ciao Rosario,
      non so spiegarlo, probabilmente é necessaria per una sorta di inizializzazione, alcuni sensori ne necessitano, e solitamente si fa mandando HIGH e LOW il pin a cui sono connessi.

      Ignoro se sia il tuo caso, nel datasheet forse non trovi il condensatore ma ti spiegano che c’è da inizializzare il sensore.

      Mauro

    • Adrian il 12 Marzo 2013 alle 19:05
    • Rispondi

    Ciao Mauro,
    grazie per le tue fantastiche guide, sono davvero utilissime. Io ho un problema con la libreria IRremote: non capisco perche questo funziona:
    #include
    int RECV_PIN = 12;

    IRrecv irrecv(RECV_PIN);

    decode_results results;
    void setup()
    {
    Serial.begin(9600);
    irrecv.enableIRIn(); // Start the receiver
    pinMode(10,OUTPUT);}
    void loop() {
    if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    switch (results.value){
    case 0x1:
    case 0x10001:
    analogWrite(10,250);
    break;
    }
    irrecv.resume(); // Receive the next value
    }}

    e questo no:

    #include
    int RECV_PIN = 12;

    IRrecv irrecv(RECV_PIN);

    decode_results results;
    void setup()
    {
    Serial.begin(9600);
    irrecv.enableIRIn(); // Start the receiver
    pinMode(3,OUTPUT);}
    void loop() {
    if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    switch (results.value){
    case 0x1:
    case 0x10001:
    analogWrite(3,250);
    break;
    }
    irrecv.resume(); // Receive the next value
    }}
    il pin 3 non funziona (credo che sia perche la libreria sia stata impostata così) , ma io ho bisogno di tutte le uscite pwm. Conosci un metodo per risolvere questo problema ? GRAZIE

    1. Ciao Adrian,
      se il doble a é la libreria non ti resta che modificarla in modo che sia tu ad indicar gli quale pin utilizzare.

      Mauro

        • Adrian il 21 Marzo 2013 alle 19:38
        • Rispondi

        Ciao Mauro,
        grazie per la tua risposta….ho risolto il problema cambiando un po la progettazione è facendo a meno di quei pin….ma cercando in giro ho visto che esiste una libreria e un metodo per avere tutte le uscite in PWM….tu nei sai qualcosa ??

        1. Ciao Adrian,
          ne avevo sentito parlare anche io, non l’ho trovata.
          Si tratta di una simulazione software come la SoftwareSerial.h per avere tutte le porte seriali che desideri.

          Non é PWM nativo eseguito dal micro controllore per cui rischia di essere lento o instabile, bisognerebbe averla per provare.

          Se hai bisogno di più PWM ti consiglio l’arduino MEGA o DUE.

          Mauro

  1. Ciao e complimenti per il sito.
    Ho provato a giocare con questa libreria al fine di interagire con il mio condizionatore mitsubishi.
    ho utilizzato per la ricezione del segnale IR del mio telecomando un TSOP2238.
    ovviamente la codifica è sconosciuta e ciò che mi acquisisce se premo on è:

    Received unknown code, saving as raw
    m3350 s1750 m400 s1300 m350 s1350 m400 s450 m400 s500 m350 s500 m350 s1350 m400 s450 m400 s450 m400 s1350 m350 s1350 m350 s500 m350 s1350 m350 s500 m350 s500 m400 s1300 m400 s1300 m400 s500 m350 s1350 m350 s1350 m400 s450 m400 s450 m400 s1350 m350 s500 m350 s500 m350 s1350 m400 s450 m350 s550 m350 s500 m350 s500 m350 s500 m400 s450 m400 s450 m400 s500 m350 s500 m350 s500 m350 s500 m400 s450 m400 s500 m350 s500 m350 s500 m350 s500 m400 s500 m350 s500 m350 s500 m350 s500 m350 s500 m400 s450 m400 s500 m350

    a volte invece, sempre premendo ON:
    64800004
    FFFFFFFF

    e premendo OFF:
    64800000
    FFFFFFFF

    Bene a me poco interessa decifrare i codici in quanto ciò che mi interessa è reinviare semplicemente tale codice(non so come) per farlo accendere senza ulteriori comandi di setting(ventola temperatura etc..)
    Come posso fare??

    Grazie mille in anticipo.

    Francesco

    1. Ciao Francesco,
      ti consiglio di leggere l’articolo dedicato all’uso di arduino come telecomando.

      Mauro

    • Giuseppe il 28 Ottobre 2013 alle 22:18
    • Rispondi

    Scusa ma non dovrebbe comparire una schermata con tutti i codici dovuti alla pressione del tasto sul telecomando. Nella libreria IRremote che ho scaricato da internet ci dovrebbe essere questa programma maa è un file CCP e non riesco ad aprirlo. (non so se sono stato molto chiaro)
    spero che tu mi possa rispondere al più presto, grazie

    1. Ciao Giuseppe,
      non ho capito il tuo problema.
      Se vuoi aprire il file .cpp usa un normale editor di testo ( notepad,vi,…)

      Mauro

        • Giuseppe il 29 Ottobre 2013 alle 15:08
        • Rispondi

        Mi appaiono tantissime scritte di cui non capisco il significato, come potrei mandarti un screenshoot
        Comunnque quello che intendevo è che il programma che serve decodificare me lo da come un .cpp e non lo riesco ad aprire

        Giuseppe

        1. Ciao Giuseppe,
          Le scritte che ti compaiono sono quelle arancioni dell’IDE?
          Se si guarda le prime in alto leggerai l’errore che si verifica.

          Considera che la libreria IRemote é stata scritta per la versione 0022 dell’IDE e tu forse usi una versione più aggiornata in cui la libreria potrebbe non funzionare.

          I file .cpp li apri con un editor di testo, come ti ho scritto nella risposta precedente.

          Mauro

    • Matteo il 7 Giugno 2014 alle 13:03
    • Rispondi

    CIao! Volevo chiederti un’info che credo sia piuttosto semplice a cui però non ho trovato spiegazione online.
    Qual’è la differenza tra questo IR: TSOP31238 e questo: tsop1737 ad esempio? ho capito che le ultime due cifre indicano la frequenza di ricezione, ma le altre in mezzo? E un ultima cosa.. per poi inviare un segnale tramite LED ir devo prendere un LED con frequenza di emissione pari a quella che mi interessa o va bene uno qualunque? grazie 🙂

    1. Ciao Matteo,
      la differenza principale è data dalle cifre finali che individuano la frequenza di ricezione del segnale, come hai intuito.
      Le altre caratteristiche puoi verificarle sui datasheet dei costruttori del componente, ogni costruttore rilascia il dettaglio delle caratteristiche.

      In merito al led: si, devi utilizzare un led che emetta sulla medesima frequenza del ricevitore.

  1. […] Ho approfittato dell’occasione per aggiungere il controllo del telecomando ad infrarossi forte degli articoli Tutorial Arduino – IR con TSOP1738 e Tutorial Arduino – IR con TSOP31238 […]

  2. […] Mauro Alfieri Tweet In questi giorni ho ripreso un vecchio post del blog: Tutorial Arduino – IR con TSOP31238 e mi sono chiesto se fosse possibile da un altro Arduino inviare dei segnali IR al primo, magari […]

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.