domenica 4 marzo 2012

Convertire il segnale IR in segnale RF

Finalmente ci sono riuscito!
La mia idea iniziale era di riuscire ad accendere una lampada tramite presa radiocomandata semplicemente con il telecomando della TV, che ricordo essere a raggi infrarossi.

Dunque, il necessario:
-Arduino
-un ricevitore IR  TSOP (il pin DATA va collegato al pin 11 di Arduino)
-un trasmettitore RF433.92mhz (il pin DATA va collegato al pin 10 di Arduino)

Sull'arduino ci si carica su questo codice:

#include <IRremote.h>
#include <RCSwitch.h>

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

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

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, DEC);
    if (results.value==3772784863){
      accendo(); 
      Serial.println("Hai premuto il tasto UNO");
        accendo();
        }
   irrecv.resume(); // Receive the next value
  }
}

void accendo() {
  Serial.println("Invio segnale per accendere");
  mySwitch.enableTransmit(10);
  mySwitch.setPulseLength(300);
  mySwitch.send("111011110101011001011100");
}




Nel mio caso ho dovuto modificare la libreria IRremoteInt.h di ken shirriff per far leggere il codice IR del telecomando del mio samsung. Modificare come segue:
// pulse parameters in usec
#define NEC_HDR_MARK    4600
#define NEC_HDR_SPACE    4400
#define NEC_BIT_MARK    650
#define NEC_ONE_SPACE    1550
#define NEC_ZERO_SPACE    650
#define NEC_RPT_SPACE    2250.

Nel file di esempio ho messo il tasto uno che corrisponde al numero 3772784863.

Se però volessimo utilizzare un altro tasto possiamo prendere questa tabella:
 Power                    0x40BF
          TV                       0xD827
          1                        0x20DF
          2                        0xA05F
          3                        0x609F
          4                        0x10EF
          5                        0x906F
          6                        0x50AF
          7                        0x30CF
          8                        0xB04F
          9                        0x708F
          0                        0x8877
          Fav.Ch                   0x22DD
          Pre-Ch                   0xC837
          Vol+                     0xE01F
          Vol-                     0xD02F
          Mute                     0xF00F
          Source                   0x807F
          Chan+                    0x48B7
          Chan-                    0x08F7
          Info                     0xF807
          Menu                     0x58A7
          Guide                    0xF20D
          Tools                    0xD22D
          Return                   0x1AE5
          Ch.List                  0xD629
          Exit                     0xB44B
          Up                       0x06F9
          Left                     0xA659
          Right                    0x46B9
          Down                     0x8679
          Enter                    0x16E9
          Red                      0x36C9
          Green                    0x28D7
          Yellow                   0xA857
          Blue                     0x6897
          TTX/Mix                  0x34CB
          SRS                      0x7689
          P.Size                   0x7C83
          Dual                     0x00FF
          AD                       0xE41B
          Subt.                    0xA45B
          Rewind                   0xA25D
          Pause                    0x52AD
          Forward                  0x12ED
          Record                   0x926D
          Play                     0xE21D
          Stop                     0x629D

Scegliere il tasto che ci interessa, prendere il numero HEX e aggiungerci davanti E0E0 (che è il PRE_DATA).
Mi spiego meglio: se ci interessasse il tasto GUIDA che corrisponde al numero 0xF20D, dovremmo trasformarlo in 0xE0E0 F20D ovvero in DEC: 37728 38413 e quindi modificare la riga del nostro sketch così:

if (results.value==3772838413){
      accendo(); 
      Serial.println("Hai premuto il tasto UNO");
        accendo();
        }


FATTO!

Lo sketch finale, ovvero all'arrivo del segnale che corrisponde al tasto ROSSO del telecomando tv si accende la presa radiocomandata, mentre il tasto BLU la spegne:
Il tasto giallo dovrebbe accendere la luce del ventilatore, mentre il tasto blu dovrebbe spegnerla..

