How to use Pro Mini to mimic signal from IR receivers signal wire

Hi,

I hope someone can point me in the right direction. Ok I have an automatic round bale wrapper with an IR remote. The IR receiver sends what I believe is a pwm signal to the controller when button on transmitter is pressed. The IR remote works, but can be temperamental in bright sun, and you have to point transmitter directly at it. I am wanting to replace it with a radio remote. I was thinking I could use arduino to read pwm signal from remote and use arduino to transmit the same signal to wrapper controller with my own circuit. I can't touch the controller on the bale wrapper.
The IR remote is fed 5v from the wrapper controller, and has a signal wire going back to controller. If I put a multimeter to the signal wire, I get 3v, and between 2.9 - 3v while transmitting.

This is the inside of the IR receiver:

The chip in the IR receiver is a SL486. Datasheet here https://www.philohome.com/sensors/laser/SL486.pdf

From what I can tell it outputs a pwm signal. So I used the following code to read it.

volatile int pwm_value = 0;
volatile int prev_time = 0;
 
void setup() {
  Serial.begin(115200);
  // when pin D2 goes high, call the rising function
  attachInterrupt(0, rising, RISING);
}
 
void loop() { }
 
void rising() {
  attachInterrupt(0, falling, FALLING);
  prev_time = micros();
}
 
void falling() {
  attachInterrupt(0, rising, RISING);
  pwm_value = micros()-prev_time;
  Serial.println(pwm_value);
}

When I run that code and press a button on IR transmitter I get a repeating pattern of numbers like this:
21484
10504
10504
6860
6860
10504

That sequence just keeps repeating.
So my questions are,
Am I correct in thinking its a pwm signal?
Can Arduino replicate it?
Am I reading the signal correctly? and if I am and those numbers are the code, how do I use arduino to resend them?

Thanks for sticking with me this far :grimacing:

definitely not
The IR transmitters uses several different signal formats, but none is PWM.

likely yes

Given the fact that you use the serial print command in the interrupt, it is unlikely that you have time to read all the signals correctly.

You have to look at dedicated IR-receiver library. Using library examples, you could read the signal, determine it format and resend it.

Thanks for reply. I was playing with the IRRemote library but wasn't getting any results. I was thinking that the SL486 chip in the receiver was changing the signal to pwm because there is a bit in the datasheet that talks about the "Output pulse stretcher for use with microprocessor decoders. So that made me think it was pwm.
So do you think its an IR code that's being sent to the controller by the remote?
Can you recommend an IR library that may be able to decode it? I'm guessing its not a standard remote.

Thanks.

In general, to resend signal you don't need to decode it. You just need to catch it accurately and resend without changing.
Try to connect the IR receiver module to the logic analyser and display the signal

Hi,

That is the output of the receiver that could be PWM, but the IR link from Tx to Rx will be modulated and coded.

To fully understand the Rx output that you want to replicate via a wireless link, you may need to use a scope to analyse the Rx output for each IR Tx command.

Tom.. :smiley: :+1: :coffee::australia:

I don't have a logic analyser sorry

It costs less than $10

Hi thanks. It's the output of the receiver that goes to the controller that I want to replicate, not the connection between Tx and Rx.
I just want to manually send whatever signal the receiver sends down the signal wire to controller. So is it a pwm signal im trying to read then?

I found the following code for a raw ir decoder:


/* Raw IR decoder sketch!
 
 This sketch/program uses the Arduno and a PNA4602 to 
 decode IR received. This can be used to make a IR receiver
 (by looking for a particular code)
 or transmitter (by pulsing an IR LED at ~38KHz for the
 durations detected 
 
 Code is public domain, check out www.ladyada.net and adafruit.com
 for more tutorials! 
 */

// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!
//uint8_t IRpin = 2;
// Digital pin #2 is the same as Pin D2 see
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
#define IRpin_PIN      PIND
#define IRpin          2

// 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[100][2];  // pair is high and low pulse 
uint8_t currentpulse = 0; // index for pulses we're storing

void setup(void) {
  Serial.begin(9600);
  Serial.println("Ready to decode IR!");
}

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();
       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();
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;

  // we read one high-low pulse successfully, continue!
  currentpulse++;
}

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");
  }
  
  // print it in a 'array' format
  Serial.println("int IRsignal[] = {");
  Serial.println("// ON, OFF ");
  for (uint8_t i = 0; i < currentpulse-1; i++) {
    //Serial.print("\t"); // tab
    Serial.print("pulseIR(");
    Serial.print(pulses[i][1] * RESOLUTION , DEC);
    Serial.print(");");
    Serial.println("");
    //Serial.print("\t");
    Serial.print("delayMicroseconds(");
    Serial.print(pulses[i+1][0] * RESOLUTION , DEC);
    Serial.println(");");

  }
  //Serial.print("\t"); // tab
  Serial.print("pulseIR(");
  Serial.print(pulses[currentpulse-1][1] * RESOLUTION, DEC);
  Serial.print(");");

}

When I ran it and pressed one of the remote buttons, I got this result on the output signal wire from the receiver:

