How to send PULSE_WIDTH IR data?

I have captured the data my IR remote sends when I press a certain button on it, now I can't figure out how to send a copy of that data using my IR transmitter.

I'm using the library IRemote and my receiver and transmitter are compatible with that library. (I've used them successfully to copy IR codes from other remotes in the past.)

Here is the captured button press:

START /home/fedora/Arduino/libraries/IRremote/examples/ReceiveDump/ReceiveDump.ino from Sep 22 2021
Using library version 3.3.0
Ready to receive IR signals at pin 2


Protocol=PULSE_WIDTH Address=0x0 Command=0x0 Raw-Data=0x1F0 9 bits LSB first

Raw result in internal ticks (50 us) - with leading gap
rawData[22]: 
     -65535
     + 119,-  79     +  20,-  20     +  20,-  20     +  20,-  20
     +  19,-  21     +  40,-  20     +  40,-  21     +  39,-  20
     +  39,-  21     +  39,-  21     +  19
Raw result in microseconds - with leading gap
rawData[22]: 
     -3276750
     +5950,-3950     +1000,-1000     +1000,-1000     +1000,-1000
     + 950,-1050     +2000,-1000     +2000,-1050     +1950,-1000
     +1950,-1050     +1950,-1050     + 950

Result as internal ticks (50 us) array - compensated with MARK_EXCESS_MICROS=20
uint8_t rawTicks[21] = {119,79, 20,20, 20,20, 20,20, 19,21, 40,20, 40,21, 39,20, 39,21, 39,21, 19};  // Protocol=PULSE_WIDTH Address=0x0 Command=0x0 Raw-Data=0x1F0 9 bits LSB first

Result as microseconds array - compensated with MARK_EXCESS_MICROS=20
uint16_t rawData[21] = {5930,3970, 980,1020, 980,1020, 980,1020, 930,1070, 1980,1020, 1980,1070, 1930,1020, 1930,1070, 1930,1070, 930};  // Protocol=PULSE_WIDTH Address=0x0 Command=0x0 Raw-Data=0x1F0 9 bits LSB first

uint16_t address = 0x0;
uint16_t command = 0x0;
uint32_t data = 0x1F0;

Pronto Hex as string
char ProntoData[] = "0000 006D 000B 0000 00E6 0097 0027 0026 0027 0026 0027 0026 0025 0028 004E 0026 004E 0028 004C 0026 004C 0028 004C 0028 0025 06C3 "

I've tried it like this:

#include <Arduino.h>
#include <IRremote.h>

#define IR_SEND_PIN 10
#define LIGHT_ON_IR_DATA 0x1F0

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
    Serial.begin(115200);
    IrSender.begin(IR_SEND_PIN, ENABLE_LED_FEEDBACK);
    delay(2000);
    
    Serial.print("Ready to send IR signals at pin ");
    Serial.println(IR_SEND_PIN);
}

void loop() {
    Serial.println("Send LIGHT_ON IR code");
    IrSender.sendNECRaw(LIGHT_ON_IR_DATA, 0);
    Serial.print("Sleeping for 1 sec");
    delay(1000);
}

I also tried using the rawData using the rawSend method, but it expects a frequency as the third parameter and I have no clue what I would put in there.

I know normal TV remotes work with a 38k (?) carrier frequency. So sending raw "data" will not work.

I suggest you look for an IR Arduino library.

Did you look at the SendRawDemo example that comes with the library? That example uses the 38kHz - don't know if it will work for yours.

I think I'm getting somewhere, but for some reason the data that I send is off a little bit.

Here is what I receive when I send it form one Arduino to the other Arduino:

Protocol=PULSE_WIDTH Address=0x0 Command=0x0 Raw-Data=0x1F0 9 bits LSB first

Raw result in internal ticks (50 us) - with leading gap
rawData[22]: 
     -65535
     + 117,-  80     +  19,-  21     +  19,-  21     +  19,-  21
     +  19,-  22     +  37,-  22     +  39,-  21     +  39,-  21
     +  38,-  23     +  37,-  23     +  18
Raw result in microseconds - with leading gap
rawData[22]: 
     -3276750
     +5850,-4000     + 950,-1050     + 950,-1050     + 950,-1050
     + 950,-1100     +1850,-1100     +1950,-1050     +1950,-1050
     +1900,-1150     +1850,-1150     + 900

