Example #1
0
void time_test()
{
    static long elapsed_time = 0;
    static long last_read = 0;
    static long is_ticking = 0;
    static char a_is_pressed = 0;
    static char c_is_pressed = 0;
    static char last_seconds = 0;

    long current_time = get_ms();
    if(is_ticking)
        elapsed_time += current_time - last_read;

    last_read = current_time;

    if(button_is_pressed(BUTTON_A) && !a_is_pressed)
    {
        // reset
        a_is_pressed = 1;
        is_ticking = 0;
        elapsed_time = 0;
        if(!is_playing()) // only play once
            play_from_program_space(beep_button_a);
    }

    // find the end of the button press without stopping
    if(!button_is_pressed(BUTTON_A))
        a_is_pressed = 0;

    if(button_is_pressed(BUTTON_C) && !c_is_pressed)
    {
        // start/stop
        c_is_pressed = 1;
        is_ticking = !is_ticking;
        play_from_program_space(beep_button_c);
    }

    // find the end of the button press without stopping
    if(!button_is_pressed(BUTTON_C))
        c_is_pressed = 0;

    print_long((elapsed_time/1000/60/10)%10); // tens of minutes
    print_long((elapsed_time/1000/60)%10); // minutes
    print_character(':');
    print_long((elapsed_time/1000)%60/10); // tens of seconds
    char seconds = ((elapsed_time/1000)%60)%10;
    print_long(seconds); // seconds
    print_character('.');
    print_long((elapsed_time/100)%10); // tenths of seconds
    print_long((elapsed_time/10)%10); // hundredths of seconds

    // beep every second
    if(seconds != last_seconds && elapsed_time != 0 && !is_playing())
        play_from_program_space(timer_tick);
    last_seconds = seconds;
}
Example #2
0
// waits for a button, plays the appropriate beep, and returns the
// button or buttons that were pressed
char wait_for_button_and_beep()
{
    char button = wait_for_button_press(ANY_BUTTON);

    if(button & BUTTON_A)
        play_from_program_space(beep_button_a);
    else if(button & BUTTON_B)
        play_from_program_space(beep_button_b);
    else
        play_from_program_space(beep_button_c);

    wait_for_button_release(button);
    return button;
}
Example #3
0
// 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;
	}
}
Example #4
0
void music_test()
{
    static char fugue_title_pos = 0;
    static long last_shift = 0;
    char c,i;

    if(get_ms() - last_shift > 250)
    {
        for(i=0; i<8; i++)
        {
            c = pgm_read_byte(fugue_title + fugue_title_pos + i);
            print_character(c);
        }
        last_shift = get_ms();

        fugue_title_pos ++;
        if(fugue_title_pos + 8 >= sizeof(fugue_title))
            fugue_title_pos = 0;
    }

    if(!is_playing())
    {
        play_from_program_space(fugue);
    }

    delay_ms(100);
}
Example #5
0
static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters )
{
unsigned short usValue = 0;
xBlockingQueueParameters *pxQueueParameters;
short sErrorEverOccurred = pdFALSE;

	pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;

	for( ;; )
	{
		if( xQueueSend( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS )
		{
			sErrorEverOccurred = pdTRUE;
		}
		else
		{
			/* We have successfully posted a message, so increment the variable
			used to check we are still running. */
			if( sErrorEverOccurred == pdFALSE )
			{
				( *pxQueueParameters->psCheckVariable )++;
			}

			/* Increment the variable we are going to post next time round.  The
			consumer will expect the numbers to	follow in numerical order. */
			++usValue;
            
            play_from_program_space(PSTR("d"));
            while (is_playing()){};
    		red_led(1);     // Turn on the red LED.
	    	delay_ms(20);  // Wait for 20 ms.
		}
	}
}
Example #6
0
void loop()                     // run over and over again
{
  // wait here for one of the three buttons to be pushed
  unsigned char button = wait_for_button(ANY_BUTTON);
  clear();
  
  if (button == TOP_BUTTON)
  {
    play_from_program_space(fugue);

    print("Fugue!");
    lcd_goto_xy(0, 1);
    print("flash ->");
  }
  if (button == MIDDLE_BUTTON)
  {
    play("! V8 cdefgab>cbagfedc");
    print("C Major");
    lcd_goto_xy(0, 1);
    print("RAM ->");
  }
  if (button == BOTTOM_BUTTON)
  {
    if (is_playing())
    {
      stop_playing();
      print("stopped");
    }
    else
    {
      play_note(A(5), 200, 15);
      print("note A5"); 
    }
  }
}
Example #7
0
/** waitForButton **********************************************
 * Pause until a button is pressed.
 * @params button -- identifier of button to wait for
 *         tune -- sequence of notes played when button is pressed
 */
void waitForButton(unsigned char button, const char *tune) {
	while(!button_is_pressed(button)) {
		delay_ms(100);
	}
	play_from_program_space(tune);
	while (button_is_pressed(button)) ; // wait for button up
	delay_ms(200);
}
Example #8
0
/** displayWelcome ******************************************
 * Output welcome message, play tune and delay 2s.
 * @modifies - lcd displays welcome message, tune is played
 */
void displayWelcome() {
	clear();
	print_from_program_space(welcome_line1);
	lcd_goto_xy(0,1);
	print_from_program_space(welcome_line2);
	play_from_program_space(welcome);
	delay_ms(2000);
}
Example #9
0
int main()
{
  TCCR0A = 0;         // configure timer0 to run at 78 kHz
  TCCR0B = 0x04;      // and overflow when TCNT0 = 256 (~3 ms)
  play_from_program_space(rhapsody);

  while(1)
  {
    // allow the sequence to keep playing automatically through the following delays
#ifndef ALWAYS_CHECK
    play_mode(PLAY_AUTOMATIC);
#else
    play_mode(PLAY_CHECK);
#endif
    lcd_goto_xy(0, 0);
    print("blink!");
    int i;
    for (i = 0; i < 8; i++)
    {
#ifdef ALWAYS_CHECK
      play_check();
#endif
      red_led(1);
      delay_ms(500);
      red_led(0);
      delay_ms(500);
    }
  
    lcd_goto_xy(0, 0);
    print("timing");
    lcd_goto_xy(0, 1);
    print("        ");    // clear bottom LCD line
    // turn off automatic playing so that our time-critical code won't be interrupted by
    // the buzzer's long timer1 interrupt.  Otherwise, this interrupt could throw off our
    // timing measurements.  Instead, we will now use playCheck() to keep the sequence
    // playing in a way that won't throw off our measurements.
#ifndef ALWAYS_AUTOMATIC
    play_mode(PLAY_CHECK);
#endif
    unsigned char maxTime = 0;
    for (i = 0; i < 8000; i++)
    {
      TCNT0 = 0;
      while (TCNT0 < 20)    // time for ~250 us
        ;
      if (TCNT0 > maxTime)
        maxTime = TCNT0;    // if the elapsed time is greater than the previous max, save it
#ifndef ALWAYS_AUTOMATIC
      play_check();   // check if it's time to play the next note and play it if so
#endif
    }
    lcd_goto_xy(0, 1);
    print("max=");
    print_long((unsigned int)maxTime);
    print(" ");  // overwrite any left over characters
  }
}
void rob_wait_play_from_program_space (const char * pSequence)
{
    vTaskSuspendAll();
    {
        play_from_program_space (pSequence);
        while (is_playing())
        {
        }
    }
    xTaskResumeAll();
}
Example #11
0
// Displays a welcome message and plays the initial music.
void initialize()
{
	load_custom_characters(); // load the custom characters
	
	play_from_program_space(welcome);
	print_two_lines_delay_1s(welcome_line1,welcome_line2);
	print_two_lines_delay_1s(demo_name_line1,demo_name_line2);
	print_two_lines_delay_1s(instructions_line1,instructions_line2);

	clear();
	print_from_program_space(instructions_line3);
	lcd_goto_xy(0,1);
	print_from_program_space(instructions_line4);

	while(!(wait_for_button_and_beep() & BUTTON_B));

	play_from_program_space(thank_you_music);

	print_two_lines_delay_1s(thank_you_line1,thank_you_line2);
}
Example #12
0
void initialize()
{
	play_from_program_space(welcome);

#ifdef DEBUG
	// start receiving data at 9600 baud.
	serial_set_baud_rate(9600);
	serial_receive_ring(buffer, 100);
#endif

	// initialize your QTR sensors
	//  unsigned char qtr_rc_pins[] = {IO_C0, IO_C1, IO_C2};
//	unsigned char qtr_rc_pins[] = {IO_C0, IO_C1, IO_C2, IO_C3, IO_C4, IO_C5, IO_D7, IO_D4};
	unsigned char qtr_rc_pins[] = {IO_D4, IO_D7, IO_C5, IO_C4, IO_C3, IO_C2, IO_C1, IO_C0};
	qtr_rc_init(qtr_rc_pins, 8, 2000, IO_D2);  // 800 us timeout, emitter pin PD2

#ifdef DEBUG
	serial_send_blocking("Press Button A to start calibrating...\n", 39);
#endif
	wait_for_button_press(BUTTON_A);
	// Always wait for the button to be released so that the robot doesn't
	// start moving until your hand is away from it.
	wait_for_button_release(BUTTON_A);
	delay_ms(800);

	// then start calibration phase and move the sensors over both
	// reflectance extremes they will encounter in your application:
	// We use a value of 2000 for the timeout, which
	// corresponds to 2000*0.4 us = 0.8 ms on our 20 MHz processor.
	unsigned int counter; // used as a simple timer
	for(counter = 0; counter < 82; counter++)
	{
		if(counter < 20 || counter >= 60)
			set_motors(60,-60);
		else
			set_motors(-60,60);

		qtr_calibrate(QTR_EMITTERS_ON);

		// Since our counter runs to 80, the total delay will be
		// 80*20 = 1600 ms.
		delay_ms(20);
	}
	set_motors(0,0);

#ifdef DEBUG
	serial_send_blocking("Press Button A to start line following...\n", 42);
#endif
	wait_for_button_press(BUTTON_A);
	wait_for_button_release(BUTTON_A);
}
Example #13
0
int main() {
	setup();
	displayWelcome();
	displayBattery();
	lineCalibration();

	followLineLaps(4);

	play_from_program_space(success);
	clear();
	print("Done.");
	while (true); // prevent exit from main
	return 0; // dead code
}
Example #14
0
// Initializes the 3pi, displays a welcome message, calibrates, and
// plays the initial music.
void initialize()
{
    // This must be called at the beginning of 3pi code, to set up the
    // sensors.  We use a value of 2000 for the timeout, which
    // corresponds to 2000*0.4 us = 0.8 ms on our 20 MHz processor.
    pololu_3pi_init(2000);
    load_custom_characters(); // load the custom characters

    play_from_program_space(welcome);
    print_two_lines_delay_1s(welcome_line1,welcome_line2);
    print_two_lines_delay_1s(demo_name_line1,demo_name_line2);
    print_two_lines_delay_1s(instructions_line1,instructions_line2);

    clear();
    print_from_program_space(instructions_line3);
    lcd_goto_xy(0,1);
    print_from_program_space(instructions_line4);

    while(!(wait_for_button_and_beep() & BUTTON_B));

    play_from_program_space(thank_you_music);

    print_two_lines_delay_1s(thank_you_line1,thank_you_line2);
}
Example #15
0
int main()
{
	play_from_program_space(PSTR(">g32>>c32"));  // Play welcoming notes.

	while(1)
	{
		// Print battery voltage (in mV) on LCD.
		clear();
		print_long(read_battery_millivolts_sv());

		red_led(1);     // Turn on the red LED.
		delay_ms(200);  // Wait for 200 ms.

		red_led(0);     // Turn off the red LED.
		delay_ms(200);  // Wait for 200 ms.
	}
}
Example #16
0
int main()
{
	play_from_program_space(PSTR(">g32>>c32"));  // Play welcoming notes.

	while(1)
	{
		// Get battery voltage (in mV) from the auxiliary processor
		// and print it on the the LCD.
		clear();
		print_long(read_battery_millivolts_svp());

		red_led(1);     // Turn on the red LED.
		delay_ms(200);  // Wait for 200 ms.

		red_led(0);     // Turn off the red LED.
		delay_ms(200);  // Wait for 200 ms.
	}
}
Example #17
0
int main()
{
    // If button A is pressed, test the PD0/PD1 outputs
	if(button_is_pressed(BUTTON_A))
		test_outputs();

	// If button C is not pressed down, go to the demo.
	if(!button_is_pressed(BUTTON_C) && !test_pushbutton_tries())
		demo();

	// Load bar graph characters.
	// Together with space and the solid block at 255, this makes almost
	// all possible bar heights, with two to spare.
	unsigned char i;
	for(i=0;i<6;i++)
	{
		lcd_load_custom_character(bars+i,i);
	}
	clear();

	pololu_3pi_init(TEST_LINE_SENSOR_TIMEOUT);

	if(test_pushbutton_tries())
		goto pushbuttons;

	play_from_program_space(welcome_test);
	print_two_lines_delay_1s_test(welcome_test_line1,welcome_test_line2);
	print_two_lines_delay_1s_test(test_name_line1,test_name_line2);

	clear();

 	test_battery();
	test_qtr();
	test_motors();
	test_pot();
pushbuttons:
	test_pushbuttons();

	clear();
	print("Success");
	play("O5 c16");
	
	while(1);
}
Example #18
0
/** makeTurn *******************************************
 * makes a turn either left or right
 *
 * @params left -- when true will turn left, else turn right
 */
void makeTurn(bool leftTurn) {

	unsigned int sensors[5];

	int sensorValue = 0;

	// turn one way for a left turn, other way for right
	if (leftTurn) {
		set_motors(-motor_speed, motor_speed);
	}
	else {
		set_motors(motor_speed, -motor_speed);
	}

	// take an initial reading of the sensors
	// could use a do..while loop here
	read_line(sensors, IR_EMITTERS_ON);

	// keep turning until we are off the line
	while (sensors[center_sensor] > 500) {
		read_line(sensors, IR_EMITTERS_ON);
	}

	// give it a small chance to ensure it is off the line
	delay_ms(10);

	// keep turning until we find a line again
	while (sensors[center_sensor] < 500) {
		read_line(sensors, IR_EMITTERS_ON);
	}
	play_from_program_space(beep_button_a);

	// keep turning until we center on the line again, fixes bug with 3pi
	// being unable to center before hitting an intersection if the
	// intersection is shortly after a dead end
	while (sensorValue > 2050 || sensorValue < 1950) {
		sensorValue = read_line(sensors, IR_EMITTERS_ON);
	}

	// all stop captain
	set_motors(0, 0);

}
Example #19
0
/** displayBattery ****************************************
 * Output battery level, wait for button B
 * @modifies lcd display has battery level output.
 */
void displayBattery() {
	int bat;
	const int LOW_BATTERY = 3500;
	const int FULL_BATTERY = 6000;
	double batPer;

	while (!button_is_pressed(BUTTON_B)) {// as long as B is not pressed
		bat = read_battery_millivolts();// read battery voltage
		batPer = (double)(bat - LOW_BATTERY)/(FULL_BATTERY-LOW_BATTERY)*100; // compute percent of full value
		clear();
		print_long(batPer); // display value
		print("%");
		lcd_goto_xy(0,1);
		print("Press B");
		delay_ms(100);	// wait a little bit
	}
	play_from_program_space(beep_button_b);
	while (button_is_pressed(BUTTON_B)) ; // wait for button up
	delay_ms(200);
}
Example #20
0
static portTASK_FUNCTION( vBlockingQueueConsumer, pvParameters )
{
unsigned short usData, usExpectedValue = 0;
xBlockingQueueParameters *pxQueueParameters;
short sErrorEverOccurred = pdFALSE;

	pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;

	for( ;; )
	{
		if( xQueueReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS )
		{
			if( usData != usExpectedValue )
			{
				/* Catch-up. */
				usExpectedValue = usData;

				sErrorEverOccurred = pdTRUE;
			}
			else
			{
				/* We have successfully received a message, so increment the
				variable used to check we are still running. */
				if( sErrorEverOccurred == pdFALSE )
				{
					( *pxQueueParameters->psCheckVariable )++;
				}

				/* Increment the value we expect to remove from the queue next time
				round. */
				++usExpectedValue;
 
            play_from_program_space(PSTR("c"));
            while (is_playing()){};
		    red_led(0);     // Turn off the red LED.
		    delay_ms(20);  // Wait for 20 ms.
			}
		}
	}
}
Example #21
0
/**lineCalibration*****************************************
* @descrip: a function to calibrate the sensors and display
* the results in the form of a bar graph. It waits for a button
* to be pressed.
* @param: none
* @returns: BUTTON_A, BUTTON_B or BUTTON_C depending on which was
*           pressed after the calibration
*
***********************************************************/
unsigned char lineCalibration() {

	const int TURN_SPEED = 40; // motor speed for turning
	const int TURN_STEPS = 20; // number of samples in a half turn
	const int SAMPLE_DELAY = 20; // ms between samples
	unsigned char button; // which button is pressed at the end

	set_motors(-TURN_SPEED, TURN_SPEED); // start turning left
	for (int i = 0; i < TURN_STEPS; i++) {// some number of times
		calibrate_line_sensors(IR_EMITTERS_ON);
		delay_ms(SAMPLE_DELAY);           // 		wait 20ms
	}
	set_motors(TURN_SPEED, -TURN_SPEED); // start turning right
	for (int i = 0; i < 2*TURN_STEPS; i++) {// twice as many times
		calibrate_line_sensors(IR_EMITTERS_ON);
		delay_ms(SAMPLE_DELAY);           // 		wait 20ms
	}
	set_motors(-TURN_SPEED, TURN_SPEED); // start turning left
	for (int i = 0; i < TURN_STEPS; i++) {// some number of times
		calibrate_line_sensors(IR_EMITTERS_ON);
		delay_ms(SAMPLE_DELAY);           // 		wait 20ms
	}
	set_motors(0,0);

	// Display calibrated values as a bar graph.
	unsigned int sensor[5]; // place to store sensor readings
	while ((button = button_is_pressed(ANY_BUTTON)) == 0) {// as long as a button is not pressed
		unsigned int position = read_line(sensor, IR_EMITTERS_ON); //    read the sensors
		clear();
		print_long(position); //    display the value on the top line
		display_readings(sensor); 	//    display the bar graph on the bottom line
		delay_ms(100);             //    wait a bit
	}
	play_from_program_space(beep_button_b); // beep for B button
	while (button_is_pressed(button)) ;   // empty loop - wait until button released
	delay_ms(200); // wait a bit more
	return button;
}
void initialize()
{
	// Set PC5 as an input with internal pull-up disabled
	DDRC5 &= ~(1<< PORTC5); //port 5 is an input
	PORTC &= ~(1<< PORTC5);
	// Play welcome music and display a message
	print_from_program_space(welcome_line1);
	lcd_goto_xy(0,1);
	print_from_program_space(welcome_line2);
	//play_from_program_space(welcome);
	delay_ms(1000);
	clear();
	print_from_program_space(name_line1);
	lcd_goto_xy(0,1);
	print_from_program_space(name_line2);
	delay_ms(1000);
	// Display battery voltage and wait for button press
	while(!button_is_pressed(BUTTON_B))
	{
		clear();
		print_long(read_battery_millivolts());
		print("mV");
		lcd_goto_xy(0,1);
		print("Press B");
		delay_ms(100);
	}

// Always wait for the button to be released so that 3pi doesn't
// start moving until your hand is away from it.
wait_for_button_release(BUTTON_B);
clear();
print("Go!");
// Play music and wait for it to finish before we start driving.
play_from_program_space(go);
while(is_playing());
}
Example #23
0
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;
    }
}
Example #24
0
/** followSegment ****************************************
 * follow segment until a turn is found, an end of the line
 * or the target
 *
 * @params left -- by reference if a left branches was found
 *         right -- by reference if a right branches was found
 *         straight -- by reference if a straight line was found
 */