Ready to decode IR!



Received: 

OFF 	ON
32608 usec, 500 usec
22120 usec, 480 usec
10820 usec, 500 usec
10800 usec, 500 usec
7060 usec, 500 usec
7060 usec, 480 usec
10820 usec, 480 usec
22120 usec, 500 usec
10820 usec, 480 usec
10820 usec, 480 usec
7060 usec, 500 usec
7060 usec, 500 usec
10800 usec, 500 usec
int IRsignal[] = {
// ON, OFF 
pulseIR(500);
delayMicroseconds(22120);
pulseIR(480);
delayMicroseconds(10820);
pulseIR(500);
delayMicroseconds(10800);
pulseIR(500);
delayMicroseconds(7060);
pulseIR(500);
delayMicroseconds(7060);
pulseIR(480);
delayMicroseconds(10820);
pulseIR(480);
delayMicroseconds(22120);
pulseIR(500);
delayMicroseconds(10820);
pulseIR(480);
delayMicroseconds(10820);
pulseIR(480);
delayMicroseconds(7060);
pulseIR(500);
delayMicroseconds(7060);
pulseIR(500);
delayMicroseconds(10800);
pulseIR(500);

This is pretty much the same results as i got before, but more detailed. So is this the rite output and can i use it?

Thanks.

agh thanks. I thought it would be more expensive. I'll have a look. Can you recommend one?

Thanks

I think so

This looks as a ready-to-go code sequence to resend received signal:

pulseIR(500);
delayMicroseconds(22120);
pulseIR(480);
delayMicroseconds(10820);
pulseIR(500);
delayMicroseconds(10800);
pulseIR(500);
delayMicroseconds(7060);
pulseIR(500);
delayMicroseconds(7060);
pulseIR(480);
delayMicroseconds(10820);
pulseIR(480);
delayMicroseconds(22120);
pulseIR(500);
delayMicroseconds(10820);
pulseIR(480);
delayMicroseconds(10820);
pulseIR(480);
delayMicroseconds(7060);
pulseIR(500);
delayMicroseconds(7060);
pulseIR(500);
delayMicroseconds(10800);
pulseIR(500);

Cool. How do I send it though? Is it just a case writing HIGH and LOW with those delay times?

Thanks.

Yes, you just write HIGh or LOW to the pin

But I don’t want to send an infrared signal. It’s the signal between ir receiver and wrapper controller that I want to replicate.
Sorry if I’m not being clear

that is, the signal that you wrote down in the post#8 is already inside your wrapper?
It seemed to me that you did not want to get inside the device...

yeah post 8 is the output I get from the signal wire of the ir receiver that goes to the wrapper controller. I just want to mimic this signal so I can remove the ir receiver from the setup, and use an arduino board in its place so I can manually send signals to controller via the same signal wire.
I still want to connect to the controller, but I just meant I couldn't alter it in any way.

Thanks.

So I was looking at the datasheet a bit more for the ir receiver, and it says the output is a stretched PPM. Does this make it any easier to read?

Are you rejected this idea?

No I still want to replicate the signal, but I wasn't sure that I was reading the correct thing now that I've found out its a PPM signal.. Although I've tried a few PPM sketches, and they give me more or less the same values i got in #8. My problem is I don't know how to make these values into a signal for sending.
I have found a few PPM sender sketches, but they only seem to range pulses between 1000 and 2000. I need to go a lot higher and lower than that.

As far as I understand, you just should try to run code from post #10

Ok I am progressing a bit. I wrote the following code and ran it, and it's giving me roughly the same numbers as I was getting from the ir receiver. I used milliseconds at the start because as far as I know microseconds don't go that high.
My HIGH times in code are roughly 500 Microseconds higher than the value I'm getting, but I'm guessing that's because of the 500 microseconds delay I've added.
I also used digitalWrite instead of analoyWrite, and it seemed to make things better.

void setup() {
  // put your setup code here, to run once:
  pinMode(9, OUTPUT);
}

void loop() {
  digitalWrite(9, HIGH);
  delay(22);
  digitalWrite(9, LOW);
  delayMicroseconds(500);
  digitalWrite(9, HIGH);
  delayMicroseconds(11000);
  digitalWrite(9, LOW);
  delayMicroseconds(500);
  digitalWrite(9, HIGH);
  delayMicroseconds(11000);
  digitalWrite(9, LOW);
  delayMicroseconds(500);
  digitalWrite(9, HIGH);
  delayMicroseconds(7300);
  digitalWrite(9, LOW);
  delayMicroseconds(500);
  digitalWrite(9, HIGH);
  delayMicroseconds(7300);
  digitalWrite(9, LOW);
  delayMicroseconds(500);
  digitalWrite(9, HIGH);
  delayMicroseconds(11000);
  digitalWrite(9, LOW);
  delayMicroseconds(500);
}

I still get a lot of lines of jumbled numbers, but every say third line is the correct sequence of numbers. Do you know of any way of making sure it only puts out the proper sequence?

Still not sure if I'm on the write tracks, but it's starting to look better.