Result as internal ticks (50 us) array - compensated with MARK_EXCESS_MICROS=20
uint8_t rawTicks[21] = {117,80, 19,21, 19,21, 19,21, 19,22, 37,22, 39,21, 39,21, 38,23, 37,23, 18};  // Protocol=PULSE_WIDTH Address=0x0 Command=0x0 Raw-Data=0x1F0 9 bits LSB first

Result as microseconds array - compensated with MARK_EXCESS_MICROS=20
uint16_t rawData[21] = {5830,4020, 930,1070, 930,1070, 930,1070, 930,1120, 1830,1120, 1930,1070, 1930,1070, 1880,1170, 1830,1170, 880};  // Protocol=PULSE_WIDTH Address=0x0 Command=0x0 Raw-Data=0x1F0 9 bits LSB first

uint16_t address = 0x0;
uint16_t command = 0x0;
uint32_t data = 0x1F0;

Pronto Hex as string
char ProntoData[] = "0000 006D 000B 0000 00E2 0099 0025 0028 0025 0028 0025 0028 0025 002A 0048 002A 004C 0028 004C 0028 004A 002B 0048 002B 0023 06C3 "

Using that code:

#include <Arduino.h>
#include "PinDefinitionsAndMore.h"
#include <IRremote.h>

////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////Captured IR data (from the original remote)////////////////////
////////////////////////////////////////////////////////////////////////////////////////
// Result as internal ticks (50 us) array - compensated with MARK_EXCESS_MICROS=20
uint8_t rawTicks[21] = {119,79, 20,20, 20,20, 20,20, 19,21, 40,20, 40,21, 39,20, 39,21, 39,21, 19};  // Protocol=PULSE_WIDTH Address=0x0 Command=0x0 Raw-Data=0x1F0 9 bits LSB first

// Result as microseconds array - compensated with MARK_EXCESS_MICROS=20
uint16_t rawData[21] = {5930,3970, 980,1020, 980,1020, 980,1020, 930,1070, 1980,1020, 1980,1070, 1930,1020, 1930,1070, 1930,1070, 930};  // Protocol=PULSE_WIDTH Address=0x0 Command=0x0 Raw-Data=0x1F0 9 bits LSB first

uint16_t address = 0x0;
uint16_t command = 0x0;
uint32_t data = 0x1F0;

// Pronto Hex as string
char ProntoData[] = "0000 006D 000B 0000 00E6 0097 0027 0026 0027 0026 0027 0026 0025 0028 004E 0026 004E 0028 004C 0026 004C 0028 004C 0028 0025 06C3 ";
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////

#define IR_SEND_PIN 13

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
    Serial.begin(115200);
    IrSender.begin(IR_SEND_PIN, ENABLE_LED_FEEDBACK); // Specify send pin and enable feedback LED at default feedback LED pin
}

void loop() {
    const uint8_t NEC_KHZ = 38; // 38kHz carrier frequency for the NEC protocol
    uint16_t irSignal[] = {5930,3970, 980,1020, 980,1020, 980,1020, 930,1070, 1980,1020, 1980,1070, 1930,1020, 1930,1070, 1930,1070, 930};
    Serial.println("SEND IR CODE");
    IrSender.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), NEC_KHZ);
    delay(5000);
}

As you can see the first byte of the rawTicks array is 119 when I send it, but when i receive it I get 117.

The library uses 50-microsecond intervals so pulse widths being off by 50 or 100 microseconds is likely not a problem.

1 Like

Thank you, turns out it actually works. The IR transmitters I bought just were extremely weak which caused me to think it doesn't work.

Most LED's work fine at 10mA but high-power IR LEDs may take 100 mA, far beyond the drive capability of an Arduino pin. You need a transistor to drive them at full power.

Yeah, I figured. It was just surprising to me because the sensor was explicitly marketed as Arduino compatible and had its own pcb with a couple of components (only resistors apparently).

I ended up using this:


using a 940nm TSAL6400 IR LED and a 2N3904 NPN transistor.

It looks like you might be over driving your LED. The datasheet says 100mA at 1.6V and you are supplying 3.3V (minus a couple of tenths of volt drop across the transistor). Better get a resistor in there or it might not last long. It also wouldn't hurt to put a resistor between your bin and the base of that transistor to limit current.

Yes I'm definitely over driving it, but considering that it's probably running for not more than a few milliseconds every day, it will probably still live a long life. I was just going for a quick and dirty solution that gives me good range.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.