IR Signals record and send same for Onida AC

Hi,

I am working on a project to record IR signals of all kind of devices and store them and send them back.
I have sample code. I am able to receive the signals from AC remote and transmit back but the the AC doesn’t respond.

Here I have attached source code and output of my program. please check and help ASAP!

#define IRpin_PIN      PIND
#define IRpin          2
#define IRled          13
#define STATUS_PIN     12
 
// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
 
// what our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing
#define RESOLUTION 20 
 
// we will store up to 100 pulse pairs (this is -a lot-)
uint16_t pulses[200][2];  // pair is high and low pulse 
uint8_t currentpulse = 0; // index for pulses we're storing
 
void setup(void) {
  pinMode(IRled, OUTPUT); 
  pinMode(STATUS_PIN, OUTPUT);
  Serial.begin(9600);
  Serial.println("Ready to decode IR! and send ");
}
 
void loop(void) {
  uint16_t highpulse, lowpulse;  // temporary storage timing
  highpulse = lowpulse = 0; // start out with no pulse length
 
 
//  while (digitalRead(IRpin)) { // this is too slow!
    while (IRpin_PIN & (1 << IRpin)) {
     // pin is still HIGH
 
     // count off another few microseconds
     highpulse++;
     delayMicroseconds(RESOLUTION);
 
     // If the pulse is too long, we 'timed out' - either nothing
     // was received or the code is finished, so print what
     // we've grabbed so far, and then reset
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       SendChannelUpCode();
       currentpulse=0;
       return;
     }
  }
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;
 
  // same as above
  while (! (IRpin_PIN & _BV(IRpin))) {
     // pin is still LOW
     lowpulse++;
     delayMicroseconds(RESOLUTION);
     if ((lowpulse >= MAXPULSE)  && (currentpulse != 0)) {
       //printpulses();
       //SendChannelUpCode();
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;
 
  // we read one high-low pulse successfully, continue!
  currentpulse++;
  //SendChannelUpCode();
}
 
void printpulses(void) {
  Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
  for (uint8_t i = 0; i < currentpulse; i++) {
    Serial.print(pulses[i][0] * RESOLUTION, DEC);
    Serial.print(" usec, ");
    Serial.print(pulses[i][1] * RESOLUTION, DEC);
    Serial.println(" usec");
  }
}
void pulseIR(long microsecs) {
  // we'0ll count down from the number of microseconds we are told to wait
 
  cli();  // this turns off any background interrupts
 //Serial.println("\nSending IR");
  while (microsecs > 0) {
    // 38 kHz is about 13 microseconds high and 13 microseconds low
    //Serial.println("\nSending IR");
   digitalWrite(IRled, HIGH);  // this takes about 3 microseconds to happen
   digitalWrite(STATUS_PIN, HIGH);
   delayMicroseconds(10);   // hang out for 10 microseconds
   digitalWrite(STATUS_PIN, LOW);
   digitalWrite(IRled, LOW);   // this also takes about 3 microseconds
   digitalWrite(STATUS_PIN, HIGH);
   delayMicroseconds(10);   // hang out for 10 microseconds
   digitalWrite(STATUS_PIN, LOW);
 
   // so 26 microseconds altogether
   microsecs -= 26;
  }
 // digitalWrite(IRled, LOW);
  sei();  // this turns them back on
}
void SendChannelUpCode() {
  // This is the code for the CHANNEL + for the downstairs TV COMCAST
  Serial.println("\nSending");
  delayMicroseconds(2000000); 
  for (uint8_t i = 0; i < currentpulse; i++) {
  delayMicroseconds(pulses[i][0]); //Time off (Left Column on serial monitor)
  pulseIR(pulses[i][1]);
  }
}

Output.txt (780 Bytes)

Without looking too much into the code - this could possibly be one of your issues:

digitalWrite(IRled, HIGH);  // this takes about 3 microseconds to happen
digitalWrite(STATUS_PIN, HIGH);   //<<<<<<<<<<<<<<<<<<<<<<<<<<<<How long does this take ???
delayMicroseconds(10);   // hang out for 10 microseconds

You said in your comments that you are trying to alternate HIGHs and LOWs - with the aim to keep each IRled HIGH for 13 microseconds and each IRled LOW for 13 microseconds. (Total = 26 microseconds)
But I am guessing that your digitalWrite to turn the STATUS_PIN on and off is also taking ~3 microseconds.
So you may need to reduce your delay to accommodate for that line.

OK,Then I will comment the STATUS_PIN and I will check what happens next.

I have tried removing the below the status

digitalWrite(STATUS_PIN, HIGH); <<<<<<<<<<<< commented all occurences.

But still no use. I didn’t get any output.

Is there any way I can do this

I would use a potentiometer to programatically modify the delay. Trial and error. Print the delay to the Serial Monitor so that you can hard code it later. This assumes that you have nothing else wrong with your code, and that your method is sound. I have not looked too deeply into your code.

How can i print the delay?

Sorry - I did not explain that well.

1) Read the values of a potentiometer using AnalogRead 2) "Map" and "constrain" the values to a specific range eg. 1 to 30 3) Use a Serial.println(value); command to show the "mapped" value in your Serial Monitor 4) Use this value as your delay (instead of 10).

