# CircuitPython Servo Tester

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/065/831/medium800thumb/feather_demo.jpg?1542218264)

Servos are great fun, and incredibly useful when you want to make something move.

They do have some issues at times, though. Sometimes you need to set them to a specific angle for assembly. Turning the output shaft manually can be problematic since they're not made for that and on cheaper servos you can strip gears or break teeth pretty easily. If the servo already has broken teeth or such, it's motion can be erratic and it's best to know that before you put things together. Finally servos can vary a bit in what their pulse width bounds are. If you need a full range of motion from them you need to figure out and account for those bounds (Adafruit servo libraries allow you to set them when you construct a servo object).

All in all, it would be nice to have a way to fiddle around with a servo before building it into a project.

This project does just that. Hook up a servo and test it's range of motion (0-180 degrees), test the smoothness of its motion by having it sweep back and forth between 0 and 180 at different speeds, and try different boundary pulse widths to find the servo's limits.

### Adafruit Feather M0 Express

[Adafruit Feather M0 Express](https://www.adafruit.com/product/3403)
At the Feather M0's heart is an ATSAMD21G18 ARM Cortex M0+ processor, clocked at 48 MHz and at 3.3V logic, the same one used in the new&nbsp;[Arduino Zero](https://www.adafruit.com/products/2843). This chip has a whopping 256K of FLASH (8x more than the Atmega328 or 32u4) and...

In Stock
[Buy Now](https://www.adafruit.com/product/3403)
[Related Guides to the Product](https://learn.adafruit.com/products/3403/guides)
![Angled shot of rectangular microcontroller.](https://cdn-shop.adafruit.com/640x480/3403-04.jpg)

### Adafruit FeatherWing OLED - 128x32 OLED Add-on For Feather

[Adafruit FeatherWing OLED - 128x32 OLED Add-on For Feather](https://www.adafruit.com/product/2900)
A Feather board without ambition is a Feather board without FeatherWings! This is the **FeatherWing OLED** : it adds a 128x32 monochrome OLED plus 3 user buttons to _any_ Feather main board. Using our [Feather Stacking...](https://www.adafruit.com/products/2830)

In Stock
[Buy Now](https://www.adafruit.com/product/2900)
[Related Guides to the Product](https://learn.adafruit.com/products/2900/guides)
![Angled shot of a Adafruit FeatherWing OLED - 128x32 OLED Add-on For Feather connected to a white breadboard and a lithium battery. ](https://cdn-shop.adafruit.com/640x480/2900-10.jpg)

### FeatherWing Tripler Mini Kit - Prototyping Add-on For Feathers

[FeatherWing Tripler Mini Kit - Prototyping Add-on For Feathers](https://www.adafruit.com/product/3417)
This is the **FeatherWing Tripler** - a prototyping add-on and more for all Feather boards. This is similar to our [FeatherWing Proto](https://www.adafruit.com/products/2884) except there are three! The magic of the Tripler comes when you want to connect your Feather to...

In Stock
[Buy Now](https://www.adafruit.com/product/3417)
[Related Guides to the Product](https://learn.adafruit.com/products/3417/guides)
![Triple prototyping feather wing PCB with socket headers installed](https://cdn-shop.adafruit.com/640x480/3417-05.jpg)

### FeatherWing Proto - Prototyping Add-on For All Feather Boards

[FeatherWing Proto - Prototyping Add-on For All Feather Boards](https://www.adafruit.com/product/2884)
A Feather board without ambition is a Feather board without FeatherWings!

This is the **FeatherWing Proto** - a prototyping add-on for all Feather boards. Using our [Feather Stacking Headers](https://www.adafruit.com/products/2830) or <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/2884)
[Related Guides to the Product](https://learn.adafruit.com/products/2884/guides)
![Angled Shot of the FeatherWing Proto - Prototyping Add-on For All Feather Boards.](https://cdn-shop.adafruit.com/640x480/2884-13.jpg)

### Rotary Encoder + Extras

[Rotary Encoder + Extras](https://www.adafruit.com/product/377)
This rotary encoder is the best of the best, it's a high-quality 24-pulse encoder, with detents and a nice feel. It is panel mountable for placement in a box, or you can plug it into a breadboard (just cut/bend the two mechanical side tabs.) We also include a nice soft-touch knob with an...

Out of Stock
[Buy Now](https://www.adafruit.com/product/377)
[Related Guides to the Product](https://learn.adafruit.com/products/377/guides)
![Rotary Encoder with rubbery knob](https://cdn-shop.adafruit.com/640x480/377-02.jpg)

### 4-channel I2C-safe Bi-directional Logic Level Converter

[4-channel I2C-safe Bi-directional Logic Level Converter](https://www.adafruit.com/product/757)
Because the Arduino (and Basic Stamp) are 5V devices, and most modern sensors, displays, flashcards, and modes are 3.3V-only, many makers find that they need to perform level shifting/conversion to protect the 3.3V device from 5V. Here we've got a **&nbsp;4-channel I2C-safe...**

In Stock
[Buy Now](https://www.adafruit.com/product/757)
[Related Guides to the Product](https://learn.adafruit.com/products/757/guides)
![Angled shot of a 4-channel I2C-safe Bi-directional Logic Level Converter.](https://cdn-shop.adafruit.com/640x480/757-06.jpg)

## Other Tools and Supplies

- Soldering iron and solder
- hookup wire, the [30AWG Silicone Covered Stranded-Core Wire](https://www.adafruit.com/product/3164) works great
- 3 pins of male header, either [straight](https://www.adafruit.com/product/2671) or [right-angle](https://www.adafruit.com/product/1540).

# CircuitPython Servo Tester

## Circuitry

![](https://cdn-learn.adafruit.com/assets/assets/000/065/959/medium800/feather_Feather_ServoTester.png?1542309780)

The circuit diagram above uses a Feather M0 Express and OLED breakout. Much of the wiring is taken care of by using a Feather and wings as we do here. All we need to build is a wing with the rotary encoder, level shifter, and servo header.

There's a level shifter to drive the servo with a 5v signal. This avoids any potential issue with a 3.3v signal not being a high enough voltage signal.

Using Feathers, wings, and a Feather doubler/tripler wing is a nice way to prototype a design even if you want make it more compact and put it in a case for a final build.

The rotary encoder fits nicely at the "usb" end of the proto wing, straddling the 3.3 and ground bus lines. The servo header goes at the other end, with the level shifter fitting neatly between them. If you use right angle header as shown here, there's just enough room to fit everything without the header pins extending beyond the edge of the wing.

&nbsp;

Here, you can see the wiring. Colored wire is used:

- red - both 3.3 to the level shifter and 5v lines to the shifter and servo
- black - ground
- yellow and blue - the two rotary inputs
- green - the encoder switch input
- white - the PWM signal for the servo (on both sides ot the level shifter)

![feather_wing_top.jpg](https://cdn-learn.adafruit.com/assets/assets/000/065/825/medium640/feather_wing_top.jpg?1542213868)

![feather_wing_bottom.jpg](https://cdn-learn.adafruit.com/assets/assets/000/065/842/medium640/feather_wing_bottom.jpg?1542223463)

Once the encoder/servo wing is built, snap it all onto the triple, connect a servo and power via USB.

![](https://cdn-learn.adafruit.com/assets/assets/000/065/827/medium800/feather_final.jpg?1542214631)

# CircuitPython Servo Tester

## Code

![](https://cdn-learn.adafruit.com/assets/assets/000/065/837/medium800/feather_circuitpython_blinka-small.png?1542219080)

We'll be using CircuitPython for this project. Are you new to using CircuitPython? No worries,&nbsp;[there is a full getting started guide here](https://learn.adafruit.com/welcome-to-circuitpython).

Adafruit suggests using the Mu editor to edit your code and have an interactive REPL in CircuitPython.&nbsp;[You can learn about Mu and its installation in this tutorial](https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor).

Be sure to load CircuitPython on your board. [See this tutorial](https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython) for the process.

Purple: This project needs CircuitPython 4.0.0 or later. All modern versions should work.

Like the circuit, the code is also straight-forward.

It works as a simple linear, looping state machine that moves to the next state each time the encoder button is pressed:

- Mode 0 - adjust the servo angle
- Mode 1 - sweep the servo repeated between 0 and 180 and back, allowing the time to sweep to be adjusted
- Mode 2 - adjust the lower bound of the pulse width
- Mode 3 - adjust the upper bound of the pulse width

To start it initializes hardware and sets up some variables, including a debouncer for the encoder switch. There's nothing special about this and it can be seen in the full listing below.

The main loop is made up of 6 sections.

## Housekeeping

We start by grabbing the current time. This is the elapsed time actually, as we just need to measure differences in time, not absolute time of day. We also update the debouncer now.

```
    now = time.monotonic()
    button.update()

```

## Sweep

Next, if the current mode is the sweep mode, the servo angle will need to be updated if the time between steps has passed. If the angle reaches either extreme, the direction of rotation is reversed.

```
    if mode == 1:
        if now &gt;= (last_movement_at + sweep_time / 36):
            last_movement_at = now
            angle += delta
            if (angle &gt; 180) or (angle &lt; 0):
                delta *= -1
                angle += delta
```

## Mode

If the button was just pressed, we change the mode. If we are switching into mode 0 the angle is set to 0. If we are going into mode 1 we set the time it takes to sweep and next time to step the servo. If we are going into mode 2 or 3, the angle is set to the appropriate extreme.

```
    if button.fell:
        servo.angle = 0
        if mode == 0:
            mode = 1
            sweep_time = 1.0
            last_movement_at = now
        elif mode == 1:
            mode = 2
            angle = 0
        elif mode == 2:
            mode = 3
            angle = 180
        elif mode == 3:
            mode = 0
            angle = 0

```

## Adjust

If the encoder switch wasn't just pressed, the encoder is use to adjust the relevant parameter (depending on the current mode).

```
    else:
        current_position, change = get_encoder_change(rotary_encoder, current_position)
        if change != 0:
            if mode == 0:
                angle = min(180, max(0, angle + change * 5))
            elif mode == 1:
                sweep_time = min(5.0, max(1.0, sweep_time + change * 0.1))
            elif mode == 2:
                min_pulse_index = min(10, max(min_pulse_index + change, 0))
                test_servo = servo.Servo(pwm, 
                                         min_pulse=min_pulses[min_pulse_index], 
                                         max_pulse=max_pulses[max_pulse_index])
                test_servo.angle = 0
            elif mode == 3:
                max_pulse_index = min(10, max(max_pulse_index + change, 0))
                test_servo = servo.Servo(pwm, 
                                         min_pulse=min_pulses[min_pulse_index], 
                                         max_pulse=max_pulses[max_pulse_index])
                test_servo.angle = 180
```

## Display

Once any mode change or adjustment has been made, the display is updated as appropriate for the mode.

```
oled.fill(0)
    if mode == 0:
        oled.text("Angle: {0}".format(angle), 0, 0)
    elif mode == 1:
        oled.text("Sweep time: {0}".format(sweep_time), 0, 0)
    elif mode == 2:
        oled.text("Min width: {0}".format(min_pulses[min_pulse_index]), 0, 0)
    elif mode == 3:
        oled.text("Max width: {0}".format(max_pulses[max_pulse_index]), 0, 0)
    oled.show()
```

## Servo

The final step in the loop is to update the angle of the servo.

```
    test_servo.angle = angle
```

And that's it. Below is the full code. You can download it by clicking "Download Project Bundle." You'll need the debouncer as well which can be found in the library bundle.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Servo_Tester/code.py

After you've done this, your CIRCUITPY drive should look like this:

![CIRCUITPY](https://adafruit.github.io/Adafruit_Learning_System_Guides/Servo_Tester.png )

# CircuitPython Servo Tester

## Next Steps

If you do a lot with servos this could be a handy tool to have on your shelf.

If so, the next step might be to simplify it and put it in a case of some sort. The prototype in this guide was built using Feather ecosystem components for ease of construction using the tripler wing. Since using 5v for the servo was a requirement, being battery powered wasn't. That makes it easy to switch to an ItsyBitsy M0 Express (it has no onboard battery support). The OLED display comes in a breakout version that's identical functionally to the FeatherWing for our purpose (it is just the display, no buttons). The level shifter and rotary encoder don't change.

![](https://cdn-learn.adafruit.com/assets/assets/000/065/962/medium800/feather_ItsyBitsy_ServoTester.png?1542309849)

### Adafruit ItsyBitsy M0 Express - for CircuitPython & Arduino IDE

[Adafruit ItsyBitsy M0 Express - for CircuitPython & Arduino IDE](https://www.adafruit.com/product/3727)
What's smaller than a Feather but larger than a Trinket? It's an **Adafruit ItsyBitsy M0 Express**! Small, powerful, with a rockin' ATSAMD21 Cortex M0 processor running at 48 MHz - this microcontroller board is perfect when you want something very compact, but still...

In Stock
[Buy Now](https://www.adafruit.com/product/3727)
[Related Guides to the Product](https://learn.adafruit.com/products/3727/guides)
![Angled shot of Adafruit ItsyBitsy M0 Express - for CircuitPython & Arduino IDE.](https://cdn-shop.adafruit.com/640x480/3727-06.jpg)

The author anticipates doing this when he gets time to spend in Fusion360, so watch for an update if you are interested.


## Featured Products

### Adafruit Feather M0 Express

[Adafruit Feather M0 Express](https://www.adafruit.com/product/3403)
At the Feather M0's heart is an ATSAMD21G18 ARM Cortex M0+ processor, clocked at 48 MHz and at 3.3V logic, the same one used in the new&nbsp;[Arduino Zero](https://www.adafruit.com/products/2843). This chip has a whopping 256K of FLASH (8x more than the Atmega328 or 32u4) and...

In Stock
[Buy Now](https://www.adafruit.com/product/3403)
[Related Guides to the Product](https://learn.adafruit.com/products/3403/guides)
### Adafruit FeatherWing OLED - 128x32 OLED Add-on For Feather

[Adafruit FeatherWing OLED - 128x32 OLED Add-on For Feather](https://www.adafruit.com/product/2900)
A Feather board without ambition is a Feather board without FeatherWings! This is the **FeatherWing OLED** : it adds a 128x32 monochrome OLED plus 3 user buttons to _any_ Feather main board. Using our [Feather Stacking...](https://www.adafruit.com/products/2830)

In Stock
[Buy Now](https://www.adafruit.com/product/2900)
[Related Guides to the Product](https://learn.adafruit.com/products/2900/guides)
### FeatherWing Tripler Mini Kit - Prototyping Add-on For Feathers

[FeatherWing Tripler Mini Kit - Prototyping Add-on For Feathers](https://www.adafruit.com/product/3417)
This is the **FeatherWing Tripler** - a prototyping add-on and more for all Feather boards. This is similar to our [FeatherWing Proto](https://www.adafruit.com/products/2884) except there are three! The magic of the Tripler comes when you want to connect your Feather to...

In Stock
[Buy Now](https://www.adafruit.com/product/3417)
[Related Guides to the Product](https://learn.adafruit.com/products/3417/guides)
### FeatherWing Proto - Prototyping Add-on For All Feather Boards

[FeatherWing Proto - Prototyping Add-on For All Feather Boards](https://www.adafruit.com/product/2884)
A Feather board without ambition is a Feather board without FeatherWings!

This is the **FeatherWing Proto** - a prototyping add-on for all Feather boards. Using our [Feather Stacking Headers](https://www.adafruit.com/products/2830) or <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/2884)
[Related Guides to the Product](https://learn.adafruit.com/products/2884/guides)
### Rotary Encoder + Extras

[Rotary Encoder + Extras](https://www.adafruit.com/product/377)
This rotary encoder is the best of the best, it's a high-quality 24-pulse encoder, with detents and a nice feel. It is panel mountable for placement in a box, or you can plug it into a breadboard (just cut/bend the two mechanical side tabs.) We also include a nice soft-touch knob with an...

Out of Stock
[Buy Now](https://www.adafruit.com/product/377)
[Related Guides to the Product](https://learn.adafruit.com/products/377/guides)
### 4-channel I2C-safe Bi-directional Logic Level Converter

[4-channel I2C-safe Bi-directional Logic Level Converter](https://www.adafruit.com/product/757)
Because the Arduino (and Basic Stamp) are 5V devices, and most modern sensors, displays, flashcards, and modes are 3.3V-only, many makers find that they need to perform level shifting/conversion to protect the 3.3V device from 5V. Here we've got a **&nbsp;4-channel I2C-safe...**

In Stock
[Buy Now](https://www.adafruit.com/product/757)
[Related Guides to the Product](https://learn.adafruit.com/products/757/guides)
### Silicone Cover Stranded-Core Wire - 50ft 30AWG Black

[Silicone Cover Stranded-Core Wire - 50ft 30AWG Black](https://www.adafruit.com/product/3164)
Silicone-sheathing wire is super-flexible and soft, and its also strong! Able to handle up to 200°C and up to 600V, it will do when PVC covered wire wimps out. We like this wire for being extremely supple and flexible, so it is great for wearables or projects where the wire-harness has to...

In Stock
[Buy Now](https://www.adafruit.com/product/3164)
[Related Guides to the Product](https://learn.adafruit.com/products/3164/guides)
### 2mm Pitch 40-Pin Break-apart Male Headers - Pack of 5

[2mm Pitch 40-Pin Break-apart Male Headers - Pack of 5](https://www.adafruit.com/product/2671)
Never get frustrated with 2mm-pitch modules again! Each one of these **40-pin break-apart header&nbsp;packs** contains 5 pieces of 40-pin, **2mm** pitch headers. Great for when you need to connect to something with 2mm pitch. Stack these headers&nbsp;side by side or...

In Stock
[Buy Now](https://www.adafruit.com/product/2671)
[Related Guides to the Product](https://learn.adafruit.com/products/2671/guides)

## Related Guides

- [Adafruit OLED FeatherWing](https://learn.adafruit.com/adafruit-oled-featherwing.md)
- [Adafruit Feather M0 Express](https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython.md)
- [CircuitPython OLED Watch Clock](https://learn.adafruit.com/circuitpython-oled-watch.md)
- [CircuitPython Painter](https://learn.adafruit.com/circuitpython-painter.md)
- [DAC Hacks for Circuit Playground Express & other ATSAMD21 Boards](https://learn.adafruit.com/circuit-playground-express-dac-hacks.md)
- [MAC Address Finder](https://learn.adafruit.com/mac-address-finder.md)
- [CircuitPython Powered AT Hand-Raiser](https://learn.adafruit.com/at-hand-raiser.md)
- [Sensor Plotting with Mu and CircuitPython](https://learn.adafruit.com/sensor-plotting-with-mu-and-circuitpython.md)
- [CircuitPython Motorized Camera Slider](https://learn.adafruit.com/circuitpython-motorized-camera-slider.md)
- [CircuitPython Hardware: SSD1306 OLED Display](https://learn.adafruit.com/micropython-hardware-ssd1306-oled-display.md)
- [Program CircuitPython USB Devices with iPhone & iPad](https://learn.adafruit.com/use-circuitpython-devices-with-iphone-ipad.md)
- [Remote Effects Trigger Box](https://learn.adafruit.com/remote-effects-trigger.md)
- [CircuitPython Hardware: PCA9685 PWM & Servo Driver](https://learn.adafruit.com/micropython-hardware-pca9685-pwm-and-servo-driver.md)
- [Adafruit USB Host FeatherWing with MAX3421E](https://learn.adafruit.com/adafruit-usb-host-featherwing-with-max3421e.md)
- [I Vote(d) Pin](https://learn.adafruit.com/i-vote-d-pin.md)
- [CircuitPython Libraries on Linux and the 96Boards DragonBoard 410c](https://learn.adafruit.com/circuitpython-libraries-on-linux-and-the-96boards-dragonboard-410c.md)
