# Scrolling Countdown Timer

## Overview

https://youtu.be/_ds7ru2SQKk

## Countdown

Build an IoT countdown clock using Adafruit QT Py ESP32-S2, alphanumeric STEMMA QT displays and CircuitPython!&nbsp;

The alphanumeric displays text that scrolls the time remaining until your next exciting event!

![3d_printing_hero-xmas.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/137/medium640/3d_printing_hero-xmas.jpg?1671138302)

This uses three alphanumeric displays daisy chained together using I2C STEMMA QT cables.

The electronics are housed in a 3D printed stand that snap fits together for any easy assembly.

![adafruit_io_hero-qtpy.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/170/medium640/adafruit_io_hero-qtpy.jpg?1671475602)

![](https://cdn-learn.adafruit.com/assets/assets/000/117/139/medium800/3d_printing_hero-xmas-wide.jpg?1671138482)

## Necessary Hardware

The following hardware is needed to complete this project.

### QT Py ESP32-S2 Microcontroller

You need only **one** of the following boards.

Featured
### Adafruit QT Py ESP32-S2 WiFi Dev Board with STEMMA QT

[Adafruit QT Py ESP32-S2 WiFi Dev Board with STEMMA QT](https://www.adafruit.com/product/5325)
What has your favorite Espressif WiFi microcontroller, comes with&nbsp;[our favorite connector - the STEMMA QT](http://adafruit.com/stemma), a chainable I2C port, and has lots of Flash and RAM memory for your next IoT project? What will make your next IoT project flyyyyy? What a...

In Stock
[Buy Now](https://www.adafruit.com/product/5325)
[Related Guides to the Product](https://learn.adafruit.com/products/5325/guides)
![Angled shot of small square purple dev board.](https://cdn-shop.adafruit.com/640x480/5325-12.jpg)

### Quad Alphanumeric Display STEMMA QT Backpacks

This project requires **three** alphanumeric display backpacks and **three pairs** of the alphanumeric displays. **The backpacks are bundled with the displays.**

The bundles are available with displays in red, green, blue, white, and yellow. Only blue is included below. Check the Featured Products on the right side of this page to find links to the others.

Featured
### Quad Alphanumeric Display - Blue 0.54" Digits w/ I2C Backpack

[Quad Alphanumeric Display - Blue 0.54" Digits w/ I2C Backpack](https://www.adafruit.com/product/1912)
Display, elegantly, 012345678 or 9! Gaze, hypnotized, at ABCDEFGHIJKLM - well it can display the whole alphabet. You get the point. This is a nice, bright alphanumeric display that shows letters and numbers in a beautiful blue hue. It's super bright and designed for viewing from distances...

In Stock
[Buy Now](https://www.adafruit.com/product/1912)
[Related Guides to the Product](https://learn.adafruit.com/products/1912/guides)
![Overhead video of an assembled 14-segment LED backpack, emitting the follow text in blue LEDS: "AdaFruit 14-Segment Backpack"](https://cdn-shop.adafruit.com/product-videos/640x480/1912-06.jpg)

### STEMMA QT Cable

You will need **three** of the following cables.

Any length will work, but the 50mm cable is the best option because it leaves the least amount of excess cable behind the displays.

Featured
### STEMMA QT / Qwiic JST SH 4-Pin Cable - 50mm Long

[STEMMA QT / Qwiic JST SH 4-Pin Cable - 50mm Long](https://www.adafruit.com/product/4399)
This 4-wire cable is&nbsp;50mm / 1.9" long and fitted with JST SH female 4-pin connectors on both ends. Compared with the chunkier JST PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert and remove.

<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4399)
[Related Guides to the Product](https://learn.adafruit.com/products/4399/guides)
![Angled of of JST SH 4-Pin Cable.](https://cdn-shop.adafruit.com/640x480/4399-00.jpg)

### Power

To power the project, you can use a USB C cable plugged into a USB battery or a USB port on your computer.

Featured
### Pink and Purple Woven USB A to USB C Cable - 1 meter long

[Pink and Purple Woven USB A to USB C Cable - 1 meter long](https://www.adafruit.com/product/5153)
This cable is not only super-fashionable, with a woven pink and purple Blinka-like pattern, it's also made for USB C for our modernized breakout boards, Feathers, and more.&nbsp;&nbsp;[If you want something just like it but for Micro B, we...](https://www.adafruit.com/product/4111)

Out of Stock
[Buy Now](https://www.adafruit.com/product/5153)
[Related Guides to the Product](https://learn.adafruit.com/products/5153/guides)
![Angled shot of coiled pink and purple USB cable with USB A and USB C connectors.](https://cdn-shop.adafruit.com/640x480/5153-02.jpg)

# Scrolling Countdown Timer

## CAD Files

## CAD Parts List

STL files for 3D printing are oriented to print "as-is" on FDM style machines. Parts are designed to 3D print without any support material with PLA filament. Original design source may be downloaded using the links below:

- cdt-plate.stl
- cdt-qt-mount.stl
- cdt-base.stl

![3d_printing_cura-slice.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/101/medium640/3d_printing_cura-slice.jpg?1671111183)

[Download STLs.zip](https://cdn-learn.adafruit.com/assets/assets/000/117/105/original/STLs.zip?1671115017)
[Download CAD Source](https://cdn-learn.adafruit.com/assets/assets/000/117/106/original/CAD.zip?1671115849)
## Build Volume

The parts require a 3D printer with a minimum build volume.

- 166mm (X) x 78mm (Y) x 50mm (Z)

![3d_printing_cura-bedsize.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/102/medium640/3d_printing_cura-bedsize.jpg?1671111326)

## CAD Assembly

The QT Py is snap fitted into the QT Py mount. the QT Py mount is secured to the base with two M2.5 screws and hex nuts. The three alphanumeric displays are press fitted into the open cutouts on the plate. The plate is press fitted into the slot on the base.&nbsp;

![3d_printing_cad-explode.gif](https://cdn-learn.adafruit.com/assets/assets/000/117/103/medium640thumb/3d_printing_cad-explode.jpg?1671114579)

## Design Source Files

The project assembly was designed in Fusion 360. This can be downloaded in different formats like STEP, STL and more. Electronic components like Adafruit's boards, displays, connectors and more can be downloaded from the&nbsp;[Adafruit CAD parts GitHub Repo](https://github.com/adafruit/Adafruit_CAD_Parts/).

![3d_printing_5325_QTPy_ESP32S2.gif](https://cdn-learn.adafruit.com/assets/assets/000/117/104/medium640thumb/3d_printing_5325_QTPy_ESP32S2.jpg?1671114773)

# Scrolling Countdown Timer

## 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_qtpy_esp32s2/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_most_boards_CircuitPython_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/102/129/medium640/install_circuitpython_on_most_boards_CircuitPython_downloaded.jpg?1620922559)

![](https://cdn-learn.adafruit.com/assets/assets/000/107/612/medium800/adafruit_products_QTESP_reset_NeoPixel.jpg?1641246436)

Info: The board above has a chip antenna, not the u.Fl connector, but the process is the same.

Plug your board into your computer, using a known-good data-sync cable, directly, or via an adapter if needed.

Click the **reset** button once (highlighted in red above), and then click it again when you see the **RGB status LED(s)** (highlighted in green above) turn purple (approximately half a second later). Sometimes it helps to think of it as a "slow double-click" of the reset button.

If you do not see the LED turning purple, you will need to reinstall the UF2 bootloader. See the&nbsp; **Factory Reset** &nbsp;page in this guide for details.

On some very old versions of the UF2 bootloader, the status LED turns red instead of purple.

For this board, tap reset and wait for the LED to turn purple, and as soon as it turns purple, tap reset again. The second tap needs to happen while the LED is still purple.

Once successful, you will see the **RGB status LED(s)** turn green (highlighted in green above), and a disk drive ending in " **...BOOT**" should appear on your host computer. If you see red, try another port, or if you're using an adapter or hub, try without the hub, or different adapter or hub.

If double-clicking doesn't work the first time, try again. Sometimes it can take a few tries to get the rhythm right!

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.**

Info: 

You will see a new disk drive appear called **QTPYS2BOOT**.

&nbsp;

&nbsp;

Drag the **adafruit\_circuitpython\_etc.uf2** file to **QTPYS2BOOT**.

![adafruit_products_uf2install.png](https://cdn-learn.adafruit.com/assets/assets/000/107/577/medium640/adafruit_products_uf2install.png?1640641747)

Copy or drag the UF2 file you downloaded to the **BOOT** drive.

The **BOOT** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it!

![install_circuitpython_on_most_boards_CIRCUITPY.jpg](https://cdn-learn.adafruit.com/assets/assets/000/102/130/medium640/install_circuitpython_on_most_boards_CIRCUITPY.jpg?1620923145)

# Scrolling Countdown Timer

## Create Your settings.toml File

CircuitPython works with WiFi-capable boards to enable you to make projects that have network connectivity. This means working with various passwords and API keys. As of [CircuitPython 8](https://circuitpython.org/downloads), there is support for a **settings.toml** file. This is a file that is stored on your **CIRCUITPY** drive, that contains all of your secret network information, such as your SSID, SSID password and any API keys for IoT services. It is designed to separate your sensitive information from your **code.py** file so you are able to share your code without sharing your credentials.

CircuitPython previously used a **secrets.py** file for this purpose. The **settings.toml** file is quite similar.

Warning: Your **settings.toml** file should be stored in the main directory of your **CIRCUITPY** drive. It should not be in a folder.

## CircuitPython **settings.toml** File

This section will provide a couple of examples of what your **settings.toml** file should look like, specifically for CircuitPython WiFi projects in general.

The most minimal **settings.toml** file must contain your WiFi SSID and password, as that is the minimum required to connect to WiFi. Copy this example, paste it into your **settings.toml** , and update:

- `your_wifi_ssid`
- `your_wifi_password`

```auto
CIRCUITPY_WIFI_SSID = "your_wifi_ssid"
CIRCUITPY_WIFI_PASSWORD = "your_wifi_password"
```

Many CircuitPython network-connected projects on the Adafruit Learn System involve using Adafruit IO. For these projects, you must _also_ include your Adafruit IO username and key. Copy the following example, paste it into your settings.toml file, and update:

- `your_wifi_ssid`
- `your_wifi_password`
- `your_aio_username`
- `your_aio_key`

```auto
CIRCUITPY_WIFI_SSID = "your_wifi_ssid"
CIRCUITPY_WIFI_PASSWORD = "your_wifi_password"
ADAFRUIT_AIO_USERNAME = "your_aio_username"
ADAFRUIT_AIO_KEY = "your_aio_key"
```

Some projects use different variable names for the entries in the **settings.toml** file. For example, a project might use `ADAFRUIT_AIO_ID` in the place of `ADAFRUIT_AIO_USERNAME`. **If you run into connectivity issues, one of the first things to check is that the names in the settings.toml file match the names in the code.**

Warning: Not every project uses the same variable name for each entry in the **settings.toml** file! Always verify it matches the code.

## **settings.toml** File Tips
Here is an example **settings.toml** file.

```auto
# Comments are supported
CIRCUITPY_WIFI_SSID = "guest wifi"
CIRCUITPY_WIFI_PASSWORD = "guessable"
CIRCUITPY_WEB_API_PORT = 80
CIRCUITPY_WEB_API_PASSWORD = "passw0rd"
test_variable = "this is a test"
thumbs_up = "\U0001f44d"
```

In a **settings.toml** file, it's important to keep these factors in mind:

- Strings are wrapped in double quotes; ex: `"your-string-here"`
- Integers are _ **not** _ quoted and may be written in decimal with optional sign (`+1`, `-1`, `1000`) or hexadecimal (`0xabcd`).
  - Floats (decimal numbers), octal (`0o567`) and binary (`0b11011`) are not supported.

- Use `\u` escapes for weird characters, `\x` and `\ooo` escapes are not available in **.toml** files
  - Example: `\U0001f44d` for 👍 (thumbs up emoji) and `\u20ac` for € (EUR sign)

- Unicode emoji, and non-ASCII characters, stand for themselves as long as you're careful to save in "UTF-8 without BOM" format

&nbsp;

&nbsp;

When your&nbsp; **settings.toml&nbsp;** file is ready, you can save it in your text editor with the **.toml** &nbsp;extension.

![adafruit_products_dotToml.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/071/medium640/adafruit_products_dotToml.jpg?1671034293)

## Accessing Your **settings.toml** Information in **code.py**
In your **code.py** file, you'll need to `import` the `os` library to access the **settings.toml** file. Your settings are accessed with the `os.getenv()` function. You'll pass your settings entry to the function to import it into the **code.py** file.

```python
import os

print(os.getenv("test_variable"))
```

![](https://cdn-learn.adafruit.com/assets/assets/000/117/072/medium800/adafruit_products_tomlOutput.jpg?1671034496)

In the upcoming CircuitPython WiFi examples, you'll see how the **settings.toml&nbsp;** file is used for connecting to your SSID and accessing your API keys.

# Scrolling Countdown Timer

## Environment Variables Docs

# Scrolling Countdown Timer

## Code the Timer

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

To do this, click on the **&nbsp;Download Project Bundle** &nbsp;button in the window below. It will download as a zipped folder.

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

## Upload the Code and Libraries to the QT Py

After downloading the Project Bundle, plug your QT Py ESP32-S2 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&nbsp; **CIRCUITPY**. Unzip the folder and copy the following folder and file to the QT Py's **CIRCUITPY** &nbsp;drive.

- **/lib**
- **code.py**

**Copy the entire lib folder, including all of its contents.**

Your QT Py **CIRCUITPY&nbsp;** drive should resemble the following after copying the&nbsp; **lib** &nbsp;folder and the&nbsp; **code.py&nbsp;** file.

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

## Add Your **settings.toml** File

Remember to add your **settings.toml** file as described in the [Create Your settings.toml File page](https://learn.adafruit.com/scrolling-countdown-timer/create-your-settings-toml-file) earlier in the guide. You'll need to include your `CIRCUITPY_WIFI_SSID`, `CIRCUITPY_WIFI_PASSWORD`, `aio_username` and `aio_key` in the file.

```auto
CIRCUITPY_WIFI_SSID = "your-wifi-ssid-here"
CIRCUITPY_WIFI_PASSWORD = "your-wifi-password-here"

aio_username = "your-Adafruit-IO-username-here"
aio_key = "your-Adafruit-IO-key-here"
```

## How the CircuitPython Code Works

The code begins by assigning a series of variables and a separate single variable. These variables are assigned at the top to enable the user to easily find them in the event they would like to update them.

The series of variables is used to indicate the name, time and date of the event, and the message that will be displayed when the event has started.

```python
EVENT_YEAR = 2022
EVENT_MONTH = 12
EVENT_DAY = 25
EVENT_HOUR = 0
EVENT_MINUTE = 0
EVENT_NAME = "Christmas"
EVENT_MSG = "Merry Christmas * "
```

The separate single variable sets the scroll speed of the text across the displays.

```python
scroll_speed = 0.25
```

## Alphanumeric Setup
The next section sets up the three displays in series on I2C via the STEMMA QT connector on the QT Py.

**The provided I2C addresses assume you did not solder any address jumpers on the back of the first display, soldered A0 on the back of the second display, and soldered A1 on the back of the third display.** If you did not do the same, you may need to change the addresses to match.

```python
i2c = board.STEMMA_I2C()
display = Seg14x4(i2c, address=(0x70, 0x71, 0x72))
```

Info: 

Then you set the brightness to `0.2` out of a range of 0.0 to 1.0, and you print "HELLO WORLD" to the display to give you an indicator of whether everything is wired up and initiated properly.

```python
display.brightness = 0.2
display.print("HELLO WORLD")
```

## Reset On Error
Next is the `reset_on_error()` function. When the code encounters an error, this function resets the microcontroller after a specified delay. This resets everything, and gives it an opportunity to begin fresh, which can clear up many potential errors.

```python
def reset_on_error(delay, error):
    print("Error:\n", str(error))
    display.print("Error :(")
    print("Resetting microcontroller in %d seconds" % delay)
    time.sleep(delay)
    microcontroller.reset()
```

## Connect
Then, the QT Py connects to your WiFi network, followed by Adafruit IO. Both of these connection attempts are wrapped in `try`/`except` loops so that the code does not get stuck in the event of an error. Rather, the board will reset and try connecting again.&nbsp;

```python
try:
    wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
# any errors, reset MCU
except Exception as e:  # pylint: disable=broad-except
    reset_on_error(10, e)

aio_username = os.getenv("aio_username")
aio_key = os.getenv("aio_key")
location = os.getenv("aio_location")

pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
# Initialize an Adafruit IO HTTP API object
try:
    io = IO_HTTP(aio_username, aio_key, requests)
except Exception as e:  # pylint: disable=broad-except
    reset_on_error(10, e)
print("Connected to Adafruit IO")
display.print("Connected IO")
```

## Timekeeping
Right before the loop, `clock` is setup as a `time.monotonic()` device for timekeeping, `event_time` packs the event variables into a `struct_time()` format and `scroll_time` is set to `0`. `scroll_time` is used to dynamically adjust the length of time needed to scroll the countdown information across the displays. It's used to loop the countdown as seamlessly as possible.

```python
clock = time.monotonic()

event_time = time.struct_time(
    (EVENT_YEAR, EVENT_MONTH, EVENT_DAY, EVENT_HOUR, EVENT_MINUTE, 0, -1, -1, False)
)
scroll_time = 0
```

## The Loop
In the loop, after `scroll_time` has passed, Adafruit IO is pinged to get the current time. Then the current time is subtracted from the event time to find how much time is remaining. This calculation is done by passing `event_time` and `now` to the `mktime()` function, which converts `struct_time()` format to seconds. The result of this is stored in `remaining`.

```python
if (clock + scroll_time) < time.monotonic():
            now = io.receive_time()
            # print(now)
            # print(event_time)
            remaining = time.mktime(event_time) - time.mktime(now)
```

If `remaining` is less than zero, then that means that the day of your event is here and the text you stored in `EVENT_MSG` is scrolled across the displays on a loop.

```auto
# if it's the day of the event...
if remaining < 0:
      # scroll the event message on a loop
      display.marquee(EVENT_MSG, scroll_speed, loop=True)
```

Otherwise, the seconds remaining are calculated back into days, hours, minutes and seconds. These values are packed into the `countdown_string`.

```python
# calculate the seconds remaining
            secs_remaining = remaining % 60
            remaining //= 60
            # calculate the minutes remaining
            mins_remaining = remaining % 60
            remaining //= 60
            # calculate the hours remaining
            hours_remaining = remaining % 24
            remaining //= 24
            # calculate the days remaining
            days_remaining = remaining
            # pack the calculated times into a string to scroll
            countdown_string = (
                "* %d Days, %d Hours, %d Minutes & %s Seconds until %s *"
                % (
                    days_remaining,
                    hours_remaining,
                    mins_remaining,
                    secs_remaining,
                    EVENT_NAME,
                )
            )
```

## Looping the Marquee
The length of the `countdown_string` is multiplied by the `scroll_speed` variable to calculate `scroll_time`. This means that `scroll_time` has the length of time needed to scroll each character in the string across the displays.

`clock` is reset right before the `marquee()` function begins to scroll the text. After the `marquee()` scroll finishes, then `scroll_time` will have elapsed and the process can begin again. This allows for the displays to continuously loop the countdown information while updating.

```python
# get the length of the packed string
display_length = len(countdown_string)
# print(display_length)
# calculate the amount of time needed to scroll the string
scroll_time = display_length * scroll_speed
# print(scroll_time)
# reset the clock
clock = time.monotonic()
# scroll the string once
display.marquee(countdown_string, scroll_speed, loop=False)
```

# Scrolling Countdown Timer

## Display Setup

## Solder Backpacks

Follow the documentation in the [main product page](https://learn.adafruit.com/adafruit-led-backpack/0-54-alphanumeric-assembly) to learn how to solder the display backpacks to the breakout boards.

![3d_printing_led_matrix_solder2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/113/medium640/3d_printing_led_matrix_solder2.jpg?1671126412)

[Go to the Backpack Learn Guide](https://learn.adafruit.com/adafruit-led-backpack/0-54-alphanumeric-assembly)
## Setup Breakouts

Two of the three breakout boards will need their I2C address changes via solder jumper.&nbsp;

The order of the displays are depicted with the PCB side facing up. The order will be reversed when mounted to the 3D printed plate to show the display characters in the correct orientation.

![3d_printing_i2c-displays.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/110/medium640/3d_printing_i2c-displays.jpg?1671126251)

## Display #1

This display does not need any jumpers solder and will use the default I2C address.

![3d_printing_display-None.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/115/medium640/3d_printing_display-None.jpg?1671126959)

## Display #2

This display will need the **A0** jumper soldered to change the I2C address.

![3d_printing_display-A0.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/116/medium640/3d_printing_display-A0.jpg?1671126986)

## Display #3

This display will need the **A1** jumper soldered to change the I2C address.

![3d_printing_display-A1.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/117/medium640/3d_printing_display-A1.jpg?1671127005)

# Scrolling Countdown Timer

## Circuit Diagram

![](https://cdn-learn.adafruit.com/assets/assets/000/117/146/medium800/adafruit_io_Countdown_wiring_diagram_bb.png?1671199947)

**You must follow the steps on the [Display Setup](https://learn.adafruit.com/scrolling-countdown-timer/display-setup) page before following the steps below.**

Info: 

QT Py and First Display (no address jumper soldered closed on the back)

- **QT Py STEMMA QT connector** to&nbsp; **first display right STEMMA QT connector** using a [STEMMA QT cable](https://www.adafruit.com/product/4399).

First Display and Second Display (A0 jumper soldered closed on the back)

- **First display left STEMMA QT connector** to **second display right STEMMA QT connector** using a [STEMMA QT cable](https://www.adafruit.com/product/4399).

Second Display to Third Display (A1 jumper soldered closed on the back)

- **Second display left STEMMA QT connector** to **third display right STEMMA QT connector** using a [STEMMA QT cable](https://www.adafruit.com/product/4399).

# Scrolling Countdown Timer

## Assembly

## Install Base Plate

The 3D printed base and plate snap fit together.

Insert the plate into the base's clip with the notches lined up.

Press the two parts together to fully seat the plate to the base.&nbsp;

![3d_printing_base-plate-install.gif](https://cdn-learn.adafruit.com/assets/assets/000/117/118/medium640thumb/3d_printing_base-plate-install.jpg?1671127673)

## Displays Installed

The three displays are press fitted into the cutouts on the 3D printed plate.

Reference the image for thecorrect order and orientation of displays.

From left to right, Display #3, Display #2 and Display #1.

![3d_printing_displays-installed.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/120/medium640/3d_printing_displays-installed.jpg?1671128603)

## Installing Displays

The displays are press fitted into the cutouts on the 3D printed panel with the correct orientation and order.

![3d_printing_display-plate-install.gif](https://cdn-learn.adafruit.com/assets/assets/000/117/119/medium640thumb/3d_printing_display-plate-install.jpg?1671128468)

## Connecting Stemma Cables

The displays are chained together using short STEMMA QT cables.

Begin connecting display #3 to display #2. Then, display #2 to display #1.

![3d_printing_display-stemmacable-install.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/121/medium640/3d_printing_display-stemmacable-install.jpg?1671128766)

## Connected Displays

Take a moment to ensure the STEMMA QT cable have been properly connected.

Reference the image for the correct placement.

![3d_printing_displays-stemma-connected.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/122/medium640/3d_printing_displays-stemma-connected.jpg?1671128806)

## Holder for QT Py

The QT Py board will be press-fitted into the 3D printed holder.

The QT Py board is oriented with the USB-C port lined up with the tabs on the 3D printed holder.

![3d_printing_qtpy-holder.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/123/medium640/3d_printing_qtpy-holder.jpg?1671128892)

## Install QT Py

Insert the QT Py at an angle with the corners fitted underneath the clips on the back of the holder.

Using your fingers, slightly bend the front side to allow the front clips to fit over the front of the QT Py.

![3d_printing_install-qtpy.gif](https://cdn-learn.adafruit.com/assets/assets/000/117/124/medium640thumb/3d_printing_install-qtpy.jpg?1671129625)

## Install STEMMA QT Cable

Connect the remaining STEMMA QT cable to the QT Py board.

&nbsp;

![3d_printing_installed-qtpy-cable.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/125/medium640/3d_printing_installed-qtpy-cable.jpg?1671129911)

## Installing QT Py Holder

Place the QT Py holder over the base plate assembly with the mounting holes lined up with the tabs.

![3d_printing_installing-qtpy-base.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/126/medium640/3d_printing_installing-qtpy-base.jpg?1671129975)

## Secure QT Py Holder

Use 2x M2.5 x 10mm long screws and hex nuts to secure the QT Py holder to the base plate assembly.

![3d_printing_secure-qtpy-holder.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/127/medium640/3d_printing_secure-qtpy-holder.jpg?1671130041)

## Secured QT Py Holder

The screws are inserted with the screw heads facing down and hex nuts facing up.

Finger tighten the hex nuts to avoid stripping them.&nbsp;

![3d_printing_secured-qtpy-holder.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/128/medium640/3d_printing_secured-qtpy-holder.jpg?1671130072)

## Connect QT Py to Displays&nbsp;

Connect the remaining STEMMA QT cable to the remaining STEMMA QT port on display #1.

![3d_printing_connect-qtpy-display.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/129/medium640/3d_printing_connect-qtpy-display.jpg?1671130114)

## Final Build

Congratulations on your build!

![3d_printing_final-build.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/130/medium640/3d_printing_final-build.jpg?1671130176)

## Power QT Py

Connect USB-C cable to a 5V power supply 5V battery bank or USB hub to power up the QT Py.

![3d_printing_usb-battery.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/135/medium640/3d_printing_usb-battery.jpg?1671137437)

# Scrolling Countdown Timer

## Usage

![](https://cdn-learn.adafruit.com/assets/assets/000/117/142/medium800thumb/3d_printing_Countdown_scrolling.jpg?1671141618)

# Countdown to Something New

Eventually, the timer will reach zero, and your event will start. What can you do with your countdown timer after that? Count down to another event!

There are two things you can easily customise in the example code: event info, and scroll speed.

## Event Info

At the top of the example code, you'll find a list of variables. These are used to determine the future event date, and subsequently how much time should show on the timer as the event gets closer. You can change these to any future date, and update the event name and message to match your countdown.

- `EVENT_YEAR` - The year of your event, using the full 4-digit year number.
- `EVENT_MONTH` - The month of your event.
- `EVENT_DAY` - The day of your event.
- `EVENT_HOUR` - The hour part of the time of your event, if it has a specific time. Otherwise, for an all-day event, you can leave this at `0`.
- `EVENT_MINUTE` - The minute part of the time of your event, if it has a specific time. Otherwise, for an all-day event, you can leave this at `0`.
- `EVENT_NAME` - The name of your event. Must be wrapped in `"`.
- `EVENT_MSG` - The message you would like to display when it's time for the event. Must be wrapped in `"`.

```python
EVENT_YEAR = 2022
EVENT_MONTH = 12
EVENT_DAY = 25
EVENT_HOUR = 0
EVENT_MINUTE = 0
EVENT_NAME = "Christmas"
EVENT_MSG = "Merry Christmas * "
```

## Scroll Speed

This sets the amount of time each character is shown on the right-most segment of the three displays before the it is bumped one to the left and the next character is displayed. More simply, it controls the speed at which text scrolls on the display.

Increase the value to slow down the scrolling. Decrease the value to speed up the scrolling. It can be any value `0` or above, including both integers and floats. That said, `0` is too fast to read, and `1` takes forever. Keep that in mind, and find a speed that works for you!

```python
scroll_speed = 0.25
```


## Guide Products

### Adafruit QT Py ESP32-S2 WiFi Dev Board with STEMMA QT

[Adafruit QT Py ESP32-S2 WiFi Dev Board with STEMMA QT](https://www.adafruit.com/product/5325)
What has your favorite Espressif WiFi microcontroller, comes with&nbsp;[our favorite connector - the STEMMA QT](http://adafruit.com/stemma), a chainable I2C port, and has lots of Flash and RAM memory for your next IoT project? What will make your next IoT project flyyyyy? What a...

In Stock
[Buy Now](https://www.adafruit.com/product/5325)
[Related Guides to the Product](https://learn.adafruit.com/products/5325/guides)
### Quad Alphanumeric Display - Blue 0.54" Digits w/ I2C Backpack

[Quad Alphanumeric Display - Blue 0.54" Digits w/ I2C Backpack](https://www.adafruit.com/product/1912)
Display, elegantly, 012345678 or 9! Gaze, hypnotized, at ABCDEFGHIJKLM - well it can display the whole alphabet. You get the point. This is a nice, bright alphanumeric display that shows letters and numbers in a beautiful blue hue. It's super bright and designed for viewing from distances...

In Stock
[Buy Now](https://www.adafruit.com/product/1912)
[Related Guides to the Product](https://learn.adafruit.com/products/1912/guides)
### STEMMA QT / Qwiic JST SH 4-Pin Cable - 50mm Long

[STEMMA QT / Qwiic JST SH 4-Pin Cable - 50mm Long](https://www.adafruit.com/product/4399)
This 4-wire cable is&nbsp;50mm / 1.9" long and fitted with JST SH female 4-pin connectors on both ends. Compared with the chunkier JST PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert and remove.

<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4399)
[Related Guides to the Product](https://learn.adafruit.com/products/4399/guides)
### Pink and Purple Woven USB A to USB C Cable - 1 meter long

[Pink and Purple Woven USB A to USB C Cable - 1 meter long](https://www.adafruit.com/product/5153)
This cable is not only super-fashionable, with a woven pink and purple Blinka-like pattern, it's also made for USB C for our modernized breakout boards, Feathers, and more.&nbsp;&nbsp;[If you want something just like it but for Micro B, we...](https://www.adafruit.com/product/4111)

Out of Stock
[Buy Now](https://www.adafruit.com/product/5153)
[Related Guides to the Product](https://learn.adafruit.com/products/5153/guides)
### USB Battery Pack - 2200 mAh Capacity - 5V 1A Output

[USB Battery Pack - 2200 mAh Capacity - 5V 1A Output](https://www.adafruit.com/product/1959)
A smaller-sized rechargeable battery pack for your&nbsp;[Raspberry Pi](http://www.adafruit.com/raspberrypi)&nbsp;or [Raspberry Pi B+](https://www.adafruit.com/product/1914)&nbsp;(or&nbsp;[Arduino](http://www.adafruit.com/arduino), or&nbsp;<a...></a...>

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/1959)
[Related Guides to the Product](https://learn.adafruit.com/products/1959/guides)

## Related Guides

- [Adafruit LED Backpacks](https://learn.adafruit.com/adafruit-led-backpack.md)
- [Adafruit QT Py ESP32-S2 and QT Py ESP32-S2 with uFL Antenna](https://learn.adafruit.com/adafruit-qt-py-esp32-s2.md)
- [USB C Power Delivery Monitor](https://learn.adafruit.com/usb-c-benchtop-power-supply.md)
- [Adafruit Feather RP2040 Adalogger](https://learn.adafruit.com/adafruit-feather-rp2040-adalogger.md)
- [No-Code Battery Monitoring with WipperSnapper](https://learn.adafruit.com/no-code-battery-monitoring-with-wippersnapper.md)
- [Adafruit ItsyBitsy ESP32](https://learn.adafruit.com/adafruit-itsybitsy-esp32.md)
- [Adafruit QT Py Activity Timer and Hydration Reminder](https://learn.adafruit.com/qt-py-activity-timer-and-hydration-reminder.md)
- [QT Py CH32V203 eInk / ePaper Daily Calendar and Clock](https://learn.adafruit.com/ch32v203-eink-epaper-calendar-and-clock.md)
- [Blahaj Alarm and Lamp](https://learn.adafruit.com/blahaj-alarm.md)
- [Raspberry Pi Azure IoT Hub Dashboard with CircuitPython](https://learn.adafruit.com/raspberry-pi-iot-dashboard-with-azure-and-circuitpython.md)
- [Face Tracking Robot with MEMENTO](https://learn.adafruit.com/face-tracking-robot-with-memento.md)
- [USB MIDI Host2Host](https://learn.adafruit.com/usb-midi-host2host.md)
- [OpenAI Image Descriptors with MEMENTO](https://learn.adafruit.com/openai-image-descriptors-with-memento.md)
- [Adafruit IO IOT Hub with the Adafruit FunHouse](https://learn.adafruit.com/adafruit-io-hub-with-the-adafruit-funhouse.md)
- [Adafruit Feather RP2040 with USB Type A Host](https://learn.adafruit.com/adafruit-feather-rp2040-with-usb-type-a-host.md)
- [Canary Nightlight ](https://learn.adafruit.com/canary-nightlight.md)
- [Driving TM1814 addressable LEDs](https://learn.adafruit.com/driving-tm1814-addressable-leds.md)
