Receber e Enviar Sinal IR - Arduino

Olá pessoal... Recorri ao forum pois estou com dificuldades para fazer meu projeto, preciso programar minha placa Arduino para ela receber um sinal IR de um controle remoto da TV na tecla ON/OFF e se esse sinal for recebido o arduino devera enviar pelo LED IR um outro sinal que ja decodifiquei de um outro controle remoto...

Esse é o sinal IR do controle da TV: NEC: 202B24D (32 bits)

E esse é o sinal do controle do som que ele é pra enviar: Sony A81 12bits

//------------------------------------------------------------------------------
// Include the IRremote library header
//
#include <IRremote.h>

IRsend irsend;
#define POWER 0x202B24D
#define Vol_Mais 0x202D02F
#define Vol_men 0x202708F

//------------------------------------------------------------------------------
// Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838)
//
int LED = 3;
int recvPin = 11;
IRrecv irrecv(recvPin);

//+=============================================================================
// Configure the Arduino
//
void setup ( )
{
Serial.begin(9600); // Status message will be sent to PC at 9600 baud
irrecv.enableIRIn(); // Start the receiver
}

//+=============================================================================
// Display IR code
//
void ircode (decode_results *results)
{
// Panasonic has an Address
if (results->decode_type == PANASONIC) {
Serial.print(results->address, HEX);
Serial.print(":");
}

// Print Code
Serial.print(results->value, HEX);
}

//+=============================================================================
// Display encoding type
//
void encoding (decode_results *results)
{
switch (results->decode_type) {
default:
case UNKNOWN: Serial.print(“UNKNOWN”); break ;
case NEC: Serial.print(“NEC”); break ;
case SONY: Serial.print(“SONY”); break ;
case RC5: Serial.print(“RC5”); break ;
case RC6: Serial.print(“RC6”); break ;
case DISH: Serial.print(“DISH”); break ;
case SHARP: Serial.print(“SHARP”); break ;
case JVC: Serial.print(“JVC”); break ;
case SANYO: Serial.print(“SANYO”); break ;
case MITSUBISHI: Serial.print(“MITSUBISHI”); break ;
case SAMSUNG: Serial.print(“SAMSUNG”); break ;
case LG: Serial.print(“LG”); break ;
case WHYNTER: Serial.print(“WHYNTER”); break ;
case AIWA_RC_T501: Serial.print(“AIWA_RC_T501”); break ;
case PANASONIC: Serial.print(“PANASONIC”); break ;
case DENON: Serial.print(“Denon”); break ;
}
}

