Skip to content

Instantly share code, notes, and snippets.

@taqpan
Created August 19, 2012 10:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save taqpan/3394216 to your computer and use it in GitHub Desktop.
Save taqpan/3394216 to your computer and use it in GitHub Desktop.
IR-signal receiver for Arduino with PL-IRM-2161-C438
#define PIN_LED_OUT 7
#define PIN_IR_IN 8
// NEC format
/*
#define SIGNAL_LEADER_HIGH_TIME 16
#define SIGNAL_LEADER_LOW_TIME 8
#define SIGNAL_TIMEOUT 8000
//*/
// AEHA format
//*
#define SIGNAL_LEADER_HIGH_TIME 8
#define SIGNAL_LEADER_LOW_TIME 4
#define SIGNAL_TIMEOUT 4000
//*/
#define DATA_LEN 512
byte buf[DATA_LEN];
void clearBuf(int range)
{
for (int i = 0; i < range; i++)
buf[i] = 0;
}
// see pulseIn() code. (hardware/arduino/cores/arduino/wiring_pulse.c)
unsigned long switchIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t stateMask = (state ? bit : 0);
unsigned long width = 0;
unsigned long numloops = 0;
unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
// wait for the signal to start
while ((*portInputRegister(port) & bit) != stateMask)
if (numloops++ == maxloops)
return 0;
// wait for the signal to stop
while ((*portInputRegister(port) & bit) == stateMask) {
if (numloops++ == maxloops)
return 0;
width++;
}
return clockCyclesToMicroseconds(width * 21 + 16);
}
int receiveIR()
{
// IR High Signal -> Pin is LOW (0)
// IR Low Signal -> Pin is HIGH (1)
// wait signal
while (digitalRead(PIN_IR_IN) != 0);
int count = 0;
unsigned long t = 0;
unsigned long tHigh, tLow;
// leader
tHigh = switchIn(PIN_IR_IN, LOW, SIGNAL_TIMEOUT);
tLow = switchIn(PIN_IR_IN, HIGH, SIGNAL_TIMEOUT);
digitalWrite(PIN_LED_OUT, HIGH);
//Serial.println(tHigh);
//Serial.println(tLow);
// calc TimeUnit from leader.
t = (tHigh + tLow) / (SIGNAL_LEADER_HIGH_TIME + SIGNAL_LEADER_LOW_TIME);
t *= 2;
// receive data bits.
for (int i = 0; i < DATA_LEN; i++) {
byte in = 0;
for (int j = 0; j < 8; j++) {
tHigh = switchIn(PIN_IR_IN, LOW, SIGNAL_TIMEOUT);
if (tHigh == 0) goto ERROR_RECEIVE;
tLow = switchIn(PIN_IR_IN, HIGH, SIGNAL_TIMEOUT);
if (tLow == 0) goto END_RECEIVE;
in |= (tLow > t) ? in |= (0x1 << j) : 0;
}
buf[i] = in;
count++;
}
ERROR_RECEIVE:
Serial.println("error");
END_RECEIVE:
Serial.print("T=");
Serial.println(t / 2);
for (int i = 0; i < count; i++) {
Serial.print(buf[i], HEX);
Serial.write(',');
}
Serial.write('\n');
clearBuf(count);
digitalWrite(PIN_LED_OUT, LOW);
}
void setup()
{
Serial.begin(9600);
pinMode(PIN_IR_IN, INPUT);
pinMode(PIN_LED_OUT, OUTPUT);
clearBuf(DATA_LEN);
Serial.print("setup\n");
}
void loop()
{
digitalWrite(PIN_LED_OUT, LOW);
Serial.print("ready\n");
receiveIR();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment