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

Prima di inserire un commento, per favore, leggi il regolamento

Permanent link to this article: https://www.mauroalfieri.it/elettronica/tutorial-arduino-ir-con-tsop31238.html

51 pings

Skip to comment form

  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

Your email address will not be published.

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