Last active
October 20, 2021 18:19
-
-
Save houseofjeff/8cfe3c52000f754a6b01 to your computer and use it in GitHub Desktop.
Capture/Record IR remote signals with an Arduino
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//------------------------------------------------------------------------------ | |
// 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