# Motorized Camera Slider 2-Axis

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/136/752/medium800/3d_printing_hero-white.jpg?1747058070 )

https://youtu.be/5qv4TInZV0k

https://youtube.com/live/7giKCuUSC2M?feature=share

## Slide & Pan

This project uses two stepper motors to create smooth cinematic motion for capturing video or timelapse photography. You can use it to automate both trucking and panning for beautiful compound camera motion. It features a 1.3in TFT screen for displaying a user interface and a rotary encoder for controlling the stepper motors.&nbsp;

It's powered by an Adafruit KB2040 running CircuitPython. The TMC2209 stepper motor drivers offer smooth and silent micro stepping.&nbsp;

The software features a mode for capturing timelapses and a one shot mode for filming video.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/767/medium640/3d_printing_hero-unicorn.jpg?1747078288)

## DIY Motorized Slider

3D printed parts support two pieces of aluminum extrusion. A timing belt and pulley wheels are used to slide the carriage along the profile offering about 16 inches (40cm) of travel. A second motor is dedicated for panning offering a bit over 180 degrees.

A custom PCB reduces the amount of wiring connecting the microcontroller, TFT display, buck converter and two stepper motor drivers. It runs off a 12V AA battery pack making the build portable for filming outdoors.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/768/medium640/3d_printing_hero-outside.jpg?1747079593)

## Crank It!

Use the rotary encoder to set the start and ending positions of the panning motor. A 3D printed rotary handle lets you crank the motor making an intuitive interface for setting the panning stepper motor.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/758/medium640thumb/3d_printing_motor2-loop.jpg?1747069575)

Primary: This learn guide assumes prior experience with electronics, 3D printing, mechanical engineering and videography. It is not recommend for beginner makers but is achievable with patience and the willingness to learn new skills.

# Parts from Adafruit
### Adafruit KB2040 - RP2040 Kee Boar Driver

