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() { set_analog_mode(MODE_8_BIT); // 8-bit analog-to-digital conversions sum = 0; samples = 0; avg = 0; start_analog_conversion(TRIMPOT); // start initial conversion while(1) { if (!analog_is_converting()) // if conversion is done... { sum += analog_conversion_result(); // get result start_analog_conversion(TRIMPOT); // start next conversion if (++samples == 20) // if 20 samples have been taken... { avg = sum / 20; // compute 20-sample average of ADC result samples = 0; sum = 0; } } // when avg == 0, the red LED is almost totally off. // when avg == 255, the red LED is almost totally on. // brightness should scale approximately linearly in between. red_led(0); // red LED off delay_us(256 - avg); red_led(1); // red LED on delay_us(avg+1); } }
int main() { set_analog_mode(MODE_10_BIT); // 10-bit analog-to-digital conversions while(1) // run over and over again { lcd_goto_xy(0,0); // LCD cursor to home position (upper-left) print_long(to_millivolts(read_trimpot())); // trimpot output in mV print(" mV "); // added spaces are to overwrite left over chars lcd_goto_xy(0, 1); // LCD cursor to start of the second line unsigned int temp = read_temperature_f(); // get temp in tenths of a degree F print_long(temp/10); // get the whole number of degrees print_character('.'); // print the decimal point print_long(temp - (temp/10)*10); // print the tenths digit print_character(223); // print a degree symbol print("F "); // added spaces are to overwrite left over chars delay_ms(100); // wait for 100 ms (otherwise LCD flickers too much) } }
void test_analog() { // test that set/get mode works set_analog_mode(MODE_8_BIT); printf("\nGet8BIT"); assert(MODE_8_BIT == get_analog_mode()); set_analog_mode(MODE_10_BIT); printf("\nGet10BIT"); assert(MODE_10_BIT == get_analog_mode()); // read the trimpot in 10 bit mode and compare it to 8 bit mode int x1 = analog_read(7); set_analog_mode(MODE_8_BIT); delay_ms(1); // required for readings to stabilize int x2 = analog_read(7); printf("\n8BIT10BIT %d %d",x1,x2); assert( abs((x1>>2) - x2) < 10 ); // make sure that the average reading is more stable than individual readings set_analog_mode(MODE_10_BIT); unsigned char i; int min = 1023, max = 0, avg_min = 1023, avg_max = 0; for(i=0;i<10;i++) { int x1 = analog_read(7); int x2 = analog_read_average(7,256); if(x1 > max) max = x1; if(x1 < min) min = x1; if(x2 > avg_max) avg_max = x2; if(x2 < avg_min) avg_min = x2; printf("\nAvgComp %03x %03x", x1, x2); assert( abs(x1-x2) < 10); } printf("\nAB%03x%03x%03x%03x",max,min,avg_max,avg_min); assert( max - min >= avg_max - avg_min); // check that temp C and F return appropriate values in 10bit mode set_analog_mode(MODE_10_BIT); x1 = analog_read_average(6,100); int expect_temp_f = (((int)(analog_read_average_millivolts(TEMP_SENSOR, 20)) * 12) - 634) / 13; int expect_temp_c = (((int)(analog_read_average_millivolts(TEMP_SENSOR, 20) * 20)) - 7982) / 39; int temp_f = read_temperature_f(); int temp_c = read_temperature_c(); printf("\nTF10 %d %d", expect_temp_f, temp_f); assert( expect_temp_f/5 == temp_f/5 ); printf("\nTC10 %d %d", expect_temp_c, temp_c); assert( expect_temp_c/5 == temp_c/5 ); // try temp in 8bit mode set_analog_mode(MODE_8_BIT); delay_ms(1); // required for readings to stabilize? temp_f = read_temperature_f(); temp_c = read_temperature_c(); printf("\nTF8 %d %d", expect_temp_f, temp_f); assert( (expect_temp_f - temp_f) <= 20 ); printf("\nTC8 %d %d", expect_temp_c, temp_c); assert( abs(expect_temp_c - temp_c) <= 20 ); // test background conversion set_analog_mode(MODE_10_BIT); delay_ms(1); // required for readings to stabilize x1 = analog_read_average(6,100); start_analog_conversion(6); while(analog_is_converting()) printf("\nConvert"); x2 = analog_conversion_result(); printf("%d %d", x1, x2); assert( abs(x1 - x2) < 10 ); // make sure to_millivolts works in 8 and 10 bit mode set_analog_mode(MODE_10_BIT); x1 = 5000; x2 = to_millivolts(1023); printf("\nmV1 %d %d",x1,x2); assert( x1 == x2 ); x1 = 2498; x2 = to_millivolts(511); printf("\nmV2 %d %d",x1,x2); assert( x1 == x2 ); x1 = 0; x2 = to_millivolts(0); printf("\nmV3 %d %d",x1,x2); assert( x1 == x2 ); set_analog_mode(MODE_8_BIT); x1 = 5000; x2 = to_millivolts(255); printf("\nmV4 %d %d",x1,x2); assert( x1 == x2 ); x1 = 2490; x2 = to_millivolts(127); printf("\nmV5 %d %d",x1,x2); assert( x1 == x2 ); x1 = 0; x2 = to_millivolts(0); printf("\nmV6 %d %d",x1,x2); assert( x1 == x2 ); }
int main() { // wait wait_with_message("Press B"); // init and calibrate light sensors unsigned int sensors[5]; pololu_3pi_init_disable_emitter_pin(2000); // (2000 for the timeout corresponds to 2000*0.4 us = 0.8 ms on our 20 MHz processor) wait_for_button_release(BUTTON_B); delay_ms(1000); for(int counter=0;counter<80;counter++) { if(counter < 20 || counter >= 60) set_motors(40,-40); else set_motors(-40,40); calibrate_line_sensors(IR_EMITTERS_ON); delay_ms(20); } set_motors(0,0); // init IR sensors set_analog_mode(MODE_8_BIT); DDRC &= ~(1<< PORTC5); PORTC &= ~(1<< PORTC5); // wait wait_with_message("Press B"); delay_ms(1000); int left_speed = 110; int right_speed = 110; int set_point = 0; while(1) { // check light sensors for our boundary unsigned int position = read_line(sensors,IR_EMITTERS_ON); if(position > 5 && position < 1000) { turn_right(55,65); } else if(position > 1000 && position < 1800) { turn_right(55,95); } else if(position > 1800 && position < 3000) { turn_left(55,95); } else if(position > 3000 && position < 3995) { turn_left(55,65); } // check IR sensors int left = analog_read(6); int right = analog_read(5); int front = analog_read(7); /*if((get_ms() % 300) == 0) { clear(); lcd_goto_xy(0,0); print_long(left); lcd_goto_xy(0,1); print_long(right); }*/ int balance = 0; if (left > 20 || right > 20) { balance = right - left - 20; } if (set_point == 0 && front > 162) { set_point = 1; set_motors(25,25); } else { set_motors(left_speed + balance,right_speed - balance); } } halt(); clear(); //print("f="); //print_long(front); // end while(1); }
// *** 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" } }
// *** 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" } }