/*
RI Codes:
TAPE = 42157
DVD = 31612
CD = 71327
PORT = 81993
CDR = 71322
MD = 71808
*/
#include "signals.h"
//#include <SoftwareSerial.h>
// Digital pin #2 is the same as Pin D2 see
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
#define IRread_PIN PINB
#define IRread 1
#define ARRAY_LEN(array) (sizeof(array)/sizeof((array)[0]))
#define MAXPULSE 500
#define RESOLUTION 20
#define FUZZINESS 50
uint8_t raw[2];
uint64_t listenForIR(ir_t *proto);
int getPulseLength();
int getPulseLengthInRange(int expected);
//SoftwareSerial wdlive_serial(11, 12);
void sendToggle(int pin, int delayTime[]) {
digitalWrite(pin, LOW);
delayMicroseconds(delayTime[0] * 10);
digitalWrite(pin, HIGH);
delayMicroseconds(delayTime[1] * 10);
}
void send(ir_t *proto, uint64_t value, int pin, bool inverted) {
bool low = inverted;
int i;
uint8_t bit;
for (i = 0; i < ARRAY_LEN(proto->header); i++) {
digitalWrite(pin, low ? LOW : HIGH);
delayMicroseconds(proto->header[i] * 10);
low = !low;
}
for (i = proto->prebits - 1; i >= 0; i--) {
bit = (proto->pre >> i) & 1;
sendToggle(pin, proto->values[bit]);
}
for (i = proto->bits - 1; i >= 0; i--) {
bit = (value >> i) & 1;
sendToggle(pin, proto->values[bit]);
}
for (i = 0; i < ARRAY_LEN(proto->trail); i++) {
digitalWrite(pin, low ? LOW : HIGH);
delayMicroseconds(proto->trail[i] * 10);
low = !low;
}
digitalWrite(pin, low ? LOW : HIGH);
}
void setup(void) {
Serial.begin(9600);
Serial.println("Ready to decode IR!");
// wdlive_serial.begin(115200);
// wdlive_serial.println("irinject down");
pinMode(8, OUTPUT);
digitalWrite(8, HIGH);
}
void findKey(ir_map_t *ir_map, uint8_t count, uint64_t code) {
uint8_t i;
for (i = 0; i < count; i++) {
if (ir_map[i].from == code) {
send(&pioneer, ir_map[i].to, 8, true);
return;
}
}
}
void loop(void) {
uint64_t code = listenForIR(&onkyo);
Serial.println((long unsigned int)code, HEX);
findKey(ir_map, ARRAY_LEN(ir_map), code);
}
int getPulseLength() {
bool high = IRread_PIN & (1 << IRread);
bool check = true;
int length = 0;
while (check) {
length++;
delayMicroseconds(RESOLUTION);
if (length >= MAXPULSE) {
return -1;
}
check = IRread_PIN & (1 << IRread);
if (! high) {
check = ! check;
}
}
return length * RESOLUTION / 10;
}
bool inRange(int value, int expected) {
return (abs(value - expected) <= FUZZINESS);
}
int getPulseLengthInRange(int expected) {
int length = getPulseLength();
if (length <= 0 || !inRange(length, expected)) {
return 0;
}
return length;
}
uint64_t listenForIR(ir_t *proto) {
int length;
uint64_t code;
uint8_t i, j, k;
bool found;
start:
code = 0;
for (i = 0; i < ARRAY_LEN(proto->header); i++) {
length = getPulseLengthInRange(proto->header[i]);
if (length <= 0)
goto start;
}
for (j = 0; j < proto->bits; j++) {
for (i = 0; i < ARRAY_LEN(raw); i++) {
raw[i] = getPulseLength();
if (raw[i] <= 0)
goto start;
}
for (k = 0; k < ARRAY_LEN(proto->values); k++) {
found = true;
for (i = 0; i < ARRAY_LEN(raw); i++) {
if (!inRange(raw[i], proto->values[k][i])) {
found = false;
break;
}
}
if (found) {
code <<= 1;
code += k;
break;
}
}
if (!found) {
Serial.println(raw[0]);
Serial.println(raw[1]);
goto start;
}
}
for (i = 0; i < ARRAY_LEN(proto->trail); i++) {
length = getPulseLengthInRange(proto->trail[i]);
if (length <= 0)
goto start;
}
return code;
}