Ok, first of all, i'm verry new to any programming language (i'm only 16 years old...)(plc's are no problem for me...)
I have been experimenting a little with my arduino.
My goal is to use a universal tv remote (from Phillips) to control 2 servos, and a flashing led at the same time
the code below (without flashing leds and servo) works, but when i modify it, i make a mess of it and it won't work like i want it to =(
what i want:
press button one on the remote ( hex code 0x00 ) to let the led (pin 13) flash on and off
press button 4 to set the servo to 0 degrees, button 5 for 90 degrees, button 6 for 180 degrees
(not really really necessary:) press button 7 to set the servo to 0 degrees, button 8 for 90 degrees, button 9 for 180 degrees
(the website of the original code: http://www.5volt.eu/archives/14)
original code: http://www.5volt.eu/wp-content/uploads/2007/12/remote_control_receiver.pde
my messed up code: (everything with " //-------------- " is my failed modification)
// my modified messed up non-working code:
#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
#include <Servo.h> //--------------------------------
Servo myservo; //--------------------------------
int degrees = 0; //--------------------------------
// 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() {
myservo.attach(9); //--------------------------------------------
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(13, OUTPUT); //-------------------
// 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
digitalWrite(13,1); //- I WANT PIN 13 TO BLINK!!!----------------------!!!
break;
case 0x04:
degrees = 1; //-------------------------------------
myservo.write(degrees); //-------------------------------------
break;
case 0x05:
degrees = 90; //-------------------------------------
myservo.write(degrees); //-------------------------------------
break;
case 0x06:
degrees = 180; //-------------------------------------
myservo.write(degrees); //-------------------------------------
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
*/