Example sketch IRremote ReceiveDump not working

[Edit: See next post for an updated version of the sketch.]

Below is a sketch for an Arduino using the Atmega328P (Uno, Nano, Pro Mini) running at 16 MHz, with an IR receiver module connected to D8.

It will display the raw times in microseconds from the first active carrier detected to one second later. So if it repeats, that should show up.

For greatest accuracy, you want the ambient light to be dark, and you want to be 6 feet or more from the receiver. For some reason if it's too close, it messes things up. And you want to hit the remote's button for the briefest possible time to see whether it always does a repeat.

Positive numbers are when the remote is actively transmitting carrier. Negative numbers are when it is idle. To run it again, hit the Arduino's reset button.

There's a variable called Adjust that shifts some count between the positive and negative numbers to reflect the fact that a particular receiver may turn on faster than it turns off, or vice versa. The value I chose makes my Roku remote produce numbers on my receiver that look closest to NEC, which I know it is.

But be advised that results will depend on how close your Arduino's crystal is to 16 MHz, and how close the remote's crystal is to whatever it's supposed to be, and how accurately the remote follows the protocol.

Anyway, in theory if you can plug the data into a sketch that transmits raw data, it should work.

No libraries were harmed in writing this sketch.

unsigned int bitTime[300];
bool active [300];
int Adjust = -15;                        // receiver turn on, turn off times not the same
const byte recvPin = 8;
volatile unsigned int timerMSB = 0;
volatile unsigned int capMSB = 0;
volatile bool Capture = false;
unsigned long timerLO, timerHI, newTime, prevTime;
int i = 0, j = 1, k;
bool activeLO;
bool activeNow = false;
bool Waiting = true;

void setup() {
  
  delay(1000);
  Serial.begin (115200);
  pinMode(recvPin, INPUT);
  activeLO = true;
  if (!digitalRead(recvPin)) activeLO = false;

  cli();
  TIMSK0 = 0;                             // Disable Timer0 interrupts (millis)
  TCCR0A = 0;
  TCCR0B = 0;
  TIFR0  = 0xFF;

  TCCR1A = 0;                             // set up Timer1
  TCCR1B = 0;
  TCCR1C = 0;
  TCNT0  = 0;                             // clear Timer1
  TIFR1  = 0xFF;                          // clear flags
  TIMSK1 = 0b00100001;                    // enable capture and overflow interrupt (GPS)
  TIFR1  = 0xFF;                          // clear flags
  TCCR1A = 0b00000000;                    // Normal mode, no output, WGM #0
  if (activeLO) TCCR1B = 0b00000010;      // falling edge capture, timer1 on, prescale /8
  else TCCR1B = 0b01000010;               // rising edge capture, timer1 on, prescale /8
  TIFR1  = 0xFF;
  sei();
}

void loop() {

  if (Waiting) {
    if (timerMSB) {
      cli();
      timerMSB = 0;
      sei();
    }
  }

  if(Capture) {
    Capture = false;
    Waiting = false;
    timerLO = ICR1;                        // read timer values
    timerHI = capMSB;
    newTime = ((timerHI << 16) + timerLO +1) >> 1;  // combine timer counts to one long value
    if (i) {
      bitTime[i] = newTime - prevTime;         // collect last numToAvg values into array
      active[i] = activeNow;
    }
    prevTime = newTime;
    activeNow = !activeNow;
    TCCR1B ^= 0b01000000;
    i++;
  }

  if (timerMSB > 40) {
    TCCR1B &= 0xFE;                         // stop Timer1 clock
    for (k = 1; k < i; k++) {
      if (active[k]) bitTime[k] += Adjust;
      else bitTime[k] -= Adjust;
    }
    Serial.println();
    while (j < i) {
      for (k = 0; k < 8; k++) {
        if (k) Serial.print (", ");
        if (!active[j]) Serial.print ("-");
        Serial.print (bitTime[j]);
        j++;
        if (j == i) break;
      }
      Serial.println();
    }
    Serial.println();
    while (1);
  }
}

ISR(TIMER1_CAPT_vect) {
  capMSB = timerMSB;                      // also capture MSB at same instant
  Capture = true;
}

ISR(TIMER1_OVF_vect) {
  timerMSB++;                             // increment MSB on overflow
}