sabato 3 marzo 2012

Capire il segnale IR dei telecomandi Samsung con Arduino

Necessario:
-arduino
-modulo IR ricevente TSOP183X o simile
-telecomando :-)

Parte Hardware:
il TSOP ha tre pin, quello a sinistra è il DATA, il centrale è il GND mentre quello a destra è il 5+.
Bisogna collegare il pin 5+ al PIN11 dell'Arduino e caricare su di esso il file di esempio "IRrecvDump".

Una volta avviato, si preme il solito tasto Serial Monitor e si preme il tasto UNO del telecomando Samsung. Dovrebbe apparire una stringa simile a questa:
Could not decode message
Raw (68): -20600 4550 -4450 600 -1650 600 -1650 600 -1650 600 -500 650 -500 600 -500 650 -500 600 -500 650 -1600 650 -1600 600 -1650 600 -550 600 -500 600 -550 600 -500 600 -550 600 -500 600 -550 600 -1650 600 -500 600 -550 600 -500 600 -550 600 -500 600 -1650 600 -1650 600 -550 600 -1650 600 -1650 600 -1650 600 -1650 600 -1650 600.

 Seguendo le istruzioni di questa pagina:
http://www.arcfn.com/2010/03/understanding-sony-ir-remote-codes-lirc.html
e della pagina LIRC del telecomando samsung:

begin remote

  name  Samsung_BN59-00940A
  bits           16
  flags SPACE_ENC|CONST_LENGTH
  eps            30
  aeps          100

  header       4605  4344
  one           678  1551
  zero          678   436
  ptrail        679
  pre_data_bits   16
  pre_data       0xE0E0
  gap          107626
  toggle_bit_mask 0x0

      begin codes
          Power                    0x40BF
          TV                       0xD827
          1                        0x20DF
          2                        0xA05F
         
Si capisce che il treno di dati è composto da 16 bit di pre-data e 16 bit di data.
Cosa vuol dire? prendiamo i dati ricavati prima:
Raw (68): -20600 4550 -4450 600 -1650 600 -1650 600 -1650 600 -500 650 -500 600 -500 650 -500 600 -500 650 -1600 650 -1600 600 -1650 600 -550 600 -500 600 -550 600 -500 600 -550 600 -500 600 -550 600 -1650 600 -500 600 -550 600 -500 600 -550 600 -500 600 -1650 600 -1650 600 -550 600 -1650 600 -1650 600 -1650 600 -1650 600 -1650 600.

Secondo il LIRC:
  header       4605  4344
  one           678  1551
  zero          678   436
  ptrail        679

Ciò vuol dire che il bit header per la sincronizzazione sarà di circa 4605ms on e 4344ms off, il bit ONE sarà di 678ms ON e 1551ms OFF, mentre lo ZERO sarà 678ms ON e 436ms OFF. E il ptrail? è un bit finale che sarà di 679msON. 
Quindi, mettendo i suddetti dati in colonna ricaviamo:

4600 -4400 Bit di sincronia
700 -1550    1
650 -1600    1
700 -1550    1
700 -400      0
700 -450      0
700 -400      0
700 -450      0
650 -450      0
700 -1550    1
700 -1550    1
700 -1550    1
700 -450      0
650 -450      0
700 -450      0
650 -450     0
700 -450     0
650 -450     0
700 -450     0
650 -1600    1
650 -450     0
700 -450     0
650 -450     0
700 -450     0
650 -450     0
700 -1550    1
700 -1550    1
700 -400      0
700 -1600    1
650 -1600    1
650 -1600    1
650 -1600    1
650 -1600    1

650  ptrail BIT

Quindi avremo questi dati:
1110000011100000 0010000011011111  
Ovvero in HEX:  0xE0E0 e 0x20DF, ovvero ancora, il suddetto PRE_DATA_BIT e il tasto corrispondente, ovvero il tasto UNO!!!

venerdì 2 marzo 2012

Arduino e prese radiocomandate:

