Shop Learn
ESP32 MicroPython and Parallax Servos — Parallax Forums

ESP32 MicroPython and Parallax Servos

The book Robotics with the Boe-Bot discusses the CR servos and says that the signal should be high for 1.5ms, low for 20ms to center the servo. To change the speed, reduce the on time to 1.3ms for full speed clockwise and 1.7ms for full speed counterclockwise.

I would like to use the CR servos and standard servos with MicroPython on my ESP32 boards. I have available to me the PWM class, which takes a frequency and duty cycle, not up time and down time. What values should I use to control these servos?

MicroPython PWM docs are here:


  • AwesomeCronkAwesomeCronk Posts: 1,055
    edited 2021-05-22 00:51

    After researching for a good while I found that the 20ms delay is not critical but roughly where servo control needs to be. Following like that, I did some math and found that a good centering signal is 50Hz with a 7.5% duty cycle. Duty cycles for full speed clockwise and counterclockwise are 6.5% and 8.5%, respectively.

    MycroPython on the ESP32 uses values of 0-1024 for it's PWM duty (always off a slight bit), so I multiplied the range of these values (1024) by the percents I found and got PWM values of 77 for centering and 67, 87 for full speed clockwise and counterclockwise. I centered a servo with my Stamp and then tried my MicroPython centering code and it didn't move at all! I then "raced" two servos after tying their signal lines together to make sure their speeds matched (at least visually), one driven by the Stamp and the other by the ESP32. Visually, there was no difference. It seems that as a good rule of thumb for servo control, the duty cycle percentage is roughly 1/100 of what the PULSOUT value would be.

    My MicroPython code for servo control:

    from machine import Pin, PWM
    import time
    servoPin = 12
    # CW refers to "clockwise" and CCW refers to "counterclockwise"
    # Initialize the driver with centering signal
    servo = PWM(Pin(servoPin), freq = 50, duty = 77)
    # Full speed CW
    # Full Speed CCW
    #Ramp from full speed CCW to full speed CW
    for d in range(67, 88): # 88 because python excludes the end point
        time.sleep(1) # Wait one second to change the value again

    I definitely don't have the finest control over speed (1/10th of the resolution of the Stamp's method), but I am able to run it in the background and just update it as necessary, which frees up my code compared to BASIC a LOT.

    So far I have only been able to get this working with CR servos. Standard servos just won't behave for me, but I've never been able to properly drive my standard servos, so I think the problem there is wither in the servos or between the keyboard and the chair... :joy:

Sign In or Register to comment.