Ok, Thanks. It’s bit difficult because I don’t have potentiometer.

You could perhaps just program it so that you transmit the signal repetitively (eg. 10-100 times) using a delay of (1), make sure to send the delay value to the Serial monitor using Serial.println(1); - so that you know what delay value is being used.

Maybe pause between transmissions...

Then transmit it 10-100 times using a delay of 2 Serial.println(2);

Keep incrementing... until you get to the maximum delay you want to try.

If it works - you should be able to tell which delay was successful - due to the Serial print commands. If it doesn't work - then you need to focus somewhere else, and then maybe come back to this part afterwards.

I have tried. But no result. I will try once again. Do you think is there any problem with my IR_LED. How can I check is it strong enough to send?

Because in the Remote I have large LED compared to the LED connected to my arduino.

Have you got 2 Arduino's ? Get one of the Arduino's to transmit the code, and then get the other one to receive and check the signal that you are transmitting. Make sure that it is the same as the one you received from the remote?

Are you following the Adafruit example? And if so, are you using the same components that they used?

Hey,

Thanks for ur advice. I have used arduino boards. As you said I have compared the outputs.
Actually there is difference. How can I get the exact values.

I am attaching two files. pls check and revert back ASAP!

out_remote.txt (1.21 KB)

out_arduino.txt (1.99 KB)

There are differences between the two… but you would have to do your experiment 10 times to see if the difference is due to reading inaccuracies or due to transmission inaccuracies etc etc.

Have you tried cleaning up the signal (that you want to transmit), by converting all numbers < 600 to the most common number (eg. 540)… So you change all of the numbers that are less than 600 to 540.
And then changing all numbers > 1000 to 1590 (except for the very big numbers - you can keep them the same)… I am not sure if that will work… but you can try that.

If that fails, then it may be an issue with your LED brightness - you may need to look into that.

I have repeated the experiment for many times. But there are difference.

I will clean the signal and check once again, as you mentioned.

Hey I have repeated the experiment for many times after cleaning the signal. But still there are differences each time I receive

I am attach three different outputs.

And

the code I used for sending

unsigned int key[99][2]={{27304,5980},
{7260,520},
{1640,520},
{1580,520},
{1600,540},
{1600,520},
{1580,540},
{1600,520},
{1600,540},
{1580,520},
{580,540},
{540,540},
{540,520},
{540,540},
{540,520},
{540,540},
{540,520},
{540,540},
{1620,540},
{1580,540},
{1580,540},
{1580,540},
{1580,540},
{1580,540},
{1600,520},
{1580,560},
{560,520},
{540,540},
{540,540},
{540,520},
{540,540},
{540,520},
{540,540},
{540,540},
{1620,520},
{1600,540},
{1580,540},
{1580,540},
{1580,540},
{1580,520},
{1600,540},
{1600,500},
{600,520},
{540,540},
{540,520},
{540,540},
{540,520},
{560,520},
{540,540},
{540,520},
{1620,540},
{540,540},
{1580,540},
{1620,540},
{1580,540},
{1580,520},
{1600,540},
{1600,560},
{560,520},
{1600,540},
{540,500},
{580,520},
{540,540},
{540,520},
{540,540},
{540,520},
{580,520},
{1600,540},
{1580,520},
{1600,540},
{1600,520},
{540,540},
{1580,520},
{1600,540},
{1620,520},
{540,540},
{540,540},
{540,520},
{540,540},
{1600,520},
{540,540},
{540,520},
{580,520},
{1600,540},
{540,520},
{1580,540},
{540,520},
{1600,540},
{540,520},
{560,520},
{1620,540},
{540,520},
{1600,540},
{540,520},
{1580,540},
{540,520},
{1600,540},
{1580,540},
{7240,520}};


