0

Note I am able to send and recieve IR signals. This question is only for purposes of learning.

When using the existing library #include <IRremote.h> it is very simple to read and transmit infrared signals. However I will like to send the signals myself with digitalWrite(pin, HIGH);

1) Receive an infrared signal from a remote control in order to clone it and send it later with Arduino.

For this to work I have purchased an infrared LED.

I connect the left leg of the IR LED to pin 11, the middle leg to the ground and the right leg to 5 volts.

Then I upload the following sketch to arduino:

#include <IRremote.h>

int receiverpin = 11; // left leg of IR receiver is connected to this pin

IRrecv irrecv(receiverpin);
decode_results results;


void setup() {
  pinMode(receiverpin, INPUT);
  Serial.begin(9600);
  irrecv.enableIRIn();
}

void loop() {
  if (irrecv.decode(&results))
  {
    Serial.println(results.value, HEX);
    irrecv.resume();
    delay(150);
  }
}

When I run that and press the power button of my samsung remote control this is what I capture through serial:

Encoding  : SAMSUNG
Code      : E0E040BF (32 bits)
Timing[67]: 
 +4500, -4500     + 550, -1650     + 550, -1700     + 550, -1700
 + 550, - 600     + 500, - 550     + 550, - 550     + 550, - 600
 + 550, - 550     + 550, -1700     + 550, -1650     + 550, -1700
 + 550, - 550     + 550, - 550     + 550, - 600     + 550, - 550
 + 550, - 550     + 550, - 600     + 550, -1650     + 550, - 600
 + 550, - 550     + 550, - 550     + 550, - 550     + 550, - 600
 + 550, - 550     + 550, -1700     + 550, - 550     + 550, -1700
 + 500, -1700     + 550, -1700     + 550, -1650     + 550, -1750
 + 500, -1650     + 550
unsigned int  rawData[67] = {4500,4500, 550,1650, 550,1700, 550,1700, 550,600, 500,550, 550,550, 550,600, 550,550, 550,1700, 550,1650, 550,1700, 550,550, 550,550, 550,600, 550,550, 550,550, 550,600, 550,1650, 550,600, 550,550, 550,550, 550,550, 550,600, 550,550, 550,1700, 550,550, 550,1700, 500,1700, 550,1700, 550,1650, 550,1750, 500,1650, 550};  // SAMSUNG E0E040BF
unsigned int  data = 0xE0E040BF;

What is this supposed to mean. How can I conver this to 0s and 1s?

2) Sending cloned signal from arduino.

Now if I want to power on my TV with arduino I will need a Infrared LED. I will connect pin 3 to the long leg of my LED and ground to the short leg. Once I pefrom that connection I will run this sketch:

#include <IRremote.h>

IRsend irsend;

void setup() {}

void loop() {

  irsend.sendSAMSUNG(0xE0E040BF, 32); //Power Code
  delay(1000); // try again in 1 second

}

Note this code works and my TV powers on with my Arduino!

3) Now my question

It was very simple to read and transmit infrared signals using IRremote.h header.The only thing I had to do was capture 0xE0E040BF that I got when reading the infrared signal and use that hex code on part 2. From reading on the internet I have researched that sending an IR signal is just turning and IR LED on and off very fast (38khz). How can I tranlate what I read:

 rawData[67] = {4500,4500, 550,1650, 550,1700, 550,1700, 550,600, 500,550, 550,550, 550,600, 550,550, 550,1700, 550,1650, 550,1700, 550,550, 550,550, 550,600, 550,550, 550,550, 550,600, 550,1650, 550,600, 550,550, 550,550, 550,550, 550,600, 550,550, 550,1700, 550,550, 550,1700, 500,1700, 550,1700, 550,1650, 550,1750, 500,1650, 550}; 

To 0s and 1s and then send that hard coded for puposes of learning.

Acording to this link: http://www.remotecentral.com/cgi-bin/codes/samsung/tv_functions/

The infrared code to power on a samsung tv is:

0000 006d 0022 0003 00a9 00a8 0015 003f 0015 003f 0015 003f 0015 0015 0015 
0015 0015 0015 0015 0015 0015 0015 0015 003f 0015 003f 0015 003f 0015 0015 
0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 003f 0015 0015 0015 
0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0040 0015 0015 0015 003f 
0015 003f 0015 003f 0015 003f 0015 003f 0015 003f 0015 0702 00a9 00a8 0015 
0015 0015 0e6e

I have converted that to binary and it comes to be:

000000000000000000000000011011010000000000100010000000000000001100000000101010010000000010101000000000000001010100000000001111110000000000010101000000000011111100000000000101010000000000111111000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000111111000000000001010100000000001111110000000000010101000000000011111100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000111111000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000010000000000000000010101000000000001010100000000000101010000000000111111000000000001010100000000001111110000000000010101000000000011111100000000000101010000000000111111000000000001010100000000001111110000000000010101000000000011111100000000000101010000011100000010000000001010100100000000101010000000000000010101000000000001010100000000000101010000111001101110