void followSegment(bool& left, bool& right, bool& straight) {

	// the value returned from the line sensors
	int sensorValue = 2000;

	// the raw sensor values from the 3pi
	unsigned int sensors[5];

	// the change in speed
	signed int delta_speed = 0;



	// inital read of the sensor value
	sensorValue = read_line(sensors, IR_EMITTERS_ON);
	left = right = false;

	// while we have a line at center and not at a branch
	while (!left && !right) {

		// could have this in the while but this way is slightly easier to read
		// if we go off the line stop we break out of the loop
		if (sensorValue > 2000 + sensor_threshold || sensorValue < 2000 - sensor_threshold) {
			break;
		}

		// normalize the sensor value to a motor delta value and turn motors on
		// delta is between 0 and motor_speed
		delta_speed = ((motor_speed - (-motor_speed)) * (sensorValue - 0.0))/(4000.0 - 0.0) + (-motor_speed);
		set_motors(motor_speed + delta_speed, motor_speed - delta_speed);

		// we need to update the sensor values of the 3pi will just repeat forever
		sensorValue = read_line(sensors, IR_EMITTERS_ON);
		left = sensors[left_sensor] > 500;
		right = sensors[right_sensor] > 500;

		// if we have a reading to the left or right keep moving forward a bit
		// this is to fix a big where the 3pi would read one part of a branch but
		// miss the other because it read one side too fast
		if (left || right) {

			// move forward some and read the sensors again
			set_motors(motor_speed, motor_speed);
			delay_ms(55);
			sensorValue = read_line(sensors, IR_EMITTERS_ON);
			left = sensors[left_sensor] > 500;
			right = sensors[right_sensor] > 500;

		}


		// if we are at target we stop and return from the function
		if (isTarget()) {
			set_motors(0,0);
			done = true;
			return;
		}

	}

	set_motors(motor_speed, motor_speed);


	// if we have left and right sensor values we move forward until they are both clear of a line
	// if only left we wait for the left sensor to clear
	// if only right we wait for the right sensor to clear
	// we always break out when we move off the center of the line
	if (left && right) {
		while (sensors[center_sensor] > 500 && ((sensors[left_sensor] > 500) == left) && ((sensors[right_sensor] > 500) == right)) {
			read_line(sensors, IR_EMITTERS_ON);
		}
	}
	else if (left) {
		while (sensors[center_sensor] > 500 && ((sensors[left_sensor] > 500) == left)) {
			read_line(sensors, IR_EMITTERS_ON);
		}
	}
	else if (right) {
		while (sensors[center_sensor] > 500 && ((sensors[right_sensor] > 500) == right)) {
			read_line(sensors, IR_EMITTERS_ON);
		}

	}

	// check straight now since we are off the intersection
	straight = (sensors[center_sensor] > 500);

	// let us know what you are doing Mr. 3pi
	play_from_program_space(beep_button_b);
	set_motors(0,0);
}
Example #25
0
// Initializes the 3pi, displays a welcome message, calibrates, and
// plays the initial music.
void initialize()
{
	unsigned int counter; // used as a simple timer
	unsigned int sensors[5]; // an array to hold sensor values

	// This must be called at the beginning of 3pi code, to set up the
	// sensors.  We use a value of 2000 for the timeout, which
	// corresponds to 2000*0.4 us = 0.8 ms on our 20 MHz processor.
	pololu_3pi_init(2000);
	load_custom_characters(); // load the custom characters
	
	// Play welcome music and display a message
	print_from_program_space(welcome_line1);
	lcd_goto_xy(0,1);
	print_from_program_space(welcome_line2);
	play_from_program_space(welcome);
	delay_ms(1000);

	clear();
	print_from_program_space(demo_name_line1);
	lcd_goto_xy(0,1);
	print_from_program_space(demo_name_line2);
	delay_ms(1000);

	// Display battery voltage and wait for button press
	while(!button_is_pressed(BUTTON_B))
	{
		int bat = read_battery_millivolts();

		clear();
		print_long(bat);
		print("mV");
		lcd_goto_xy(0,1);
		print("Press B");

		delay_ms(100);
	}

	// Always wait for the button to be released so that 3pi doesn't
	// start moving until your hand is away from it.
	wait_for_button_release(BUTTON_B);
	delay_ms(1000);

	// Auto-calibration: turn right and left while calibrating the
	// sensors.
	for(counter=0;counter<80;counter++)
	{
		if(counter < 20 || counter >= 60)
			set_motors(40,-40);
		else
			set_motors(-40,40);

		// This function records a set of sensor readings and keeps
		// track of the minimum and maximum values encountered.  The
		// IR_EMITTERS_ON argument means that the IR LEDs will be
		// turned on during the reading, which is usually what you
		// want.
		calibrate_line_sensors(IR_EMITTERS_ON);

		// Since our counter runs to 80, the total delay will be
		// 80*20 = 1600 ms.
		delay_ms(20);
	}
	set_motors(0,0);

	// Display calibrated values as a bar graph.
	while(!button_is_pressed(BUTTON_B))
	{
		// Read the sensor values and get the position measurement.
		unsigned int position = read_line(sensors,IR_EMITTERS_ON);

		// Display the position measurement, which will go from 0
		// (when the leftmost sensor is over the line) to 4000 (when
		// the rightmost sensor is over the line) on the 3pi, along
		// with a bar graph of the sensor readings.  This allows you
		// to make sure the robot is ready to go.
		clear();
		print_long(position);
		lcd_goto_xy(0,1);
		display_readings(sensors);

		delay_ms(100);
	}
	wait_for_button_release(BUTTON_B);

	clear();

	print("Go!");		

	// Play music and wait for it to finish before we start driving.
	play_from_program_space(go);
	while(is_playing());
}
Example #26
0
// This is the main function, where the code starts.  All C programs
// must have a main() function defined somewhere.
int main()
{
	unsigned int sensors[8]; // an array to hold sensor values
	unsigned int slow = 30;

#ifdef DEBUG
	unsigned int counter = 0;
#endif

	// set up the 3pi
	initialize();

	// This is the "main loop" - it will run forever.
	while(1)
	{
		// Get the position of the line.  Note that we *must* provide
		// the "sensors" argument to read_line() here, even though we
		// are not interested in the individual sensor readings.
		unsigned int position = qtr_read_line(sensors,QTR_EMITTERS_ON);
		position = position - 50;
		
		/*
		// If I lift the robot, it should stop the motors. When the 
		// sensors are no longer near a surface, they will all read 1000,
		// and the position given by read_line functions will be 3500.
		//if (sensors[0] + sensors[1] + sensors[2] + sensors[3] + sensors[4]
		//		+ sensors[5] + sensors[6] + sensors[7] == 7000)
		if (sensors[0] + sensors[3] + sensors[4] + sensors[7] == 4000) // Shorter and quicker
		{
			set_motors(0,0);
			break;
		}

		if(position < 1000)
		{
			// We are far to the right of the line: turn left.

			// Set the right motor to 100 and the left motor to zero,
			// to do a sharp turn to the left.  Note that the maximum
			// value of either motor speed is 255, so we are driving
			// it at just about 40% of the max.
			set_motors(0,170);
#ifdef DEBUG
			if (counter > 100)
				serial_send_blocking("LEFT \n", 6);
#endif

		}
		else if(position < 2000)
		{
			set_motors(60,150);
#ifdef DEBUG
			if (counter > 100)
				serial_send_blocking("left \n", 6);
#endif
		}
		else if (position < 3000)
		{
			set_motors(90,150);
		}
		else if (position < 3300) // CENTER = 3500
		{
			set_motors(130,150);
		}
		else if (position < 3700)
		{
			// We are somewhat close to being centered on the line:
			// drive straight.
			set_motors(160,160);
#ifdef DEBUG
			if (counter > 100)
				serial_send_blocking("OK   \n", 6);
#endif
		}
		else if (position < 4000)
		{
			set_motors(150,130);
		}
		else if (position < 5000)
		{
			set_motors(150,90);
#ifdef DEBUG
			if (counter > 100)
				serial_send_blocking("right\n", 6);
#endif
		}
		else if (position < 6000)
		{
			set_motors(150,60);
		}
		else // (position < 7000)
		{
			// We are far to the left of the line: turn right.
			set_motors(170,0);
#ifdef DEBUG
			if (counter > 100)
				serial_send_blocking("RIGHT\n", 6);
#endif
		}

#ifdef DEBUG
		if (counter > 100)
			counter = 0;
		else
			counter++;
#endif
		*/

		if(position < 1000)
		{
			// We are far to the right of the line: turn left.

			// Set the right motor to 100 and the left motor to zero,
			// to do a sharp turn to the left.  Note that the maximum
			// value of either motor speed is 255, so we are driving
			// it at just about 40% of the max.
			set_motors(0, 180 - slow);

		}
		else if(position < 2000)
		{
			set_motors(40 - slow, 150 - slow);
		}
		else if (position < 3000)
		{
			set_motors(90 - slow, 150 - slow);
		}
		else if (position < 3300) // CENTER = 3500
		{
			set_motors(130 - slow, 150 - slow);
		}
		else if (position < 3700)
		{
			// We are somewhat close to being centered on the line:
			// drive straight.
			set_motors(160 - slow, 160 - slow);
		}
		else if (position < 4000)
		{
			set_motors(150 - slow, 130 - slow);
		}
		else if (position < 5000)
		{
			set_motors(150 - slow, 90 - slow);
		}
		else if (position < 6000)
		{
			set_motors(150 - slow, 40 - slow);
		}
		else // (position < 7000)
		{
			// We are far to the left of the line: turn right.
			set_motors(180 - slow, 0);
		}

	}

	// This part of the code is never reached.  A robot should
	// never reach the end of its program, or unpredictable behavior
	// will result as random code starts getting executed.  If you
	// really want to stop all actions at some point, set your motors
	// to 0,0 and run the following command to loop forever:
	play_from_program_space(bye);
	set_motors(0,0);
	while(1);
}
Example #27
0
// *** 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
		}
		
	}
}