Mousebot
Overview
The Mousebot is our attempt to create a robot that can navigate a maze. It has no name, but we borrow the name of the competition which inspired it originally.
links
http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf
atmega8 datasheet
schematic
code
// *********************************************************** // // Project: Differential Drive Robot with Wheel Encoders // Author: Charles Hart 2007 // // Module description: Control and Testing sans PID functions // // *********************************************************** #define F_CPU 8000000 //Reflects desired system clock in Hz #include <avr/io.h> // Most basic include files #include <avr/interrupt.h> // Add the necessary ones #include <util/delay.h> #define USART_BAUDRATE 9600 #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) /* see atmega datasheet for more info on the preceding definitions */ //Hardware configuration definitions //////////////// #define MOTORPORT PORTD #define MOTOR_A_EN PD4 #define MOTOR_A_DIR PD6 #define MOTOR_B_EN PD5 #define MOTOR_B_DIR PD7 #define WW_A_DIR PB0 #define WW_B_DIR PB1 //Function prototypes //////////////// void set_direction(uint8_t direction); void set_turn(uint8_t angle, uint8_t velocity); //Global Variables //////////////// uint32_t ticks_a = 0; //ticks for motor a uint32_t ticks_b = 0; //ticks for motor b static uint8_t foo; //Interrupts //////////////// ISR(USART_RXC_vect) { char ReceivedByte; //UDR is strange, one address with different values for r/w ReceivedByte = UDR; // Fetch the recieved byte value into the variable "ReceivedByte" UDR = ticks_a; // send the number of encoder ticks back to the computer } ISR(INT0_vect) { ticks_a++; //just count ticks for now } ISR(INT1_vect) { ticks_b++; } ISR(TIMER1_COMPA_vect) { //control speed of wheels //turn off motor A MOTORPORT &= ~(1<<MOTOR_A_EN); } ISR(TIMER1_COMPB_vect) { //control speed of wheels //turn off motor B MOTORPORT &= ~(1<<MOTOR_B_EN); } // the pulse train goes like: // TIMER1_OVF TIMER1_COMP(a/b) TIMER1_COMP(a/b) // \/ \/ \/ //..======---.....======---.....======---... //legend: . no motors = both motors - one motor ISR(TIMER1_OVF_vect) { //go about 15 feet/3071ticks before quitting if(ticks_a < 0xBFF) { //set direction to always be forward MOTORPORT &= ~(1<<MOTOR_A_DIR) & ~(1<<MOTOR_B_DIR); //turn on the motors MOTORPORT |= (1<<MOTOR_A_EN) | (1<<MOTOR_B_EN); } } void set_direction(uint8_t direction) { if(direction) { //forward MOTORPORT &= ~(1<<MOTOR_A_DIR) & ~(1<<MOTOR_B_DIR); } else { //reverse MOTORPORT |= (1<<MOTOR_A_DIR) | (1<<MOTOR_B_DIR); } return; } void set_turn(uint8_t angle, uint8_t velocity) { /*********************************** * 65535 * ^ |.....,,,,, * | | ,. * OCR1X | , . . = left motor * | | , . , = right motor * v | , . * 0 +----------100-- * angle----> ************************************/ //velocity and angle are on 1-100 scale btw if(angle < 50) //turning right (right motor limited/turns off first) { OCR1A = (velocity*angle*2*6.55)+35; OCR1B = (velocity*50*2*6.55)+35; } else //turning left (left motor limited/turns off first) { OCR1A = (velocity*50*2*6.55)+35; OCR1B = (velocity*(100-angle)*2*6.55)+35; } } //Main Program //////////////// int main(void) { //Initialization TCCR0 = (1<<CS02) | (1<<CS00); //Timer clock =system clock /64 TIMSK = 1<<TOIE0; //Enable Timer0 Overflow Interrupt UCSRB |= (1 << RXEN) | (1 << TXEN); // Turn on the tx/rx hardware UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes UBRRL = BAUD_PRESCALE; // Load lower 8-bits of baud rate value into the low byte of the UBRR register UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of baud rate value into the high byte of the UBRR register UCSRB |= (1 << RXCIE); // Enable USART Rx Complete interrupt (USART_RXC) GICR |= (1 << INT0) | (1 << INT1); //enable external interrupts //...rising edge interrupts MCUCR |= (1 << ISC00) | (1 << ISC01) | (1 << ISC10) | (1 << ISC11); //First set up duty cycle via timer1a and b //that means i want the counter to interrupt //at both compare registers, and continue to MAX. //..======---.....======---.....======---... TCCR1A = 0; // Normal timer mode TCCR1B = 1; //timer1 clock = sytem clock TIMSK = (1<<OCIE1A) | (1<<OCIE1B) | (1<<TOIE1); //Enable interrupts for compare 1a, 1b, //and overflow 1. //clobbers/disables timer0 interuppt too DDRD = 0xF0; //Set Port D upper nibble as output //lower nibble as input sei(); //Enable interrupts globally while(1) //infinite looooooooooooooooooop { // set speed //go straight for 1000 ms set_turn(50, 80); _delay_ms(100); set_turn(0,50); _delay_ms(500); set_turn(50,0); _delay_ms(1000); //asm volatile("nop"); //volatile ensures nonoptimization, nop nop } return 0; }
page_revision: 8, last_edited: 1207170161|%e %b %Y, %H:%M %Z (%O ago)





