#define LED_PIN 13 #define INPUT_PIN 2 #define OUTPUT_PIN 5 #define VERSION "101" #define RING_SIZE 64 static char ring[RING_SIZE]; void setup() { Serial.begin(9600); Serial.print("hello---"); pinMode(LED_PIN, OUTPUT); pinMode(OUTPUT_PIN, OUTPUT); pinMode(INPUT_PIN, INPUT); digitalWrite(LED_PIN, HIGH); unsigned i; for (i = 0; i < RING_SIZE; i++) { ring[i] = 3; } } static unsigned long await_timer = 0; static unsigned long await_start = 0; static void await(unsigned us) { int ok = 0; await_timer += us; while((micros() - await_start) < await_timer) {} } static void send_high(void) { digitalWrite(OUTPUT_PIN, HIGH); await(220); digitalWrite(OUTPUT_PIN, LOW); } static void send_zero(void) { send_high(); await(1330); } static void send_one(void) { send_high(); await(320); } static unsigned char wait_read(void) { while(!Serial.available()) {} return Serial.read(); } static unsigned char synth_high[256]; static unsigned char synth_low[256]; static void synthesiser(void) { unsigned char size = wait_read(); unsigned char multiplier = wait_read(); unsigned char repeat = wait_read(); unsigned i, j; for (i = 0; i < (unsigned) size; i++) { synth_high[i] = wait_read(); synth_low[i] = wait_read(); } Serial.write('S'); await_timer = 0; await_start = micros(); for (i = 0; i < (unsigned) repeat; i++) { for (j = 0; j < (unsigned) size; j++) { unsigned x; digitalWrite(OUTPUT_PIN, HIGH); x = (unsigned) synth_high[j]; x *= (unsigned) multiplier; await(x); digitalWrite(OUTPUT_PIN, LOW); x = (unsigned) synth_low[j]; x *= (unsigned) multiplier; await(x); } } } static void transmit_code(unsigned long tx_code) { unsigned char i, j; await_timer = 0; await_start = micros(); for (i = 0; i < 10; i++) { send_high(); // Start code await(2700); j = 32; while (j > 0) { j -= 2; unsigned long bits = (tx_code >> (unsigned long) j) & 3; if (bits == 0) { send_one(); send_zero(); send_one(); send_zero(); } else if (bits == 1) { send_one(); send_zero(); send_zero(); send_one(); } else if (bits == 2) { send_zero(); send_one(); send_one(); send_zero(); } else { send_zero(); send_one(); send_zero(); send_one(); } } send_high(); // End code await(10270); // Gap } } static void input(void) { unsigned char ch = Serial.read(); unsigned char i; switch (ch) { case 'T': // Transmit a code (4 bytes) unsigned long tx_code; tx_code = 0; for (i = 0; i < 4; i++) { tx_code = tx_code << 8; tx_code |= wait_read(); } Serial.write('T'); transmit_code(tx_code); return; case 'S': synthesiser(); return; case 'V': Serial.print("V" VERSION); return; case 'L': digitalWrite(LED_PIN, HIGH); Serial.write(ch); return; case 'l': digitalWrite(LED_PIN, LOW); Serial.write(ch); return; default: if ((ch >= '0') && (ch <= '6')) { unsigned val = analogRead(ch - '0'); Serial.write(ch); Serial.write(val >> 8); Serial.write(val); return; } break; } Serial.write('?'); } void loop() { unsigned char wr_ptr = 0; unsigned char rd_ptr = 0; unsigned char i = 0; unsigned char invalid_pulses = 0; unsigned long start = 0; unsigned long stop = 0; unsigned long previous_code = 0; while(1) { // Wait until we reach the low time while (digitalRead(INPUT_PIN) == HIGH) {} // Process previous low time unsigned long low_time = stop - start; start = micros(); unsigned long high_time = start - stop; unsigned char enter = ring[wr_ptr]; if (high_time > 400) { ring[wr_ptr] = 3; } else if (low_time < 900) { ring[wr_ptr] = 1; } else if (low_time < 2200) { ring[wr_ptr] = 0; } else { ring[wr_ptr] = 7; invalid_pulses ++; if (invalid_pulses > 100) { previous_code = 0; } } wr_ptr = (wr_ptr + 1) & (RING_SIZE - 1); // scan for valid codes rd_ptr = wr_ptr; unsigned long shifter = 0; for (i = 0; i < RING_SIZE; i += 4) { char a = ring[rd_ptr]; rd_ptr = (rd_ptr + 1) & (RING_SIZE - 1); char b = ring[rd_ptr]; rd_ptr = (rd_ptr + 1) & (RING_SIZE - 1); char c = ring[rd_ptr]; rd_ptr = (rd_ptr + 1) & (RING_SIZE - 1); char d = ring[rd_ptr]; rd_ptr = (rd_ptr + 1) & (RING_SIZE - 1); unsigned char bits = 0; if ((a | b | c | d) & 2) { // code block is invalid break; } else if (a & c & (~b) & (~d) & 1) { // 0xa bits = 0; } else if (a & (~b) & (~c) & d & 1) { // 0x9 bits = 1; } else if ((~a) & b & c & (~d) & 1) { // 0x6 bits = 2; } else if ((~a) & b & (~c) & d & 1) { // 0x5 bits = 3; } else { // code block is invalid break; } shifter = (shifter << 2) | bits; } // in the event of a valid code, print out if ((i >= RING_SIZE) && ((shifter >> 28) == 0) && (enter == 7) && (shifter != 0)) { if (shifter == previous_code) { Serial.write('r'); } else { Serial.write('R'); Serial.write(shifter >> 24); Serial.write(shifter >> 16); Serial.write(shifter >> 8); Serial.write(shifter); previous_code = shifter; } invalid_pulses = 0; } // Wait until we reach the high time while (digitalRead(INPUT_PIN) == LOW) { if (Serial.available()) { input(); } } stop = micros(); } }