/** *Turns on LED lights signifying reaching the retrieval area of the course. *The LED light at the Power Button will transition from Green to Red and back repeatedly until the robot is turned off. *The two other LED lights will flash repeatedly until robot is turned off. */ void final_LED_sequence(void) { char power_color = 0; char advance_play_led = 0; char intensity = 255; while(1) { for (power_color; power_color < 255; ++power_color) { if(advance_play_led == 0) { advance_play_led = 1; } else { advance_play_led = 0; } oi_set_leds(advance_play_led, advance_play_led, power_color, intensity); wait_ms(10); } for (power_color; power_color > 0; --power_color) { if(advance_play_led == 0) { advance_play_led = 1; } else { advance_play_led = 0; } oi_set_leds(advance_play_led, advance_play_led, power_color, intensity); wait_ms(10); } } }
/// Initialize the Create void oi_init(oi_t *self) { lcd_clear(); lcd_puts("Starting OI..."); // Setup USART1 to communicate to the iRobot Create using serial (baud = 57600) UBRR1L = 16; // UBRR = (FOSC/16/BAUD-1); UCSR1B = (1 << RXEN) | (1 << TXEN); UCSR1C = (3 << UCSZ10); // Starts the SCI. Must be sent first oi_byte_tx(OI_OPCODE_START); oi_byte_tx(OI_OPCODE_BAUD); oi_byte_tx(8); // baud code for 28800 wait_ms(100); // Set the baud rate on the Cerebot II to match the Create's baud UBRR1L = 33; // UBRR = (FOSC/16/BAUD-1); // Use Full mode, unrestricted control oi_byte_tx(OI_OPCODE_FULL); oi_set_leds(1, 1, 7, 255); oi_update(self); oi_update(self); // call twice to clear distance/angle lcd_clear(); }
int main(void) { usart0_init(25, 8, 1, USART_PARITY_EVEN,1); //38400 usart1_init(25, 8, 1, USART_PARITY_DISABLED,0); //TODO check oi_alternative OI_ALTERNATE_BAUD_RATE _delay_ms(333); oi_switch_baud_rate(); _delay_ms(333); oi_init(); oi_full_mode(); int i; int val; for (i = 0; i < 10; i++) { val = i % 2; oi_set_leds(val, val, val, val, 0xFF * val, 0xFF); _delay_ms(50); } oi_init(); //input_capture_test(); printf0("Hello world!\r\n"); printf0(" 0x%02X 0x%02X 0x%02X", UCSR0A, UCSR0B, UCSR0C); _delay_ms(3000); doSweepLoop(); doPingLoop(); doIrLoop(); servo_test(); }
//Handler for OI, moved from control. void oi_system() { movement_data_t movement_data; rotation_data_t rotation_data; enum { oi_command_init = 0, oi_command_move = 1, oi_command_rotate = 2, oi_command_play_song = 3, oi_command_dump = 4, oi_command_end_sequence = 5 } oi_command = usart_rx(); txq_enqueue(oi_command); switch (oi_command) { case oi_command_init: oi_init(&(control.oi_state)); break; case oi_command_move: if(rx_frame()) { r_error(error_frame,"Move should not have multiple frames."); } struct { uint16_t speed; uint16_t dist; bool stream; } *move_data = (void *) &control.data; struct { uint16_t dist; uint8_t flag; } *response_move = (void *) &control.data; #warning "Stream functionality to be implemented later." //Stream returns the distance traveled //lcd_puts ("In OI subsystem"); //debug movement_data = move_dist(&(control.oi_state), move_data->dist, move_data->speed); response_move->dist = movement_data.travelled; response_move->flag = movement_data.flag; if (movement_data.flag != 0) { movement_data = move_dist(&(control.oi_state), -20, move_data->speed); response_move->dist += movement_data.travelled; } control.data_len = 3; tx_frame(false); break; case oi_command_rotate: if (rx_frame()) { r_error(error_bad_message, "Rotate should only have one data frame."); } int16_t *angle = &(control.data[0]); // TODO: test if this is the right number of bytes if (control.data_len != 2/*sizeof(*angle)*/) { // TODO: hardcoding to debug r_error(error_bad_message, "Received too much data with rotate " "message."); } struct { uint16_t rotation; } *response_rotation = (void *) &control.data; rotation_data = turn(&(control.oi_state), *angle); response_rotation->rotation = rotation_data.rotated; control.data_len = 2; tx_frame(false); break; //Sing me a song. case oi_command_play_song: #warning "oi_command_play_song is deprecated" ; //assuming that we get two data frames, the first containing the notes and the second containing the durations. int j; struct { uint8_t n; //The number of notes present in the song //char data[n]; uint8_t index; } *song_data = (void *) &control.data; // int j; while(rx_frame()) { //this should happen twice please char tmp_notes[song_data->n]; char tmp_durs[song_data->n]; for(j =0; j<song_data->n; j++) { //tmp_notes[n]; TODO: broken #warning "oi_command_play_song not implemented" } } break; case oi_command_dump: //copies all of the data from OI_UPDATE and transmits to Control. oi_update(&(control.oi_state)); memcpy(control.data, &control.oi_state, sizeof(control.oi_state)); control.data_len = sizeof(control.oi_state); tx_frame(false); break; case oi_command_end_sequence: #warning "oi_command_end_sequence not implemented" // Switch power LED off oi_set_leds(1, 1, 0, 0); wait_ms(50); // Switch power LED to orange oi_set_leds(1, 1, 170, 255); wait_ms(50); // Switch power LED off oi_set_leds(1, 1, 0, 0); wait_ms(50); // Switch power LED to yellow oi_set_leds(1, 1, 70, 255); wait_ms(50); // Switch power LED off oi_set_leds(1, 1, 0, 0); wait_ms(50); // Switch power LED back to default state (from oi_init()) oi_set_leds(1, 1, 7, 255); // Play song songs_load(RICK_ROLL); break; default: r_error(error_bad_message, "Bad OI Command"); break; } }
/** *Turns on LEDs to show that start command has been given and the robot has not completed the course *Power LED will be (NOT SURE), all other LEDs will be off */ void running_LED(void) { oi_set_leds(0,0,0,255); }
/** *Turns on LEDs to show that it is in waiting for the start command to be transmitted *Power LED will be red, all other LEDs will be off */ void initial_LED(void) { oi_set_leds(255, 255, 255, 255); }