int IRledPin =  3;
int i=0;

void setup() {
  // put your setup code here, to run once:
pinMode(IRledPin, OUTPUT);     
  Serial.begin(9600);
  Serial.println("Starting Sending");
}

void loop() {
  // put your main code here, to run repeatedly:
  SendChannelUpCode();

  delay(5*1000);  // wait twenty seconds (20 seconds * 1000 milliseconds) Change this value for different intervals.

}
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 SendChannelUpCode() {
  // This is the code for the CHANNEL + for the TV COMCAST
  Serial.println("Sending with 5 s delay");
  Serial.println("OFF\tON\n");
  for(i=0;i<99;i++){
    Serial.print(key[i][0]);
    Serial.print("\t");
    Serial.print(key[i][1]);
    Serial.println("\n");
  }
 for(i=0;i<99;i++){
   if(key[i][0] > 1000 && key[i][0]){
  delayMicroseconds(1690);      //Time off (LEFT column)   
   }  
   else {
     delayMicroseconds(key[i][0]);
   }  
   if(key[i][1] > 500 && key[i][1] <600){
  pulseIR(560);    //Time on (RIGHT column)
   }
   else {
     pulseIR(key[i][1]);
   }  
 }
}

OUT1.txt (1.99 KB)

OUT2.txt (1.99 KB)

OUT3.txt (1.99 KB)

pulseIR(560); should be pulseIR(5*4*0);

delayMicroseconds(10); - may need to modify slightly to get the correct signal length

delayMicroseconds(1690); should be delayMicroseconds(1*5*90);

You may get some variation when reading the signal - but try to get as close as you can. Get multiple readings from the remote control - to make sure that the signal code is consistent.

Hi,

OK. But I tried for Sony projector. I decoded the Sonysignal using IR library.

I am sending signal using irsend.Sony() using Library. Even after using Library also. I am not able to get the output. Just help me to solve for Sony.

/*
 * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
 * An IR LED must be connected to Arduino PWM pin 3.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>


IRsend irsend;

void setup()
{
  Serial.begin(9600);
}

void loop() {
  Serial.println("Sending\n");
  delay(5000);
  //irsend.sendRaw(Nec,70,38); // by nithin
  //irsend.sendSony(0x242A,15);
  //if (Serial.read() != -1) {
    for (int i = 0; i < 3; i++) {
     // irsend.sendSony(0x242A,15);
      irsend.sendSony(0x542a, 15); // Sony TV power code
     // delay(40);
    }
  //}
}

Here is the received output for power button

power button

542A
Decoded SONY: 101010000101010 (15 bits)
Raw (32): 25538 2400 -550 1200 -600 600 -600 1150 -600 600 -600 1200 -550 600 -600 600 -600 600 -550 600 -600 1200 -600 550 -600 1200 -600 600 -600 1150 -600 600

volume up

242A
Decoded SONY: 10010000101010 (15 bits)
Raw (32): 30386 2350 -600 600 -550 1200 -600 600 -600 550 -600 1200 -600 600 -600 550 -600 600 -600 600 -600 1150 -600 600 -600 1150 -600 600 -600 1200 -550 600

But no use.

So is there any way

Try this for you sony signal

/*
Automatically Generated by AnalysIR - Batch Export Utility
Registered to: xxxxxxxx
Session History
Type : Key : Value : Bits
0 : RAW :  :  : 15
*/

