# ATMega328P control servo motor speed with potentiometer

I'm trying to develop an application in atmel studio 7.0 which will allow me to control the speed of my servo motor with my potentiometer. Now, the problem is that I don't really know how to do that? Also my servo motor spins around and around instead of going 0 -> 45 -> 90 degrees and then back the same way again. I've managed to do a successfull convertion of analog signals to use, and I've set my admux input channel to 2; also, my pwm channel is 10 for the servo motor. I use an Arduino Uno with Atmega328P processor with 16 000 000 Hz.

Might also say I'm pretty new to the use of PWM, which is why this would be an exciting thing to do.

Heres the code this far:

void initPWM();
uint16_t doConversion(void);

int main(void)
{
DDRD = 0b11111111;
DDRB = 0xFF;
initPWM();

while (1)
{
PORTB = 0b00000100;
OCR1A=250;   //0 degree
_delay_ms(2000);

OCR1A=375;  //45 degree
_delay_ms(2000);

OCR1A=500;  //90 degree

_delay_ms(2000);

OCR1A = 0;

_delay_ms(5000);
}
}

void initPWM(){
TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);        //NON Inverted PWM
TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS11)|(1<<CS10); //PRESCALER=64 MODE 14(FAST PWM)
ICR1 = 4999 ; // 50 Hz
}

ADMUX = 0b11000010; //Set channel 2
// REFS1:0 = 01 -> AVCC as reference,
// MUX4:0 = 00000 -> ADC0 as input
// ADSC = 0: don't start conversion yet
// ASPS2:0 = 001: pre-scaler= 2
// ADATE = 0: disable auto trigger,
}

uint16_t doConversion(void){
uint16_t result;
// Start conversion by setting flag ADSC
// Wait until conversion is  completed
// Read the all bits, output to PORTB
return result;
}


I used 4999 as the value for ICR1 since I have a 16000000 Hz CPU and use a prescaler of 64.

My servo motors degrees are based on the following: 0 degrees = 1000 microseconds 45 degrees = 1500 microseconds 90 degrees = 2000 microseconds

PORTB is for using the pwm, and the potentiometer is connected to channel 2.

Does anyone know what I did wrong? Or can help me solve/accomplish what I'm trying to do?

• Post a link to a data sheet or product page on your servo motor. If you bought a hobbyist "servo motor" then you have an RC servo that expects a PWM command. If you bought an industrial "servo motor" then you have a bare DC motor optimized for servo use, or a "smart servo motor" with a built in driver that probably takes an up/down comand and a pulse, but may take something else. RC servo motors usually have a mechanical range of around 270 degrees, and don't spin "around and around". – TimWescott Jun 10 at 17:57
• wiki.keyestudio.com/… I'm using the one that can be seen here. Which would be identified as a hobbyist (9G servo motor). And the potentionmeter is a 10k ohm one. The servo motor also have built-in-reference circuit which gives out a reference signal , cycle of 20ms and width of 1.5ms – wazev Jun 10 at 18:00
• Do you have an oscilloscope that you can use to verify the PWM to the servo? It should be a 1ms - 2ms pulse once every 16 to 20 ms. – TimWescott Jun 10 at 18:08
• I get a correct analog input signal, and the servo motor rotates (around and around). And when I checked this the other day when I had an oscilloscope (which I sadly don't have on me today), I got the correct pulse/wave, yes. – wazev Jun 10 at 18:13
• Try another servo! It's a hobby shop item (called just "servo" in all the English-speaking countries I know of). If you know what to look for it may be as close as the nearest discarded RC plane, boat or car. – TimWescott Jun 10 at 18:22