二叔科技 发表于 2015-1-2 17:27:51

【二叔科技】学习红外接收

IRrecv::IRrecv(int recvpin)
{
irparams.recvpin = recvpin;
irparams.blinkflag = 0;
}

// initialization
void IRrecv::enableIRIn() {
cli();
// setup pulse clock timer interrupt
//Prescale /8 (16M/8 = 0.5 microseconds per tick)
// Therefore, the timer interval can range from 0.5 to 128 microseconds
// depending on the reset value (255 to 0)
TIMER_CONFIG_NORMAL();

//Timer2 Overflow Interrupt Enable
TIMER_ENABLE_INTR;

TIMER_RESET;

sei();// enable interrupts

// initialize state machine variables
irparams.rcvstate = STATE_IDLE;
irparams.rawlen = 0;

// set pin modes
pinMode(irparams.recvpin, INPUT);
}

// enable/disable blinking of pin 13 on IR processing
void IRrecv::blink13(int blinkflag)
{
irparams.blinkflag = blinkflag;
if (blinkflag)
    pinMode(BLINKLED, OUTPUT);
}
void IRrecv::resume() {
irparams.rcvstate = STATE_IDLE;
irparams.rawlen = 0;
}

二叔科技 发表于 2015-1-2 17:35:27

// Decodes the received IR message
// Returns 0 if no data ready, 1 if data ready.
// Results of decoding are stored in results
int IRrecv::decode(decode_results *results) {
results->rawbuf = irparams.rawbuf;
results->rawlen = irparams.rawlen;
if (irparams.rcvstate != STATE_STOP) {
    return ERR;
}
#ifdef DEBUG
Serial.println("Attempting NEC decode");
#endif
if (decodeNEC(results)) {
    return DECODED;
}
#ifdef DEBUG
Serial.println("Attempting Sony decode");
#endif
if (decodeSony(results)) {
    return DECODED;
}
#ifdef DEBUG
Serial.println("Attempting Sanyo decode");
#endif
if (decodeSanyo(results)) {
    return DECODED;
}
#ifdef DEBUG
Serial.println("Attempting Mitsubishi decode");
#endif
if (decodeMitsubishi(results)) {
    return DECODED;
}
#ifdef DEBUG
Serial.println("Attempting RC5 decode");
#endif
if (decodeRC5(results)) {
    return DECODED;
}
#ifdef DEBUG
Serial.println("Attempting RC6 decode");
#endif
if (decodeRC6(results)) {
    return DECODED;
}
#ifdef DEBUG
    Serial.println("Attempting Panasonic decode");
#endif
    if (decodePanasonic(results)) {
      return DECODED;
    }
#ifdef DEBUG
    Serial.println("Attempting LG decode");
#endif
    if (decodeLG(results)) {
      return DECODED;
    }
#ifdef DEBUG
    Serial.println("Attempting JVC decode");
#endif
    if (decodeJVC(results)) {
      return DECODED;
    }
#ifdef DEBUG
Serial.println("Attempting SAMSUNG decode");
#endif
if (decodeSAMSUNG(results)) {
    return DECODED;
}
// decodeHash returns a hash on any input.
// Thus, it needs to be last in the list.
// If you add any decodes, add them before this.
if (decodeHash(results)) {
    return DECODED;
}
// Throw away and start over
resume();
return ERR;
}


二叔科技 发表于 2015-1-2 17:36:13

// TIMER2 interrupt code to collect raw data.
// Widths of alternating SPACE, MARK are recorded in rawbuf.
// Recorded in ticks of 50 microseconds.
// rawlen counts the number of entries recorded so far.
// First entry is the SPACE between transmissions.
// As soon as a SPACE gets long, ready is set, state switches to IDLE, timing of SPACE continues.
// As soon as first MARK arrives, gap width is recorded, ready is cleared, and new logging starts
ISR(TIMER_INTR_NAME)
{
TIMER_RESET;

uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin);

irparams.timer++; // One more 50us tick
if (irparams.rawlen >= RAWBUF) {
    // Buffer overflow
    irparams.rcvstate = STATE_STOP;
}
switch(irparams.rcvstate) {
case STATE_IDLE: // In the middle of a gap
    if (irdata == MARK) {
      if (irparams.timer < GAP_TICKS) {
      // Not big enough to be a gap.
      irparams.timer = 0;
      }
      else {
      // gap just ended, record duration and start recording transmission
      irparams.rawlen = 0;
      irparams.rawbuf = irparams.timer;
      irparams.timer = 0;
      irparams.rcvstate = STATE_MARK;
      }
    }
    break;
case STATE_MARK: // timing MARK
    if (irdata == SPACE) {   // MARK ended, record time
      irparams.rawbuf = irparams.timer;
      irparams.timer = 0;
      irparams.rcvstate = STATE_SPACE;
    }
    break;
case STATE_SPACE: // timing SPACE
    if (irdata == MARK) { // SPACE just ended, record it
      irparams.rawbuf = irparams.timer;
      irparams.timer = 0;
      irparams.rcvstate = STATE_MARK;
    }
    else { // SPACE
      if (irparams.timer > GAP_TICKS) {
      // big SPACE, indicates gap between codes
      // Mark current code as ready for processing
      // Switch to STOP
      // Don't reset timer; keep counting space width
      irparams.rcvstate = STATE_STOP;
      }
    }
    break;
case STATE_STOP: // waiting, measuring gap
    if (irdata == MARK) { // reset gap timer
      irparams.timer = 0;
    }
    break;
}

if (irparams.blinkflag) {
    if (irdata == MARK) {
      BLINKLED_ON();// turn pin 13 LED on
    }
    else {
      BLINKLED_OFF();// turn pin 13 LED off
    }
}
}

void IRrecv::resume() {
irparams.rcvstate = STATE_IDLE;
irparams.rawlen = 0;
}
页: [1]
查看完整版本: 【二叔科技】学习红外接收