Support » Application Note: Using the Motor Driver on the 3pi Robot and Orangutan Robot Controllers »
7. Using the Trimmer Pot for Motor Control
The following sample program uses the motor control functions defined in Section 5 to drive the motors in response to the trimmer potentiometer position. Motors 1 and 2 transition linearly from full forward to stationary to full reverse as the potentiometer voltage varies from 0 to 5 V. This program uses the ATmega48/168/328’s analog-to-digital converter to determine the position of the potentiometer.
#include <avr/io.h> int main() { motors_init(); // ***** ADC INITIALIZATION ***** // On the Orangutan and 3pi, the user trimpot can be optionally jumpered // to ADC7 using a blue shorting block; the Orangutan and 3pi ship // with this shorting block in place (this shorting block is required // by this program). On the Baby Orangutan, the trimpot is permanently // connected to ADC7. ADCSRA = 0x87; // bit 7 set: ADC enabled // bit 6 clear: don't start conversion // bit 5 clear: disable autotrigger // bit 4: ADC interrupt flag // bit 3 clear: disable ADC interrupt // bits 0-2 set: ADC clock prescaler is 128 ADMUX = 0x07; // bit 7 and 6 clear: voltage ref is Vref pin // bit 5 clear: right-adjust result (10-bit ADC) // bit 4 not implemented // bits 0-3: ADC channel (channel 7) while (1) // loop forever { long sum = 0; unsigned int avg, i; // Here we accumulate 500 conversion results to get an average ADC. // According to the ATmegaxx8 datasheet, it takes approximately 13 // ADC clock cycles to perform a conversion. We have configured // the ADC run at IO clock / 128 = 20 MHz / 128 = 156 kHz, which // means it has a conversion rate of around 10 kHz. As a result, // it should take around 50 ms to accumulate 500 ADC samples. for (i = 0; i < 500; i++) { ADCSRA |= ( 1 << ADSC ); // start conversion while ( ADCSRA & ( 1 << ADSC )) // wait while converting ; sum += ADC; // add in conversion result } avg = sum / 500; // compute the average ADC result // set motors based on trimpot position (middle value = motor speed 0) // avg is a 10-bit value and hence ranges from 0 to 1023 if (avg <= 511) { M1_forward((511 - avg) / 2); M2_forward((511 - avg) / 2); } else { M1_reverse((avg - 512) / 2); M2_reverse((avg - 512) / 2); } } return 0; }