ESP32 MicroPython Joystick Servo Motor

by DIYables in Circuits > Microcontrollers

6 Views, 0 Favorites, 0 Comments

ESP32 MicroPython Joystick Servo Motor

esp32-micropython-joystick-servo-motor-cover.jpg

This is a compact build guide. The full tutorial, with the wiring diagram and a line-by-line walkthrough of the code, is here: https://newbiely.com/tutorials/esp32-micropython/esp32-micropython-joystick-servo-motor

This build uses an ESP32 running MicroPython to control two servo motors, or a pan-tilt kit, with a joystick. The joystick's X-axis and Y-axis potentiometers each send a signal to the ESP32: the X-value drives servo motor #1 and the Y-value drives servo motor #2. Mounted on a pan-tilt kit, the two servos move together in three dimensions as you move the joystick thumbstick.

Supplies

Wiring

esp32-micropython-joystick-servo-motor-wiring-diagram.jpg

Connect the joystick's VRX pin to GPIO36 and VRY pin to GPIO39 on the ESP32, both ADC inputs. Connect the joystick's SW (button) pin to GPIO23. Connect servo motor #1's signal wire to GPIO13 and servo motor #2's signal wire to GPIO25. You can wire everything on a breadboard, or use a screw terminal block breakout board for a steadier connection. If you need to drive more servos, use a PCA9685 16-channel PWM servo driver module instead to save ESP32 pins and simplify the wiring.

How It Works

The two ADC pins read the joystick's X and Y voltages as 12-bit values, 0 to 4095. The code maps each value to a servo angle between 0 and 180 degrees, then sends that angle to the corresponding servo: the X-axis value drives servo motor #1 and the Y-axis value drives servo motor #2. Moving the joystick thumbstick in any direction rotates both servos to match, letting a pan-tilt kit track in three dimensions.

Code

The script sets up the two ADC pins with 12-bit resolution and 11dB attenuation so they can read the full 0-3.3V joystick range, then creates Joystick and Servo objects from the DIYables MicroPython libraries using the pins defined at the top of the script. In the main loop, it calls joystick.loop() to update readings, reads the X and Y values, maps each to a 0-180 degree angle with a helper function, moves both servos to those angles, and prints the raw joystick values alongside the resulting servo angles over serial.

esp32-micropython-joystick-servo-motor.py - the sketch from the tutorial, unchanged.

"""
This ESP32 MicroPython code was developed by newbiely.com
This ESP32 MicroPython code is made available for public use without any restriction
For comprehensive instructions and wiring diagrams, please visit:
https://newbiely.com/tutorials/esp32-micropython/esp32-micropython-joystick-servo-motor
"""

from DIYables_MicroPython_Joystick import Joystick
from DIYables_MicroPython_Servo import Servo
from machine import Pin, ADC
import time

JOYSTICK_X_PIN = 36 # The ESP32 pin GPIO36 (ADC0) connected to VRX pin of joystick
JOYSTICK_Y_PIN = 39 # The ESP32 pin GPIO39 (ADC3) connected to VRY pin of joystick
BUTTON_PIN = 23 # The ESP32 pin GPIO23 connected to SW pin of joystick
SERVO_X_PIN = 13 # The ESP32 pin GPIO13 connected to Servo motor 1
SERVO_Y_PIN = 25 # The ESP32 pin GPIO25 connected to Servo motor 2

adc_vrx = ADC(Pin(JOYSTICK_X_PIN))
adc_vry = ADC(Pin(JOYSTICK_Y_PIN))
# Set the ADC width (resolution) to 12 bits
adc_vrx.width(ADC.WIDTH_12BIT)
adc_vry.width(ADC.WIDTH_12BIT)
# Set the attenuation to 11 dB, allowing input range up to ~3.3V
adc_vrx.atten(ADC.ATTN_11DB)
adc_vry.atten(ADC.ATTN_11DB)

joystick = Joystick(pin_x=JOYSTICK_X_PIN, pin_y=JOYSTICK_Y_PIN, pin_button=BUTTON_PIN)

# Initialize the two servos
xServo = Servo(SERVO_X_PIN) # Use the constant for the X servo pin
yServo = Servo(SERVO_Y_PIN) # Use the constant for the Y servo pin

# Function to map the joystick value to servo angle
def map_value(value, in_min, in_max, out_min, out_max):
return int((value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)

# Main loop
while True:
joystick.loop() # Must be called frequently to process joystick data

# Read the X and Y axis values (12-bit resolution from the library)
x_value = joystick.read_x()
y_value = joystick.read_y()

# Map the 12-bit values (0 to 4095) to servo angles (0 to 180 degrees)
x_angle = map_value(x_value, 0, 4095, 0, 180)
y_angle = map_value(y_value, 0, 4095, 0, 180)

# Move the servos to the mapped angles
xServo.move_to_angle(x_angle)
yServo.move_to_angle(y_angle)

# Print the joystick's X and Y values and the corresponding servo angles
print(f'Joystick X: {x_value}, Y: {y_value} => Servo X Angle: {x_angle}°, Y Angle: {y_angle}°')

time.sleep(0.05) # Delay to reduce the output frequency

Full Tutorial

The complete tutorial, wiring diagram and code explanation: https://newbiely.com/tutorials/esp32-micropython/esp32-micropython-joystick-servo-motor