Adding an analog feedback tap to a 9g Micro Servo

Internally the servo has a feedback loop that is driven off of a variable resistor.  The resistance value changes as the servo sweeps across its range of motion. This can act as a proxy for the servo's position.  You can buy servos with an extra wire that exposes the voltage across that variable resistor or you can make your own. Or, you can add your own sensing wire to the potentiometer.

I have a bunch of the 9g micro servos for various projects.  The one below has an extra green wire coming out of it that is connected to an analog input on this ESP32 C3.  The ESP32 can see the location of the servo while it is in motion.

Sample Program Output

The program in this GitHub repository FreemanSoft ESP Python 

The sample MicroPython tester moves a servo from 0 degrees to 180 degrees in steps and then returns to 0 degrees.  It logs the analog value of the potentiometer at the end of every move. It is actually before the next move but there is no effective difference for this discussion.

This is from an ESP32 with a 16-bit ADC. The sample code works for the ESP8266 10-bit ADCs also. 

  1. The low-end number shows that there may be more range below 600usec or that it is just a potentiometer artifact.
  2. The last row shows that we have probably gone past the maximum range of the servo.  The test data is for 180 degrees and a lot of servos only go to 170 degrees.  

You will have to calibrate your code against individual servos and allow for minor variations.  I didn't run enough tests to know how repeatable the values are but suspect not so much on a $5.00 device.

analog readings on two servos in 10 degree increments

Opening up the Servo

The 9g servos seem to be produced in only a couple styles.   They have 4 screws on the bottom that breaks down the case into 3 parts.  We need to remove those screws and pull off the bottom of the case.

I did not have to do any more disassembly for my servo.

Finding the potentiometer pins

The potentiometer is often mounted directly to the motor control board via through-hole solder connections.  You can see the external three wires on the right and the two white motor wires running from the motor to the chip.

The potentiometer is mounted via the three holes on the left side of the board.  One will be power, one will be ground and the third is the current proportional voltage for the location, the center tap.  

We want to attach our sensing wire to the middle solder blob.

Attaching the sending wire wire

We're going to need to solder a wire to the middle solder blob of the potentiometer.  Tin the wire to get a little solder on it.  Then hit the blob with your soldering iron and touch the wire to it.  That was enough to get a decent connection.

At this point, I kind of wanted to add some hot glue to protect the but didn't get around to it.  Mostly because I thought I might want to redo this later.

We now have a servo with the extra wire and need to figure out a way to get the wire to exit the case with just enough pinch to protect it.

Notching the case for the new wire.

The bottom piece of the case has a notch for the existing three wires.  It is undersized enough to pinch the wires and act as a strain relief.

I filed a notch into the existing one. I hoped that the insulation on the stacked would have the right amount of give to pinch them in the case.  You can see the notch in the picture.

Hook Up

The servo will operate as it has in the past whether you hook up the sensing wire or not.  You can see in this picture that we attached 4 wires to the ESP32 C3 on the right. There is power, ground and the servo control line, and the new green sensing wire.   The analog wire must be attached to an ADC if you want to read any values. Otherwise, just leave it unattached.  The green wire exists for you to sense the position and does not affect servo operation.  Note: it could affect servo operation if you suck too much current through the line.

This picture shows the servo control wire attached to GPIO 5 and the servo sensing wire attached to GPIO 4.  This is because GPIO 4 is one of the ADC-capable pins in this particular board and CPU.


Sample Code

This code comes from  It may be different from the version you see when you look at the repo. I tend to run this class from the REPL using the instructions in the class. makes use of the logging code inside Servo() and ServoSweep().  You've seen the output above. The code
  1. Creates an ADC to read the values
  2. Creates a Servo
  3. Creates a Sweeper and injects the ADC and Servo configurations
  4. Calls sweep() at regular intervals.  sweep() advances the servo and logs it's positions. 
Usage in REPL:

from checksweep import sweep_esp_32

Depends on classes from this project:
from servosweep import ServoSweep
from servo import Servo
from machine import Pin, ADC
import time

def sweep_esp_32():
    Exercises ServoSweep.
    Originally written to verify logging of servo position.
    Later extended to log the analog read back position if available.
    adc = ADC(Pin(4))
    # set full attenuation to have full 0-3v range

    servo = Servo(Pin(5))
    sweeper = ServoSweep(servo, pin_adc=adc)

    while True:
        # this advances the stepper by whatever the current step size is


I have no affiliation with the source and make no money off the links.

Revision History

Created 2023 01


Popular posts from this blog

Understanding your WSL2 RAM and swap - Changing the default 50%-25%

Installing the RNDIS driver on Windows 11 to use USB Raspberry Pi as network attached

DNS for Azure Point to Site (P2S) VPN - getting the internal IPs