#include <IRremote.h>
#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();
int RECV_PIN = 11;  //TSOP IR per ricevere i dati IR
IRrecv irrecv(RECV_PIN);
decode_results results;
int IRledPin =  13;    // LED IR emettitore per accendere e spegnere la luce del ventilatore

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

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, DEC);
    switch (results.value)
    {
     
      //rosso
      case 3772790473:                   // tasto rosso del telecomando samsung
          accendolampada();
      break;
     
      case 3772827703:                 //tasto rosso del telecomando sky
          accendolampada();
      break;
     
      //verde
      case 3772786903:
          spengolampada();
      break;
     
      //blu
      case 3772803223:
          accendoventilatore();
      break;
    }
   
   irrecv.resume(); // Receive the next value
  }
}

void accendolampada() {
  Serial.println("Invio segnale per accendere");
  mySwitch.enableTransmit(10);
  mySwitch.setPulseLength(300);
  mySwitch.send("111011110101011001011100");
                
}

void spengolampada() {
  Serial.println("Invio segnale per spegnere");
  mySwitch.enableTransmit(10);
  mySwitch.setPulseLength(300);
  mySwitch.send("111000111001100100101100");
}



void pulseIR(long microsecs) {
  // we'll count down from the number of microseconds we are told to wait

  cli();  // this turns off any background interrupts

  while (microsecs > 0) {
    // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // this takes about 3 microseconds to happen
   delayMicroseconds(10);         // hang out for 10 microseconds
   digitalWrite(IRledPin, LOW);   // this also takes about 3 microseconds
   delayMicroseconds(10);         // hang out for 10 microseconds

   // so 26 microseconds altogether
   microsecs -= 26;
  }

  sei();  // this turns them back on
}


void accendoventilatore() {
 
  Serial.println("Invio segnale per il ventilatore");
  pulseIR(1320);
  delayMicroseconds(310);
  pulseIR(1320);
  delayMicroseconds(320);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(1320);
  delayMicroseconds(320);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(7820);
  pulseIR(1320);
  delayMicroseconds(310);
  pulseIR(1320);
  delayMicroseconds(320);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(1320);
  delayMicroseconds(320);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(7820);
 
  pulseIR(1320);
  delayMicroseconds(310);
  pulseIR(1320);
  delayMicroseconds(320);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(1320);
  delayMicroseconds(320);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(7820);
 
  pulseIR(1320);
  delayMicroseconds(310);
  pulseIR(1320);
  delayMicroseconds(320);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(1320);
  delayMicroseconds(320);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(1160);
  pulseIR(500);
  delayMicroseconds(7820);
   
}

6 commenti:

  1. Ciao, molto interessante, non capisco però come hai fatto a trovare il valore del segnale RF che hai mappato al segnale IR. Io vorrei fare una cosa simile: configurare alcuni tasti del telecomando IR del TV in modo che (convertiti in RF) comandino un sistema audio BOSE. Potresti illuminarmi ? roberto.miola@gmail.com Ti ringrazio molto. Ciao e complimenti!

    RispondiElimina
  2. Nel mio caso avevo fatto una sorta di reverse engeneering (o come si scrive...) ovvero ho aperto il telecomando originale del ventilatore (segnali rf) e ho segnato il numero del chip principale... ho googlato e ho scoperto il datasheet dove era scritto tutto, compreso i codici rf che trovi nel mio listato... il tuo apparecchio Bose è comandato tramite RF o IR?

    RispondiElimina
  3. Ciao, il mio Bose è comandato da un telecomando che invia segnali RF, ho già chiesto alla Bose se mi mandano i codici del datasheet ma temo in una risposta negativa, sono molto criptici a riguardo.
    Secondo te se apro il mio telecomando e provo a fare la stessa cosa che hai fatto tu posso trovare qualcosa in rete ? Chip, datasheet, ecc. ?

    RispondiElimina
  4. Puoi provare! A volte però cancellano i dati sopra i chip proprio per evitare il reverse engeneering.. io sono stato fortunato!

    RispondiElimina
  5. "Conoscendo" BOSE...avranno fatto addirittura un chip proprietario BLINDATO!!!

    In questo caso sarebbe possibile costruire, sempre con Arduino, un progettino che "ascolti" i segnali RF inviati dal telecomando BOSE ? COsì successivamente possono essere utilizzati in accoppiata con i segnali IR...

    RispondiElimina
  6. E' molto probabile ma non impossibile! Per quanto riguarda arduino...dipende sempre a che frequenza lavora il bose...se è 433mhz teoricamente è più facile...

    RispondiElimina