User Tools

Site Tools


tutorials:arduino:irremote

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

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 ===
tutorials/arduino/irremote.1393505510.txt.gz · Last modified: 2014/02/27 20:51 by aaron