Arduinoで赤外線受光(RC5)

65 views
Skip to first unread message

hirotaka hatayama

unread,
Mar 11, 2008, 8:34:30 AM3/11/08
to oklab...@googlegroups.com
はたやん

Makeブログより
ArduinoでRC5を受光する

■記事
MAKE: Blog: Infrared remote control receiver for Arduino http://blog.makezine.com/archive/2008/03/infrared_remote_control_r_1.html?CMP=OTC-0D6B48984890

■元記事
5Volt » Blog Archive » Infrared remote control receiver for Arduino
http://www.5volt.eu/archives/14

■ソースコード
http://www.5volt.eu/wp-content/uploads/2007/12/remote_control_receiver.pde

ソースのコピー

--ここから--

// RC5 remote control receiver decoder.
// Tested with Philips or Philips compatible TV remotes.
// Developed by Alessandro Lambardi, 25/12/2007
// Released under Creative Commons license 2.5.
// Non-commercial use, attribution, share alike.
//
// Completely interrupt driven, no 'wait until' loops.
// When a valid code is received it is made available at
// variable data_word (main loop).
// External Arduino clock 16Mhz, hardware prescaler = 1
// Designed for AVR ATtiny24, adapted for Arduino.
//
// Program memory resources used (ATtiny24):
// 670 Program bytes circa out of 2048 (1/3 circa)
// 4 data bytes out of 128
//
// Internal hardware resources used:
// 8Bit Timer 0: reset by software as required
// PORTA B, bit 0 can be relocated together with pin
// change interrupt assignments

#define F_CPU 16000000UL // CPU clock in Hertz.
#define TMR0_PRESCALER 256UL
#define IR_BIT 1778UL // bit duration (us) in use for IR remote (RC5 std)
#define IR_IN 8 //IR receiver is on digital pin 8 (PORT B, bit0)

#define TMR0_T (F_CPU/TMR0_PRESCALER*IR_BIT/1000000UL)
#define TMR0_Tmin (TMR0_T - TMR0_T/4UL) // -25%
#define TMR0_Tmax (TMR0_T + TMR0_T/4UL) // +25%
#if TMR0_Tmax > 255
#error "TMR0_Tmax too big, change TMR0 prescaler value ", (TMR0_Tmax)
#endif

// Variables that are set inside interrupt routines and watched outside
// must be volatile
volatile uint8_t tmr0_OC1A_int; // flag, signals TMR0 timeout (bad !)
volatile uint8_t no_bits; // RC5 bits counter (0..14)
volatile uint16_t ir_data_word; // if <> holds a valid RC5 bits string (good !)

void start_timer0(uint8_t cnt) {
OCR0A = cnt;
TCNT0 = 0;
tmr0_OC1A_int = 0;
TIMSK0 |= _BV(OCIE0A); // enable interrupt on OC0A match
TCCR0B |= _BV(CS02); // start timer0 with prescaler = 256
}

// Interrupt service routines
ISR(PCINT0_vect) { // signal handler for pin change interrupt
if(no_bits == 0) { // hunt for first start bit (must be == 1)
if(!digitalRead(IR_IN)){
start_timer0(TMR0_Tmax);
no_bits++;
ir_data_word = 1;
}
} else {
if(!tmr0_OC1A_int) { // not too much time,
if(TCNT0 > TMR0_Tmin) { // not too little.
// if so wait next (mid bit) interrupt edge
start_timer0(TMR0_Tmax);
no_bits++;
ir_data_word <<= 1;
if(!digitalRead(IR_IN)){
ir_data_word |= 1;
} else {
ir_data_word &= ~1;
}
}
}
}
}

ISR(TIM0_COMPA_vect) { // timer0 OC1A match interrupt handler
TCCR0B &= ~(_BV(CS02) | _BV(CS01) | _BV(CS00)); // stop timer
tmr0_OC1A_int = 1; // signal timeout
no_bits = 0; // start over with hunt for valid stream
ir_data_word = 0;
}

void setup() {

Serial.begin(9600); // opens serial port, sets data rate to 9600 bps

// IR remote control receiver is on IR_IN digital port
pinMode(IR_IN, INPUT);

pinMode(4, OUTPUT); // test output : LED for remote key "1"
pinMode(5, OUTPUT); // test output : LED for remote key "2"
pinMode(6, OUTPUT); // test output : LED for remote key "3"
pinMode(7, OUTPUT); // test output : LED for remote key "4"

// pin change interrupt enable on IR_IN port
PCMSK0 |= _BV(PCINT0);
PCICR |= _BV(PCIE0);

// Timer 0 : Fast PWM mode. Stopped, for now.
TCCR0A = _BV(WGM00) | _BV(WGM01);
TCCR0B = _BV(WGM02);
no_bits = 0;
sei(); // enable interrupts
}

void loop() {

uint8_t data_word; // 0..63 holds a valid RC5 key code.

for(;;) {
if((no_bits == 14) && ((ir_data_word & 0x37C0) == 0x3000)){
no_bits = 0; // prepare for next capture
data_word = ir_data_word & 0x3F; // extract data word

Serial.print(data_word, HEX); // output code to console
Serial.print("\n\r"); // output code to console

switch(data_word) {
case 0x01: // button 1 on most RC5 remotes
// do something
digitalWrite(4,1);
digitalWrite(5,1);
digitalWrite(6,1);
digitalWrite(7,0);
break;
case 0x02: // button 2 on most RC5 remotes
// do something
digitalWrite(4,1);
digitalWrite(5,1);
digitalWrite(6,0);
digitalWrite(7,1);
break;
case 0x03: // button 3 on most RC5 remotes
// do something
digitalWrite(4,1);
digitalWrite(5,0);
digitalWrite(6,1);
digitalWrite(7,1);
break;
case 0x04: // button 4 on most RC5 remotes
// do something
digitalWrite(4,0);
digitalWrite(5,1);
digitalWrite(6,1);
digitalWrite(7,1);
break;
case 0x0C: // button POWER ON/OFF on most RC5 TV remotes
// do something
digitalWrite(4,1);
digitalWrite(5,1);
digitalWrite(6,1);
digitalWrite(7,1);
break;
// etcetera for other codes, some are in the table below
}
}
}
}

/* Typical RC5 codes:
key command bits (system bits = 0)
0 0x00
1 0x01
2 0x02
3 0x03
4 0x04
5 0x05
6 0x06
7 0x07
8 0x08
9 0x09
"right arrow" 0x10
"left arrow" 0x11
"channel shuffle +" 0x20
"channel shuffle +" 0x21
"mute" 0x0D
sleep timer 0x26
vol - 0x11
vol + 0x10
"auto fine tune" 0x3B
default restore 0x0E
power 0x0C
*/

--ここまで--

Reply all
Reply to author
Forward
0 new messages