[Adafruit KB2040 - RP2040 Kee Boar Driver](https://www.adafruit.com/product/5302)
A wild Kee Boar appears! It’s a shiny **KB2040**! An Arduino Pro Micro-shaped board for Keebs with RP2040. (#keeblife 4 evah) A lot of folks like using Adafruit parts for their Keeb builds – but with the ItsyBitsy not being pin-compatible with the Pro Micro pinout, it...

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

### MPM3610 5V Buck Converter Breakout - 21V In 5V Out at 1.2A

[MPM3610 5V Buck Converter Breakout - 21V In 5V Out at 1.2A](https://www.adafruit.com/product/4739)
This little buck converter based on the MPM3610 is a marvel, taking up to 21V input and providing a 5V output with up to 1.2A current. It's great for supplying power to popular 5V voltage circuits from a range of battery or power options. &nbsp;This chip provides up to 1.2 Amp load current...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4739)
[Related Guides to the Product](https://learn.adafruit.com/products/4739/guides)
![MPM3610 5V Buck Converter Breakout Board](https://cdn-shop.adafruit.com/640x480/4739-04.jpg)

### Adafruit 1.3" 240x240 Wide Angle TFT LCD Display with MicroSD

[Adafruit 1.3" 240x240 Wide Angle TFT LCD Display with MicroSD](https://www.adafruit.com/product/4313)
We've been looking for a display like this for a long time - it's **so small** only 1.3" diagonal but has a high density 260 ppi, 240x240 pixel display with full-angle viewing. It _looks_ a lot like our 1.44" 128x128 display, but has 4x as many pixels and...

In Stock
[Buy Now](https://www.adafruit.com/product/4313)
[Related Guides to the Product](https://learn.adafruit.com/products/4313/guides)
![Overhead shot of 1.3" TFT breakout connected via EYESPI board and microcontroller on a half-size breadboard. The TFT breakout displays a colorful hexagon.](https://cdn-shop.adafruit.com/640x480/4313-09.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)

### 8 x AA battery holder with 5.5mm/2.1mm Plug and On/Off Switch

[8 x AA battery holder with 5.5mm/2.1mm Plug and On/Off Switch](https://www.adafruit.com/product/875)
Make a portable power brick with plenty of juice! Use Alkaline AA's for a 12V 3000-4000mAh power supply, or rechargeable NiMH for 2000mAh 9.6V supply. Either one is good for running electronics that have a 5V voltage regulator (thus requiring a 7V+ supply) or perhaps some motors or...

In Stock
[Buy Now](https://www.adafruit.com/product/875)
[Related Guides to the Product](https://learn.adafruit.com/products/875/guides)
![Angled shot rectangular black 8 x AA battery holder with 5.5mm/2.1mm plug and on/off switch.](https://cdn-shop.adafruit.com/640x480/875-04.jpg)

### Part: Adafruit TMC2209
quantity: 2
Stepper Motor Driver Breakout Board
[Adafruit TMC2209](https://www.adafruit.com/product/6121)

### Part: 2.5mm Pitch Connector Kit
quantity: 1
JST XH Compatible - 560 Piece Kit
[2.5mm Pitch Connector Kit](https://www.adafruit.com/product/4423)

### Part: Switch Quick-Connect Wires 
quantity: 1
0.187" (10-pack)
[Switch Quick-Connect Wires ](https://www.adafruit.com/product/3835)

### Part: Micro Switch
quantity: 2
Premium Zippy 3-Terminal
[Micro Switch](https://www.adafruit.com/product/817)

### Part: Slotted Aluminum Extrusion
quantity: 2
20mm x 20mm - 610mm long
[Slotted Aluminum Extrusion](https://www.adafruit.com/product/1221)

### Part: DC barrel jack
quantity: 1
Breadboard-friendly 2.1mm 
[DC barrel jack](https://www.adafruit.com/product/373)

### Part: Terminal Block - 
quantity: 1
2-pin 3.5mm - pack of 5!
[Terminal Block - ](https://www.adafruit.com/product/724)

### Part: Socket Headers
quantity: 1
36-pin 0.1" Female header - pack of 5!
[Socket Headers](https://www.adafruit.com/product/598)

### Part: Little Rubber Bumper Feet
quantity: 1
Pack of 4
[Little Rubber Bumper Feet](https://www.adafruit.com/product/550)

### Part: Red Silicone Wire
quantity: 1
25ft 26AWG - Red
[Red Silicone Wire](https://www.adafruit.com/product/2513)

### Part: Black Silicone Wire
quantity: 1
25ft 26AWG - Black
[Black Silicone Wire](https://www.adafruit.com/product/2517)

### Part: Through-Hole Resistors - 2.2K ohm
quantity: 1
5% 1/4W - Pack of 25
[Through-Hole Resistors - 2.2K ohm](https://www.adafruit.com/product/2782)

# Parts from Amazon
### Part: Stepper Motor
quantity: 2
Short Body 12V 1A
[Stepper Motor](https://www.amazon.com/gp/product/B00PNEQ79Q/)

### Part: 6008-2RS Bearing
quantity: 1
40x68x15mm Bearings - 2 Pack
[6008-2RS Bearing](https://www.amazon.com/gp/product/B07MXN3BXZ/)

### Part: Pulley Wheels with Bearing Idler
quantity: 4
625zz Linear Bearing
[Pulley Wheels with Bearing Idler](https://www.amazon.com/dp/B07Q5WN3GK/)

### Part: GT2 Timing Pulley
quantity: 1
36 Teeth - 6mm belt - 5mm bore
[GT2 Timing Pulley](https://www.amazon.com/uxcell-Synchronous-Aluminum-Printer-Machine/dp/B0DNFDYX75/)

### Part: GT2 Timing Belt
quantity: 1
2mm pitch - 6mm wide - 1164mm (45in) length needed
[GT2 Timing Belt](https://www.amazon.com/Timing-Meters-Creality-Anycubic-Printer/dp/B097T3Y6WW/)

### Part: 1/4"-20 x 1/2" Tripod Screw
quantity: 1
4pcs - Red Aluminum Tee Wing Knob
[1/4"-20 x 1/2" Tripod Screw](https://www.amazon.com/dp/B0DGS2Z6YX)

### Part: 1/4"-20 Rubber Washer
quantity: 1
5 Pack - 1/4" Screw Hole for Anti-Scratch Camera
[1/4"-20 Rubber Washer](https://www.amazon.com/Anwenk-Anti-Scratch-Accessories-Protection-Anti-Slippery/dp/B07R44FP5C/)

### Part: 8x AA Rechargeable Batteries
quantity: 1
Pack of 8
[8x AA Rechargeable Batteries](https://www.amazon.com/Eneloop-8-Battery-Rechargeable-Batteries-Controllers/dp/B00JHKSN5I/)

# Motorized Camera Slider 2-Axis

## Circuit Diagram

This is a big build so there's a PCB to help keep the wiring nice and tidy. The PCB uses headers to easily plug in the breakouts and KB2040. The rotary encoder, terminal blocks, DC jack and JST connectors get soldered directly to the board. There are labels on the silkscreen to help identify the correct placement for everything. The [Eagle files and Gerber files are available on GitHub](https://github.com/adafruit/Adafruit_Learning_System_Guides/tree/main/TMC2209_Camera_Slider/PCB_Files) if you want to order your own.

[PCB Eagle Files on GitHub](https://github.com/adafruit/Adafruit_Learning_System_Guides/tree/main/TMC2209_Camera_Slider/PCB_Files)
[Gerber Files on GitHub](https://github.com/adafruit/Adafruit_Learning_System_Guides/raw/main/TMC2209_Camera_Slider/PCB_Files/TMC2209_Camera_Slider_PCB_revB_2025-05-12.zip)
## Schematic and Fab Print
![schematic for the pcb](https://cdn-learn.adafruit.com/assets/assets/000/136/595/medium800/3d_printing_schem.png?1746535225 )

![fab print for pcb](https://cdn-learn.adafruit.com/assets/assets/000/136/596/medium800/3d_printing_fab.png?1746535275 dimensions are in inches)

## Fritzing

Of course, if you're feeling adventurous, you can forego the PCB and wire the breakouts and components directly.

![fritzing diagram for slider](https://cdn-learn.adafruit.com/assets/assets/000/136/597/medium800/3d_printing_motorSliderFritzing_bb.png?1746536102 )

 **Power**

- **DC Jack 12V Power** to **MPM3601 Vin (red wire)**
- **DC Jack GND** to **MPM3601 GND (black wire**
- **DC Jack 12V Power** to **TMC2209 1 terminal block + (red wire)**
- **DC Jack GND** to **TMC2209 1 terminal block - (black wire)**
- **DC Jack 12V Power** to **TMC2209 2 terminal block + (red wire)**
- **DC Jack GND** to **TMC2209 2 terminal block - (black wire)**
- **MPM3601 5V** to **KB2040 RAW (red wire)**
- **MPM3601 GND** to **KB2040 G (black wire)**

**Rotary Encoder**

- **Encoder button** to **KB2040 D2 (purple wire)**
- **Encoder GND** to **KB2040 G (black wire)**
- **Encoder pin A** to **KB2040 D7 (orange wire)**
- **Encoder pin B** to **KB2040 D6 (cyan wire)**

**TFT**

- **TFT Vin** to **KB2040 3V (red wire)**
- **TFT Gnd** to **KB2040 G (black wire)**
- **TFT SCK** to **KB2040 SCK (green wire)**
- **TFT MOSI** to **KB2040 MOSI (blue wire)**
- **TFT TCS** to **KB2040 D10 (white wire)**
- **TFT RST** to **KB2040 D9 (grey wire)**
- **TFT DC** to **KB2040 D8 (pink wire)**

**Limit Switches**

- **Limit switch GND** to **KB2040 G (black wire)**
- **Limit switch 1 output** to **KB2040 A2 (ochre wire)**
- **Limit switch 2 output** to **KB2040 A3 (brown wire)**

**TMC2209 Breakout 1**

- **KB2040 3V** to **TMC2209 1 VDD (red wire)**
- **KB2040 G** to **TMC2209 1 GND (black wire)**
- **KB2040 TX** to **2.2K resistor (white wire)**
- **KB2040 RX** to **2.2K resistor (green wire)**
- **TMC2209 1 UART** to **RX side of resistor (purple wire)**
- **TMC2209 1 1A** to **stepper motor coil 1 positive (green wire)**
- **TMC2209 1 1B** to **stepper motor coil 1 negative (yellow wire)**
- **TMC2209 1 2A** to **stepper motor coil 2 positive (red wire)**
- **TMC2209 1 2B** to **stepper motor coil 2 negative (black wire)**

**TMC2209 Breakout 2**

- **KB2040 3V** to **TMC2209 2 VDD (red wire)**
- **KB2040 G** to **TMC2209 2 GND (black wire)**
- **KB2040 D4** to **2.2K resistor (yellow wire)**
- **KB2040 D5** to **2.2K resistor (blue wire)**
- **TMC2209 2 UART** to **RX side of resistor (purple wire)**
- **TMC2209 2 1A** to **stepper motor coil 1 positive (green wire)**
- **TMC2209 2 1B** to **stepper motor coil 1 negative (yellow wire)**
- **TMC2209 2 2A** to **stepper motor coil 2 positive (red wire)**
- **TMC2209 2 2B** to **stepper motor coil 2 negative (black wire)**

# Motorized Camera Slider 2-Axis

## Ordering PCB

## OSH Park

The PCB is available to purchase from OSH park using the green button link below or from the [projects permalink](https://oshpark.com/shared_projects/F2j5I7a1).

![](https://cdn-learn.adafruit.com/assets/assets/000/136/785/medium640/3d_printing_oshpark-PCB.jpg?1747154927)

[Order PCB from OSH Park](https://oshpark.com/shared_projects/F2j5I7a1)
## JLCPCB / PCBWay

Alternative fabrication services like [JLCPCB](https://jlcpcb.com/) or [PCBWay](https://www.pcbway.com/) are great options. You can get your boards made quickly and just use the default options. The boards are made in 1-2 days, and DHL shipping to the US from China takes less than a week. Just upload the [gerber zip file](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/TMC2209_Camera_Slider/PCB_Files/TMC2209_Camera_Slider_PCB_revB_2025-05-12.zip) and follow the ordering proccess.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/786/medium640/3d_printing_JLCPCB.jpg?1747155509)

Danger: Note: At the time this guide was written, the tariff situation between the US and China was changing every several days. If there are tariffs for goods from China, JLCPCB and PCBWay orders may come with unexpected tariff costs. OSH Park is in the US and there are no tariff costs within the US. We suggest you do some research as to costs prior to placing an order with a PCB board vendor.

[Download PCB Gerber ZIP file from GitHub](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/TMC2209_Camera_Slider/PCB_Files/TMC2209_Camera_Slider_PCB_revB_2025-05-12.zip)
# Motorized Camera Slider 2-Axis

## CAD Files

## CAD Assembly

The main assembly is available in Fusion 360 and STEP file formats. This includes all of the 3D printed parts and electronic components used in the project. Use the main assembly to create any edits, updates, or modifications.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/136/736/medium640/3d_printing_cad-assembly.jpg?1746802205)

## 3D Printed Parts

Individual 3MF files for 3D printing are oriented and ready to print on FDM machines using PLA filament. Original design source may be downloaded using the links below.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/751/medium640/3d_printing_cad-all-parts.jpg?1747053264)

[Download 3MFs.zip](https://cdn-learn.adafruit.com/assets/assets/000/136/738/original/3MFs.zip?1746802328)
[Download CAD Source](https://cdn-learn.adafruit.com/assets/assets/000/136/741/original/CAD.zip?1746804629)
## Support Material

Enable support material for the left and right **Lever Cap** parts. In the **BambuStudio** slicing app, enable the **Support critical regions only** option under the Support section. This will only apply supports to the large surface areas that need support. In other slicing applications, support blockers might be need.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/755/medium640/3d_printing_slice-supports.jpg?1747061726)

## Build Volume

The parts require a 3D printer with a minimum build volume of:

- 140mm (X) x 170mm (Y) x 30mm (Z)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/739/medium640/3d_printing_cad-size.jpg?1746804340)

# Motorized Camera Slider 2-Axis

## Install CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_kb2040/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/655/medium640/install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg?1618943202)

![](https://cdn-learn.adafruit.com/assets/assets/000/108/852/medium800/adafruit_products_KeeBoar_boot_reset.jpg?1644515196)

To enter the bootloader, hold down the **BOOT/**** BOOTSEL button**(highlighted in red above), and while continuing to hold it (don't let go!), press and release the**reset button**(highlighted in red or blue above).&nbsp;**Continue to hold the BOOT/BOOTSEL button until the RPI-RP2 drive appears!**

If the drive does not appear, release all the buttons, and then repeat the process above.

You can also start with your board unplugged from USB, press and hold the BOOTSEL button (highlighted in red above), continue to hold it while plugging it into USB, and wait for the drive to appear before releasing the button.

A lot of people end up using charge-only USB cables and it is very frustrating! **Make sure you have a USB cable you know is good for data sync.**

You will see a new disk drive appear called **RPI-RP2**.

&nbsp;

Drag the **adafruit\_circuitpython\_etc.uf2** file to **RPI-RP2.**

![install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/656/medium640/install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg?1618943666)

![install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/657/medium640/install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg?1618943674)

The **RPI-RP2** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/658/medium640/install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg?1618943864)

## Safe Mode

You want to edit your **code.py** or modify the files on your **CIRCUITPY** drive, but find that you can't. Perhaps your board has gotten into a state where **CIRCUITPY** is read-only. You may have turned off the **CIRCUITPY** drive altogether. Whatever the reason, safe mode can help.

Safe mode in CircuitPython does not run any user code on startup, and disables auto-reload. This means a few things. First, safe mode _bypasses any code in_ **boot.py** (where you can set **CIRCUITPY** read-only or turn it off completely). Second, _it does not run the code in_ **code.py**. And finally, _it does not automatically soft-reload when data is written to the_ **CIRCUITPY** _drive_.

Therefore, whatever you may have done to put your board in a non-interactive state, safe mode gives you the opportunity to correct it without losing all of the data on the **CIRCUITPY** drive.

### Entering Safe Mode
To enter safe mode when using CircuitPython, plug in your board or hit reset (highlighted in red above). Immediately after the board starts up or resets, it waits 1000ms. On some boards, the onboard status LED (highlighted in green above) will blink yellow during that time. If you press reset during that 1000ms, the board will start up in safe mode. It can be difficult to react to the yellow LED, so you may want to think of it simply as a slow double click of the reset button. (Remember, a fast double click of reset enters the bootloader.)

### In Safe Mode

If you successfully enter safe mode on CircuitPython, the LED will intermittently blink yellow three times.

If you connect to the serial console, you'll find the following message.

```terminal
Auto-reload is off.
Running in safe mode! Not running saved code.

CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.

Press any key to enter the REPL. Use CTRL-D to reload.
```

You can now edit the contents of the **CIRCUITPY** drive. Remember, _your code will not run until you press the reset button, or unplug and plug in your board, to get out of safe mode._

## Flash Resetting UF2

If your board ever gets into a really _weird_ state and CIRCUITPY doesn't show up as a disk drive after installing CircuitPython, try loading this 'nuke' UF2 to RPI-RP2. which will do a 'deep clean' on your Flash Memory. **You will lose all the files on the board** , but at least you'll be able to revive it! After loading this UF2, follow the steps above to re-install CircuitPython.

[Download flash erasing "nuke" UF2](https://cdn-learn.adafruit.com/assets/assets/000/101/659/original/flash_nuke.uf2?1618945856)
# Motorized Camera Slider 2-Axis

## Code the Slider

Once you've finished setting up your KB2040 with CircuitPython, you can access the code, images, font and necessary libraries by downloading the Project Bundle.

To do this, click on the **Download Project Bundle** button in the window below. It will download to your computer as a zipped folder.

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

## Upload the Code and Libraries to the KB2040

After downloading the Project Bundle, plug your KB2040 into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called **CIRCUITPY**. Unzip the folder and copy the following items to the KB2040's **CIRCUITPY** drive.

- **lib** folder
- **code.py**
- **adafruit\_tmc2209.py**
- **generic\_uart\_device.py**
- **icons.bmp**
- **Arial-14.bdf**

Your KB2040 **CIRCUITPY** drive should look like this after copying the **lib** folder, image file, font file and the&nbsp; **Python** files.

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

## How the Code Works

There are three code files: **adafruit\_tmc2209.py** , **generic\_uart\_device.py** and the main **code.py**. **adafruit\_tmc2209.py** and **generic\_uart\_device.py** are driver files for the TMC2209 UART control. The **code.py** file depends on these files to control the TMC2209 drivers.

At the top of **code.py** are some user parameters. `RAILS` is the length of the rails in mm. `microsteps` are the number of microsteps used by the stepper motors. `gear_ratio` is the gear reduction for the camera pan mechanism. Finally, `shot_velocities` contains the one-shot speeds in seconds.

```python
RAILS = 520 # length of rails in mm
microsteps = 128
gear_ratio = 41 / 16

shot_velocities = [
    20,
    15,
    10
]
```

### Keypad, TFT and Encoder

The two end stop switches and the rotary encoder button are instantiated as a `Keypad` object. The TFT is controlled via SPI. The rotary encoder is wired directly to GPIO for `rotaryio`.

```python
keys = keypad.Keys((board.D2, board.A2, board.A3), value_when_pressed=False, pull=True)

encoder = rotaryio.IncrementalEncoder(board.D7, board.D6)
last_position = None

spi = board.SPI()
tft_cs = board.D10
tft_dc = board.D8

display_bus = FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=board.D9)

display = ST7789(display_bus, width=240, height=240, rowstart=80, auto_refresh=False)
```

### Graphics

The icons for the different menu options are on a single bitmap file ( **icons.bmp** ) and are used as a sprite sheet with `TileGrid`. There are two text objects: `title_text` and `text_area` that update depending on the menu.

```python
splash = displayio.Group()
display.root_group = splash

bitmap = displayio.OnDiskBitmap(open("/icons.bmp", "rb"))

grid_bg = displayio.TileGrid(bitmap, pixel_shader=bitmap.pixel_shader,
                             tile_height=100, tile_width=100,
                             x=(display.width - 100) // 2,
                             y=(display.height - 100) // 2)
splash.append(grid_bg)

text_group = displayio.Group()
font = bitmap_font.load_font("/Arial-14.bdf")
title_text = "Camera Slider"
title_area = label.Label(font, text=title_text, color=0xFFFFFF)
title_area.anchor_point = (0.5, 0.0)
title_area.anchored_position = (display.width / 2, 25)
text_group.append(title_area)
splash.append(text_group)

text_area = label.Label(font, text="", color=0xFFFFFF)
text_area.anchor_point = (0.5, 1.0)
text_area.anchored_position = (display.width / 2, display.height - 25)
text_group.append(text_area)
```

### TMC2209 UART

The two TMC2209 drivers are controlled over UART. Each driver is on its on UART line. Driver 1 uses the default UART ( **RX** and **TX** ) and driver 2 uses the secondary UART ( **D4** and **D5** ). The microsteps are set for each of the drivers, along with a starting direction.

```python
uart = busio.UART(tx=board.TX, rx=board.RX, baudrate=115200, timeout=0.1)

driver1 = TMC2209(uart=uart, addr=0)
driver2 = TMC2209(tx_pin=board.D4, rx_pin=board.D5, addr=0)

version1 = driver1.version
version2 = driver2.version
print(f"TMC2209 #1 Version: 0x{version1:02X}")
print(f"TMC2209 #2 Version: 0x{version2:02X}")

driver1.microsteps = microsteps
print(driver1.microsteps)
driver2.microsteps = microsteps
print(driver2.microsteps)

STEPS_PER_MM = 200 * microsteps / 8
driver1.direction = False
driver2.direction = True
```

### Menu

The menu system is the backbone of the project. It is used to navigate through setting up a shot sequence. The TFT displays icons and text that correspond with each menu scene. The `adv_menu()` function takes care of advancing the graphics.

```python
titles = ["Camera Slider", "Motor 1", "Motor 2", "Mode",
          "Timelapse", "One-Shot", "Start?", "Running"]
home_text = ["Press to Begin", "0"]
motor1_text = ["Slide to Start Point", "0"]
motor2_text = ["Move to Start", "Move to End", "0"]
mode_text = ["Timelapse", "One-Shot"]
time_text = ["1", "5", "10", "15", "30"]
shot_text = ["Slow", "Medium", "Fast"]
start_text = ["Go!", 0]
running_text = ["STOP!", "Pause/Resume"]
running_icons = [6, 7]
mode_icons = [3, 4]
sub_titles = [home_text, motor1_text, motor2_text, mode_text,
              time_text, shot_text, start_text, running_text]
text_area.text = home_text[0]

def adv_menu(m):
    m = (m + 1) % 8
    title_area.text = titles[m]
    sub = sub_titles[m]
    if m == 4:
        grid_bg[0] = 3
    elif m == 5:
        grid_bg[0] = 4
    elif m &gt; 5:
        grid_bg[0] = m - 1
    else:
        grid_bg[0] = m
    text_area.text = sub[0]
    display.refresh()
    return m
```

### Moving the Motors

Each driver has a dictionary to track its movement and start/pause/stop state throughout the different movement functions and the main loop.

```python
motor1_movement = {
    "is_active": False,
    "current_step": 0,
    "total_steps": 0,
    "start_pos": 0,
    "end_pos": 0,
    "step_direction": 1,
    "last_step_time": 0,
    "step_interval": 0,
    "is_paused": False,
    "toggle_pause": False,
    "stop_requested": False
}

motor2_movement = {
    "is_active": False,
    "current_step": 0,
    "total_steps": 0,
    "start_pos": 0,
    "end_pos": 0,
    "step_direction": 1,
    "last_step_time": 0,
    "step_interval": 0,
    "is_paused": False,
    "toggle_pause": False,
    "stop_requested": False
}
```

A few functions are used to control the motor movement. Driver 1, which moves the camera along the rails, has its own set of functions since it is moving a much longer distance than driver 2; which pans the camera. Both drivers utilize the velocity calculation from the datasheet:

```python
vactual = int(microsteps_per_second / (fCLK / (1 &lt;&lt; 24)))
vactual = max(-(1 &lt;&lt; 23), min((1 &lt;&lt; 23) - 1, vactual))
```

Velocity is used instead of individual steps because its a lot smoother and silent. The functions let you pass the time and number of steps and calculate the velocity from that. Additionally, with the combination of the dictionaries, both motors can be paused/resumed/stopped without blocking in the loop.

### The Loop

At the top of the loop, if either of the motors' `["is_active"]` parameter is `True`, it means that they are rotating. `ticks_ms()` is used to keep track of the time.&nbsp;

```python
while True:
    if motor1_movement["is_active"]:
        current_time = supervisor.ticks_ms()
        elapsed = current_time - motor1_movement["movement_start_time"]
        if elapsed &gt;= motor1_movement["movement_duration_ms"]:
            driver1.rotate(0)
            driver1.disable_motor()
            motor1_movement["is_active"] = False
    if motor2_movement["is_active"]:
        current_time = supervisor.ticks_ms()
        elapsed = current_time - motor2_movement["movement_start_time"]
        if elapsed &gt;= motor2_movement["movement_duration_ms"]:
            driver2.rotate(0)
            driver2.disable_motor()
            motor2_movement["is_active"] = False
```

`Keypad` events and the rotary encoder are used to navigate the menu system. When the rotary encoder button is pressed (`key_number 0`), the menu advances. It is also used to pause or stop the motors while they are moving through a shot. The end stop switches and rotary encoder have different functionality depending on the menu index. The display is updated with different text if the rotary encoder is used to scroll through options.

```python
event = keys.events.get()
    if event:
        if event.pressed:
            print(f"{event.key_number} pressed")
            if event.key_number == 0:
                if menu == 0:
                    menu = adv_menu(menu)
                elif menu == 2:
                    if select == 0:
                        motor2_coordinates[select] = driver2.position
                    if select == 1:
                        motor2_coordinates[select] = driver2.position
                    select += 1
                    text_area.text = motor2_text[select]
                    if select &gt; 1:
                        select = 0
                        menu = adv_menu(menu)
                        if motor2_coordinates[0] &gt; motor2_coordinates[1]:
                            move = motor2_coordinates[0] - motor2_coordinates[1]
                        else:
                            move = motor2_coordinates[1] - motor2_coordinates[0]
                            move = -move
                        driver2.step(move)
                elif menu == 3:
                    if select == 1:
                        timelapse = False
                        menu += 1
                        select = 0
                    else:
                        timelapse = True
                    menu = adv_menu(menu)
                elif menu == 4:
                    menu += 1
                    time_mode = select
                    menu = adv_menu(menu)
                    select = 0
                    print(f"{time_text[time_mode]}, timelapse: {timelapse}")
                elif menu == 5:
                    shot_mode = select
                    menu = adv_menu(menu)
                    select = 0
                    print(f"{shot_text[shot_mode]}, timelapse: {timelapse}")
                elif menu == 6:
                    menu = adv_menu(menu)
                    if timelapse:
                        movement_time = int(time_text[time_mode]) * 60
                        print(f"starting a timelapse for {time_text[time_mode]} minutes")
                        status1 = move_motor_with_rotate(
                            driver1,
                            motor1_movement,
                            start_position=0,
                            end_position=int(RAILS * STEPS_PER_MM),
                            duration_sec=movement_time,
                            microsteps=microsteps
                        )
                        if abs(motor2_coordinates[1] - motor2_coordinates[0]) &gt; 0:
                            velocity2 = move_steps_over_time(camera_driver=True,
                                                             start_position=motor2_coordinates[0],
                                                             end_position=motor2_coordinates[1],
                                                             time_seconds=movement_time,
                                                             microsteps=microsteps,
                                                             ratio=gear_ratio)
                            print(f"driver2 velocity is: {velocity2}")
                            driver2.enable_motor(run_current=25)
                            driver2.rotate(velocity2)
                            motor2_movement["is_active"] = True
                            motor2_movement["start_pos"] = motor2_coordinates[0]
                            motor2_movement["end_pos"] = motor2_coordinates[1]
                            motor2_movement["movement_start_time"] = supervisor.ticks_ms()
                            motor2_movement["movement_duration_ms"] = movement_time * 1000
                            motor2_movement["velocity"] = velocity2
                            motor2_movement["total_steps"] = (abs(motor2_coordinates[1] -
                                                                  motor2_coordinates[0]))
                    else:
                        print(f"starting a {shot_text[shot_mode]} one-shot")
                        movement_time = shot_velocities[shot_mode]
                        status1 = move_motor_with_rotate(
                            driver1,
                            motor1_movement,
                            start_position=0,
                            end_position=int(RAILS * STEPS_PER_MM),
                            duration_sec=movement_time,
                            microsteps=microsteps
                        )
                        if abs(motor2_coordinates[1] - motor2_coordinates[0]) &gt; 0:
                            velocity2 = move_steps_over_time(camera_driver=True,
                                                             start_position=motor2_coordinates[0],
                                                             end_position=motor2_coordinates[1],
                                                             time_seconds=movement_time,
                                                             microsteps=microsteps,
                                                             ratio=gear_ratio)
                            driver2.enable_motor(run_current=25)
                            driver2.rotate(velocity2)
                            motor2_movement["is_active"] = True
                            motor2_movement["start_pos"] = motor2_coordinates[0]
                            motor2_movement["end_pos"] = motor2_coordinates[1]
                            motor2_movement["movement_start_time"] = supervisor.ticks_ms()
                            motor2_movement["movement_duration_ms"] = movement_time * 1000
                            motor2_movement["velocity"] = velocity2
                            motor2_movement["total_steps"] = (abs(motor2_coordinates[1] -
                                                                  motor2_coordinates[0]))
                elif menu == 7:
                    if select == 0:
                        stop_all_motors()
                        text_area.text = "Stopping..."
                        menu = adv_menu(menu)
                    elif select == 1:
                        pause_resume_motor1()
                        pause_resume_motor2()
                        paused_state = motor1_movement["is_paused"] or motor2_movement["is_paused"]
                        text_area.text = "Paused" if paused_state else "Running"
                    display.refresh()
            if event.key_number == 1:
                if menu == 1:
                    driver1.direction = False
                    driver1.reset_position()
                    menu = adv_menu(menu)
                elif menu == 7:
                    stop_all_motors()
                    menu = adv_menu(menu)
            if event.key_number == 2:
                if menu == 1:
                    driver1.direction = True
                    driver1.reset_position()
                    menu = adv_menu(menu)
                elif menu == 7:
                    stop_all_motors()
                    menu = adv_menu(menu)
        display.refresh()
    pos = encoder.position
    if pos != last_pos:
        if pos &gt; last_pos:
            if menu == 2:
                driver2.step(-10)
            if menu == 3:
                select = (select + 1) % 2
                text_area.text = mode_text[select]
                grid_bg[0] = mode_icons[select]
            if menu == 4:
                select = (select + 1) % len(time_text)
                text_area.text = time_text[select]
            if menu == 5:
                select = (select + 1) % len(shot_text)
                text_area.text = shot_text[select]
            if menu == 7:
                select = (select + 1) % len(running_text)
                text_area.text = running_text[select]
                grid_bg[0] = running_icons[select]
        else:
            if menu == 2:
                driver2.step(10)
            if menu == 3:
                select = (select - 1) % 2
                text_area.text = mode_text[select]
                grid_bg[0] = mode_icons[select]
            if menu == 4:
                select = (select - 1) % len(time_text)
                text_area.text = time_text[select]
            if menu == 5:
                select = (select - 1) % len(shot_text)
                text_area.text = shot_text[select]
            if menu == 7:
                select = (select - 1) % len(running_text)
                text_area.text = running_text[select]
                grid_bg[0] = running_icons[select]
        last_pos = pos
        display.refresh()
```

# Motorized Camera Slider 2-Axis

## PCB Assembly

## PCB Parts

Gather up the components that will be soldered to the PCB. The various socket headers are cut to length using a 36-pin long strip. Follow the [How To Solder Headers](https://learn.adafruit.com/how-to-solder-headers/female-headers#cutting-female-headers-to-size-3076508) for a thorough tutorial.&nbsp;

- 2x 1x13 Socket Headers
- 2x 1x10 Socket Headers
- 1x11 Socket Header
- 1x4 Socket Header
- 1x Rotary Encoder
- 1x DC Jack
- 2x 2-pin 3.5mm Terminal Block
- 2x 2.5mm pitch JST XH connectors
- 2x 2.2k resistors

![](https://cdn-learn.adafruit.com/assets/assets/000/136/604/medium640/3d_printing_pcb-parts.jpg?1746547985)

Danger: Wear eye protection when cutting header parts. Often pieces fly through the air and could injure someone if not careful.

## Install Headers

Place the socket headers into their designated spots. Use mounting tack to keep them in place.

Flip the PCB and solder all of the pins in place.

Ensure all of the socket headers have been properly soldered.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/606/medium640/3d_printing_pcb-headers-front-install.jpg?1746548576)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/607/medium640/3d_printing_pcb-headers-front-solder.jpg?1746548893)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/608/medium640/3d_printing_pcb-headers-installed.jpg?1746548944)

## Install Header for Display

Place the 1x11 socket header into pins for the TFT display on the correct side of the PCB.

Flip the PCB over and solder the pins of the socket header in place.

Ensure all of the pins have been properly soldered.

&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/136/609/medium640/3d_printing_pcb-header-back-install.jpg?1746549003)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/610/medium640/3d_printing_pcb-header-back-solder.jpg?1746549541)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/611/medium640/3d_printing_pcb-header-back-installed.jpg?1746549575)

## Install DC Jack

Place the DC jack into the designated spot on the correct side of the PCB.

Flip the PCB over and solder the pins in place.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/613/medium640/3d_printing_pcb-dc-install.jpg?1746549848)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/614/medium640/3d_printing_pcb-dc-solder.jpg?1746549871)

## Install Terminal Blocks

Fit the terminal blocks into the designated spots on the correct side of the PCB.

Ensure the terminal blocks are in the correct orientation with the wire inserts facing inwards.

Flip the PCB over and solder the pins in place.

&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/136/615/medium640/3d_printing_pcb-blocks-install.jpg?1746550683)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/616/medium640/3d_printing_pcb-blocks-solder.jpg?1746550699)

## Install Rotary Encoder

Insert the rotary encoder into the designated spot on the correct side of the PCB.

Ensure the rotary encoder is fully seated before soldering.

Flip the PCB over and solder the pins in place.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/617/medium640/3d_printing_pcb-rotary-install.jpg?1746550879)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/618/medium640/3d_printing_pcb-rotary-solder.jpg?1746550903)

## Install JST Connectors

Insert the two JST XH connectors into the designated spots on the correct side of the PCB.

Ensure the connectors are oriented correctly.

Flip the PCB over and solder the pins in place.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/620/medium640/3d_printing_pcb-jst-install.jpg?1746551003)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/621/medium640/3d_printing_pcb-jst-solder.jpg?1746551061)

## Install Resistors

Insert the 2.2k resistors into the designated spots on the correct side of the PCB.

Flip the PCB over and solder the pins in place.

Trim the leads of the resistors using flush snips.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/622/medium640/3d_printing_pcb-resistors-install.jpg?1746551475)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/627/medium640/3d_printing_pcb-resistors-solder.jpg?1746552375)

## Soldered Components

Take a moment to ensure all of the components have been properly soldered to the PCB.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/629/medium640/3d_printing_pcb-soldered-back.jpg?1746552510)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/630/medium640/3d_printing_pcb-soldered-front.jpg?1746552527)

## Power Wires

Use the red and black 26AWG silicone wires to create two sets of wires. These will be used for the 2-pin terminal blocks.

Create two wires that are 4 inches (10cm)&nbsp; in length.

Create another set of wires that are 2 inches in length (5cm) in length.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/633/medium640/3d_printing_motor-power-wires.jpg?1746552690)

## Power Wires

Insert and secure the 4in (10cm) wires into the designated block terminal.

Insert and secure the shorter wires into the remaining block terminal.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/632/medium640/3d_printing_pcb-wires-install.jpg?1746552668)

## Install Boards

Install and solder the male headers to the TMC2209 stepper motor drivers, MPM3601 buck converter, KB2040 microcontroller and 1.3in TFT display.

Fit the various boards into their designated socket headers on the carrier PCB.

Insert the shorter power wires from the terminal block into the TMC2209 on the right. Red wire to + and black wire to -.

Insert the longer power wires from the terminal block into the TMC2209 on the left. Red wire to + and black wire to -.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/642/medium640/3d_printing_pcb-boards-front-install.jpg?1746553922)

## Install TFT Display

Fit the TFT display onto the designated socket headers on the correct side of the PCB.

Optionally install M2.5 (10mm tall) standoffs to the top tabs of the display.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/643/medium640/3d_printing_pcb-tft-install.jpg?1746554164)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/644/medium640/3d_printing_tft-standoffs-install.jpg?1746554182)

# Motorized Camera Slider 2-Axis

## Pan Assembly

Shorten the wires from the stepper motors so they're 8.5in (21.6cm) in length.

Gather up the parts for the pan assembly. Parts include:

- Camera Plate
- Pan Bearing Mount
- Stepper Gear 16T
- Stepper Motor
- 6008ZZ 2RS ball bearing
- 1/4"-20 Tripod Screw / Rubber Washers
- 4x M3 x 6mm screws
- 4x M3 x 14mm screws
- 4x M3 hex nuts

![](https://cdn-learn.adafruit.com/assets/assets/000/136/645/medium640/3d_printing_pan-assembly-parts.jpg?1746554582)

## Install Ball Bearing

Press fit the 6008-2RS into the center cavity of the pan bearing mount.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/647/medium640/3d_printing_pan-mount-bearing-install.jpg?1746556563)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/648/medium640/3d_printing_pan-mount-bearing-installed.jpg?1746556596)

## Install Stepper Motor

Place the stepper motor onto the pan mount with mounting holes lined up.

Insert and fasten the M3 x 6mm long screws to secure the stepper motor to the pan mount.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/649/medium640/3d_printing_pan-mount-motor-installing.jpg?1746556695)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/650/medium640/3d_printing_pan-mount-motor-secure.jpg?1746556725)

## Stepper Motor Wires

Insert the wires from the stepper motor through the center of the ball bearing.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/651/medium640/3d_printing_pan-mount-motor-installed.jpg?1746556879)

## Install Tripod Screw

Insert the tripod screw through the center hole in the camera plate. Use the rubber washer to keep the screw in place.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/652/medium640/3d_printing_cam-plate-screw-install.jpg?1746556940)

## Secure Camera Plate

Place the camera plate over the pan mount with the mounting holes lined up.

Insert the M3 x 14mm long screws through the camera plate standoffs and pan mount.

Use the M3 hex nuts to secure the parts together.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/653/medium640/3d_printing_cam-plate-pan-mount-install.jpg?1746557177)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/654/medium640/3d_printing_cam-plate-secure.jpg?1746557188)

## Install Pan Gear

Line up the 16T stepper gear with the shaft of the stepper motor.

Press fit the gear onto the shaft of the stepper motor.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/655/medium640/3d_printing_pan-motor-gear-installing.jpg?1746557526)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/656/medium640/3d_printing_pan-motor-gear-install.jpg?1746557559)

# Motorized Camera Slider 2-Axis

## Carriage Assembly

## Switch Plate

Gather up the two switches, switch mounting plates, and M3 hardware.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/657/medium640/3d_printing_switch-parts.jpg?1746558408)

## Secure Switches

Place the switch over the switch plate. Reference the photo for the correct orientation.

Insert two M3 x 16mm long screws through the mounting plate and switch. Use the M3 hex nuts to secure the parts together.

Repeat the installation process for the second switch.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/658/medium640/3d_printing_switch-plate-secure.jpg?1746558493)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/659/medium640/3d_printing_switches-plate-secure.jpg?1746558508)

## Battery Holder

Get the battery holder, carriage motor plate, switch assembles, and M3 x 8mm hardware.

&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/136/660/medium640/3d_printing_carriage-parts.jpg?1746558865)

## Secure Battery Holder

Place the battery holder down with the bottom side facing up.

Place the carriage motor plate over the battery holder with the mounting holes lined up.

Place the two switch plates over the carriage motor plate with the mounting holes lined up.

Insert and fasten the M3 x 8mm screws through the parts then use the M3 hex nuts to secure the parts together.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/661/medium640/3d_printing_carriage-bat-switches.jpg?1746559208)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/662/medium640/3d_printing_carriage-bat-switches-install.jpg?1746559355)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/663/medium640/3d_printing_carriage-bat-switches-secured.jpg?1746559379)

## Slider Stepper Motor

Shorten the wires from the stepper motor so they're 8in (20.3cm) in length.

Gather up the 36T timing pulley and four M3 x 6mm long machine screws.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/756/medium640/3d_printing_slide-motor-parts.jpg?1747062802)

## Secure Stepper Motor

Place the second stepper motor onto the carriage motor plate with the mounting holes lined up.

Secure the stepper motor using M3 x 6mm long screws.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/672/medium640/3d_printing_slide-motor-carriage-install.jpg?1746560713)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/673/medium640/3d_printing_slide-motor-carriage-secure.jpg?1746560739)

## Install Pulley

Slide the 36T timing pulley over the shaft of the stepper motor.

Tighten the two M4 set screws to secure the timing pulley in place.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/674/medium640/3d_printing_slide-motor-pulley-install.jpg?1746561014)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/675/medium640/3d_printing_slide-motor-pulley-secure.jpg?1746561054)

## Install AA Batteries

Insert and install eight AA batteries into the battery holder.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/664/medium640/3d_printing_batteries.jpg?1746559581)

## Secure Battery

Orient the battery holder with the battery mount

Clip the battery into the tabs of the battery mount. Slightly bend the tabs to fit the battery underneath the clips.

Ensure the battery is fitted into the mount in the correct orientation.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/665/medium640/3d_printing_carriage-bat-preinstall.jpg?1746559658)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/666/medium640/3d_printing_carriage-bat-holder-install.jpg?1746559772)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/667/medium640/3d_printing_carriage-bat-installed.jpg?1746559797)

## Carriage Gear

Gather up the Carriage top plate, 41T Gear and 4x M3x8mm long screws.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/668/medium640/3d_printing_carriage-gear-screws.jpg?1746560083)

## Install Carriage Gear

Place the 41T gear over the carriage top plate with the mounting holes lined up.

Insert and fasten the 4x M3x8mm long screws to secure the parts together.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/669/medium640/3d_printing_carriage-gear-installing.jpg?1746560457)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/670/medium640/3d_printing_carriage-gear-secure.jpg?1746560473)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/671/medium640/3d_printing_carriage-gear-secured.jpg?1746560489)

## Pulley Wheels

Gather up the four pulley wheels, M5 x 25mm long screws and hex nuts.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/676/medium640/3d_printing_wheels-screws.jpg?1746561583)

## Install Pulley Wheels

Place the four pulley wheels over the corner standoffs on the carriage motor plate.

Then, carefully place the carriage top plate over the motor plate with the corner standoffs lined up.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/677/medium640/3d_printing_wheels-place.jpg?1746561997)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/678/medium640/3d_printing_carriage-top-plate.jpg?1746562102)

## Sandwich Pulley Wheels

Insert the M5 x 25mm long screws through the carriage top plate, pulley wheels and carriage motor plate.

While holding the two carriage plates together, flip the whole carriage assembly and insert the M5 hex nuts into the cavities.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/679/medium640/3d_printing_carriage-top-screws.jpg?1746562132)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/680/medium640/3d_printing_carriage-pulley-wheels.jpg?1746562229)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/681/medium640/3d_printing_carriage-nuts-install.jpg?1746562254)

## Secure Carriage Plates

Fasten the four M5 screws while holding the hex nuts in place to secure the two carriage plates.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/682/medium640/3d_printing_carriage-nuts-secure.jpg?1746562478)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/683/medium640/3d_printing_carriage-wheels-secured.jpg?1746562562)

## Secure PCB Plate

Place the PCB plate over the carriage top plate with the two mounting holes lined up.

Insert and fasten two M3 x 8mm long machine screws through the mounting holes.

Use M3 hex nuts to secure the parts together.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/684/medium640/3d_printing_carriage-pcb-plate-preinstall.jpg?1746562635)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/685/medium640/3d_printing_carriage-pcb-plate-install.jpg?1746562648)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/686/medium640/3d_printing_carriage-pcb-plate-secure.jpg?1746562698)

## Pan Motor and Carriage

Get the pan motor assembly ready to install onto the carriage assembly.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/687/medium640/3d_printing_carriage-pan-preinstall.jpg?1746563176)

## Install Pan Motor

Insert the wires from the pan stepper motor through the center of the carriage gear assembly.

Press fit the pan motor assembly into the center of the carriage gear.

Ensure the 16T stepper gear and 41T carriage gear mesh together.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/136/688/medium640/3d_printing_pan-motor-wires-install.jpg?1746563373)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/689/medium640/3d_printing_pan-carriage-installing.jpg?1746563387)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/690/medium640/3d_printing_pan-carriage-installed.jpg?1746563402)

# Motorized Camera Slider 2-Axis

## Rail Assembly

## Extrusion Feet Bumpers

Get the left and right feet mounts and stick on rubber bumpers onto the corners. Reference the photo for correct placement.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/136/692/medium640/3d_printing_feet-bumper-install.jpg?1746563616)

## Install Extrusion

Insert the two aluminum extrusion through the square holes in the left foot mount.

Insert an M4 slim t-nut into the profile of the extrusion with the top mounting hole lined up.

Fasten an M4 x 8mm into the slim t-nut. Do not fully tighten yet, just enough for the screw to grab onto the t-nut.

&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/136/693/medium640/3d_printing_feet-extrusions-installing.jpg?1746563737)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/694/medium640/3d_printing_feet-extrusions-secure.jpg?1746563965)

## Install Carriage Assembly

Carefully slide the carriage assembly onto the two aluminum extrusions.

Ensure none of the wires are being kinked or obstructed by the carriage assembly.

The pulley wheels should fit into the profiles of the aluminum extrusion.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/695/medium640/3d_printing_carriage-extrusion-install.jpg?1746564092)

## Install Right Foot

Fit the two extrusions through the square holes on the right foot mount. Reference the photo for the correct orientation.

Insert an M4 slim t-nut into the profile of the extrusion with the top mounting hole lined up.

Fasten an M4x8mm screw into the slim t-nut. Do not fully tighten yet, just enough for the screw to grab onto the t-nut.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/696/medium640/3d_printing_carriage-extrusion-foot-install.jpg?1746564218)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/697/medium640/3d_printing_carriage-extrusion-foot-secure.jpg?1746564682)

## Timing Belt

Gather up the timing belt, end caps and M4 hardware.

Cut the timing belt to length using scissors or cutters. The belt should measure out to be approximately **116.4cm** ( **45in** or **3.75ft** ) long.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/698/medium640/3d_printing_belt-parts.jpg?1746569020)

## Install Endcaps

Locate the left foot and get the left end cap.

Place an M4 slim t-nut onto the profile of the aluminum extrusion. Reference the photo for the correct location.

Slip the left end cap onto the extrusion with the mounting hole lined up.

Fasten to secure he end cap to the extrusion.

Repeat this installation process for the right foot using the right end cap.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/699/medium640/3d_printing_endcap-extrusion-install.jpg?1746569129)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/700/medium640/3d_printing_endcap-extrusion-secure.jpg?1746569361)

## Tighten Feet

With the left and right feet not fully tightened yet, begin sliding the feet over to be flush with the end cap.

Then, tighten the screws to secure the feet to the extrusion.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/701/medium640/3d_printing_feet-extrusion-scoot.jpg?1746618516)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/702/medium640/3d_printing_feet-extrusion-B-scoot.jpg?1746618528)

## Install Timing Belt

Insert the end of the timing belt through the side of the extrusion where the timing pulley is located.&nbsp;

Continue to thread the timing belt through the profile and under the pulley wheels.

Pull the timing belt over the 36T pulley that is secured to the stepper motor.

Keep the timing belt taught while threading to the opposite end of the extrusion.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/703/medium640/3d_printing_belt-extrusion-install.jpg?1746618549)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/704/medium640/3d_printing_belt-pulley-fit.jpg?1746618564)

## Lock and Tension Belt

Insert the timing belt under the other foot and through the slit on the end cap.

While holding the end of the timing belt, pull the level to lock the timing belt in place. The lever should bite into the belt.

On the other end, pull the timing belt so its taught and proceed to pull the lever on the end cap to lock the belt into place.

Cut the timing belt to length if it's too long. Tuck any excess under the end cap so it's going inside the profile of the extrusion.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/705/medium640/3d_printing_belt-extrusion-B-install.jpg?1746619058)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/706/medium640/3d_printing_endcap-belt-tighten.jpg?1746619069)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/707/medium640/3d_printing_endcap-belt-tuck.jpg?1746619101)

## Connect Switches

Orient the slider assembly so the PCB plate is facing you.

Then, locate the quick connect cable that is attached to the left switch. Plug that cable into the JST XH connector labeled A2 on the PCB.

Locate the cable for the right switch and plug that into the A3 labeled connector on the PCB.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/708/medium640/3d_printing_pcb-switches-connect.jpg?1746619122)

## Connect Motors

Locate the wires from the stepper motor with the timing pulley. Connect those wires into the block terminal of the stepper driver with the label MOTOR 1.

- B- (blue wire) from stepper motor to 2B pin on TMC2209&nbsp;
- B+ (red wire) from stepper motor to 2A pin on TMC2209
- A+ (black wire) from stepper motor to 1A pin on TMC2209
- A- (green wire) from stepper motor to 1B pin on TMC2209

Use a screwdriver to secure the wires to the terminal blocks on the stepper driver.

Repeat this process for the panning stepper motor with the wires connecting to MOTOR 2.

&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/136/709/medium640/3d_printing_pcb-motors-wires-secure.jpg?1746619160)

## PCB Standoffs

Use M3 sized standoffs and hardware to secure the PCB to the PCB mounting plate.

Combine the 10mm long and 6mm long M3 standoffs to create a 16mm long standoff.

Create four sets of extended M3 standoffs.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/710/medium640/3d_printing_pcb-standoffs.jpg?1746619200)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/711/medium640/3d_printing_standoffs-join.jpg?1746619423)

## Secure PCB&nbsp;

Install the 16mm long standoffs to the corner mounting holes on the PCB mounting plate. Finger tighten the hardware.

Place the PCB over the standoffs with the corner mounting holes lined up with the standoffs.

Insert and fasten M3 screws to secure the PCB to the PCB mounting plate.

&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/136/712/medium640/3d_printing_standoffs-pcb-plate-secure.jpg?1746619250)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/713/medium640/3d_printing_pcb-plate-installing.jpg?1746619312)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/714/medium640/3d_printing_pcb-plate-secure.jpg?1746619358)

## Power Plug

Grab the DC barrel from the battery holder and plug it into the DC jack on the PCB.

Use the on/off switch built-into the battery holder to power the circuit on.

The TFT display will power on.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/715/medium640/3d_printing_pcb-dc-plug.jpg?1746619376)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/716/medium640/3d_printing_power-test.jpg?1746619385)

## Install Rotary Crank

Orient the 3D printed crank with the shaft of the rotary encoder.

Firmly press the crank over the shaft of the rotary encoder until it's fully seated.

Rotate the crank to turn the shaft of the rotary encoder.

Press the hinge of the crank to actuate the select button that's built into the rotary encoder.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/717/medium640/3d_printing_rotary-crank-install.jpg?1746619411)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/718/medium800/3d_printing_final-build.jpg?1746619411 )

## Final Build

Congratulations on your build!&nbsp;

Proceed to the Usage page for documentation on how to set up shoots and use the UI to get going with the motorized camera slider.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/757/medium800thumb/3d_printing_thumb-loop.jpg?1747063011 )

# Motorized Camera Slider 2-Axis

## Usage

## Start Slide

Turn on the power, then press the rotary encoder to begin.

Move the carriage to either the far left or right side of the railing until the switch is actuated.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/760/medium640thumb/3d_printing_start.jpg?1747075046)

## Start Pan Motor Angle

Turn the rotary encoder left or right to the desired starting angle. Press the rotary encoder to set this as the starting pan angle.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/761/medium640thumb/3d_printing_motor2-start.jpg?1747075772)

## End Pan Motor Angle

Turn the rotary encoder left or right to the desired ending angle. Press the rotary encoder to set this as the ending pan angle. Wait for the motor to move back to the start angle.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/763/medium640thumb/3d_printing_motor2-end.jpg?1747076416)

## Set Mode

Turn the rotary encoder to select either Timelapse or One Shot mode. Press the rotary encoder to choose the selected mode.

**Timelapse Mode:** Use for long captures. Options are 1, 5, 10, 15 and 30 minutes.

**One Shot Mode:** Use for short video clips. Options are slow (20 seconds), medium (15 seconds) and fast (10 seconds).

![](https://cdn-learn.adafruit.com/assets/assets/000/136/764/medium640thumb/3d_printing_modes-loop.jpg?1747076506)

## Go

Before starting the slide, take a moment to start video recording or trigger the timelapse on your camera.

Press the rotary encoder to start the stepper motors.

The stepper motors will go through their assigned motions and then stop when the carriage reaches the end of the rail, the panning motor reach the end position, and the end stop switch has been triggered.&nbsp;

The display will return to the start screen. Repeat the setup progress to start a new session.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/765/medium640thumb/3d_printing_go.jpg?1747076602)


## Featured Products

### Adafruit KB2040 - RP2040 Kee Boar Driver

[Adafruit KB2040 - RP2040 Kee Boar Driver](https://www.adafruit.com/product/5302)
A wild Kee Boar appears! It’s a shiny **KB2040**! An Arduino Pro Micro-shaped board for Keebs with RP2040. (#keeblife 4 evah) A lot of folks like using Adafruit parts for their Keeb builds – but with the ItsyBitsy not being pin-compatible with the Pro Micro pinout, it...

In Stock
[Buy Now](https://www.adafruit.com/product/5302)
[Related Guides to the Product](https://learn.adafruit.com/products/5302/guides)
### MPM3610 5V Buck Converter Breakout - 21V In 5V Out at 1.2A

[MPM3610 5V Buck Converter Breakout - 21V In 5V Out at 1.2A](https://www.adafruit.com/product/4739)
This little buck converter based on the MPM3610 is a marvel, taking up to 21V input and providing a 5V output with up to 1.2A current. It's great for supplying power to popular 5V voltage circuits from a range of battery or power options. &nbsp;This chip provides up to 1.2 Amp load current...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4739)
[Related Guides to the Product](https://learn.adafruit.com/products/4739/guides)
### Adafruit 1.3" 240x240 Wide Angle TFT LCD Display with MicroSD

[Adafruit 1.3" 240x240 Wide Angle TFT LCD Display with MicroSD](https://www.adafruit.com/product/4313)
We've been looking for a display like this for a long time - it's **so small** only 1.3" diagonal but has a high density 260 ppi, 240x240 pixel display with full-angle viewing. It _looks_ a lot like our 1.44" 128x128 display, but has 4x as many pixels and...

In Stock
[Buy Now](https://www.adafruit.com/product/4313)
[Related Guides to the Product](https://learn.adafruit.com/products/4313/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)
### 8 x AA battery holder with 5.5mm/2.1mm Plug and On/Off Switch

[8 x AA battery holder with 5.5mm/2.1mm Plug and On/Off Switch](https://www.adafruit.com/product/875)
Make a portable power brick with plenty of juice! Use Alkaline AA's for a 12V 3000-4000mAh power supply, or rechargeable NiMH for 2000mAh 9.6V supply. Either one is good for running electronics that have a 5V voltage regulator (thus requiring a 7V+ supply) or perhaps some motors or...

In Stock
[Buy Now](https://www.adafruit.com/product/875)
[Related Guides to the Product](https://learn.adafruit.com/products/875/guides)
### Adafruit TMC2209 Stepper Motor Driver Breakout Board

[Adafruit TMC2209 Stepper Motor Driver Breakout Board](https://www.adafruit.com/product/6121)
Stepper motors are used for CNC machines, 3D printers, and whenever else one needs precise, powerful motion. But to get good behavior from steppers you need a motor driver chip that can provide high bursts of current, and for smooth motion, be able to PWM that current for microstepping...

Out of Stock
[Buy Now](https://www.adafruit.com/product/6121)
[Related Guides to the Product](https://learn.adafruit.com/products/6121/guides)
### 2.5mm Pitch Connector Kit - JST XH Compatible - 560 Piece Kit

[2.5mm Pitch Connector Kit - JST XH Compatible - 560 Piece Kit](https://www.adafruit.com/product/4423)
Totaling 560 pieces, this&nbsp; **2.5mm&nbsp;Connector Kit with&nbsp;JST-XH Compatible Connectors** &nbsp;is a must-have for your workstation.&nbsp;You'll have enough sockets and headers to fuel your maker tendencies&nbsp;for days on end!

These connectors are really common...

In Stock
[Buy Now](https://www.adafruit.com/product/4423)
[Related Guides to the Product](https://learn.adafruit.com/products/4423/guides)
### Arcade Button and Switch Quick-Connect Wires - 0.187" (10-pack)

[Arcade Button and Switch Quick-Connect Wires - 0.187" (10-pack)](https://www.adafruit.com/product/3835)
Quick connector wire sets make wiring up our arcade-style or metal buttons quicky-quick. Each wire comes as a 'pair' with two 0.187" quick-connects pre-crimped. The wires are terminated together in a JST 2.5mm 2-pin connector. This connector will fit in 0.1" headers,...

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

## Related Guides

- [Adafruit 1.3" and 1.54" 240x240 Wide Angle TFT LCD Displays](https://learn.adafruit.com/adafruit-1-3-and-1-54-240-x-240-wide-angle-tft-lcd-displays.md)
- [Adafruit KB2040](https://learn.adafruit.com/adafruit-kb2040.md)
- [Adafruit TMC2209 Stepper Motor Driver Breakout Board](https://learn.adafruit.com/adafruit-tmc2209-stepper-motor-driver-breakout-board.md)
- [Breakbeat Breadboard](https://learn.adafruit.com/breakbeat-breadboard.md)
- [CircuitPython Animated Sprite Pendants](https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters.md)
- [Planetary Gear Dreidels](https://learn.adafruit.com/planetary-gear-dreidels.md)
- [4x12 Ortho Mechanical Keyboard](https://learn.adafruit.com/4x12-ortho-mechanical-keyboard.md)
- [Fisher-Price USB Controller](https://learn.adafruit.com/fisher-price-usb-controller.md)
- [See N Say Brain Transplant](https://learn.adafruit.com/see-n-say-brain-transplant.md)
- [Stepper Motor Turntable](https://learn.adafruit.com/stepper-motor-turntable.md)
- [DOOM Keeb](https://learn.adafruit.com/doom-keeb.md)
- [Commodore Keyboard to USB HID with CircuitPython](https://learn.adafruit.com/commodore-keyboard-to-usb-hid-with-circuitpython.md)
- [Navi10 MacroPad with KB2040 and KMK CircuitPython keyboard firmware](https://learn.adafruit.com/navi10-macropad-with-kb2040-and-kmk-circuitpython-keyboard-firmware.md)
- [PB Gherkin 30% keyboard with KMK, CircuitPython, & KB2040](https://learn.adafruit.com/pb-gherkhin-30-keyboard-with-kmk-circuitpython-kb2040.md)
- [USB MIDI Keyset Controller](https://learn.adafruit.com/midi-keyset.md)
- [Rotary Phone Dial Keypad](https://learn.adafruit.com/rotary-phone-dial-keypad.md)
- [May Pad Macropad with the KB2040, KMK, and CircuitPython](https://learn.adafruit.com/maypad-macropad-with-the-kb2040-kmk-and-circuitpython.md)
