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;
}