Now every time I see a 0 I will power off the LED and every time I see a 1 I will power on the LED waiting about 10 microseconds in order to have a frequency of 38khz This is how my sketch looks like:

int pinSend=3;
char data[1248] = "000000000000000000000000011011010000000000100010000000000000001100000000101010010000000010101000000000000001010100000000001111110000000000010101000000000011111100000000000101010000000000111111000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000111111000000000001010100000000001111110000000000010101000000000011111100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000111111000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000000101010000000000010101000000000001010100000000010000000000000000010101000000000001010100000000000101010000000000111111000000000001010100000000001111110000000000010101000000000011111100000000000101010000000000111111000000000001010100000000001111110000000000010101000000000011111100000000000101010000011100000010000000001010100100000000101010000000000000010101000000000001010100000000000101010000111001101110"; 
int waitTimeInMicroseconds = 5; // counter to try with different wait times in order to see what frequency works best

void setup() {
  Serial.begin(9600);
  pinMode(pinSend,OUTPUT);
}

void loop() {

  Serial.print("Starting sending IR signal waiting ");
  Serial.print(waitTimeInMicroseconds);
  Serial.println(" microseconds");


  int len = sizeof(data);

  for(int i=0; i<len; i++)
  {
    if( data[i] == '0') // if 0 turn off LED
    {
      digitalWrite(pinSend,LOW);
    }
    else // else turn ON LED
    {
      digitalWrite(pinSend,HIGH);
    }

    delayMicroseconds(waitTimeInMicroseconds); // wait in microseconds
  }

  Serial.println("Done! Is TV on??????");
  delay(1000); // wait 1 second for next atempt

  waitTimeInMicroseconds++; // next time try with different wait time

}

When I run that code the TV does not turn on why? How can I hard code the 0s and 1s for purposes of learning?

  • Honestly, I almost always go to the web to find the exact codes for the different remote controls and devices I have. Getting an approximate code is fine. But if it is at the edge of being correct - who knows - maybe that will create times when the Ardunio appears not to work as well as the original remote control. – st2000 Nov 15 '18 at 3:14
  • The embedded delay in your code waits 150ms each iteration. But you are also executing code which takes its own time. The error will accumulate as time goes on. Causing any attempt at recreating the signal to be more off the longer the signal is. It would be better to execute the sampling based on a hardware timer interrupt. – st2000 Nov 15 '18 at 3:19
  • 1
    The receiver is more than just a photo diode. The receiver demodulates the 38KHz signal. To recreate the signal you need to turn the IR LED on and off at 38KHz and turn that signal on and off using the pattern you recorded at the output of the receiver. – st2000 Nov 15 '18 at 3:22
  • To recreate the 38KHz signal, you would have to complete a loop of your code ever 13.158us. That needs to include the time it takes to execute the code. Likely the real driver does not bother with this. Instead, code can configure the PWM hardware to generate a continuous 38KHz. Then the code would only be tasked with modulating the 38KHz code. – st2000 Nov 15 '18 at 3:33
0

Finally managed to figure it out without using any library. This is how I turn on my TV:

int pinSend=3;
int waitTimeInMicroseconds = 33; // counter to try with different wait times in order to see what frequency works best
unsigned int  rawData[67] = {4500,4500, 550,1650, 550,1700, 550,1700, 550,600, 500,550, 550,550, 550,600, 550,550, 550,1700, 550,1650, 550,1700, 550,550, 550,550, 550,600, 550,550, 550,550, 550,600, 550,1650, 550,600, 550,550, 550,550, 550,550, 550,600, 550,550, 550,1700, 550,550, 550,1700, 500,1700, 550,1700, 550,1650, 550,1750, 500,1650, 550};

int isOn =1;


void setup() {
     Serial.begin(9600);
     pinMode(pinSend,OUTPUT);
}

void loop() {

    Serial.print("starting with ");
    Serial.println(waitTimeInMicroseconds);


    for(int jj=0; jj<16; jj++)
    {
    for(int i=0; i<67; i++)
    {
        if(isOn==0)    {
          isOn=1;

          int x=0;

          while(true)
          {
            digitalWrite(pinSend,HIGH);
            delayMicroseconds(waitTimeInMicroseconds); // wait in microseconds
            digitalWrite(pinSend,LOW);
            delayMicroseconds(waitTimeInMicroseconds); // wait in microseconds

            x=x+waitTimeInMicroseconds+waitTimeInMicroseconds;

            if(x > rawData[i])
            {
              break;
            }
          }

        }
        else{
          isOn=0;
          delayMicroseconds(rawData[i]);
        }

    }
    }

    delay(2500);
    //waitTimeInMicroseconds++;

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.