//+=============================================================================
// Dump out the decode_results structure.
//
void dumpInfo (decode_results *results)
{
// Check if the buffer overflowed
if (results->overflow) {
Serial.println(“IR code too long. Edit IRremoteInt.h and increase RAWBUF”);
return;
}

// Show Encoding standard
Serial.print(“Encoding : “);
encoding(results);
Serial.println(””);

// Show Code & length
Serial.print(“Code : “);
ircode(results);
Serial.print(” (”);
Serial.print(results->bits, DEC);
Serial.println(" bits)");
}

//+=============================================================================
// Dump out the decode_results structure.
//
void dumpRaw (decode_results *results)
{
// Print Raw data
Serial.print(“Timing[”);
Serial.print(results->rawlen-1, DEC);
Serial.println("]: ");

for (int i = 1; i < results->rawlen; i++) {
unsigned long x = results->rawbuf * USECPERTICK;

  • if (!(i & 1)) { // even*
  • Serial.print("-");*
  • if (x < 1000) Serial.print(" ") ;*
  • if (x < 100) Serial.print(" ") ;*
  • Serial.print(x, DEC);*
  • } else { // odd*
  • Serial.print(" ");*
  • Serial.print("+");*
  • if (x < 1000) Serial.print(" ") ;*
  • if (x < 100) Serial.print(" ") ;*
  • Serial.print(x, DEC);*
  • if (i < results->rawlen-1) Serial.print(", "); //’,’ not needed for last one*
  • }*
  • if (!(i % 8)) Serial.println("");*
  • }*
  • Serial.println(""); // Newline*
    }
    //+=============================================================================
    // Dump out the decode_results structure.
    //
    void dumpCode (decode_results *results)
    {
  • // Start declaration*
  • Serial.print("unsigned int "); // variable type*
  • Serial.print(“rawData[”); // array name*
  • Serial.print(results->rawlen - 1, DEC); // array size*
  • Serial.print("] = {"); // Start declaration*
  • // Dump data*
  • for (int i = 1; i < results->rawlen; i++) {*
    Serial.print(results->rawbuf * USECPERTICK, DEC);
    * if ( i < results->rawlen-1 ) Serial.print(","); // ‘,’ not needed on last one*
    * if (!(i & 1)) Serial.print(" ");*
    * }*
    * // End declaration*
    * Serial.print("};"); //*
    * // Comment*
    * Serial.print(" // ");*
    * encoding(results);*
    * Serial.print(" ");*
    * ircode(results);*
    * // Newline*
    * Serial.println("");*
    * // Now dump “known” codes*
    * if (results->decode_type != UNKNOWN) {
    _
    // Some protocols have an address*_
    * if (results->decode_type == PANASONIC) {
    _
    Serial.print(“unsigned int addr = 0x”);_
    _
    Serial.print(results->address, HEX);_
    _
    Serial.println(";");_
    _
    }_
    _
    // All protocols have data*_
    * Serial.print(“unsigned int data = 0x”);*
    * Serial.print(results->value, HEX);*
    * Serial.println(";");*
    * }*
    }
    //+=============================================================================
    // The repeating section of the code
    //
    void loop ( )
    {
    * decode_results results; // Somewhere to store the results*
    * if (irrecv.decode(&results)) { // Grab an IR code*
    * dumpInfo(&results); // Output the results*
    * dumpRaw(&results); // Output the results in RAW format*
    * dumpCode(&results); // Output the results as source code*
    * Serial.println(""); // Blank line between entries*
    * irrecv.resume(); // Prepare for the next value*
    * }*
    if (irrecv.decode (&results)) {
    * if (results.value == 0x202B24D)*
    * irsend.sendSony(0xA81, 12);*

}
if (irrecv.decode (&results)) {
* if (results.value == 0x202D02F)*
* irsend.sendSony(0x481, 12);*
* }*
if (irrecv.decode (&results)) {
* if (results.value == 0xC81, 12);*
* }*
* }*

O que é que não está a acontecer?

Não recebes? Não envias?

Tentei diversas vezes alterando o codigo mas nenhum jeito deu certo, ele ate recebe o sinal do controle remoto mas não envia o outro sinal, uma das vezes que alterei o codigo ele ate acendia o led IR mas nenhum aparelho reconhecia o sinal emitido por ele... Não sei mais o que fazer...

Vou lançar um desafio, pra quem me ajudar a fazer esse meu projeto eu pago R$ 50,00...

Bastante simples, na minha perspectiva, o que está a acontecer... estás a chamar a função decode vezes a mais.

 decode_results  results;        // Somewhere to store the results
 unsigned char ret = irrecv.decode(&results); 

 if (ret) {  // Grab an IR code
   dumpInfo(&results);           // Output the results
   dumpRaw(&results);            // Output the results in RAW format
   dumpCode(&results);           // Output the results as source code
   Serial.println("");           // Blank line between entries
 }

   if (results.value == 0x202B24D)
    irsend.sendSony(0xA81, 12);

  if (results.value == 0x202D02F)
   irsend.sendSony(0x481, 12);
 
  if (results.value == 0xC81, 12); //ISTO NÃO FAZ NADA!!!!

  irrecv.resume();              // Prepare for the next value
 }

Experimenta assim.

Sempre que chamas a função decode, o Arduino vai tentar receber um novo comando.

Aparte disto, já garantiste que o teu hardware está a funcionar correctamente?

bubulindo, tudo bem? vi em outros topicos que sempre esta a ajudar os colegas... Fico muito agradecido por tentar me ajudar. Irei testar o codigo que me enviou e respondo ja em seguida...

Aparte disto, já garantiste que o teu hardware está a funcionar correctamente? Sim, pelo serial monitor consigo receber o codigo IR dos controles remoto, mas não consigo enviar o outro codigo, pela camera do celular consigo ver o led IR ligando mas nenhum dos aparelhos reconhece o sinal emitido por ele...

Tentei deste modo logo abaixo… desta forma ele não envia sinal IR, abrindo o seria monitor ele não exibe nada ao pressionar uma tecla do controle remoto…

//------------------------------------------------------------------------------
// Include the IRremote library header
//
#include <IRremote.h>
IRsend irsend;


//------------------------------------------------------------------------------
// Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838)
//
int recvPin = 11;
IRrecv irrecv(recvPin);

//+=============================================================================
// Configure the Arduino
//
void  setup ( )
{
  Serial.begin(9600);   // Status message will be sent to PC at 9600 baud
  irrecv.enableIRIn();  // Start the receiver
}

//+=============================================================================
// Display IR code
//
void  ircode (decode_results *results)
{
  // Panasonic has an Address
  if (results->decode_type == PANASONIC) {
    Serial.print(results->address, HEX);
    Serial.print(":");
  }

  // Print Code
  Serial.print(results->value, HEX);
}

//+=============================================================================
// Display encoding type
//
void  encoding (decode_results *results)
{
  switch (results->decode_type) {
    default:
    case UNKNOWN:      Serial.print("UNKNOWN");       break ;
    case NEC:          Serial.print("NEC");           break ;
    case SONY:         Serial.print("SONY");          break ;
    case RC5:          Serial.print("RC5");           break ;
    case RC6:          Serial.print("RC6");           break ;
    case DISH:         Serial.print("DISH");          break ;
    case SHARP:        Serial.print("SHARP");         break ;
    case JVC:          Serial.print("JVC");           break ;
    case SANYO:        Serial.print("SANYO");         break ;
    case MITSUBISHI:   Serial.print("MITSUBISHI");    break ;
    case SAMSUNG:      Serial.print("SAMSUNG");       break ;
    case LG:           Serial.print("LG");            break ;
    case WHYNTER:      Serial.print("WHYNTER");       break ;
    case AIWA_RC_T501: Serial.print("AIWA_RC_T501");  break ;
    case PANASONIC:    Serial.print("PANASONIC");     break ;
    case DENON:        Serial.print("Denon");         break ;
  }
}

//+=============================================================================
// Dump out the decode_results structure.
//
void  dumpInfo (decode_results *results)
{
  // Check if the buffer overflowed
  if (results->overflow) {
    Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWBUF");
    return;
  }

  // Show Encoding standard
  Serial.print("Encoding  : ");
  encoding(results);
  Serial.println("");

  // Show Code & length
  Serial.print("Code      : ");
  ircode(results);
  Serial.print(" (");
  Serial.print(results->bits, DEC);
  Serial.println(" bits)");
}

//+=============================================================================
// Dump out the decode_results structure.
//
void  dumpRaw (decode_results *results)
{
  // Print Raw data
  Serial.print("Timing[");
  Serial.print(results->rawlen-1, DEC);
  Serial.println("]: ");

  for (int i = 1;  i < results->rawlen;  i++) {
    unsigned long  x = results->rawbuf[i] * USECPERTICK;
    if (!(i & 1)) {  // even
      Serial.print("-");
      if (x < 1000)  Serial.print(" ") ;
      if (x < 100)   Serial.print(" ") ;
      Serial.print(x, DEC);
    } else {  // odd
      Serial.print("     ");
      Serial.print("+");
      if (x < 1000)  Serial.print(" ") ;
      if (x < 100)   Serial.print(" ") ;
      Serial.print(x, DEC);
      if (i < results->rawlen-1) Serial.print(", "); //',' not needed for last one
    }
    if (!(i % 8))  Serial.println("");
  }
  Serial.println("");                    // Newline
}

//+=============================================================================
// Dump out the decode_results structure.
//
void  dumpCode (decode_results *results)
{
  // Start declaration
  Serial.print("unsigned int  ");          // variable type
  Serial.print("rawData[");                // array name
  Serial.print(results->rawlen - 1, DEC);  // array size
  Serial.print("] = {");                   // Start declaration

  // Dump data
  for (int i = 1;  i < results->rawlen;  i++) {
    Serial.print(results->rawbuf[i] * USECPERTICK, DEC);
    if ( i < results->rawlen-1 ) Serial.print(","); // ',' not needed on last one
    if (!(i & 1))  Serial.print(" ");
  }

  // End declaration
  Serial.print("};");  // 

  // Comment
  Serial.print("  // ");
  encoding(results);
  Serial.print(" ");
  ircode(results);

  // Newline
  Serial.println("");

  // Now dump "known" codes
  if (results->decode_type != UNKNOWN) {

    // Some protocols have an address
    if (results->decode_type == PANASONIC) {
      Serial.print("unsigned int  addr = 0x");
      Serial.print(results->address, HEX);
      Serial.println(";");
    }

    // All protocols have data
    Serial.print("unsigned int  data = 0x");
    Serial.print(results->value, HEX);
    Serial.println(";");
  }
}

//+=============================================================================
// The repeating section of the code
//
void  loop ( )
{
decode_results  results;        // Somewhere to store the results
 unsigned char ret = irrecv.decode(&results); 

 if (ret) {  // Grab an IR code
   dumpInfo(&results);           // Output the results
   dumpRaw(&results);            // Output the results in RAW format
   dumpCode(&results);           // Output the results as source code
   Serial.println("");           // Blank line between entries
 }

   if (results.value == 0xE0E040BF)
    irsend.sendNEC(0x202B24D, 32);

  //if (results.value == 0x202D02F)
  // irsend.sendSony(0x481, 12);
 
  //if (results.value == 0xC81, 12); //ISTO NÃO FAZ NADA!!!!

  irrecv.resume();              // Prepare for the next value
 }

O que essa linha faz? unsigned char ret = irrecv.decode(&results);

Consegui fazer funcionar, porem ainda tenho que fazer alguns ajustes no código... Amanhã posto o código completo...

Adrianokistemmacher:
O que essa linha faz? unsigned char ret = irrecv.decode(&results);

essa linha chama a função que recebe o código e guarda o resultado numa variável que é depois testada...

Este é o codigo pra Receber um codigo IR e Emitir outro sinal IR, como se fosse um conversor de sinal IR.

Porem estou com outro problema, o codigo funciona perfeitamente quando a placa está alimentado pela porta USB, mas quando alimento ela pela fonte externa de 9v, 1000ma ele simplesmente não funciona de acordo, ou seja, as vezes ele emite o sinal IR e a TV reconhece o sinal e as vezes não emite, não sei se ele está recebendo o sinal IR mas o problema é que não funciona como deveria… Alguém pode me ajudar em relação a isso?

/*
 * Projeto - Receber IR e enviar outro sinal IR
 * Adriano kistemmacher
 *(45) 9-9928-785 - oadriano.kis@gmail.com
 */

#include <IRremote.h>

IRsend irsend;

int RECV_PIN = 11;
int LedPin = 3;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  pinMode(3, OUTPUT);
  pinMode(11, INPUT);
  Serial.begin(9600);
  // In case the interrupt driver crashes on setup, give a clue
  // to the user what's going on.
  Serial.println("Enabling IRin");
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, DEC); }

    while(irrecv.decode(&results))
          {

          irrecv.resume();

          if (results.value == 3782914127) {
            
              delay(100);
              irsend.sendNEC(0x20218E7, 32);
              Serial.println("Codigo enviado, vol+");                // Escrever na Serial Monitor Codigo enviado, vol+
              delay(100); 
              irrecv.enableIRIn(); }                                 // Esta função > irrecv.enableIRIn() < serve para ativar o receptor novamente

          

          if (results.value == 3782897807) {
             
              delay(100);
              irsend.sendNEC(0x202E817, 32);
              Serial.println("Codigo enviado, vol -");
              delay(100); 
              irrecv.enableIRIn(); }

          
          if (results.value == 3782922287) {
              
              delay(100);
              irsend.sendNEC(0x202D02F, 32);
              Serial.println("Codigo enviado, cima");
              delay(100);
              irrecv.enableIRIn(); }


          if (results.value == 3782881487) {
              
              delay(100);
              irsend.sendNEC(0x202708F, 32);
              Serial.println("Codigo enviado, baixo");
              delay(100);
              irrecv.enableIRIn(); }

          if (results.value == 3782924327) {
            
              delay(100);
              irsend.sendNEC(0x20208F7, 32);
              Serial.println("Codigo enviado, esquerdo");
              delay(100);
              irrecv.enableIRIn(); }

          if (results.value == 3782883527) {
              
              delay(100);
              irsend.sendNEC(0x2028877, 32);
              Serial.println("Codigo enviado, direito");
              delay(100);
              irrecv.enableIRIn(); }

          if (results.value == 3782912087) {
              
              delay(100);
              irsend.sendNEC(0x202B04F, 32);
              Serial.println("Codigo enviado, Enter");
              delay(100);
              irrecv.enableIRIn(); }

          if (results.value == 3782903927) {
              
              delay(100);
              irsend.sendNEC(0x20242BD, 32);
              Serial.println("Codigo enviado, Voltar");
              delay(100);
              irrecv.enableIRIn(); }
              
              delay(100);    
  }}

