Skip to content

Instantly share code, notes, and snippets.

@houseofjeff
Last active October 20, 2021 18:19
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save houseofjeff/8cfe3c52000f754a6b01 to your computer and use it in GitHub Desktop.
Save houseofjeff/8cfe3c52000f754a6b01 to your computer and use it in GitHub Desktop.
Capture/Record IR remote signals with an Arduino
//------------------------------------------------------------------------------
// Interrupt 0 fires on pin D2
#define IR_PIN 2
// the maximum pulse we'll listen for
#define MAX_PULSE 30000
// the largest message we expect to receive (in bits)
#define MAX_MSG_SIZE 50
// These variables hold the info for the incoming IR message. If we have received
// a message, then these will hold the message length and the pulse width values.
// We'll store up to 50 pulse pairs (high and low), which is more than enough.
volatile uint8_t ir_msg_len = 0;
volatile uint16_t ir_msg[MAX_MSG_SIZE*2]; // pair is high and low pulse
//------------------------------------------------------------------------------
// Initialize the arduino, attach the interrupt that will fire whenever pin 2
// goes HIGH. (On the Uno, interrupt 0 goes to pin D2, but it depends on the
// model
void setup() {
Serial.begin(9600);
attachInterrupt( 0, captureIR, RISING );
Serial.println("Ready to capture message");
}
//------------------------------------------------------------------------------
// Test if there is a message (if ir_msg_len > 0) and, if so, print it.
void loop() {
if (ir_msg_len > 0) {
// print the message
Serial.println("message caught:");
print_message();
// reset to 'no message' state when finished.
ir_msg_len = 0;
}
}
//------------------------------------------------------------------------------
// captureIR() captures the pulse-width data that is delivered to pin 2 when
// an infrared message triggers the IR sensor.
uint32_t last_time = 0;
const float cycle_time = (1.0/36000.0)*1000000; // 27.7778 uS per cycle
void captureIR() {
// If the previous call came in less than 0.25 seconds ago, just ignore it.
uint32_t now = micros();
if (now - last_time < 250000)
return;
last_time = now;
// Track the pin as it rises and falls and record the time it spends in HIGH
// then LOW state. If we pass MAX_PULSE uS, the message is over.
uint32_t hightime, lowtime;
ir_msg_len = 0;
while (ir_msg_len < MAX_MSG_SIZE*2) {
hightime = pulseIn(IR_PIN, HIGH, MAX_PULSE);
lowtime = pulseIn(IR_PIN, LOW, MAX_PULSE);
if ( (hightime == 0) || (lowtime == 0) ) {
// Finished with message
return;
}
ir_msg[ir_msg_len++] = round(hightime/cycle_time);
ir_msg[ir_msg_len++] = round(lowtime/cycle_time);
}
}
//------------------------------------------------------------------------------
// Output the message as a set of pairs in a format that will be easy to cut and
// paste into code in the next step, like this:
// uint16_t target_seq[5*2] = { 14,15, 62,15, 14,15, 15,15, 900,14 };
void print_message(void) {
Serial.print("uint16_t target_seq[");
Serial.print( int(ir_msg_len/2) );
Serial.print("*2] = { ");
for (uint8_t i = 0; i < ir_msg_len; i+=2) {
Serial.print( ir_msg[i] );
Serial.print(",");
Serial.print( ir_msg[i+1] );
if (i != ir_msg_len-2) {
Serial.print(", ");
}
}
Serial.println(" };");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment