#include #include #include #include /* 500Hz -> 2ms */ #define MAXPULSFREQ 500 /* timer1 value for a 2ms puls */ #define TIMER_MAXPULS F_CPU/MAXPULSFREQ /* min/max values */ #define MINPULS 13500 #define MAXPULS 30000 /* baud rate for serial communication */ #define BAUD 9600UL /* hardware settings for baud rate */ #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) /* compile time check if baud rate is ok */ #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010)) #error systematic error of baud rate is > 1% #endif static uint16_t servo_pulslength[20]; static uint8_t activated = 0; /* init IO pins */ static inline void init_io() { /* PB1 = left:red, PB2 = left:green, PB3 = left:blue */ DDRB = (1 << PB1) | (1 << PB2) | (1 << PB3); /* PD3 = right:red, PD5 = right:green, PD6 = right:blue */ DDRD = (1 << PD3) | (1 << PD5) | (1 << PD6); /* These pins are broken, so enable them */ DDRC = (1 << PC4) | (1 << PC5) | (1 << PC6); PORTC = (1 << PC4) | (1 << PC5) | (1 << PC6); } /* INTERRUPT: timer for software pwm to control servos */ ISR(TIMER1_OVF_vect) { static uint8_t servo_indexhalf = 0; switch(servo_indexhalf) { case 0 : PORTB |= (1 << PB1); break; case 1 : PORTB &= ~(1 << PB1); break; case 2 : PORTB |= (1 << PB2); break; case 3 : PORTB &= ~(1 << PB2); break; case 4 : PORTB |= (1 << PB3); break; case 5 : PORTB &= ~(1 << PB3); break; case 6 : PORTD |= (1 << PD3); break; case 7 : PORTD &= ~(1 << PD3); break; case 8 : PORTD |= (1 << PD5); break; case 9 : PORTD &= ~(1 << PD5); break; case 10: PORTD |= (1 << PD6); break; case 11: PORTD &= ~(1 << PD6); break; } /* set time for the next interrupt */ TCNT1 = servo_pulslength[servo_indexhalf]; servo_indexhalf++; if(servo_indexhalf == 20) servo_indexhalf = 0; } /* setup serial communication */ static inline void init_uart() { UBRR0 = UBRR_VAL; UCSR0B |= (1 << TXEN0); UCSR0B |= (1 << RXEN0); /* Frame Format: Asynchron 8N1 */ UCSR0C = (1<= 0x01 && c <= 0x06) { uint8_t speed = uart_getc(); servo_set(c-1, speed); /* set speed for all engines */ } else if(c == 0xFF) { uint8_t speed = uart_getc(); for(int i=0;i<6;i++) servo_set(i, speed); /* activate engines */ } else if(c == 0xCA) { if(uart_getc() != 0xFE) continue; if(uart_getc() != 0xBA) continue; if(uart_getc() != 0xBE) continue; activated=1; /* disable engines */ } else if(c == 0xDE) { if(uart_getc() != 0xAD) continue; if(uart_getc() != 0xBA) continue; if(uart_getc() != 0xBE) continue; activated=0; for(int i=0;i<6;i++) servo_set(i, 0); /* ignore unknown commands */ } else if(c != 0x00) { continue; } /* acknowledge command */ uart_putc('.'); } return 0; }