Thursday, April 7, 2011

Project 27 - Joystick Servo Control Part 2

It didn't take me that long to solder the six wires to the joystick, so I went ahead and plugged it in to the circuit I made in Project 26... pushing the joystick forward or backward causes one of the servo motors to rotate ... pushing the joystick left or right causes the other servo to rotate.

The code is also fairly straightforward and easy to understand... I can totally see how you can create remote control devices using a couple of joysticks and servos. (Notice I said devices, not robots - I'm still in that group that believes any device that is tethered to a remote control is NOT a robot... a debate for another day.)

Now - a question - in the code each potentiometer has a value that is read between 0 and 1023... that's a 10 bit number if I'm correct. This number is then "mapped" to a value between 0 and 180 for the number of degrees to rotate. So... why 1023? Do the potentiometers send a 10bit signal that represents direction and rotation? I'm still trying to understand that little bit of code... any help out there?

Two videos below... first shows a closeup of the joystick I soldered up... second shows Project 27 in action.


  1. I may be a little off, but here is how I understand it. You answered your own question. It uses 10 bits to store 0-5 volts. The joy stick varies the voltage to the input pin in a range of 0-5 volts, which the Arduino then stores in 10 bis if data. Therefore the 5 volts are scaled across 1024 "segments". Next you have to "map" or use that same percentage for the 180 degrees of rotation that the servo can operate in. So basically 2.5 volts would equal 512 number of bits which in turn is sent out to the servo as 90 degrees.

  2. The joystick does not send any digital values (such as 10-bit). It is simply pots; one for the X and one for the Y axis. The Arduino has ADCs that convert the analog value returned by the pots, into a digital value that the processor can work with. Scaling it to 180 would just be something like this: Scaled_value=(10-bit ADC value)/5.68; The analog voltage the joystick pots output could be used for other stuff as well. For example, you could use it to change the flashing rate of an LED connected to a 555. You can use that analog voltage for many things, but in robotics/programmable electronics, an ADC is often used to convert the value into a digital one that the processor can use.

  3. I just started tinkering with servos myself. You are correct. The pots are adjusting the voltage fed into your two analog inputs from 0 to 5 Volts and that voltage is being converted into a 10 bit signal. That 10 bit number is processed by more code within the Servo library (which is likely part of your code) and converted to an angle between 0 and 180. I am guessing that within the servo library there is code that then converts those values to the appropriate pulse widths for the angle of the motor.

  4. The potentiometers vary the voltage level that is read on the analog input. That's what they are, by definition. The arduino then reads that level, and using the onboard ADC converts it to a digital number from 0 to 1023, based on the value at the analog input. 0 would correspond to 0V and 1023 to 5V.

    Potentiometers are resistors and purely analog devices. They don't send any digital signal--it's not possible to have it be accurate anyway, since they're on no common clock signal as the arduino.

  5. The ADC reads a voltage of between 0 and 5 volts. These are 'spread' across 1024 values so in other words, 5/1024 volts per step.

  6. I'm surprised that no one else has answered this yet but in case you are still wondering why and as a test of commenting as requested in your latest post, here goes a try from Google.

    I don't have a copy of the book or the code so I am assuming you are still using a basic Arduino. As you have noticed the joystick is simply 2 x 10k potentiometers in a fancy wiper control casing and only outputs a value between either end of the applied ground/voltage pins. As such the code is presumably reading the wiper value using the Arduino's normal analogue input pins via the internal 10 bit A2D converters giving the 0-1023 range. Mapping to a range of 0-180 is for the user/programmer's convenience only.

    In the words of the official example file ...

    The analogRead() command converts the input voltage range, 0 to 5 volts, to a digital value between 0 and 1023. This is done by a circuit inside the Arduino called an analog-to-digital converter or ADC.