static void jump_to_app(void) { const uint32_t *app_base = (const uint32_t *)APP_LOAD_ADDRESS; // Check that flash has been programmed if (app_base[0] == 0xffffffff) goto fail; // Check that reset vector is somewhere in the app's boundaries if (app_base[1] < APP_LOAD_ADDRESS) goto fail; if (app_base[1] >= (APP_LOAD_ADDRESS + (1024 * 1024))) goto fail; // LEDs to known state green_led(1); red_led(0); // Set vector table address SCB->VTOR = APP_LOAD_ADDRESS; // Jump to the application do_jump(app_base[0], app_base[1]); // LEDs indicate error fail: green_led(0); red_led(0); for(;;); }
int main(void) { led_setup(); for(int i = 0; i < 4; i++) { red_led(1); green_led(1); sleep(500); red_led(0); green_led(0); sleep(500); red_led(1); sleep(500); red_led(0); sleep(500); } jump_to_app(); }
void pot_test() { long start = get_ms(); char elapsed_ms; int value; set_analog_mode(MODE_10_BIT); print_long(read_trimpot()); print(" "); // to clear the display while((elapsed_ms = get_ms() - start) < 100) { value = read_trimpot(); play_frequency(value, 200, 15); if(value < elapsed_ms*10) { red_led(0); green_led(1); } else { red_led(1); green_led(0); } } }
int main() // run over and over again { while(1) { // note that the following line could also be accomplished with: // int pot = analogRead(7); int pot = read_trimpot(); // determine the trimpot position // avoid clearing the LCD to reduce flicker lcd_goto_xy(0, 0); print("pot="); print_long(pot); // print the trim pot position (0 - 1023) print(" "); // overwrite any left over digits int motorSpeed = (512 - pot) / 2; lcd_goto_xy(0, 1); print("spd="); print_long(motorSpeed); // print the resulting motor speed (-255 - 255) print(" "); set_motors(motorSpeed, motorSpeed); // set speeds of motors 1 and 2 // all LEDs off red_led(0); green_led(0); // turn green LED on when motors are spinning forward if (motorSpeed > 0) green_led(1); // turn red LED on when motors are spinning in reverse if (motorSpeed < 0) red_led(1); delay_ms(100); } }
void led_pololu() { while (1) { green_led(0); delay(1000); green_led(1); delay(1000); } }
// Blinks the LEDs void led_test() { play("c32"); print("Red 1 "); red_led(1); if(wait_for_250_ms_or_button_b()) return; red_led(0); if(wait_for_250_ms_or_button_b()) return; play(">c32"); lcd_goto_xy(0,0); print("Green 1 "); green_led(1); if(wait_for_250_ms_or_button_b()) return; green_led(0); if(wait_for_250_ms_or_button_b()) return; play("d32"); lcd_goto_xy(0,0); print("Red 2 "); red_led2(1); if(wait_for_250_ms_or_button_b()) return; red_led2(0); if(wait_for_250_ms_or_button_b()) return; play(">d32"); lcd_goto_xy(0,0); print("Green 2 "); green_led2(1); if(wait_for_250_ms_or_button_b()) return; green_led2(0); if(wait_for_250_ms_or_button_b()) return; play("e32>e32"); lcd_goto_xy(0,0); print("Yellow "); yellow_led(1); if(wait_for_250_ms_or_button_b()) return; yellow_led(0); if(wait_for_250_ms_or_button_b()) return; }
// *** triggered by middle button *** // This function tests the motors by first ramping motor1 speed from zero // to full speed "forward", to full speed "reverse", and finally back to zero. // It then does the same for motor2 before repeating all over again. // While motor1 is running, the red user LED is on, otherwise it is off. // While the currently active motor is moving "forward", the green user LED // is on, otherwise it is off. The LCD gives you feedback as to which motor // is currently moving in which direction (F = "forward", R = "reverse", and // - = inactive). unsigned char motorTest() { unsigned char button; int speed; unsigned char motor = 0; clear(); // clear the LCD, go to the start of the first LCD line print("motor2"); // print to the first line of the LCD lcd_goto_xy(0, 1); // go to the start of the second LCD line print("motor1"); // print to the second line of the LCD while (1) { red_led(!motor); // turn red LED on when m1 is active, off for m2 lcd_goto_xy(7, !motor); // go to end of LCD line for active motor print("F"); // print "F" for "forward" lcd_goto_xy(7, motor); // go to end of LCD line for inactive motor print("-"); // print "-" for "inactive" green_led(1); // turn green LED on when motor is moving "forward" for (speed = 0; speed < 255; speed++) { button = motorUpdate(motor, speed); // ramp up motor speed if (button != 0) // from 0 to 255 return button; } for (speed = 255; speed > -255; speed--) { if (speed == -1) // motor starts moving in "reverse" { green_led(0); // green LED off when motor going "reverse" lcd_goto_xy(7, !motor); // go to end of active motor's LCD line print("R"); // print "R" for "reverse" } button = motorUpdate(motor, speed); // ramp down motor speed if (button != 0) // from 255 to -255 return button; } for (speed = -255; speed <= 0; speed++) { button = motorUpdate(motor, speed); // ramp up motor speed if (button != 0) // from -255 to 0 return button; } motor = !motor; // alternate between m1 and m2 } }
int main() { while(1) { red_led(1); // red LED on delay_ms(1000); // waits for a second red_led(0); // red LED off delay_ms(1000); // waits for a second green_led(1); // green LED on (will not work on the Baby Orangutan) delay_ms(500); // waits for 0.5 seconds green_led(0); // green LED off (will not work on the Baby Orangutan) delay_ms(500); // waits for 0.5 seconds } }
// This is the main function, where the code starts. All C programs // must have a main() function defined somewhere. int main() { // Set all five user LEDs as outputs driven low. // Otherwise, the LEDs are driven by the LCD and can appear // on or partially on. red_led(0); green_led(0); red_led2(0); green_led2(0); yellow_led(0); clear(); delay(10); // if any button is pressed, go into the old version of the test code if(button_is_pressed(ANY_BUTTON)) { print("Simple Test"); wait_for_button_release(button_is_pressed(ANY_BUTTON)); test(); // activate the simpler test code } // set up the robot initialize(); // This is the "main loop" - it will run forever. while(1) { menu_select(); } }
const char *getmfgstr(int speed, long *len){ //This will be turned off by another thread, //but when we call it often the light becomes visible. green_led(1); //Hook the USB DNLOAD handler. hookusb(); static long adr=0; long val; char *usbstring=(char*) 0x2001c080; //2.032 char buffer[]="@________ : ________"; //Read four bytes from SPI Flash. spiflash_read(&val,adr,4); //Print them into the manufacturer string. strhex(buffer+1, adr); strhex(buffer+12, val); //Look forward a bit. adr+=4; //Return the string as our value. return loadusbstr(usbstring,buffer,len); }
/* La melodie qui sera jouée lorsque le robot atteindra l'objectif */ void melodie() { set_motors(0,0); green_led(0); green_led(1); play("! O5 L16 agafaea dac+adaea fa<aa<bac#a dac#adaea f" "O6 dcd<b-d<ad<g d<f+d<gd<ad<b- d<dd<ed<f+d<g d<f+d<gd<ad" "L8 MS <b-d<b-d MLe-<ge-<g MSc<ac<a ML d<fd<f O5 MS b-gb-g" "ML >c#e>c#e MS afaf ML gc#gc# MS fdfd ML e<b-e<b-" "O6 L16ragafaea dac#adaea fa<aa<bac#a dac#adaea faeadaca" "<b-acadg<b-g egdgcg<b-g <ag<b-gcf<af dfcf<b-f<af" "<gf<af<b-e<ge c#e<b-e<ae<ge <fe<ge<ad<fd" "O5 e>ee>ef>df>d b->c#b->c#a>df>d e>ee>ef>df>d" "e>d>c#>db>d>c#b >c#agaegfe f O6 dc#dfdc#<b c#4"); delay_ms(1000); }
static void panic(void) { led_setup(); green_led(0); for(;;){ red_led(1); spin_sleep(200); red_led(0); spin_sleep(200); } }
int main() { print("Hello!"); play("L16 ceg>c"); while(1) { red_led(0); green_led(1); delay_ms(100); red_led(1); green_led(0); delay_ms(100); } return 0; }
void test_leds() { while(!button_is_pressed(ALL_BUTTONS)) { clear(); printf("Check\n"); printf("Red"); red_led(1); play_frequency(440,50,15); delay_ms(250); if(button_is_pressed(ALL_BUTTONS)) break; red_led(0); delay_ms(250); if(button_is_pressed(ALL_BUTTONS)) break; clear(); printf("Check\n"); printf("Green"); green_led(1); play_frequency(880,50,15); delay_ms(250); if(button_is_pressed(ALL_BUTTONS)) break; green_led(0); delay_ms(250); } while(button_is_pressed(ALL_BUTTONS)); delay_ms(100); }
// Blinks the LEDs void led_test() { play("c32"); print("Red "); red_led(1); if(wait_for_250_ms_or_button_b()) return; red_led(0); if(wait_for_250_ms_or_button_b()) return; play(">c32"); lcd_goto_xy(0,0); print("Green"); green_led(1); if(wait_for_250_ms_or_button_b()) return; green_led(0); if(wait_for_250_ms_or_button_b()) return; }
void servo() { clear(); const unsigned char demuxPins[] = { }; servos_start(demuxPins, sizeof(demuxPins)); set_servo_target(0, 1300); set_servo_speed(0, 0); while (1) { if (button_is_pressed(TOP_BUTTON)) { red_led(1); green_led(0); clear(); print("Moving Left..."); set_servo_target(0, 0); _delay_ms(400); set_servo_target(0, 200); } if (button_is_pressed(BOTTOM_BUTTON)) { red_led(0); green_led(1); clear(); print("Moving Right..."); set_servo_target(0, 0); _delay_ms(400); set_servo_target(0, 1800); } } }
// process_received_byte: Responds to a byte that has been received on // USB_COMM. If you are writing your own serial program, you can // replace all the code in this function with your own custom behaviors. void process_received_byte(char byte) { clear(); // clear LCD print("RX: "); print_character(byte); lcd_goto_xy(0, 1); // go to start of second LCD row switch(byte) { // If the character 'G' or 'g' is received, toggle the green LED. case 'G': case 'g': green_led(TOGGLE); print("green LED"); break; // If the character 'R' or 'r' is received, toggle the red LED. case 'R': case 'r': red_led(TOGGLE); print("red LED"); break; // If the character 'C' or 'c' is received, play the note C. case 'C': case 'c': play_from_program_space(PSTR("c16")); print("play note C"); break; // If the character 'D' or 'd' is received, play the note D. case 'D': case 'd': play_from_program_space(PSTR("d16")); print("play note D"); break; // If any other character is received, change its capitalization and // send it back. default: wait_for_sending_to_finish(); send_buffer[0] = byte ^ 0x20; serial_send(USB_COMM, send_buffer, 1); print("TX: "); print_character(send_buffer[0]); break; } }
int main() { // Set mode to CTC // WGM2 = 0 // WGM1 = 1 // WGM0 = 0 TCCR0A &= ~(0 << WGM00); TCCR0A |= (1 << WGM01); TCCR0B &= ~(0 << WGM02); //Set the scaler to 256 // CS00 = 0 // CS01 = 0 // CS02 = 1 TCCR0B &= ~(0 << CS00); TCCR0B &= ~(0 << CS01); TCCR0B |= (1 << CS02); //Set the top OCR0A = 78; // Turn on global interupts sei(); // Turn on interupt for TIMSK0 |= (1 << OCIE0A); clear(); while(1) { //lcd_goto_xy(0,0); //print_long(msTicks); if(redReleased) { redOn ^= 1; red_led(redOn); green_led(!redOn); redReleased = 0; } } return 0; }
int main() { Led red_led(LED1, ON); Led green_led(LED2, OFF); Switch button(S2); while (1) { while (!button.is_pressed()) ; red_led.toggle(); green_led.toggle(); while (button.is_pressed()) ; } }
// This function comprises the main part of the motor speed update loop. // If a button press is detected, both the red and green user LEDs are // turned off, as are the motor outputs. This function also includes // a brief delay that ensures the entire loop takes the desired amount // of time. unsigned char motorUpdate(unsigned char motor, int speed) { unsigned char button; if (motor == 0) // set the desired motor to the desired speed set_m1_speed(speed); else set_m2_speed(speed); delay_ms(2); // delay here for 2 milliseconds // check if top or bottom buttons have been pressed button = button_is_pressed(TOP_BUTTON | MIDDLE_BUTTON); if (button != 0) // if so, turn off motors and LEDs, return button ID { red_led(0); green_led(0); set_motors(0, 0); } return button; }
// *** triggered by top button *** // This function plays a melody from flash in the background while the two // user LEDs alternately fade in and out. unsigned char melodyTest() { unsigned char button; int i = 0; // the following function does not block execution play_from_program_space(fugue); // play music from flash in the background red_led(0); // turn red and green LEDs off green_led(0); clear(); // clear the LCD, go to the start of the first LCD line print("melody:"); // print to the LCD lcd_goto_xy(0, 1); // go to the start of the second LCD line print("fugue"); // print to the LCD time_reset(); // reset the internal millisecond timer count to zero while (1) // loop here until we detect a button press and return { if (get_ms() >= 5) // if 5 or more milliseconds have elapsed { time_reset(); // reset timer count to zero // check if middle or bottom buttons have been pressed button = button_is_pressed(MIDDLE_BUTTON | BOTTOM_BUTTON); if (button != 0) // if so, stop melody and return the button ID { stop_playing(); // stop playing music return button; } i += 5; // increase our state variable based on the time if (i >= 1000) // once a second has elapsed, reset the state var i = 0; } // the following code alternately flashes the red and green LEDs, // fading them in and out over time as the music plays in the // background. This is accomplished by using high-frequency PWM // signals on the LED lines. Essentially, each LED is flickering // on and off very quickly, which gives it the apperance of variable // brightness depending on the percentage of the cycle the LED is on. // Each LED flicker cycle takes a total approximately 251 us. if (i < 250) // phase 1: ramp up the red LED brightness { // as i increases over time red_led(1); // turn the red LED on delay_us(i + 1); // microsecond delay red_led(0); // turn the red LED off delay_us(250 - i); // microsecond delay } else if (i < 500) // phase 2: ramp down the red LED brightness { red_led(1); // turn the red LED on delay_us(500 - i); // microsecond delay red_led(0); // turn the red LED off delay_us(i - 249); // microsecond delay } else if (i < 750) // phase 3: ramp up the green LED brightness { green_led(1); // turn the green LED on delay_us(i - 499); // microsecond delay green_led(0); // turn the green LED off delay_us(750 - i); // microsecond delay } else // phase 4: ramp down the green LED brightness { green_led(1); // turn the green LED on delay_us(1000 - i); // microsecond delay green_led(0); // turn the green LED off delay_us(i - 749); // microsecond delay } } }
void activate_pid(void) { red_led( FALSE ); yellow_led( TRUE ); green_led( FALSE ); }
/********************** Function implementations *************************/ void menu_task(void *pvParameters) { menu_t *menu; INT8U i; //setup menus init_menus(); menu = menu_handler(SYSTEM_START_MENU); red_led( FALSE ); yellow_led( FALSE ); green_led( FALSE ); //setup initial system parameters parameter(PUSH,PAN_SETPOINT_P,0); parameter(PUSH,TILT_SETPOINT_P,0); parameter(PUSH,PAN_PWM_P,0); parameter(PUSH,TILT_PWM_P,0); parameter(PUSH,NEXT_POS_P,0); parameter(PUSH,SAVE_POS_P,0); // position(NEW,0); parameter(PUSH,PAN_CURRENT_P,-150); parameter(PUSH,TILT_CURRENT_P,860); position(SAVE,1); parameter(PUSH,PAN_CURRENT_P,150); parameter(PUSH,TILT_CURRENT_P,-2600); position(SAVE,2); exit_freemode(); deactivate_regulator(); deactivate_automode(); while(TRUE) { //handle inputs menu = parse_dreh_event(menu); if(menu->type.is_input) { for(i = 0 ; i < NUMBER_OF_FIELDS ; i++) { if(menu->field[i].dreh_input) parameter(ADD, menu->field[i].parameter, DREH_TO_DEG(counter(RESET,DREH_C)) ); if(menu->field[i].adc_input) parameter(PUSH, menu->field[i].parameter, ADC_TO_DEG(get_adc()) ); if(menu->field[i].numpad_input) if(event(PEEK,NUMPAD_E)) parameter(PUSH, menu->field[i].parameter, CHAR_TO_NUMBER(event(POP,NUMPAD_E) )); } } //update display buffer display_buffer_write_string(0,0,menu->text.topline); display_buffer_write_string(0,1,menu->text.bottomline); for(i=0 ; i < NUMBER_OF_FIELDS ; i++) { if(menu->field[i].show) display_buffer_write_decimal( menu->field[i].begin.x, menu->field[i].begin.y, menu->field[i].size, NUMBER_OF_DECIMALS, parameter(POP,menu->field[i].parameter)); } //handle task states if(state(POP,AUTO_WAIT_S)) { //check if wait time has lapsed if(counter(POP,TIME_C) > TIME_TO_WAIT_ON_HIT) { //change to next position and resume regulation if(parameter(ADD,NEXT_POS_P,1) > NUMBER_OF_POSITIONS) parameter(PUSH,NEXT_POS_P,1); position(GOTO,parameter(POP,NEXT_POS_P)); state(PUSH,AUTO_WAIT_S,FALSE); red_led( FALSE ); activate_automode(); activate_regulator(); } else red_led( TRUE ); } YIELD(YIELD_TIME_MENU_T) } }
// *** triggered by middle button *** // This function tests the eight user I/O pins and the trimmer potentiometer. // At any given time, one pin is being driven low while the rest are weakly // pulled high (to 5 V). At the same time, the LCD is displaying the input // values on the eight user I/O pins. If you short a pin to *GROUND* (note: // do not short the pin to power, only short it to one of the ground pads // along the top edge of the board), you will see the corresponding bit on // the LCD go to zero. The PD1 bit will always read zero as it is being // pulled down through the red user LED. unsigned char IOTest() { // the bits of the "outputs" byte will correspond to the pin states of // the user I/O lines as follows: // outputs: b7 b6 b5 b4 b3 b2 b1 b0 // user I/O: PC5 PC4 PC3 PC2 PC1 PC0 PD1 PD0 // Only one bit of "outputs" will ever be set (1) at a time; the rest will // be cleared (0). The user I/O pin that corresponds to the set bit will // be an output that is driven low while all of the other user I/O pins // will be inputs with internal pull-ups enabled (i.e. they will be weakly // pulled to 5V and will read as high). unsigned int outputs = 0x8000; // binary: 10000000 00000000 unsigned char *outputsA = (unsigned char *)&outputs; // pointer to low byte of outputs unsigned char *outputsD = outputsA + 1; // pointer to high byte of outputs unsigned char direction = 0; unsigned char button; red_led(1); green_led(1); clear(); // clear the LCD print("User I/O"); lcd_goto_xy(0, 1); print("DDDDDDDD AAAAAAAA"); lcd_goto_xy(0, 2); print("76543210 76543210"); set_analog_mode(MODE_8_BIT); // configure ADC for 8-bit readings while (1) // loop here until we detect a button press and return { time_reset(); // reset millisecond timer count to zero DDRA = 0; // make PA0 - PA7 inputs PORTA = 0; // PA0 - PA7 -> high impedance inputs DDRD = 0; // make PD0 - PD7 inputs PORTD = 0; // PD0 - PD7 -> high impedance inputs PORTD |= ~(*outputsD); DDRD |= *outputsD; PORTA |= (~(*outputsA)) & 0x3F; DDRA |= *outputsA & 0x3F; // never make PA6 and PA7 outputs // The following loop will execute for an amount of time determined // by the position of the user trimmer potentiometer (trimpot). // When the trimpot is at one extreme, the loop will take 256*2 = 512 // milliseconds. When the trimpot is at the other extreme, the // loop will only execute once, which takes slightly more than 20 ms. // In this way, the trimpot controls the speed at which the output // byte changes. do { // The bits of the "inputs" byte reflect the input values of pins // PD0, PD1, and PC0 - PC5. Bit 0 corresponds to PD0, bit 1 to // PD1, and bits 2 - 7 to PC0 - PC5, respectively. unsigned char inputsA = PINA; unsigned char inputsD = PIND; lcd_goto_xy(0, 3); // go to the start of the fourth LCD line print_binary(inputsD); // print the "input" byte in binary print(" "); print_binary(inputsA); delay_ms(20); // delay here for 20 milliseconds // check if top or bottom buttons have been pressed button = button_is_pressed(TOP_BUTTON | BOTTOM_BUTTON); if (button != 0) // if so, reset I/O states, return button ID { DDRA = 0; // make PA0 - PA7 inputs PORTA = 0; // PA0 - PA7 -> high impedance inputs DDRD = 0; // make PD0 - PD7 inputs PORTD = 0; // PD0 - PD7 -> high impedance inputs return button; } } while (get_ms() < read_trimpot() * 2); if (direction) outputs <<= 1; // bit-shift our output byte left by one bit else outputs >>= 1; // bit-shift our output byte right by one bit if (outputs == 1) // if we have reached the right edge direction = 1; // switch direction to "left" if (outputs == 0x8000) // if we have reached the left edge direction = 0; // switch direction to "right" } }
void menu_select() { static int menu_index = 0; print_two_lines_delay_1s(main_menu_intro_line1,main_menu_intro_line2); while(1) { clear(); lcd_goto_xy(0,1); print_from_program_space(menu_line2); lcd_goto_xy(0,0); print_from_program_space(main_menu_options[menu_index]); lcd_show_cursor(CURSOR_BLINKING); // the cursor will be blinking at the end of the option name // wait for all buttons to be released, then a press while(button_is_pressed(ANY_BUTTON)); char button = wait_for_button_press(ANY_BUTTON); if(button & BUTTON_A) { play_from_program_space(beep_button_a); menu_index --; } else if(button & BUTTON_B) { lcd_hide_cursor(); clear(); play_from_program_space(beep_button_b); wait_for_button_release(button); while(!button_is_pressed(BUTTON_B)) { lcd_goto_xy(0,1); print_from_program_space(back_line2); lcd_goto_xy(0,0); main_menu_functions[menu_index](); } set_motors(0,0); stop_playing(); m1_speed = 0; m2_speed = 0; red_led(0); green_led(0); play_from_program_space(beep_button_b); return; } else if(button & BUTTON_C) { play_from_program_space(beep_button_c); menu_index ++; } if(menu_index < 0) menu_index = main_menu_length-1; if(menu_index >= main_menu_length) menu_index = 0; } }
// *** triggered by middle button *** // This function tests the motors by first ramping motor1 speed from zero // to full speed "forward", to full speed "reverse", and finally back to zero. // It then does the same for motor2 before repeating all over again. // While motor1 is running, the red user LED is on, otherwise it is off. // While the currently active motor is moving "forward", the green user LED // is on, otherwise it is off. The LCD gives you feedback as to which motor // is currently moving in which direction (FWD = "forward", RVS = "reverse", and // OFF = inactive). unsigned char motorTest() { unsigned char button; red_led(1); green_led(1); clear(); // clear the LCD, go to the start of the first LCD line print("motor2"); // print to the first line of the LCD lcd_goto_xy(0, 1); // go to the start of the second LCD line print("motor1"); // print to the second line of the LCD x2_set_acceleration(MOTOR1, 70, 0); x2_set_brake_duration(MOTOR1, 0, 0); x2_set_acceleration(MOTOR2, 70, 0); x2_set_brake_duration(MOTOR2, 0, 0); while (1) { lcd_goto_xy(0, 0); print("M1: FWD"); x2_set_motor(MOTOR1, ACCEL_DRIVE, 255); button = motor_wait(700); if (button) return button; lcd_goto_xy(0, 0); print("M1: "); x2_set_motor(MOTOR1, IMMEDIATE_DRIVE, 0); button = motor_wait(150); if (button) return button; lcd_goto_xy(0, 0); print("M1: RVS"); x2_set_motor(MOTOR1, ACCEL_DRIVE, -255); button = motor_wait(700); if (button) return button; lcd_goto_xy(0, 0); print("M1: OFF"); lcd_goto_xy(0, 1); print("M2: FWD"); x2_set_motor(MOTOR1, IMMEDIATE_DRIVE, 0); x2_set_motor(MOTOR2, ACCEL_DRIVE, 255); button = motor_wait(700); if (button) return button; lcd_goto_xy(0, 1); print("M2: "); x2_set_motor(MOTOR2, IMMEDIATE_DRIVE, 0); button = motor_wait(150); if (button) return button; lcd_goto_xy(0, 1); print("M2: RVS"); x2_set_motor(MOTOR2, ACCEL_DRIVE, -255); button = motor_wait(700); if (button) return button; lcd_goto_xy(0, 1); print("M2: OFF"); x2_set_motor(MOTOR2, IMMEDIATE_DRIVE, 0); } }
// *** triggered by middle button *** // This function tests the eight user I/O pins and the trimmer potentiometer. // At any given time, one pin is being driven low while the rest are weakly // pulled high (to 5 V). At the same time, the LCD is displaying the input // values on the eight user I/O pins. If you short a pin to *GROUND* (note: // do not short the pin to power, only short it to one of the ground pads // along the top edge of the board), you will see the corresponding bit on // the LCD go to zero. The PD1 bit will always read zero as it is being // pulled down through the red user LED. unsigned char IOTest() { // the bits of the "outputs" byte will correspond to the pin states of // the user I/O lines as follows: // outputs: b7 b6 b5 b4 b3 b2 b1 b0 // user I/O: PC5 PC4 PC3 PC2 PC1 PC0 PD1 PD0 // Only one bit of "outputs" will ever be set (1) at a time; the rest will // be cleared (0). The user I/O pin that corresponds to the set bit will // be an output that is driven low while all of the other user I/O pins // will be inputs with internal pull-ups enabled (i.e. they will be weakly // pulled to 5V and will read as high). unsigned char outputs = 0x80; // binary: 10000000 unsigned char direction = 0; unsigned char button; red_led(0); // turn red and green LEDs off green_led(0); clear(); // clear the LCD print("User I/O"); set_analog_mode(MODE_8_BIT); // configure ADC for 8-bit readings while (1) // loop here until we detect a button press and return { time_reset(); // reset millisecond timer count to zero DDRC = 0; // make PC0 - PC5 inputs PORTC = 0; // PC0 - PC5 -> high impedance inputs DDRD &= ~0x03; // clear PD0 & PD1 bits (make them inputs) PORTD &= ~0x03; // PD0 & PD1 -> high impedance inputs PORTC |= ~outputs >> 2; // set the outputs states of PC0 - PC5 DDRC |= outputs >> 2; // make low pin an output (inputs for rest) PORTD |= ~outputs & 0x03; // set the output states of PD0 and PD1 DDRD |= outputs & 0x03; // make low pin an output (inputs for rest) // The following loop will execute for an amount of time determined // by the position of the user trimmer potentiometer (trimpot). // When the trimpot is at one extreme, the loop will take 256*2 = 512 // milliseconds. When the trimpot is at the other extreme, the // loop will only execute once, which takes slightly more than 20 ms. // In this way, the trimpot controls the speed at which the output // byte changes. do { // The bits of the "inputs" byte reflect the input values of pins // PD0, PD1, and PC0 - PC5. Bit 0 corresponds to PD0, bit 1 to // PD1, and bits 2 - 7 to PC0 - PC5, respectively. unsigned char inputs = PIND & 0x03; // store PD0 and PD1 input vals inputs |= PINC << 2; // store PC0 - PC5 input values lcd_goto_xy(0, 1); // go to the start of the second LCD line print_binary(inputs); // print the "input" byte in binary delay_ms(20); // delay here for 20 milliseconds // check if top or bottom buttons have been pressed button = button_is_pressed(TOP_BUTTON | BOTTOM_BUTTON); if (button != 0) // if so, reset I/O states, return button ID { DDRC = 0; // make PC0 - PC5 inputs PORTC = 0; // disable pull-ups on PC0 - PC5 DDRD &= ~0x03; // make PD0 and PD1 inputs PORTD &= ~0x03; // disable pull-ups on PD0 and PD1 return button; } } while (get_ms() < read_trimpot() * 2); if (direction) outputs <<= 1; // bit-shift our output byte left by one bit else outputs >>= 1; // bit-shift our output byte right by one bit if (outputs == 1) // if we have reached the right edge direction = 1; // switch direction to "left" if (outputs == 0x80) // if we have reached the left edge direction = 0; // switch direction to "right" } }
void test() { unsigned char button; clear(); delay(200); print("Orangutan"); // print to the top line of the LCD delay_ms(400); // delay 200 ms lcd_goto_xy(0, 1); // go to the start of the second LCD line print(" X2"); // print to the bottom line of the LCD red_led(1); delay_ms(100); green_led(1); delay_ms(100); red_led2(1); delay_ms(100); green_led2(1); delay_ms(100); yellow_led(1); delay_ms(100); red_led(0); delay_ms(100); green_led(0); delay_ms(100); red_led2(0); delay_ms(100); green_led2(0); delay_ms(100); yellow_led(0); delay_ms(100); clear(); // clear the LCD, move cursor to start of top line print(" VBAT"); do { // Perform 10-bit analog-to-digital conversions on ADC channel 6. // Average ten readings and return the result, which will be one // third of the battery voltage when the "ADC6 = VBAT/3" solder // bridge is in place on the bottom of the Orangutan PCB int vbat = read_battery_millivolts_x2(); lcd_goto_xy(0, 1); // go to the start of the second LCD line print_long(vbat); // display battery voltage in millivolts print(" mV "); // display the units delay_ms(50); // delay for 50 ms button = button_is_pressed(ANY_BUTTON); // check for button press } while (button == 0); // loop if no buttons are being pressed red_led(1); green_led(1); red_led2(1); green_led2(1); yellow_led(1); // *** MAIN LOOP *** while (1) // loop forever { if (button & TOP_BUTTON) // if the top button is pressed button = melodyTest(); // this func. loops until next button press else if (button & MIDDLE_BUTTON) // if the middle button is pressed button = IOTest(); // this func. loops until next button press else if (button & BOTTOM_BUTTON) // if the bottom button is pressed button = motorTest(); // this func. loops until next button press } }