Here is an updated version of the sketch. It lets you change the Adjust value, or just run it again, without having to reset.
// This interprets incoming IR from a remote control as raw data.
// An IR receiver module should be connected to D8.
// The Adjust variable adjusts time between On and Off periods since
// receivers may turn on faster than they turn off, or vice verse.
// Results will include any repeats.
// The displayed numbers alternate between transmitting and idle states.
const int maxEntries = 300;
unsigned int bitTime[maxEntries]; // uSeconds in each state
bool active [maxEntries]; // transmitting or idle
int Adjust = 15, newAdjust; // receiver turn on, turn off times not the same
const byte recvPin = 8;
volatile unsigned int timerMSB, capMSB; // third byte of 24-bit timer (timer1 = 1st two)
volatile bool Capture; // a state change has occurred, and time captured
unsigned long timerLO, timerHI, newTime, prevTime;
int i, j, k;
bool activeLO; // receiver output is low when receiving carrier
bool activeNow = false;
bool Waiting, Start;
void setup() {
delay(1000);
Serial.begin (115200);
pinMode(recvPin, INPUT);
activeLO = true; // assume no transmission now
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
sei();
Start = true;
}
void loop() {
if(Start) { // initialize everything on start or restart
Start = false;
i = 0;
j = 1;
Waiting = true;
Capture = false;
activeNow = false;
cli();
if (activeLO) TCCR1B = 0b00000010; // falling edge capture, timer1 on, prescale /8
else TCCR1B = 0b01000010; // rising edge capture, timer1 on, prescale /8
TIFR1 = 0xFF;
sei();
Serial.print("Adjust = "); Serial.println(Adjust);
Serial.println("Enter new Adjust value, or [Enter]");
while (!Serial.available());
newAdjust = Serial.parseInt(SKIP_NONE);
if (newAdjust) Adjust = newAdjust;
Serial.print("Adjust = "); Serial.println(Adjust);
while(Serial.available()) Serial.read();
Serial.println("Waiting for IR transmission...");
}
if (Waiting) { // keep MSB cleared
if (timerMSB) {
cli();
timerMSB = 0;
sei();
}
}
if(Capture) { // input has changed state
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) { // skip i=0
bitTime[i] = newTime - prevTime; // collect duration and activity state
active[i] = activeNow;
}
prevTime = newTime; // prepare for next state change
activeNow = !activeNow;
TCCR1B ^= 0b01000000; // capture on opposite edge
i++;
}
if ((timerMSB > 40) || (i > maxEntries)) {
TCCR1B &= 0xFE; // stop Timer1 clock
for (k = 1; k < i; k++) { // adjust on (Mark) and off (Space) times
if (active[k]) bitTime[k] -= Adjust;
else bitTime[k] += Adjust;
}
Serial.println();
// This has been modified to remove the minus signs
while (j < i) {
for (k = 0; k < 8; k++) {
Serial.print (bitTime[j]);
j++;
if (j == i) break;
else Serial.print (", ");
}
Serial.println();
}
Serial.println();
Start = true;
}
}
ISR(TIMER1_CAPT_vect) {
capMSB = timerMSB; // also capture MSB at same instant
Capture = true;
}
ISR(TIMER1_OVF_vect) {
timerMSB++; // increment MSB on overflow
}