This shows you the differences between two versions of the page.
|
tutorials:arduino:irremote [2014/02/27 20:51] aaron created |
tutorials:arduino:irremote [2014/02/28 10:14] (current) sam |
||
|---|---|---|---|
| Line 9: | Line 9: | ||
| ===== Abstract ===== | ===== Abstract ===== | ||
| + | How to do this,please refer to [[http://docs.cubieboard.org/tutorials/arduino/controlling_led |light led]] and [[http://docs.cubieboard.org/tutorials/arduino/connecting|how to connect cubieboard and arduino]] | ||
| {{:tutorials:arduino:照片_6_.jpg|400}} | {{:tutorials:arduino:照片_6_.jpg|400}} | ||
| ===== Headline ===== | ===== Headline ===== | ||
| - | ==== Headline ==== | + | ===== Source Code ===== |
| + | <code> | ||
| + | /* | ||
| + | * Test send/receive functions of IRremote, using a pair of Arduinos. | ||
| + | * | ||
| + | * Arduino #1 should have an IR LED connected to the send pin (3). | ||
| + | * Arduino #2 should have an IR detector/demodulator connected to the | ||
| + | * receive pin (11) and a visible LED connected to pin 3. | ||
| + | * | ||
| + | * The cycle: | ||
| + | * Arduino #1 will wait 2 seconds, then run through the tests. | ||
| + | * It repeats this forever. | ||
| + | * Arduino #2 will wait for at least one second of no signal----- | ||
| + | * (to synchronize with #1). It will then wait for the same test | ||
| + | * signals. It will log all the status to the serial port. It will | ||
| + | * also indicate status through the LED, which will flash each time a test | ||
| + | * is completed. If there is an error, it will light up for 5 seconds. | ||
| + | * | ||
| + | * The test passes if the LED flashes 19 times, pauses, and then repeats. | ||
| + | * The test fails if the LED lights for 5 seconds. | ||
| + | * | ||
| + | * The test software automatically decides which board is the sender and which is | ||
| + | * the receiver by looking for an input on the send pin, which will indicate | ||
| + | * the sender. You should hook the serial port to the receiver for debugging. | ||
| + | * | ||
| + | * Copyright 2010 Ken Shirriff | ||
| + | * http://arcfn.com | ||
| + | */ | ||
| + | #include <IRremote.h> | ||
| - | ===== Headline ===== | + | int RECV_PIN = 11; |
| + | int LED_PIN = 3; | ||
| + | |||
| + | IRrecv irrecv(RECV_PIN); | ||
| + | IRsend irsend; | ||
| + | |||
| + | decode_results results; | ||
| + | |||
| + | #define RECEIVER 1 | ||
| + | #define SENDER 2 | ||
| + | #define ERROR 3 | ||
| + | |||
| + | int mode; | ||
| + | |||
| + | void setup() | ||
| + | { | ||
| + | Serial.begin(9600); | ||
| + | // Check RECV_PIN to decide if we're RECEIVER or SENDER | ||
| + | if (digitalRead(RECV_PIN) == HIGH) { | ||
| + | mode = RECEIVER; | ||
| + | irrecv.enableIRIn(); | ||
| + | pinMode(LED_PIN, OUTPUT); | ||
| + | digitalWrite(LED_PIN, LOW); | ||
| + | Serial.println("Receiver mode"); | ||
| + | } | ||
| + | else { | ||
| + | mode = SENDER; | ||
| + | Serial.println("Sender mode"); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Wait for the gap between tests, to synchronize with | ||
| + | // the sender. | ||
| + | // Specifically, wait for a signal followed by a gap of at last gap ms. | ||
| + | void waitForGap(int gap) { | ||
| + | Serial.println("Waiting for gap"); | ||
| + | while (1) { | ||
| + | while (digitalRead(RECV_PIN) == LOW) { | ||
| + | } | ||
| + | unsigned long time = millis(); | ||
| + | while (digitalRead(RECV_PIN) == HIGH) { | ||
| + | if (millis() - time > gap) { | ||
| + | return; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Dumps out the decode_results structure. | ||
| + | // Call this after IRrecv::decode() | ||
| + | void dump(decode_results *results) { | ||
| + | int count = results->rawlen; | ||
| + | if (results->decode_type == UNKNOWN) { | ||
| + | Serial.println("Could not decode message"); | ||
| + | } | ||
| + | else { | ||
| + | if (results->decode_type == NEC) { | ||
| + | Serial.print("Decoded NEC: "); | ||
| + | } | ||
| + | else if (results->decode_type == SONY) { | ||
| + | Serial.print("Decoded SONY: "); | ||
| + | } | ||
| + | else if (results->decode_type == RC5) { | ||
| + | Serial.print("Decoded RC5: "); | ||
| + | } | ||
| + | else if (results->decode_type == RC6) { | ||
| + | Serial.print("Decoded RC6: "); | ||
| + | } | ||
| + | Serial.print(results->value, HEX); | ||
| + | Serial.print(" ("); | ||
| + | Serial.print(results->bits, DEC); | ||
| + | Serial.println(" bits)"); | ||
| + | } | ||
| + | Serial.print("Raw ("); | ||
| + | Serial.print(count, DEC); | ||
| + | Serial.print("): "); | ||
| + | |||
| + | for (int i = 0; i < count; i++) { | ||
| + | if ((i % 2) == 1) { | ||
| + | Serial.print(results->rawbuf[i]*USECPERTICK, DEC); | ||
| + | } | ||
| + | else { | ||
| + | Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); | ||
| + | } | ||
| + | Serial.print(" "); | ||
| + | } | ||
| + | Serial.println(""); | ||
| + | } | ||
| + | |||
| + | |||
| + | // Test send or receive. | ||
| + | // If mode is SENDER, send a code of the specified type, value, and bits | ||
| + | // If mode is RECEIVER, receive a code and verify that it is of the | ||
| + | // specified type, value, and bits. For success, the LED is flashed; | ||
| + | // for failure, the mode is set to ERROR. | ||
| + | // The motivation behind this method is that the sender and the receiver | ||
| + | // can do the same test calls, and the mode variable indicates whether | ||
| + | // to send or receive. | ||
| + | void test(char *label, int type, unsigned long value, int bits) { | ||
| + | if (mode == SENDER) { | ||
| + | Serial.println(label); | ||
| + | if (type == NEC) { | ||
| + | irsend.sendNEC(value, bits); | ||
| + | } | ||
| + | else if (type == SONY) { | ||
| + | irsend.sendSony(value, bits); | ||
| + | } | ||
| + | else if (type == RC5) { | ||
| + | irsend.sendRC5(value, bits); | ||
| + | } | ||
| + | else if (type == RC6) { | ||
| + | irsend.sendRC6(value, bits); | ||
| + | } | ||
| + | else { | ||
| + | Serial.print(label); | ||
| + | Serial.println("Bad type!"); | ||
| + | } | ||
| + | delay(200); | ||
| + | } | ||
| + | else if (mode == RECEIVER) { | ||
| + | irrecv.resume(); // Receive the next value | ||
| + | unsigned long max_time = millis() + 30000; | ||
| + | Serial.print(label); | ||
| + | |||
| + | // Wait for decode or timeout | ||
| + | while (!irrecv.decode(&results)) { | ||
| + | if (millis() > max_time) { | ||
| + | Serial.println("Timeout receiving data"); | ||
| + | mode = ERROR; | ||
| + | return; | ||
| + | } | ||
| + | } | ||
| + | if (type == results.decode_type && value == results.value && bits == results.bits) { | ||
| + | Serial.println (": OK"); | ||
| + | digitalWrite(LED_PIN, HIGH); | ||
| + | delay(20); | ||
| + | digitalWrite(LED_PIN, LOW); | ||
| + | } | ||
| + | else { | ||
| + | Serial.println(": BAD"); | ||
| + | dump(&results); | ||
| + | mode = ERROR; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Test raw send or receive. This is similar to the test method, | ||
| + | // except it send/receives raw data. | ||
| + | void testRaw(char *label, unsigned int *rawbuf, int rawlen) { | ||
| + | if (mode == SENDER) { | ||
| + | Serial.println(label); | ||
| + | irsend.sendRaw(rawbuf, rawlen, 38 /* kHz */); | ||
| + | delay(200); | ||
| + | } | ||
| + | else if (mode == RECEIVER ) { | ||
| + | irrecv.resume(); // Receive the next value | ||
| + | unsigned long max_time = millis() + 30000; | ||
| + | Serial.print(label); | ||
| + | |||
| + | // Wait for decode or timeout | ||
| + | while (!irrecv.decode(&results)) { | ||
| + | if (millis() > max_time) { | ||
| + | Serial.println("Timeout receiving data"); | ||
| + | mode = ERROR; | ||
| + | return; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Received length has extra first element for gap | ||
| + | if (rawlen != results.rawlen - 1) { | ||
| + | Serial.print("Bad raw length "); | ||
| + | Serial.println(results.rawlen, DEC); | ||
| + | mode = ERROR; | ||
| + | return; | ||
| + | } | ||
| + | for (int i = 0; i < rawlen; i++) { | ||
| + | long got = results.rawbuf[i+1] * USECPERTICK; | ||
| + | // Adjust for extra duration of marks | ||
| + | if (i % 2 == 0) { | ||
| + | got -= MARK_EXCESS; | ||
| + | } | ||
| + | else { | ||
| + | got += MARK_EXCESS; | ||
| + | } | ||
| + | // See if close enough, within 25% | ||
| + | if (rawbuf[i] * 1.25 < got || got * 1.25 < rawbuf[i]) { | ||
| + | Serial.println(": BAD"); | ||
| + | dump(&results); | ||
| + | mode = ERROR; | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | Serial.println (": OK"); | ||
| + | digitalWrite(LED_PIN, HIGH); | ||
| + | delay(20); | ||
| + | digitalWrite(LED_PIN, LOW); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // This is the raw data corresponding to NEC 0x12345678 | ||
| + | unsigned int sendbuf[] = { /* NEC format */ | ||
| + | 9000, 4500, | ||
| + | 560, 560, 560, 560, 560, 560, 560, 1690, /* 1 */ | ||
| + | 560, 560, 560, 560, 560, 1690, 560, 560, /* 2 */ | ||
| + | 560, 560, 560, 560, 560, 1690, 560, 1690, /* 3 */ | ||
| + | 560, 560, 560, 1690, 560, 560, 560, 560, /* 4 */ | ||
| + | 560, 560, 560, 1690, 560, 560, 560, 1690, /* 5 */ | ||
| + | 560, 560, 560, 1690, 560, 1690, 560, 560, /* 6 */ | ||
| + | 560, 560, 560, 1690, 560, 1690, 560, 1690, /* 7 */ | ||
| + | 560, 1690, 560, 560, 560, 560, 560, 560, /* 8 */ | ||
| + | 560}; | ||
| + | |||
| + | void loop() { | ||
| + | if (mode == SENDER) { | ||
| + | delay(2000); // Delay for more than gap to give receiver a better chance to sync. | ||
| + | } | ||
| + | else if (mode == RECEIVER) { | ||
| + | waitForGap(1000); | ||
| + | } | ||
| + | else if (mode == ERROR) { | ||
| + | // Light up for 5 seconds for error | ||
| + | digitalWrite(LED_PIN, HIGH); | ||
| + | delay(5000); | ||
| + | digitalWrite(LED_PIN, LOW); | ||
| + | mode = RECEIVER; // Try again | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | // The test suite. | ||
| + | test("SONY1", SONY, 0x123, 12); | ||
| + | test("SONY2", SONY, 0x000, 12); | ||
| + | test("SONY3", SONY, 0xfff, 12); | ||
| + | test("SONY4", SONY, 0x12345, 20); | ||
| + | test("SONY5", SONY, 0x00000, 20); | ||
| + | test("SONY6", SONY, 0xfffff, 20); | ||
| + | test("NEC1", NEC, 0x12345678, 32); | ||
| + | test("NEC2", NEC, 0x00000000, 32); | ||
| + | test("NEC3", NEC, 0xffffffff, 32); | ||
| + | test("NEC4", NEC, REPEAT, 32); | ||
| + | test("RC51", RC5, 0x12345678, 32); | ||
| + | test("RC52", RC5, 0x0, 32); | ||
| + | test("RC53", RC5, 0xffffffff, 32); | ||
| + | test("RC61", RC6, 0x12345678, 32); | ||
| + | test("RC62", RC6, 0x0, 32); | ||
| + | test("RC63", RC6, 0xffffffff, 32); | ||
| + | |||
| + | // Tests of raw sending and receiving. | ||
| + | // First test sending raw and receiving raw. | ||
| + | // Then test sending raw and receiving decoded NEC | ||
| + | // Then test sending NEC and receiving raw | ||
| + | testRaw("RAW1", sendbuf, 67); | ||
| + | if (mode == SENDER) { | ||
| + | testRaw("RAW2", sendbuf, 67); | ||
| + | test("RAW3", NEC, 0x12345678, 32); | ||
| + | } | ||
| + | else { | ||
| + | test("RAW2", NEC, 0x12345678, 32); | ||
| + | testRaw("RAW3", sendbuf, 67); | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| === See Also === | === See Also === | ||