Skip to content

Commit f40f065

Browse files
Merge pull request #2587 from arduino/pedromsousalima/micropython/servo
[PXCT-51] MicroPython Servo Motor Docs
2 parents 02e6cb8 + b1fb580 commit f40f065

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

content/micropython/01.basics/01.analog-io/analog-io.md

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ In this guide, we will be using some additional electronic components:
5151
1. Open the [Arduino Lab for MicroPython](https://labs.arduino.cc/en/labs/micropython) application.
5252
2. Plug the Arduino board into the computer using a USB cable.
5353
![Connect board to computer.](assets/usb-comp.png)
54-
3. Press the connection button on the top left corner of the window. The connected Arduino board should appear (by its port name), and we can click it:
54+
3. Press the Connect button on the top left corner of the window. The connected Arduino board should appear (by its port name), and we can click it:
5555
![Connect to the board in the editor.](assets/select-board-ide.png)
5656

5757
***Need help installing MicroPython on your board? Visit the [MicroPython installation guide](/micropython/first-steps/install-guide).***
@@ -163,6 +163,71 @@ Let's take a look at what's included in this code example:
163163
- **Duty Cycle**: `duty_u16()` takes a value between 0 and 65535. The higher the value, the longer the signal stays HIGH, making the LED brighter.
164164
- **Loop**: The brightness gradually increases and decreases by adjusting the duty cycle in small steps, causing the LED to fade in and out.
165165

166+
### Servo Motor Control with PWM
167+
168+
Servo motors are precise actuators that can rotate to specific angles, making them ideal for robotics, automated mechanisms, and precise positioning tasks. Think of a servo as a highly trained dancer who can move to exact positions and hold them steady unlike regular motors that spin continuously, servos respond to specific commands to rotate to precise angles between 0° and 180°.
169+
170+
Servos use PWM signals, but in a special way. Instead of varying brightness like with LEDs, servos interpret the width of PWM pulses as position commands. The servo expects pulses every 20 milliseconds (50Hz frequency), and the width of each pulse determines the angle: a 1ms pulse commands 0°, a 1.5ms pulse commands 90°, and a 2ms pulse commands 180°.
171+
172+
![Servo PWM Demo](assets/servoPWM.gif.gif)
173+
174+
Important: Even small servos use much more power than LEDs or sensors so they can cause voltage drops in your circuit. Adding a 100-470µF capacitor near the servo helps smooth out these power demands and prevents erratic behavior.
175+
176+
### Code Example: Servo Sweep
177+
178+
For this example, we will need the following external components:
179+
180+
- Breadboard
181+
- Servo motor
182+
- Jumper wires
183+
- Optional but recommended: 100-470µF electrolytic capacitor
184+
185+
Connect the servo to the Arduino board:
186+
- **Red wire** (power) to **3.3V** (check your servo's specifications)
187+
- **Black/Brown wire** (ground) to **GND**
188+
- **Orange/Yellow wire** (signal) to a PWM-capable digital pin
189+
- If using capacitor: Connect positive leg to **3.3V**, negative leg to GND
190+
191+
![Circuit Overview](assets/ServoCircuit.png)
192+
193+
After completing the circuit, copy the following code into your editor and run the script.
194+
195+
```python
196+
from machine import Pin, PWM
197+
import time
198+
199+
# Initialize PWM for the servo pin
200+
servo = PWM(Pin(9)) # Replace '9' with your PWM pin number
201+
servo.freq(50) # Set frequency to 50Hz (example)
202+
203+
def set_servo_angle(angle):
204+
# Convert angle (0-180) to duty cycle for 16-bit PWM
205+
# Servo expects pulses between 1ms (0°) and 2ms (180°)
206+
# For 50Hz: 1ms = ~3277, 1.5ms = ~4915, 2ms = ~6553
207+
min_duty = 3277 # ~1ms pulse width (0 degrees)
208+
max_duty = 6553 # ~2ms pulse width (180 degrees)
209+
duty = int(min_duty + (angle / 180) * (max_duty - min_duty))
210+
servo.duty_u16(duty)
211+
212+
# Continuous sweeping motion
213+
while True:
214+
# Sweep from 0 to 180 degrees
215+
for angle in range(0, 181, 2): # Step by 2 degrees
216+
set_servo_angle(angle)
217+
time.sleep(0.02) # Small delay for smooth motion
218+
219+
# Sweep back from 180 to 0 degrees
220+
for angle in range(180, -1, -2): # Step by 2 degrees backwards
221+
set_servo_angle(angle)
222+
time.sleep(0.02) # Small delay for smooth motion
223+
```
224+
225+
Let's examine this code:
226+
227+
- **PWM Setup**: Creates a `PWM` object and set the frequency to 50Hz—the standard frequency servos expect for position updates.
228+
- **Angle Conversion**: The `set_servo_angle()` function converts degrees (0-180) into the appropriate 16-bit duty cycle values that correspond to the pulse widths the servo understands.
229+
- **Sweeping Motion**: The servo continuously sweeps back and forth between 0° and 180°, moving in 2-degree increments with a small delay between each step to create smooth, fluid motion.
230+
166231
## Analog Resolution
167232

168233
The resolution of an ADC can simply be explained as how detailed it is. When using MicroPython, the default is **16-bits**, while using the Arduino programming language it is **10-bits**. So what is the difference?
628 KB
Loading
184 KB
Loading

0 commit comments

Comments
 (0)