9V é horrível para quase tudo… Existe uma probabilidade bastante grande que essa pilha não tem capacidade para fornecer a corrente que o LED precisa para funcionar.
Já experimentaste com outro tipo de pilhas?

Outro conselho, não coloques o teu número de telefone e email disponível na internet… há quem consiga fazer muita coisa com essa informação.

bubulindo:
9V é horrível para quase tudo... Existe uma probabilidade bastante grande que essa pilha não tem capacidade para fornecer a corrente que o LED precisa para funcionar.
Já experimentaste com outro tipo de pilhas?

9v 1.0A é pouco para receber e emitir sinal IR? Porque a tensão padrão de uma porta USB 2.0 é de 5V, ou seja, a mesma dos carregadores de celular e a corrente máxima é de 0,5 A. Já uma porta USB 3.0 a corrente será de até 0,9 A.
E pela porta USB ele funciona normalmente... e pela fonte de alimentação não funciona. (no momento não tenho outra fonte de alimentação pra testar pois não não estou na minha cidade)

Outra coisa, isso pode ser um problema no codigo? ou vai ser da alimentação?

Ola,
Se funciona na USB não deve ser problema de código.
Não tem nem um carregador de celular de 5V? Liga como se fosse conectar no arduino no computador.

Qual a origem dessa fonte de 9V?
Existem fontes tão porcarias que não condizem com o que esta escrito na etiqueta.
Se Possuir um multímetro, verifique a tensão dessa fonte quando ligado ao Arduíno.
Não tem multímetro? Não tem problema, pode usar próprio arduino para medir a tensão da fonte. Mas vai precisar de dois resistores para fazer um divisor de tensão. Dois resistores de valores iguais, ou um com duas vezes a resistência do outro, esse de valor maior vai para o positivo da fonte e de menor valor para o GND, o nó entre os dois vai para uma das entradas anaĺógicas. Depois e só usar o analogRead() e um pouco de matemática e a lei do Ohms, para obter a tensão correta.