// NB: Not all protocols are supported by IRremote or IRLib. You may need to edit the code below manually
// Automatically Generated by AnalysIR for xxxxxxxx, visit http://www.AnalysIR.com or email info@....... for further details
int khz=38; //NB Change this default value as neccessary to the correct carrier frequency


unsigned int Signal_0_0[] = {2400,600,1200,600,600,600,1200,600,600,600,1200,600,600,600,600,600,600,600,600,600,1200,600,600,600,1200,600,600,600,1200,600,600}; //AnalysIR Batch Export (IRremote) - RAW

irsend.sendRaw(Signal_0_0, sizeof(Signal_0_0)/sizeof(int), khz); //AnalysIR Batch Export (IRremote) - RAW
 // AnalysIR IR Protocol: RAW, Key:

you could also use the sendSONY as you did in your example. However, you missed that the SONY signal should be sent 3 times with a gap of 15 to 20 mSecs between them.

Actually you will also need to do that (send 3 times) for the RAW signal I posted above.

I suggest you stick with RAW, as you will need that for your AC signal.

Ok,

I will try using ur code for Sony…

I have tried sending RAW signal for AC,but it didn’t work for me.

The below is the code I used to send RAW signals for AC. Please check!

unsigned int key[99][2]={{27304,5980},
{7260,520},
{1640,520},
{1580,520},
{1600,540},
{1600,520},
{1580,540},
{1600,520},
{1600,540},
{1580,520},
{580,540},
{540,540},
{540,520},
{540,540},
{540,520},
{540,540},
{540,520},
{540,540},
{1620,540},
{1580,540},
{1580,540},
{1580,540},
{1580,540},
{1580,540},
{1600,520},
{1580,560},
{560,520},
{540,540},
{540,540},
{540,520},
{540,540},
{540,520},
{540,540},
{540,540},
{1620,520},
{1600,540},
{1580,540},
{1580,540},
{1580,540},
{1580,520},
{1600,540},
{1600,500},
{600,520},
{540,540},
{540,520},
{540,540},
{540,520},
{560,520},
{540,540},
{540,520},
{1620,540},
{540,540},
{1580,540},
{1620,540},
{1580,540},
{1580,520},
{1600,540},
{1600,560},
{560,520},
{1600,540},
{540,500},
{580,520},
{540,540},
{540,520},
{540,540},
{540,520},
{580,520},
{1600,540},
{1580,520},
{1600,540},
{1600,520},
{540,540},
{1580,520},
{1600,540},
{1620,520},
{540,540},
{540,540},
{540,520},
{540,540},
{1600,520},
{540,540},
{540,520},
{580,520},
{1600,540},
{540,520},
{1580,540},
{540,520},
{1600,540},
{540,520},
{560,520},
{1620,540},
{540,520},
{1600,540},
{540,520},
{1580,540},
{540,520},
{1600,540},
{1580,540},
{7240,520}};


int IRledPin =  3;
int i=0;

void setup() {
  // put your setup code here, to run once:
pinMode(IRledPin, OUTPUT);     
  Serial.begin(9600);
  Serial.println("Starting Sending");
}

void loop() {
  // put your main code here, to run repeatedly:
  SendChannelUpCode();

  delay(5*1000);  // wait twenty seconds (20 seconds * 1000 milliseconds) Change this value for different intervals.

}
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 SendChannelUpCode() {
  // This is the code for the CHANNEL + for the TV COMCAST
  Serial.println("Sending with 5 s delay");
  Serial.println("OFF\tON\n");
  for(i=0;i<99;i++){
    Serial.print(key[i][0]);
    Serial.print("\t");
    Serial.print(key[i][1]);
    Serial.println("\n");
  }
 for(i=0;i<99;i++){
   if(key[i][0] > 1000 && key[i][0]){
  delayMicroseconds(1690);      //Time off (LEFT column)   
   }  
   else {
     delayMicroseconds(key[i][0]);
   }  
   if(key[i][1] > 500 && key[i][1] <600){
  pulseIR(560);    //Time on (RIGHT column)
   }
   else {
     pulseIR(key[i][1]);
   }  
 }
}

Any suggestions :slight_smile:

Hey,

I am using T1838 IR receiver. Is it any problem?