servo_pwm.py

Adafruit Feather nRF52840 Express · File : servo_pwm.py · Language : Python · Use case : Animer un micro-servo sur une broche PWM

A micro-servo (SG90, MG90) on D5 sweeps 0 to 180°: 50 Hz PWM, 0.5-2.5 ms pulses computed on the pulseio 16-bit scale. The classic radar-sweep command, ready to accept any position.

Hardware

An Adafruit Feather nRF52840 Express (nRF52840 Cortex-M4F SoC, BLE 5 / 802.15.4) with on-board NeoPixel, red LED, 2 MB QSPI flash for the CircuitPython filesystem and a LiPo battery connector. A 5 V micro-servo; power it from VOUT (5 V on USB) or a separate battery — the board 3V3 regulator is too weak for the stall spike.

Wiring

Signal (orange/yellow wire) to D5, servo + to VOUT, servo ground to GND — common ground with the Feather is mandatory.

How it works

pulseio.PWMOut generates the hardware 50 Hz; the angle function maps 0-180° onto 2.5-12.5 % duty (0.5-2.5 ms in 20 ms). The for loops sweep in ~1.4 s per pass.

Running it

CircuitPython (feather_nrf52840_express build) installed via the UF2 bootloader (double reset); edit code.py on the CIRCUITPY drive, console in Mu/Thonny.

Variants

Drive the angle from BLE or a sensor, add a second servo for a two-axis arm, or smooth motion with interpolation.

servo_pwm.py

# Micro-servo sur D5 : balaie 0 -> 180 -> 0 degrés.
# Alimentation servo : broche VOUT (USB) ou batterie, pas le 3V3 seul.
import time
import board
import pulseio

servo = pulseio.PWMOut(board.D5, frequency=50, duty_cycle=0)

def angle(a):
    # 20 ms de période : 0,5 ms = 0°, 2,5 ms = 180°
    # duty_cycle 16 bits : 65535 = 20 ms
    mini = int(65535 * 0.5 / 20)
    maxi = int(65535 * 2.5 / 20)
    servo.duty_cycle = mini + (maxi - mini) * a // 180

while True:
    for a in range(0, 181, 5):
        angle(a)
        time.sleep(0.02)
    for a in range(180, -1, -5):
        angle(a)
        time.sleep(0.02)

← Back to the board