pksato:
Ola,
Se funciona na USB não deve ser problema de código.
Não tem nem um carregador de celular de 5V? Liga como se fosse conectar no arduino no computador.

Qual a origem dessa fonte de 9V?
Existem fontes tão porcarias que não condizem com o que esta escrito na etiqueta.
Se Possuir um multímetro, verifique a tensão dessa fonte quando ligado ao Arduíno.
Não tem multímetro? Não tem problema, pode usar próprio arduino para medir a tensão da fonte. Mas vai precisar de dois resistores para fazer um divisor de tensão. Dois resistores de valores iguais, ou um com duas vezes a resistência do outro, esse de valor maior vai para o positivo da fonte e de menor valor para o GND, o nó entre os dois vai para uma das entradas anaĺógicas. Depois e só usar o analogRead() e um pouco de matemática e a lei do Ohms, para obter a tensão correta.

Esqueceste-te do pormenor que o Arduino tem um ADC relativamente fraco e as resistências podem dar um desvio do valor calculado bastante superior a qualquer multimetro que há por aí.
Depois tens também o comportamento de bilhas/baterias quando em carga, ou seja, a precisão que necessitas na gama alta de valores não existe porque a precisão do Arduino está espalhada pela gama toda.

Porque não dar logo os valores

pksato:
Ola,
Se funciona na USB não deve ser problema de código.
Não tem nem um carregador de celular de 5V? Liga como se fosse conectar no arduino no computador.

