Control of Servo Through the Use of the Petentiometer

Hi,

My goal is to control the servo through the use of the petentiometer, where depending on how far I turn the petentiometer, which is the resistance, it correlates to the amount of degrees the servo turns to.

In order to achieve this, I combined the Basics Analog Read Serial circuit (which is here on this website under Learning --> Tutorials --> Built in Examples) with the USK guide Code (from viros.com). The same can be said for my code, with slight modifications here and there. However, the servo is not responding in the desired way, and i don't understand why

Here is my code:

#include <Servo.h> // servo library

Servo servo1; // servo control object

void setup()
{
Serial.begin(9600); //initialized communication speed
servo1.attach(9); //correlates control of servo to pin 9
}

void loop()
{
int sensorValue = analogRead(A0);
Serial.println(sensorValue); //printing of sensorValue 's (its excessive to servo control, but has uses)
delay(1);

servo1.write(sensorValue * 180 / 1023); // conversion factor from resistance value to degrees modifies sensorValue into degrees, and then is outputed as the value of degrees for servo to go to
delay(20);
}

What happens is the servo does move slightly when I twist the petentiometer, but it doesn't move in correlation to how much I turn it, and it seems unpredictable in its turning. Also, its constantly buzzing, even when I don't touch the petentiometer. What am I doing wrong?

Thanks,

Davidka :slight_smile:

PS
If you have any questions, or suspicions, please comment. Even if you don't think your right, or even if you don't know why but have a direction to turn to, please respond. It might ring a bell for me, or a start a conversation between us that might lead us to a resolution. :slight_smile:

analogRead returns a value in the range 0 to 1023.
This value you then multiply by 180, but this is done using signed sixteen bit arithmetic, so any value greater than about 182 will exceed the range of this arithmetic.

 servo1.write(sensorValue * 180L/ 1023L);

(deleted)

I understood the technical error you identified of the arithmetic limitations of the program; however, could you explain further the meaning of the L's following the numbers in the operations (by the way, your fix worked :slight_smile: )?

Davidka:
I understood the technical error you identified of the arithmetic limitations of the program; however, could you explain further the meaning of the L's following the numbers in the operations (by the way, your fix worked :slight_smile: )?

The compiler defaults to doing such arithmetic treating the constants as integers 'int' type. The "L" forces the compiler to do 'long' arithmetic.

From the reference page:-

U & L formatters

By default, an integer constant is treated as an int with the attendant limitations in values. To specify an integer constant with another data type, follow it with:

  • a 'u' or 'U' to force the constant into an unsigned data format. Example: 33u
  • a 'l' or 'L' to force the constant into a long data format. Example: 100000L
  • a 'ul' or 'UL' to force the constant into an unsigned long constant. Example: 32767ul

For floats, include a decimal point - 10.0

Edit: Incidentally, there's an example provided with the IDE that does exactly what you're doing - "Knob".
It can be found under >File >Examples >Servo .

Also, its constantly buzzing, even when I don't touch the petentiometer.

This is often an indication that the code is trying to drive the servo beyond it's physical limits. Many servos cannot handle travelling exactly to 0 or 180, so you need to narrow that range until the servo doesn't quite hit the end-stops.
It happens because the servo library maps 0 to 180 to pulsewidths from 544us to 2400us, whereas an ideal servo would have a range of 1000us to 2000us. ('Real-world' servos fall somewhere between the two.)

OldSteve:
The compiler defaults to doing such arithmetic treating the constants as integers. The "L" forces the compiler to do 'long' arithmetic.

sp. "The compiler defaults to doing such arithmetic treating the constants as "int"s".

AWOL:
sp. "The compiler defaults to doing such arithmetic treating the constants as "int"s".

Quite right. int, not integer. :blush:
(Corrected.)