# Star Fragment IoT Lamp

## Overview

https://youtu.be/j6_Fr98rQgY

Inspired by _Star Fragments_ from video games such as [Zelda: Breath of the Wild](https://zelda.fandom.com/wiki/Star_Fragment) and [Animal Crossing: New Horizons](https://nookipedia.com/wiki/Item:Star_fragment_(New_Horizons)), this fully 3D printed star shaped lamp uses a QT Py ESP32-S2 and NeoPixel LEDs to turn on when the sun rises and off when it sets.

![](https://cdn-learn.adafruit.com/assets/assets/000/119/393/medium800/led_pixels_hero-nightstand-remotes.jpg?1678480193)

The CircuitPython code uses the [Open-Meteo](https://open-meteo.com/) weather API to get location data for requesting the sunrise and sunset times. This IoT project knows when to light up and turn off, effectively automating a nightstand lamp.

The core of the star fragment is a dodecahedron that has 12 hollow spikes that snap fit together and are 3D printed without any support material.

A 3D printed mount houses two NeoPixel stick PCBs and snap fits into the bottom of the dodecahedron.

![led_pixels_hero-outside-1.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/439/medium640/led_pixels_hero-outside-1.jpg?1678800214)

![](https://cdn-learn.adafruit.com/assets/assets/000/119/440/medium800/led_pixels_hero-outside-2.jpg?1678800244)

## Parts from Adafruit

Following parts are used in this project.

- QT Py ESP32-S2
- NeoPixel Driver BFF
- 2x NeoPixel Sticks
- 3-pin JST cable

![led_pixels_parts.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/310/medium640/led_pixels_parts.jpg?1678369816)

### 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)

### Adafruit NeoPixel Driver BFF Add-On for QT Py and Xiao

[Adafruit NeoPixel Driver BFF Add-On for QT Py and Xiao](https://www.adafruit.com/product/5645)
Our QT Py boards are a great way to make very small microcontroller projects that pack a ton of power - and now we have a way for you to quickly add a [strand of NeoPixels](https://www.adafruit.com/category/168) with a 5V level shifter and a detachable JST PH connector. It's an...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5645)
[Related Guides to the Product](https://learn.adafruit.com/products/5645/guides)
![Video of a driver board lighting up an RGBW half-meter long LED strip.](https://cdn-shop.adafruit.com/product-videos/640x480/5645-02.jpg)

### JST PH 2mm 3-pin Plug-Plug Cable - 100mm long

[JST PH 2mm 3-pin Plug-Plug Cable - 100mm long](https://www.adafruit.com/product/4336)
This cable is a little over 100mm / 4" long&nbsp;and fitted with JST-PH 3-pin connectors on either end.&nbsp;

We dig the solid and compact nature of these connectors and the latch that keeps the cable from coming apart easily. We're carrying these to <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4336)
[Related Guides to the Product](https://learn.adafruit.com/products/4336/guides)
![Angled shot of JST PH 3-pin Plug-Plug Cable - 100mm long.](https://cdn-shop.adafruit.com/640x480/4336-01.jpg)

### Silicone Cover Stranded-Core Ribbon Cable - 10 Wire 1 Meter Long

[Silicone Cover Stranded-Core Ribbon Cable - 10 Wire 1 Meter Long](https://www.adafruit.com/product/3890)
For those who are fans of our silicone-covered wires, but are always looking to _up their wiring game_. We now have **Silicone Cover Ribbon cables!** These may look _a lot_ like <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/3890)
[Related Guides to the Product](https://learn.adafruit.com/products/3890/guides)
![10 wire Silicone Cover Stranded-Core Ribbon Cable](https://cdn-shop.adafruit.com/640x480/3890-01.jpg)

### USB C Round Panel Mount Extension Cable

[USB C Round Panel Mount Extension Cable](https://www.adafruit.com/product/4218)
If you need to add a panel-mount connection&nbsp;but don't have the time or ability to cut a custom oval or square hole, this **USB C&nbsp;Round Panel Mount Extension Cable&nbsp;** is the easiest and fastest way to panel-ify your project. The adapter can fit holes...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4218)
[Related Guides to the Product](https://learn.adafruit.com/products/4218/guides)
![USB C Round Panel Mount Extension Cable - 30 cm](https://cdn-shop.adafruit.com/640x480/4218-03.jpg)

### 2x NeoPixel Sticks

This project requires two 8x NeoPixel LED sticks.

### NeoPixel Stick - 8 x 5050 RGB LED with Integrated Drivers

[NeoPixel Stick - 8 x 5050 RGB LED with Integrated Drivers](https://www.adafruit.com/product/1426)
Make your own little LED strip arrangement with this stick of NeoPixel LEDs. We crammed 8 of the tiny 5050 (5mm x 5mm) smart RGB LEDs onto a PCB with mounting holes and a chainable design. Use only one microcontroller pin to control as many as you can chain together! Each LED is addressable as...

In Stock
[Buy Now](https://www.adafruit.com/product/1426)
[Related Guides to the Product](https://learn.adafruit.com/products/1426/guides)
![NeoPixel Stick with 8 x 5050 RGB LED ](https://cdn-shop.adafruit.com/640x480/1426-05.jpg)

### Part: M2 Hardware Kit
quantity: 1
M2 Male Female Nylon Hex Spacer Standoff Screw Nut Assorted Assortment Kit
[M2 Hardware Kit](https://www.amazon.com/gp/product/B07D78PFQL/)

### Part: M3 x 6mm pan head machine screws
quantity: 3
M3 pan head screws
[M3 x 6mm pan head machine screws](https://www.mcmaster.com/92000A116/)

### Part: Heat Shrink Pack
quantity: 1
Multi-Colored Heat Shrink Pack - 3/32" + 1/8" + 3/16" Diameters
[Heat Shrink Pack](https://www.adafruit.com/product/1649)

# Star Fragment IoT Lamp

## 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)

# Star Fragment IoT Lamp

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

# Star Fragment IoT Lamp

## Code the Star Fragment Lamp

![](https://cdn-learn.adafruit.com/assets/assets/000/119/441/medium800/led_pixels_hero-code.jpg?1678800827)

Once you've finished setting up your QT Py ESP32-S2 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 to your computer as a zipped folder.

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

## Upload the Code and Libraries to the QT Py ESP32-S2

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 items to the QT Py ESP32-S2's&nbsp; **CIRCUITPY** &nbsp;drive.&nbsp;

- **lib** &nbsp;folder
- **code.py**

Your QT Py ESP32-S2&nbsp; **CIRCUITPY&nbsp;** drive should look like this after copying the&nbsp; **lib** &nbsp;folder and the&nbsp; **code.py&nbsp;** file.

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

## Add Your&nbsp; **settings.toml** File

As of CircuitPython 8, there is support for [Environment Variables](https://docs.circuitpython.org/en/latest/docs/environment.html). These Environmental Variables are stored in a **settings.toml** file. Similar to **secrets.py** , the **settings.toml** file separates your sensitive information from your main **code.py** file. Add your **settings.toml** file as described in the [Create Your settings.toml File page](https://learn.adafruit.com/neopixel-sprite-weather-display/create-your-settings-toml-file) earlier in this guide. You'll need to include your `CIRCUITPY_WIFI_SSID`, `CIRCUITPY_WIFI_PASSWORD`, `aio_username` and `aio_key` in the file.

```python
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 Open-Meteo weather API uses latitude and longitude to determine your location when creating an API request. At the top of the code, you can add your latitude and longitude coordinates by editing the `lat` and `long` variables.

```python
# latitude
lat = 42.36
# longitude
long = -71.06
```

`weather_url` is a string that holds the Open-Meteo API request. It passes the latitude and longitude variables and requests the sunrise and sunset times.

```python
# API request to open-meteo
weather_url = "https://api.open-meteo.com/v1/forecast?"
# pass latitude and longitude
# will return sunrise and sunset times
weather_url += "latitude=%d&amp;longitude=%d&amp;timezone=auto&amp;daily=sunrise,sunset" % (lat, long)
```

## Internet Connect!

The QT Py ESP32-S2 connects to your network by passing your SSID name and SSID password information from the **settings.toml** file. `io` is instantiated as an Adafruit IO HTTP object by passing your IO username and password from the **settings.toml** file as well. Adafruit IO is used to get the current time.

```python
#  connect to SSID
wifi.radio.connect(os.getenv('CIRCUITPY_WIFI_SSID'), os.getenv('CIRCUITPY_WIFI_PASSWORD'))

pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())

pool = socketpool.SocketPool(wifi.radio)

# adafruit IO info
aio_username = os.getenv('aio_username')
aio_key = os.getenv('aio_key')
location = "America/New York"

# io HTTP for getting the time from the internet
io = IO_HTTP(aio_username, aio_key, requests)
```

## Error Checking

The `reset_on_error()` function takes an `Exception` error and resets the QT Py depending on the delay time.&nbsp;

The `get_request()` function uses a try/except loop to attempt an HTTP request. In the event of an error, the request will be attempted again after a delay. Once the number of tries has been exceeded, then the loop breaks.

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

# function for making http requests with try/except
def get_request(tries, ping):
    for i in range(tries):
        try:
            n = ping
        except Exception as error:
            print(error)
            time.sleep(10)
            if i &lt; tries - 1:
                continue
            raise
        break
    return n
```

These two functions are utilized together in a `try`/`except` loop for each HTTP request. If the `try`/`except` loop exceeds the tries in `get_request()`, then `reset_on_error()` is called and the QT Py resets itself.

```python
try:
    now = get_request(5, io.receive_time())
except Exception as e:
    reset_on_error(10, e)
```

## When and Where Is The Sun?

The `sun_clock()` function makes the Open-Meteo API request and returns that day's sunrise and sunset timestamp.

```python
# function to make a request to open-meteo
def sun_clock():
    # make the API request
    response = get_request(5, requests.get(weather_url))
    # packs the response into a JSON
    response_as_json = response.json()
    # gets sunrise
    _rise = response_as_json['daily']['sunrise'][0]
    # gets sunset
    _set = response_as_json['daily']['sunset'][0]
    return _rise, _set
```

However, the sunrise and sunset timestamps are returned as strings, which isn't very helpful for doing math. The `divide_time()` function chops up the string and returns a `struct_time` object.

```python
def divide_time(z):
    string_time = z.split("-")
    clock_time = string_time[2].split("T")
    int_time = clock_time[1].split(":")
    event_time = time.struct_time(
    (int(string_time[0]), int(string_time[1]), int(clock_time[0]), int(int_time[0]),
    int(int_time[1]), 0, -1, -1, False)
    )
    # print(event_time)
    return event_time
```

Then, the `sun_countdown()` function calculates the time remaining until either sunrise or sunset.

```python
# function that tracks how many hours/minutes until sunrise or sunset
def sun_countdown(sun_event):
    n = get_request(5, io.receive_time())
    remaining = time.mktime(sun_event) - time.mktime(n)
    r = remaining
    # print(remaining)
    # calculate the seconds remaining
    secs_remaining = remaining % 60 # pylint: disable=unused-variable
    remaining //= 60
    # calculate the minutes remaining
    minutes_until = remaining % 60
    remaining //= 60
    # calculate the hours remaining
    hours_until = remaining % 24
    remaining //= 24
    return r, hours_until, minutes_until, n
```

Before the loop, it's determined if the sun has already set. This sets the state for `star_glow`, which is used in the loop to turn the NeoPixels on or off.

```python
# check to see if the star fragment should be lit up on start-up
if total_until_set &lt; 0:
    print("star glow true")
    star_glow = True
    percent_red = 255
    percent_yellow = 125
    # turn neopixels on using RGB values
    pixels.fill((percent_red, percent_yellow, 0))
    pixels.show()
else:
    print("star glow false")
    star_glow = False
    percent_red = 0
    percent_yellow = 0
    # turn neopixels on using RGB values
    pixels.fill((percent_red, percent_yellow, 0))
    pixels.show()
```

## The Loop

In the loop, `ticks_ms()` is used to track time. Every 15 minutes, requests are sent to Open-Meteo and Adafruit IO to retrieve the sunrise and sunset times and the current time. Depending on whether or not `star_glow` is `True` determines if sunrise or sunset is tracked.

```python
while True:
    try:
        # if it's daytime
        if not star_glow:
            # every 15 minutes...
            if first_run or ticks_diff(ticks_ms(), clock) &gt; time_check:
                print("pinging Open-Meteo")
                sunrise, sunset = sun_clock()
                (total_until_set, hours_until_sunset,
                mins_until_sunset, now) = sun_countdown(set_time)
                print(now)
                print("%d hour(s) until sunset" % hours_until_sunset)
                print("%d minutes(s) until sunset" % mins_until_sunset)
                print(sunset)
                print(percent_red)
                print()
```

## Mapping Color to Time

When there is less than an hour until sunrise or sunset, Open-Meteo and Adafruit IO begin to be pinged every 5 minutes. The NeoPixels begin to either dim or brighten during that hour countdown. Their red and green values are mapped to the minutes remaining.

Once the sun event has been reached, the NeoPixels are set to fully yellow or fully off, the `time_check` is reset to 15 minutes, and the state of `star_glow` is updated.

```python
# less than an hour until sunset...
if hours_until_sunset in (0, 23):
  # check every minute
  time_check = 300000
  # map color to ramp up in brightness over the course of the final hour
  percent_red = simpleio.map_range(mins_until_sunset, 59, 0, 0, 255)
  percent_yellow = simpleio.map_range(mins_until_sunset, 59, 0, 0, 125)
  # if the sun has set..
  if total_until_set &lt; 0:
    percent_red = 255
    percent_yellow = 125
    time_check = 900000
    star_glow = True
    print("star is glowing")
```

## What Day Is It?

There is some additional logic in place to prevent errors while the star is glowing. Once the day changes (aka once it's past midnight), the `looking_for_sunrise` state is set to `True` to begin checking Open-Meteo for the sunrise and sunset times for the new day.

```python
if first_run or ticks_diff(ticks_ms(), clock) &gt; time_check:
  if today != now.tm_mday or (first_run and now.tm_hour &lt; rise_time.tm_hour):
    today = now.tm_mday
    looking_for_sunrise = True
    # begin tracking the incoming sunrise
    if looking_for_sunrise:
      print("pinging Open-Meteo")
      sunrise, sunset = sun_clock()
      (total_until_rise, hours_until_sunrise,
       mins_until_sunrise, now) = sun_countdown(rise_time)
```

While the code waits for the new day, the time is checked every 15 minutes and the NeoPixels are fully yellow.

```auto
# otherwise just keep checking every 15 minutes
# and keep neopixels on
else:
    now = get_request(5, io.receive_time())
    print("not looking for sunrise")
    print(now)
    print()
    time_check = 900000
    percent_red = 255
    percent_yellow = 125
```

# Star Fragment IoT Lamp

## Circuit Diagram

The diagram below provides a general visual reference for wiring of the components once you get to the **Assembly** page. This diagram was created using the software package [Fritzing](http://fritzing.org/download/).

## Adafruit Library for Fritzing

Use Adafruit's Fritzing parts library to create circuit diagrams for your projects. Download the library or just grab individual parts. Get the library and parts from [GitHub - Adafruit Fritzing Parts](https://github.com/adafruit/Fritzing-Library/tree/master/parts).

Warning: 

![](https://cdn-learn.adafruit.com/assets/assets/000/119/307/medium800/led_pixels_Circuit-Diagram-v2.jpg?1678303609)

## Wired Connections

The QT Py is powered by a 5V 1A power supply wall adapter.&nbsp;

**NeoPixel Stick to NeoPixel Stick**

- DATA OUT to DATA In
- GND to GND pin
- 5V to 5V pin

**NeoPixel Stick to BFF NeoPixel Drive**

The power, data, and ground connections from the first NeoPixel stick connect directly to the 3-pin JST port on the NeoPixel BFF board.

# Star Fragment IoT Lamp

## CAD Files

## CAD Assembly

The two NeoPixel sticks are secured to the NeoPixel Stick Mount with hardware screws and nuts. The NeoPixel mount snap fits into the bottom side of the star core. Eleven spikes snap fit into the star core. The star bottom piece snap fits into the NeoPixel stick mount. The star fragment assembly rests onto the stand. The stand is secured to the star case top cover with machine screws. The star case top and bottom covers snap fit onto the star case frame.&nbsp;

![led_pixels_cad-explode.gif](https://cdn-learn.adafruit.com/assets/assets/000/119/374/medium640thumb/led_pixels_cad-explode.jpg?1678468786)

## 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 using PLA filament. Original design source may be downloaded using the links below.

- NeoPixel Stick Mount.stl
- simple-case-bottom.stl
- simple-case-frame.stl
- simple-case-top.stl
- Star-Bottom.stl
- Star-Case-Bottom.stl
- Star-Case-Frame.stl
- Star-Case-Top.stl
- Star-Core.stl
- Star-Spike.stl
- Star-Stand.stl

![led_pixels_3d-parts-star.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/376/medium640/led_pixels_3d-parts-star.jpg?1678469042)

![led_pixels_3d-parts-case.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/377/medium640/led_pixels_3d-parts-case.jpg?1678469053)

[Download STLs.zip](https://cdn-learn.adafruit.com/assets/assets/000/119/413/original/STLs.zip?1678732304)
[CAD Source](https://cdn-learn.adafruit.com/assets/assets/000/135/807/original/CAD_source.zip?1742301482)
## Transparent Filament

For best illumination, we suggest printing the **Star-Core** and **NeoPixel Stick Mount** parts in translucent / transparent PLA filament.

The star spikes were 3D printed in a yellow colored PLA filament.

![led_pixels_cura-slide.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/411/medium640/led_pixels_cura-slide.jpg?1678732076)

## Build Volume

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

- 138mm (X) x 132mm (Y) x 42mm (Z)

![led_pixels_cura-bedsize.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/412/medium640/led_pixels_cura-bedsize.jpg?1678732175)

## Bed Adhesion

Applying brim to the star spikes can help improve bed adhesion. A minimum of 6 perimeters is suggested to keep the part from coming off the bed of the 3D printer.

![led_pixels_cura-brim.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/416/medium640/led_pixels_cura-brim.jpg?1678737509)

# Star Fragment IoT Lamp

## Headers Assembly

## Headers for QT Py and BFF

Trim the included strip of headers to create two 1x7 headers.

![led_pixels_qtpy-bff-headers.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/316/medium640/led_pixels_qtpy-bff-headers.jpg?1678453976)

## Install Headers to QT Py

Insert the two strips of header pins to the bottom of the QT Py PCB.

![led_pixels_qtpy-headers-install.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/317/medium640/led_pixels_qtpy-headers-install.jpg?1678453998)

## Install NeoPixel Driver BFF

Place the NeoPixel Driver BFF board under the QT Py to get a sense of the correct orientation.&nbsp;&nbsp;

![led_pixels_qtpy-bff-headers-install.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/318/medium640/led_pixels_qtpy-bff-headers-install.jpg?1678454022)

## Soldering Headers

Use a breadboard to help keep the two strips of header pins straight when soldering them to the QT Py.

![led_pixels_qtpy-solder-headers.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/319/medium640/led_pixels_qtpy-solder-headers.jpg?1678454052)

## Solder NeoPixel Driver BFF to QT Py

Carefully solder the header pins from the QT Py to the NeoPixel Driver BFF.

![led_pixels_qtpy-bff-soldered.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/320/medium640/led_pixels_qtpy-bff-soldered.jpg?1678454071)

# Star Fragment IoT Lamp

## NeoPixel Wiring

## Short Cable for NeoPixels

The two NeoPixel sticks will be daisy chained using a short 3-wire ribbon cable.

Peel three wires from the 10-wire ribbon cable to create a short 3-pin cable for connecting the two NeoPixel sticks together.

![led_pixels_neopixel-wire-short.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/321/medium640/led_pixels_neopixel-wire-short.jpg?1678454490)

## JST Cable for NeoPixels

Separate three wires from the 10-wire ribbon cable to create a long cable extension for the 3-pin JST cable.&nbsp;

Cut the 3-wire ribbon cable to the desired length. Make sure it's a has a minimum length of 6in (15cm).&nbsp;

A 3-pin JST cable will connect the NeoPixel sticks to the NeoPixel Driver BFF board.

![led_pixels_neopixel-cables.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/322/medium640/led_pixels_neopixel-cables.jpg?1678454503)

## Solder Short Cable

Connect the short 3-wire ribbon cable to one of the NeoPixel sticks by soldering to the GND, 5VDC and DOUT pads.

![led_pixels_neopixel-dout-solder.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/323/medium640/led_pixels_neopixel-dout-solder.jpg?1678454514)

## Solder Short Cable (Continued)

Connect the other end of the short ribbon cable to the second NeoPixel stick by soldering to the GND, 5VDC and DIN pads.

The connections between the two boards are:

- **GND** to **GND**
- **5VDC** to **5VDC**
- **DOUT** to **DIN**

![led_pixels_neopixel-din-solder.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/325/medium640/led_pixels_neopixel-din-solder.jpg?1678454547)

## Soldered NeoPixel Sticks

Double check the short cable has been soldered to the correct pads.

![led_pixels_neopixels-wire-soldered.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/326/medium640/led_pixels_neopixels-wire-soldered.jpg?1678454623)

## Solder 3-pin JST Extension

Connect the long ribbon cable to the 3-pin JST cable by soldering the individual wires to the red, black and white colored wires.&nbsp;&nbsp;

Use pieces of heat shrink tubing to insulate the exposed wire.

![led_pixels_neopixel-cable-ext-soldering.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/327/medium640/led_pixels_neopixel-cable-ext-soldering.jpg?1678454733)

## 3-pin JST Cable

Double check the soldered wires have a good and strong connection.

![led_pixels_neopixel-cable-ext.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/328/medium640/led_pixels_neopixel-cable-ext.jpg?1678454843)

## Connect JST Cable to NeoPixels

Solder the three wires from the JST cable/extension to the NeoPixel stick with the DIN pad. Connect red wire extension to 5VDC, black wire extension to GND and white wire extension to the DIN pad.

![led_pixels_neopixel-cable-solder.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/329/medium640/led_pixels_neopixel-cable-solder.jpg?1678454893)

## Wired NeoPixel Sticks

Take a moment to double check the wired connections have been properly soldered.

![led_pixels_neopixel-cable-soldered.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/330/medium640/led_pixels_neopixel-cable-soldered.jpg?1678454958)

# Star Fragment IoT Lamp

## Assembly

## Hardware for NeoPixel Mount

You'll use the following hardware to secure the NeoPixel sticks to the 3D printed mount.

- 2x M2 x 12mm long screws
- 2x M2 hex nuts
- 4x M2 washers

![led_pixels_neopixel-mount-screws.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/331/medium640/led_pixels_neopixel-mount-screws.jpg?1678455063)

## Install Cable to NeoPixel Mount

Insert the 3-pin JST through the center opening of the 3D printed mount and pull it all the way through.

![led_pixels_neopixel-mount-cable-install.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/333/medium640/led_pixels_neopixel-mount-cable-install.jpg?1678455279)

## Mounting NeoPixel

Place both NeoPixel sticks onto the 3D printed mount and line up the mounting holes.

![led_pixels_neopixel-mount-installing.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/332/medium640/led_pixels_neopixel-mount-installing.jpg?1678455253)

Insert the M2 screws through the NeoPixel sticks and 3D printed mount with the washers fitted in between. The washer will allow airflow to help with heat dissipation to prevent the 3D print from warping.

![led_pixels_neopixel-mount-setup.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/334/medium640/led_pixels_neopixel-mount-setup.jpg?1678455293)

## Secure NeoPixels

Fasten M2 hex nuts onto the threads of the screws and use a screwdriver to secure them together.

![led_pixels_neopixel-mount-secure.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/335/medium640/led_pixels_neopixel-mount-secure.jpg?1678455301)

## Assembled NeoPixel Holder

Take a moment to inspect the NeoPixel holder assembly and ensure it has been properly secured.

![led_pixels_neopixel-mount-secured.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/336/medium640/led_pixels_neopixel-mount-secured.jpg?1678455382)

## Install NeoPixel Holder

Locate the bottom side of the 3D printed star core. It's the surface that touched the 3D printer's bed.

Insert the NeoPixel holder through the bottom side of the star core and firmly press it through the edges.

![led_pixels_neopixel-star-core-install.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/341/medium640/led_pixels_neopixel-star-core-install.jpg?1678460714)

## Install Bottom Spike

Insert the JST cable through the hole on the side of the 3D printed bottom spike and pull it all the way through.

Orient the bottom spike so the protruding lips are lined up with the NeoPixel holder.

Firmly press the bottom spike into the star core until the surfaces sit flush.

![led_pixels_star-core-spike-btm-install.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/342/medium640/led_pixels_star-core-spike-btm-install.jpg?1678460727)

## Install Top Spike

Insert one of the eleven spikes to the top side of the star core. Firmly press the spike into the star core until the surfaces are flush with each other.

![led_pixels_star-core-spike-top.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/343/medium640/led_pixels_star-core-spike-top.jpg?1678460751)

## Install Another Spike

Proceed to install one of remaining spikes into another side of the star core ensuring the surfaces are flush.

![led_pixels_star-core-spike-2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/344/medium640/led_pixels_star-core-spike-2.jpg?1678460764)

## Install Spikes (Continued)

Continue to install spikes by press fitting them into the remaining sides of the star core.

![led_pixels_star-core-spike-5.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/345/medium640/led_pixels_star-core-spike-5.jpg?1678460784)

## Installed Spikes

Double check all of the spikes have been properly installed onto the star core.

![led_pixels_star-core-spikes-installed.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/346/medium640/led_pixels_star-core-spikes-installed.jpg?1678460796)

## Connect JST to BFF

Grab the 3-pin JST plug from the NeoPixels and connect it to the NeoPixel Driver BFF.

![led_pixels_neoBFF-connect.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/347/medium640/led_pixels_neoBFF-connect.jpg?1678460810)

## Connect USB to QT Py

Plug in a USB-C cable to the USB port on QT Py board.

![led_pixels_qtpy-connect.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/348/medium640/led_pixels_qtpy-connect.jpg?1678460826)

## Power Test

Plug the other end of the USB cable into a 5V 1A (minimum, higher current rating is fine to use) USB power supply to turn on the circuit.&nbsp;

![led_pixels_star-power.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/349/medium640/led_pixels_star-power.jpg?1678460863)

## Simple Case Setup

Use the simple snap fit case if you prefer to use the star fragment off the stand.

Insert the JST plug from the NeoPixel through the smaller hole on the side of the case.

Insert the USB cable through the bigger hole on the side of the case.

![led_pixels_qtpy-simple-case.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/350/medium640/led_pixels_qtpy-simple-case.jpg?1678460879)

![led_pixels_qtpy-simple-case-set.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/351/medium640/led_pixels_qtpy-simple-case-set.jpg?1678460890)

## Lamp Stand Setup

Insert the USB-C extension cable through the hole on the side of the lamp stand base. Use the included hex nut to secure the cable.

![led_pixels_lamp-cable-install.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/353/medium640/led_pixels_lamp-cable-install.jpg?1678460960)

![led_pixels_lamp-cable-secured.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/354/medium640/led_pixels_lamp-cable-secured.jpg?1678460997)

## Lamp Base Bottom Install

Line up the snap fit edges of the bottom cover with the lamp base. Firmly press bottom cover to snap fit them together.&nbsp;

![led_pixels_lamp-base-bottom.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/385/medium640/led_pixels_lamp-base-bottom.jpg?1678478845)

![led_pixels_lamp-base-bottom-installed.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/386/medium640/led_pixels_lamp-base-bottom-installed.jpg?1678478886)

## Hardware for Lamp Stand

Use three M3 x 6mm long machine screws to secure the stand to the lamp base top cover.

![led_pixels_lamp-stand-screws.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/355/medium640/led_pixels_lamp-stand-screws.jpg?1678461131)

## Secure Lamp Stand to Top Cover

Place the lamp stand over the base top cover and line up the three mounting holes.

Insert and fasten the M3 screws through the bottom of the top cover to secure the stand to the top cover.

![led_pixels_lamp-stand-cover-secure.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/356/medium640/led_pixels_lamp-stand-cover-secure.jpg?1678461153)

## Install NeoPixel Cable to Lamp Stand

Insert the NeoPixel cable through the lamp stand and pull it through the other end.

![led_pixels_lamp-stand-cable-install.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/357/medium640/led_pixels_lamp-stand-cable-install.jpg?1678461187)

## Connect NeoPixel and QT Py

Proceed to connect the 3-pin JST cable to the NeoPixel Driver BFF and the USB-C extension cable to the QT Py.

![led_pixels_lamp-stand-cables-connect.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/358/medium640/led_pixels_lamp-stand-cables-connect.jpg?1678461201)

## Install PCBs into Lamp Base

Place the QT Py and NeoPixel Driver BFF into the lamp case with the extension cable neatly coiled.

![led_pixels_lamp-case-qtpy-fit.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/359/medium640/led_pixels_lamp-case-qtpy-fit.jpg?1678461273)

## Install Top Cover to Lamp Base

Line up the snap fit edges of the top cover with the lamp base and firmly press to snap fit them together.

![led_pixels_lamp-case-top-snap.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/360/medium640/led_pixels_lamp-case-top-snap.jpg?1678461288)

## Install Star Fragment to Lamp Stand

Pull on the cable from the NeoPixels through the openings on the bottom cover until the star fragment can rest on the lamp stand.

Orient the star fragment so it can rest over the tapered edges of the lamp stand.

Optionally use glue to permanently adhere the star fragment to the lamp stand.

![led_pixels_lamp-power-test.jpg](https://cdn-learn.adafruit.com/assets/assets/000/119/370/medium640/led_pixels_lamp-power-test.jpg?1678462764)


## Featured 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)
### Adafruit NeoPixel Driver BFF Add-On for QT Py and Xiao

[Adafruit NeoPixel Driver BFF Add-On for QT Py and Xiao](https://www.adafruit.com/product/5645)
Our QT Py boards are a great way to make very small microcontroller projects that pack a ton of power - and now we have a way for you to quickly add a [strand of NeoPixels](https://www.adafruit.com/category/168) with a 5V level shifter and a detachable JST PH connector. It's an...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5645)
[Related Guides to the Product](https://learn.adafruit.com/products/5645/guides)
### NeoPixel Stick - 8 x 5050 RGB LED with Integrated Drivers

[NeoPixel Stick - 8 x 5050 RGB LED with Integrated Drivers](https://www.adafruit.com/product/1426)
Make your own little LED strip arrangement with this stick of NeoPixel LEDs. We crammed 8 of the tiny 5050 (5mm x 5mm) smart RGB LEDs onto a PCB with mounting holes and a chainable design. Use only one microcontroller pin to control as many as you can chain together! Each LED is addressable as...

In Stock
[Buy Now](https://www.adafruit.com/product/1426)
[Related Guides to the Product](https://learn.adafruit.com/products/1426/guides)
### Silicone Cover Stranded-Core Ribbon Cable - 10 Wire 1 Meter Long

[Silicone Cover Stranded-Core Ribbon Cable - 10 Wire 1 Meter Long](https://www.adafruit.com/product/3890)
For those who are fans of our silicone-covered wires, but are always looking to _up their wiring game_. We now have **Silicone Cover Ribbon cables!** These may look _a lot_ like <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/3890)
[Related Guides to the Product](https://learn.adafruit.com/products/3890/guides)
### JST PH 2mm 3-pin Plug-Plug Cable - 100mm long

[JST PH 2mm 3-pin Plug-Plug Cable - 100mm long](https://www.adafruit.com/product/4336)
This cable is a little over 100mm / 4" long&nbsp;and fitted with JST-PH 3-pin connectors on either end.&nbsp;

We dig the solid and compact nature of these connectors and the latch that keeps the cable from coming apart easily. We're carrying these to <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4336)
[Related Guides to the Product](https://learn.adafruit.com/products/4336/guides)
### USB C Round Panel Mount Extension Cable

[USB C Round Panel Mount Extension Cable](https://www.adafruit.com/product/4218)
If you need to add a panel-mount connection&nbsp;but don't have the time or ability to cut a custom oval or square hole, this **USB C&nbsp;Round Panel Mount Extension Cable&nbsp;** is the easiest and fastest way to panel-ify your project. The adapter can fit holes...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4218)
[Related Guides to the Product](https://learn.adafruit.com/products/4218/guides)
### Multi-Colored Heat Shrink Pack - 3/32" + 1/8" + 3/16" Diameters

[Multi-Colored Heat Shrink Pack - 3/32" + 1/8" + 3/16" Diameters](https://www.adafruit.com/product/1649)
Heat shrink is the duct tape of electronics which I guess makes this heat shrink the colorful and exciting duct tape they sell&nbsp;at craft stores. &nbsp;This heat shrink comes in six different colors - red, blue, green, yellow, white and the traditional black.

Each pack contains ten...

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

## Related Guides

- [Adafruit QT Py ESP32-S2 and QT Py ESP32-S2 with uFL Antenna](https://learn.adafruit.com/adafruit-qt-py-esp32-s2.md)
- [Adafruit NeoPixel Driver BFF](https://learn.adafruit.com/adafruit-neopixel-driver-bff.md)
- [Blinka LED Sign](https://learn.adafruit.com/blinka-led-sign.md)
- [Experimenting with NeverWet + Electronics](https://learn.adafruit.com/neverwet-electronics.md)
- [QT Py Snap Fit Case](https://learn.adafruit.com/qt-py-snap-fit-case.md)
- [NeoPixels on Raspberry Pi](https://learn.adafruit.com/neopixels-on-raspberry-pi.md)
- [WiFi Jellyfish Lantern with WLED](https://learn.adafruit.com/wifi-jellyfish-lantern-with-wled.md)
- [Making Adabot: Part 2](https://learn.adafruit.com/making-adabot-part-2.md)
- [3D Printed Unicorn Horn](https://learn.adafruit.com/3d-printed-unicorn-horn.md)
- [LED Acrylic Sign](https://learn.adafruit.com/led-acrylic-sign.md)
- [IoT Moon Phase Guide](https://learn.adafruit.com/moon-phase.md)
- [Traffic Light Conference Badge](https://learn.adafruit.com/traffic-light-conference-badge.md)
- [Adafruit IO Time Tracking Cube](https://learn.adafruit.com/time-tracking-cube.md)
- [No-Code Indoor Air Quality Monitor with Separate Display](https://learn.adafruit.com/no-code-indoor-air-quality-monitor-with-separate-display.md)
- [Adabot Toy Robot Friend](https://learn.adafruit.com/adabot-rp2040.md)
- [NAU7802 Pet Food Scale](https://learn.adafruit.com/nau7802-pet-food-scale.md)
- [Wireless LED Juggling Balls with ESP-NOW](https://learn.adafruit.com/wireless-juggling-balls-esp-now.md)