Qual a origem dessa fonte de 9V?

Testei com carregador de celular tbm, testei na porta USB da televisão, ficou na mesma... Tenho multímetro mas não estou em casa, vou poder testar apenas hj a noite... Tenho outra fonte de alimentação tbm, tenho uma de 9v 1.5A... vou testar hj a noite tbm...

Mas depois de testar a posição do controle remoto vi que está funcionando corretamente, porém o controle remoto tem que está mirado na diagonal para o receptor IR, ou seja, ele deve ficar uns 45° da posição do receptor... Se eu mirar o controle para o receptor ele não funciona... Porque isso acontece? É um problema do receptor? Precisa ter algo na frente do receptor pra filtrar ? Alguém sabe dizer alguma coisa sobre?

Ola,

Adrianokistemmacher:
Mas depois de testar a posição do controle remoto vi que está funcionando corretamente, porém o controle remoto tem que está mirado na diagonal para o receptor IR, ou seja, ele deve ficar uns 45° da posição do receptor... Se eu mirar o controle para o receptor ele não funciona... Porque isso acontece? É um problema do receptor? Precisa ter algo na frente do receptor pra filtrar ? Alguém sabe dizer alguma coisa sobre?

O controle remoto e o receptor podem ser incompatível. De duas formas:

  1. O led do controle remoto tem comprimento de onda (cor) diferente do esperado pelo receptor. Tipicamente o led e de 950nm.
  2. A frequência dos pulsos podem ser diferentes, essa frequência pode ser de 30kHz, 36kHz, 38kHz e 56kHz. de 38kHz e o mais comum, por exemplo o TSOP1738.

pksato:
Ola,

O controle remoto e o receptor podem ser incompatível. De duas formas:

  1. O led do controle remoto tem comprimento de onda (cor) diferente do esperado pelo receptor. Tipicamente o led e de 950nm.
  2. A frequência dos pulsos podem ser diferentes, essa frequência pode ser de 30kHz, 36kHz, 38kHz e 56kHz. de 38kHz e o mais comum, por exemplo o TSOP1738.

Amigo, é o seguinte...Esse problema foi resolvido, fiz o mesmo teste com outro controle remoto e funcionou como esperado. Mas resolvi usar esse codigo pra controlar o ar condicionado da Carrier, decodifiquei o codigo do controle original dele e é do tipo NEC de 32bits, 0xC04012C0; porém o ar condicionado não reconhece o sinal, decodifiquei as teclas ON/OFF e temperatura + e -... alguém sabe como fazer pra ele funcionar? Devo enviar o codigo no modo RAW? ou tem alguma outra alternativa?