Ecco il necessario:
-piattaforma ARDUINO (nel mio caso arduino uno)
-prese radiocomandate SILVERCREST mod.53117 comprate alla LIDL
-modulo trasmettitore RF 433.92 mhz (http://www.sparkfun.com/products/10534)
-modulo ricevitore RF433.92 mhz (http://www.sparkfun.com/products/10532).

Dunque..collegando ARDUINO al modulo ricevitore, come indicato in figura:
 Il pin DATA del modulo è da collegare al pin 2 di  Arduino.

ovviamente il modulo è diverso, bisogna guardare i pin del proprio modulo.
Ad esempio il modulo che ho usato io (ricavato da una delle prese radiocomandate è questo:

 Dove il pin 1 è il GND, il pin 2 è il DATA e il pin 3 è il Vcc.

Installando sull'arduino questo sketch (previa installazione del modulo RC-Switch):

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

void setup() {

  Serial.begin(9600);
  mySwitch.enableReceive(0, output);

}

void loop() {

}

void output(unsigned long decimal, unsigned int length, unsigned int delay, unsigned int* raw) {

  if (decimal == 0) {
    Serial.print("Unknown encoding.");
  } else {
    Serial.print("Decimal: ");
    Serial.print(decimal);
    Serial.print(" (");
    Serial.print( length );
    Serial.print("Bit) ");
    Serial.print(" PulseLength: ");
    Serial.print(delay);
    Serial.println(" microseconds");
  }
  
  Serial.print("Raw data: ");
  for (int i=0; i<= length*2; i++) {
    Serial.print(raw[i]);
    Serial.print(",");
  }
  Serial.println();
  Serial.println();

}

Si ottengono i dati dal telecomando originale, ad esempio, nel mio caso, se schiaccio il tasto A ON ottengo questi dati:
Unknown encoding.Raw data: 7116,936,596,928,592,932,604,428,1100,424,1100,420,1100,920,604,428,1108,428,1092,432,1092,928,600,432,1096,428,1088,932,600,428,1088,436,1100,932,600,428,1092,932,596,432,1092,928,600,928,596,432,1092,432,1108

Come interpretare questi dati?
Semplice, grazie a questo sito:
http://test.sui.li/oszi/
Incollando qui i dati si ottiene, in forma grafica, l'onda della trasmissione RF.

Da qui ho capito che ogni bit è composto da 4 parti, e che quindi il bit 1 è composto da 3 pulse HIGH e 1 LOW, mentre il bit 0 è composto da 1 pulse HIGH e 3 LOW, di cui ogni PULSE equivale a circa 380 mS, per cui ad esempio il primo bit (936,596) equivale a 3 pulse HIGH e uno LOW, ovvero a UNO.
 Seguendo questo schema ho tradotto la nostra stringa di dati in una serie di 1 e di 0, più precisamente questa:
111011110101011001011100

Ora, montando un trasmettitore RF sull'arduino come questo schema:
http://code.google.com/p/rc-switch/wiki/HowTo_Send
ed installando questo sketch:



void setup() {

  Serial.begin(9600);
  mySwitch.enableTransmit(10);
  mySwitch.setPulseLength(380);
  
}

void loop() {
  Serial.println("Invio segnale per accendere");
  mySwitch.send("111011110101011001011100");
  delay(5000);  

  Serial.println("Invio segnale per spegnere");
  mySwitch.send("111000111001100100101100");
  delay(5000);  
}


 


dovrei ottenere che accendo e spengo la presa radiocomandata ogni 5 secondi.
Invece non funziona.
Ed è qui che mi sono perso per giorni e giorni, fino ad oggi che ho avuto l'illuminazione!
Il
 problema sta nel segnale di sincronizzazione iniziale (7116) che nella 
versione di RCSwitch dice che è fatto da 1 pulse ON e 31 pulse OFF.
Ora,
 visto che all'inizio abbiamo detto che ogni PULSE equivale a 380mS 
circa, il nostro segnale di sincronizzazione doveva essere di circa 
11700 mS, invece è circa 7100, ovvero equivalente a 18 pulse OFF.
Così ho modificato il file della libreria di RCSwich, ovvero RCSwitch.cpp, nella riga dove dice  



void RCSwitch::sendSync() {
  this->transmit(1,31);
}


 


Così facendo funziona tutto!