Servo motor

In this tutorial we are going to use a servo motor. Servo motors are commonly used in robotics. They are mass produced and can be obtained cheaply. In contrast to "normal" motors, a servo motor is designed to turn its shaft to a specific angle, depending on the signal it gets.


We assume that you have a basic understanding of how pulse width modulation (henceforth "PWM") works, and how it is used in Toit. If necessary, have a look at the Fading LED tutorial first.


Connect the servo as follows:

  • Connect the red wire to 3.3V.
  • Connect the black (or brown) wire to GND.
  • Connect the yellow (or orange) wire to pin 12.
Servo motor diagram
Servo motor diagram
Servo motor schematics
Servo motor schematics


A servo motor is controlled by a PWM signal. The duty cycle of the PWM signal determines the angle of the servo motor. The frequency of the PWM signal is usually 50Hz, but the actual frequency depends on the motor.

Similarly to the fading LED example we just need to create a PWM generator and then hook pin 12 to it. This time the frequency of the wave should be 50Hz.

Write the following servo.toit program and run or watch it:

import gpio
import gpio.pwm

  servo := gpio.Pin 12
  generator := pwm.Pwm --frequency=50

  // Start with the half-way angle.
  channel := generator.start servo --duty_factor=0.075
  sleep --ms=1500

  // Max angle.
  channel.set_duty_factor 0.125
  sleep --ms=1500

  // Min angle.
  channel.set_duty_factor 0.025
  sleep --ms=1500

Servo motors only have a limited range in which they should operate: the maximum duty factor is 0.125, and the minimum is 0.025.

If the motor is operated out of the recommended range it may use significantly more power, trying to reach the desired angle. However, the 3.3V supply is limited, and eventually the 5V-to-3.3V converter (converting USB 5V to the 3.3V that are needed by the ESP32) can't deliver anymore. At that point the voltage drops and the ESP32 detects a brownout, and shuts down.

This can be seen when running toit monitor:

entry 0x400805c8
clearing RTC memory: powered on by hardware source
[flash reg] address 0x3f430000, size 0x00200000
[jaguar] INFO: program 1 re-starting from flash @ [442368,466944]

Brownout detector was triggered

For programs that are installed (see container install) this can be an issue if the servo draws too much power before Jaguar is able to update the program. In that case, one has to unplug the servo to get back into a state where Jaguar is able to install a corrected program.


Be careful not to run with frequencies that aren't supported by the servo. Furthermore keep the angle in a range that is supported by the servo. Otherwise the motor could draw too much power leading to an unstable system. Unless the system is stressed for a long period of time, there should not be any permanent damage. This assumes that the connections were made correctly.

  • Use the servo as an actuator for a button (for example the space bar of a keyboard).
  • Use the servo as a gauge showing different values.