# WiFi-Controlled NeoPixel Matrix LED Sign

## Overview

https://youtu.be/wxHuXBSE7Ms

![](https://cdn-learn.adafruit.com/assets/assets/000/097/776/medium800/3d_printing_hero-sign-tree.jpg?1607973890)

## IoT Scrolling Text

In this guide, we'll build an Internet of Things (IoT) sign with NeoPixels and CircuitPython. This is a wooden sign with LED strips that can display scrolling text from Adafruit IO. You can create a dashboard and update the text with your mobile device. With the color picker, you can change the color of the text so you can easily customize your message.

## NeoPixel LED Sign with CircuitPython

The pixelframe buf library for CircuitPython makes it easy to create custom LED matrices using NeoPixels.&nbsp;

![3d_printing_hero-sign-closeup.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/774/medium640/3d_printing_hero-sign-closeup.jpg?1607973625)

## Wifi with Metro ESP32-S2&nbsp;

The Metro ESP32-S2 has built-in WiFi and CircuitPython Support. It’s housed in a 3D printed enclosure and secured to the wooden frame.

![3d_printing_hero-metroesp32s2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/775/medium640/3d_printing_hero-metroesp32s2.jpg?1607973798)

## Parts
### Adafruit Metro ESP32-S2

[Adafruit Metro ESP32-S2](https://www.adafruit.com/product/4775)
What's Metro shaped and has an ESP32-S2 WiFi module? What has a STEMMA QT connector for I2C devices, and a Lipoly charger circuit? What has your favorite Espressif WiFi microcontroller and lots of memory for your next IoT project?

That's right - its the new Adafruit Metro...

In Stock
[Buy Now](https://www.adafruit.com/product/4775)
[Related Guides to the Product](https://learn.adafruit.com/products/4775/guides)
![Angled shot of Adafruit Metro esp32-s2 ](https://cdn-shop.adafruit.com/640x480/4775-06.jpg)

### Adafruit Mini Skinny NeoPixel Digital RGB LED Strip - 30 LED/m

[Adafruit Mini Skinny NeoPixel Digital RGB LED Strip - 30 LED/m](https://www.adafruit.com/product/2949)
So thin.&nbsp;So mini.&nbsp;So teeeeeeny-tiny. It's the 'skinny' version of our classic NeoPixel strips!

These NeoPixel strips have 30 digitally-addressable pixel Mini LEDs per meter and are very affordable and are...

In Stock
[Buy Now](https://www.adafruit.com/product/2949)
[Related Guides to the Product](https://learn.adafruit.com/products/2949/guides)
![Adafruit NeoPixel Digital RGB LED Strip wired with all the LEDs illuminating various colors. ](https://cdn-shop.adafruit.com/product-videos/640x480/2949-07.jpg)

### Cable Gland PG-9 size - 0.158" to 0.252" Cable Diameter

[Cable Gland PG-9 size - 0.158" to 0.252" Cable Diameter](https://www.adafruit.com/product/761)
We have some great [waterproof and weather-proof items in the adafruit shop](https://www.adafruit.com/?q=waterproof&), but once you have a project built, you'll want to enclose it. But how to keep an enclosure weather/waterproof while still attaching cables for power, data...

In Stock
[Buy Now](https://www.adafruit.com/product/761)
[Related Guides to the Product](https://learn.adafruit.com/products/761/guides)
![Cable Gland PG-9 size](https://cdn-shop.adafruit.com/640x480/761-00.jpg)

### Waterproof Polarized 4-Wire Cable Set

[Waterproof Polarized 4-Wire Cable Set](https://www.adafruit.com/product/744)
Outdoor enthusiasts rejoice! We now have very useful 4-wire polarized cable sets in a waterproof variety. These cable sets are ideal for projects that must weather the weather: dust, water, rain, snow, tornado (not volcano proof!). Each cable has 4 color-coded conductors (red, black, white...

In Stock
[Buy Now](https://www.adafruit.com/product/744)
[Related Guides to the Product](https://learn.adafruit.com/products/744/guides)
![Two black, waterproof, 4-wire cable assemblies.](https://cdn-shop.adafruit.com/640x480/744-05.jpg)

### Part: Silicone Ribbon Cable
quantity: 1
Silicone Cover Stranded-Core Ribbon Cable - 10 Wire 1 Meter Long - 28AWG Black
[Silicone Ribbon Cable](https://www.adafruit.com/product/3890)

### Part: USB Micro-B PCB
quantity: 1
USB Micro-B Breakout Board
[USB Micro-B PCB](https://www.adafruit.com/product/1833)

### Part: Heat-Set Insert For Soldering Irons
quantity: 1
M3 sized
[Heat-Set Insert For Soldering Irons](https://www.adafruit.com/product/4239)

### Part: M3 Heat Set Inserts
quantity: 1
M3 x 4mm heat set inserts
[M3 Heat Set Inserts](https://www.adafruit.com/product/4255)

### Part: USB C breakouts
quantity: 1
USB 3.1 Type C male Connector
[USB C breakouts](https://www.amazon.com/gp/product/B07T97LC9L)

## Hardware Screws

Use the following list of hardware to secure the Metro ESP32-S2 to the 3D printed enclosure.

- 8x M3 x 6mm long screws
- 4x M3 x 10mm long FF standoffs&nbsp;
- 4x M3 x 4mm heat set inserts

# WiFi-Controlled NeoPixel Matrix LED Sign

## CAD Files

## Source Files

The cad files are available to download using the links below.

- Fusion 360, STEP files
- Adjustable User Parameters

![3d_printing_cad-hero.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/649/medium640/3d_printing_cad-hero.jpg?1607701165)

[Download CAD source files](https://cdn-learn.adafruit.com/assets/assets/000/097/758/original/CAD.zip?1607953856)
[Download STL files](https://cdn-learn.adafruit.com/assets/assets/000/097/759/original/STLs.zip?1607953874)
## Plans

The wood working portion of the project feature a set of plans for printing out. These are handy to reference while cutting and assembling the parts.

![3d_printing_plans-hero.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/650/medium640/3d_printing_plans-hero.jpg?1607701725)

[Download Parts PDF](https://cdn-learn.adafruit.com/assets/assets/000/097/761/original/parts.pdf?1607954140)
[Download Steps PDF](https://cdn-learn.adafruit.com/assets/assets/000/097/760/original/steps.pdf?1607954129)
## 3D 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. Original design source may be downloaded using the links below.

- 1x case-box.stl
- 1x case-gasket.stl
- 1x case-cover.stl
- 2x panel-bracket.stl
- 4x frame-bracket.stl
- 6x neopixel-holder.stl

![3d_printing_3d-parts.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/676/medium640/3d_printing_3d-parts.jpg?1607712686)

## Slicing Parts

Slice with setting for PLA material. The parts were sliced using CURA using the slice settings below.

**PLA filament**  
215c extruder  
0.2 layer height  
10% gyroid infill  
60mm/s print speed  
60c heated bed

![3d_printing_cura-slice.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/651/medium640/3d_printing_cura-slice.jpg?1607702143)

https://www.youtube.com/watch?v=xCwAXL_CacY

# WiFi-Controlled NeoPixel Matrix LED Sign

## Circuit Diagram

The diagram below provides a visual reference for wiring of the components. 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).

![](https://cdn-learn.adafruit.com/assets/assets/000/097/636/medium800/3d_printing_circuit-diagram.jpg?1607634336)

Info: 

## Wired Connections

The wiring diagram only shows 4 strips for simplicity. This project is designed to use 12x strips with 12x pixels on each strip. Arrange the NeoPixel strips so the flow of data is in a zigzag pattern.

NeoPixels to Metro

- DIN from NeoPixel strip to Pin 6 on Metro
- 5V from NeoPixel strip to VHI on Metro
- GND from NeoPixel strip to GND on Metro

NeoPixel strip to NeoPixels strip

- DOUT from strip to DIN on strip
- 5V from strip to 5V on strip
- GND from strip to GND on strip

## Powering

The Adafruit board can be powered via USB or JST using a 3.7v lipo battery. In this project, a 5V power supply is used. If a lipo battery is being used, it can be rechargeable over the USB-C port on the Metro ESP32-S2.

# WiFi-Controlled NeoPixel Matrix LED Sign

## Adafruit IO Setup

## Obtain Adafruit IO Key

Adafruit IO is Adafruit's free internet of things data portal. If you do not have an account, navigate to [https://io.adafruit.com/](https://io.adafruit.com/) and create one.

You will need your Adafruit IO username and secret API key.

[**Navigate to Adafruit IO**](https://io.adafruit.com/profile) and **click the Adafruit IO Key button** to retrieve these values. Write them down in a safe place, you'll need them later.

## Create Group

This guide will use multiple Adafruit IO feeds to store sensor values. To organize these feeds, you will need to create a new group.&nbsp;

 **Navigate** to [your Adafruit IO Feeds page](https://io.adafruit.com/feeds).

**Click** _Actions -\> Create a New Group_

**Name the group** _sign-quotes_. You can optionally set a description.

**Click Create**

![led_pixels_io-newgroup.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/777/medium640/led_pixels_io-newgroup.jpg?1607975365)

![led_pixels_io-group-create.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/779/medium640/led_pixels_io-group-create.jpg?1607975613)

## Add Feeds to Group

Let's add a few feeds to the **sign-quotes** group to hold NeoPixel color and text.&nbsp;

 **Click** _Actions -\> Create a New Feed_

**Name the feed** _signcolor_

**Click** _Add to Groups&nbsp;_and&nbsp;select the **sign-quotes** group

**Click Create**

![led_pixels_io-newfeed.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/780/medium640/led_pixels_io-newfeed.jpg?1607975855)

![led_pixels_io-feed-create.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/781/medium640/led_pixels_io-feed-create.jpg?1607975873)

Repeat the process in the step above to create a feed for **signtext.**

Before proceeding, make sure your Air Quality Sensor group looks exactly like the screenshot below.

![](https://cdn-learn.adafruit.com/assets/assets/000/097/783/medium800/led_pixels_io-group-feeds.jpg?1607976106)

## Adafruit IO Dashboard

Dashboards allow you to visualize data and control Adafruit IO connected projects from any modern web browser. We'll be adding a text block to enter text and color picker to choose a color for the NeoPixels.

Navigate to&nbsp;[the dashboards page on Adafruit IO](https://io.adafruit.com/dashboards).&nbsp;

**Click Actions -\> Create New Dashboard**

**Name the dashboard** My IoT NeoPixel LED Sign&nbsp;

**Click Create&nbsp;**

![led_pixels_io-newdash.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/784/medium640/led_pixels_io-newdash.jpg?1607976310)

![led_pixels_io-dash-create.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/785/medium640/led_pixels_io-dash-create.jpg?1607976320)

You should see your new dashboard pop-up in the list of Dashboards. **Click the My IoT NeoPixel LED Sign dashboard link** to navigate to the dashboard page.

![](https://cdn-learn.adafruit.com/assets/assets/000/097/786/medium800/led_pixels_io-dashes.jpg?1607976515)

You should see an empty dashboard. Let's fill it with blocks!

**Click the '+' button on your dashboard to add a new block**.

![](https://cdn-learn.adafruit.com/assets/assets/000/097/787/medium800/led_pixels_io-newblock.jpg?1607976841)

From the Create a New Block picker,&nbsp; **click the Text Block**

On the Choose Feed picker, **select the signtext feed** &nbsp;

Under Block Settings:

- **Set Block Title** to LED Text
- **Set Font Size** to Large
- **Click** Create Block

![led_pixels_io-blocks.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/788/medium640/led_pixels_io-blocks.jpg?1607977010)

![led_pixels_io-block-signtext.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/789/medium640/led_pixels_io-block-signtext.jpg?1607977048)

![led_pixels_io-signtext-settings.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/790/medium640/led_pixels_io-signtext-settings.jpg?1607977133)

From the Create a New Block picker, click the **Color Picker Block**

On the Choose Feed Picker, select the **signcolor feed**

Name the block **Text Color**

**Click Create**

![led_pixels_io-blocks.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/791/medium640/led_pixels_io-blocks.jpg?1607977247)

![led_pixels_io-block-signcolor.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/792/medium640/led_pixels_io-block-signcolor.jpg?1607977260)

![led_pixels_io-signcolor-settings.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/793/medium640/led_pixels_io-signcolor-settings.jpg?1607977276)

## Organize Dashboard

You can drag the dashboard blocks around to re-organize your dashboard.&nbsp;

Before moving on, make sure your dashboard contains the same blocks as the screenshot below

![](https://cdn-learn.adafruit.com/assets/assets/000/097/794/medium800/led_pixels_io-dashboard-orangize.jpg?1607977424)

# WiFi-Controlled NeoPixel Matrix LED Sign

## CircuitPython Internet Test

One of the great things about most Espressif microcontrollers are their built-in WiFi capabilities. This page covers the basics of getting connected using CircuitPython.

The first thing you need to do is update your **code.py** to the following (it will error until WiFi details are added). Click the **Download Project Bundle** button to download the necessary libraries and the&nbsp; **code.py** file in a zip file. Extract the contents of the zip file, and copy the **entire**  **lib**  **folder** and the **code.py** file to your **CIRCUITPY** drive.

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

Your **CIRCUITPY** drive should resemble the following.

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

To get connected, the next thing you need to do is update the **settings.toml** file.

## The settings.toml File

We expect people to share tons of projects as they build CircuitPython WiFi widgets. What we want to avoid is people accidentally sharing their passwords or secret tokens and API keys. So, we designed all our examples to use a **settings.toml** file, that is on your&nbsp; **CIRCUITPY** &nbsp;drive, to hold secret/private/custom data. That way you can share your main project without worrying about accidentally sharing private stuff.

If you have a fresh install of CircuitPython on your board, the initial **settings.toml** file on your **CIRCUITPY** drive is empty.

To get started, you can update the **settings.toml** on your **CIRCUITPY** drive to contain the following code.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/ESP32_S2_WiFi_Tests/CPy_Native_WiFi_Test/settings.toml

This file should contain a series of Python variables, each assigned to a string. Each variable should describe what it represents (say&nbsp;`wifi_ssid`), followed by an **=&nbsp;** (equals sign), followed by the data in the form of a Python string (such as `"my-wifi-password"` including the quote marks).

**At a minimum you'll need to add/update your WiFi SSID and WiFi password, so do that now!**

As you make projects you may need more tokens and keys, just add them one line at a time. See for example other tokens such as one for accessing GitHub or the Hackaday API. Other non-secret data like your timezone can also go here.

For the correct time zone string, look at&nbsp;[http://worldtimeapi.org/timezones](http://worldtimeapi.org/timezones)&nbsp;and remember that if your city is not listed, look for a city in the same time zone, for example Boston, New York, Philadelphia, Washington DC, and Miami are all on the same time as New York.

Of course, don't share your **settings.toml** - keep that out of GitHub, Discord or other project-sharing sites.

Warning: 

If you connect to the serial console, you should see something like the following:

![](https://cdn-learn.adafruit.com/assets/assets/000/097/014/medium800/adafruit_products_1__screen__Users_brentrubell__screen_.png?1605218222)

In order, the example code...

Checks the ESP32's MAC address.

```python
print(f"My MAC address: {[hex(i) for i in wifi.radio.mac_address]}")
```

Performs a scan of all access points and prints out the access point's name (SSID), signal strength (RSSI), and channel.

```python
print("Available WiFi networks:")
for network in wifi.radio.start_scanning_networks():
    print("\t%s\t\tRSSI: %d\tChannel: %d" % (str(network.ssid, "utf-8"),
                                             network.rssi, network.channel))
wifi.radio.stop_scanning_networks()
```

Connects to the access point you defined in the **settings.toml** file, and prints out its local IP address.

```python
print(f"Connecting to {os.getenv('WIFI_SSID')}")
wifi.radio.connect(os.getenv("WIFI_SSID"), os.getenv("WIFI_PASSWORD"))
print(f"Connected to {os.getenv('WIFI_SSID')}")
print(f"My IP address: {wifi.radio.ipv4_address}")
```

Attempts to ping a Google DNS server to test connectivity. If a ping fails, it returns `None`. Initial pings can sometimes fail for various reasons. So, if the initial ping is successful (`is not None`), it will print the echo speed in ms. If the initial ping fails, it will try one more time to ping, and then print the returned value. If the second ping fails, it will result in `"Ping google.com: None ms"` being printed to the serial console. Failure to ping does not always indicate a lack of connectivity, so the code will continue to run.

```python
ping_ip = ipaddress.IPv4Address("8.8.8.8")
ping = wifi.radio.ping(ip=ping_ip) * 1000
if ping is not None:
    print(f"Ping google.com: {ping} ms")
else:
    ping = wifi.radio.ping(ip=ping_ip)
    print(f"Ping google.com: {ping} ms")
```

The code creates a socketpool using the wifi radio's available sockets. This is performed so we don't need to re-use sockets. Then, it initializes a a new instance of the [requests](http://docs.python-requests.org/en/master/) interface - which makes getting data from the internet _really really easy._

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

To read in plain-text from a web URL, call `requests.get` - you may pass in either a http, or a http **s** url for SSL connectivity.&nbsp;

```python
print(f"Fetching text from {TEXT_URL}")
response = requests.get(TEXT_URL)
print("-" * 40)
print(response.text)
print("-" * 40)
```

Requests can also display a JSON-formatted response from a web URL using a call to `requests.get`.&nbsp;

```python
print(f"Fetching json from {JSON_QUOTES_URL}")
response = requests.get(JSON_QUOTES_URL)
print("-" * 40)
print(response.json())
print("-" * 40)
```

Finally, you can fetch and parse a JSON URL using `requests.get`. This code snippet obtains the `stargazers_count` field from a call to the GitHub API.

```python
print(f"Fetching and parsing json from {JSON_STARS_URL}")
response = requests.get(JSON_STARS_URL)
print("-" * 40)
print(f"CircuitPython GitHub Stars: {response.json()['stargazers_count']}")
print("-" * 40)
```

OK you now have your ESP32 board set up with a proper **settings.toml** file and can connect over the Internet. If not, check that your **settings.toml** file has the right SSID and password and retrace your steps until you get the Internet connectivity working!

## IPv6 Networking

Starting in CircuitPython 9.2, IPv6 networking is available on most Espressif wifi boards. Socket-using libraries like **adafruit\_requests** and **adafruit\_ntp** will need to be updated to use the new APIs and for now can only connect to services on IPv4.

### IPv6 connectivity & privacy

IPv6 addresses are divided into many special kinds, and many of those kinds (like those starting with&nbsp; **FC** , **FD** , **FE** ) are private or local; Addresses starting with other prefixes like&nbsp; **2002:** and **2001:** are globally routable. In 2024, far from all ISPs and home networks support IPv6 internet connectivity. For more info consult resources like [Wikipedia](https://en.wikipedia.org/wiki/IPv6_address#Local_addresses). If you're interested in global IPv6 connectivity you can use services like [Hurricane Electric](https://www.he.net/) to create an "IPv6 tunnel" (free as of 2024, but requires expertise and a compatible router or host computer to set up)

It's also important to be aware that, as currently implemented by Espressif, there are privacy concerns especially when these devices operate on the global IPv6 network: The device's unique identifier (its EUI-64 or MAC address) is used by default as part of its IPv6 address. This means that the device identity can be tracked across multiple networks by any service it connects to.

### Enable IPv6 networking

Due to the privacy consideration, IPv6 networking is not automatically enabled. Instead, it must be explicitly enabled by a call to `start_dhcp_client` with the `ipv6=True` argument specified:

```python
wifi.start_dhcp_client(ipv6=True)
```

### Check IP addresses

The read-only&nbsp;`addresses` property of the `wifi.radio` object holds all addresses, including IPv4 and IPv6 addresses:

```python
&gt;&gt;&gt; wifi.radio.addresses
('FE80::7EDF:A1FF:FE00:518C', 'FD5F:3F5C:FE50:0:7EDF:A1FF:FE00:518C', '10.0.3.96')
```

The `wifi.radio.dns` servers can be IPv4 or IPv6:

```python
&gt;&gt;&gt; wifi.radio.dns
('FD5F:3F5C:FE50::1',)
&gt;&gt;&gt; wifi.radio.dns = ("1.1.1.1",)
&gt;&gt;&gt; wifi.radio.dns
('1.1.1.1',)
```

### Ping v6 networks

`wifi.radio.ping` accepts v6 addresses and names:

```python
&gt;&gt;&gt; wifi.radio.ping("google.com")
0.043
&gt;&gt;&gt; wifi.radio.ping("ipv6.google.com")
0.048
```

### Create & use IPv6 sockets

Use the address family `socket.AF_INET6`. After the socket is created, use methods like `connect`, `send`, `recfrom_into`, etc just like for IPv4 sockets. This code snippet shows communicating with a private-network NTP server; this IPv6 address will not work on your network:

```python
&gt;&gt;&gt; ntp_addr = ("fd5f:3f5c:fe50::20e", 123)
&gt;&gt;&gt; PACKET_SIZE = 48
&gt;&gt;&gt; 
&gt;&gt;&gt; buf = bytearray(PACKET_SIZE)
&gt;&gt;&gt; with socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) as s:
...     s.settimeout(1)
...     buf[0] = 0b0010_0011
...     s.sendto(buf, ntp_addr)
...     print(s.recvfrom_into(buf))
...     print(buf)
... 
48
(48, ('fd5f:3f5c:fe50::20e', 123))
bytearray(b'$\x01\x03\xeb\x00\x00\x00\x00\x00\x00\x00GGPS\x00\xeaA0h\x07s;\xc0\x00\x00\x00\x00\x00\x00\x00\x00\xeaA0n\xeb4\x82-\xeaA0n\xebAU\xb1')
```

# WiFi-Controlled NeoPixel Matrix LED Sign

## Code

First, install CircuitPython on your board, following the [instructions in the Metro ESP-32 Learn Guide](https://learn.adafruit.com/adafruit-metro-esp32-s2/circuitpython).

## Add Font

Download the font file below and add it to the root of the CircuitPython drive.

[Download Font File](https://github.com/adafruit/Adafruit_CircuitPython_framebuf/blob/master/examples/font5x8.bin)
## Required Libraries&nbsp;

- **adafruit\_framebuf.mpy**
- **adafruit\_io**
- **adafruit\_minimqtt/**
- **adafruit\_connection\_manager.mpy**
- **adafruit\_ticks.mpy**
- **adafruit\_led\_animation**
- **adafruit\_pixel\_framebuf.mpy**
- **adafruit\_requests.mpy**
- **neopixel.mpy**

![CIRCUITPY](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/folder-images/IoT_NeoPixel_Sign.png?raw=true )

Once we have all the files we need, a directory listing will look similar to above as far as files and directories.

## Upload Code

Click on the Download Project Zip link below to grab the main code directly from GitHub. **Rename the file** to **code.py** and drop it onto the main (root) directory of the **CIRCUITPY** drive that appeared in your computer file explorer/finder when the board was plugged in via a known, good USB cable The code will run properly when all of the files have been uploaded including libraries.

Use any text editor or favorite IDE to modify the code. We suggest using [Mu](https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor).

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

# WiFi-Controlled NeoPixel Matrix LED Sign

## Building the Wooden Sign

## Materials

The wood used to build the sign feature the same material width and thickness. The lengths of the each piece are listed below and in the downloadable plans.

- Bottom Base
  - 2x 20in x 2.5in x 1in
  - 2x 18in x 2.5in x 1in

- Leg Frame
  - 2x 18in x 2.5in x 1in
  - 2x 28in x 2.5 x 1in

- LED Frame
  - 2x 19.5in x 2.5in x 1in
  - 2x 30.5in x 2.5in x 1in

- Leg Supports
  - 4x 3in x 2.5in x 1in

- LED Panel
  - 1x 27in x 16in x 1/2in

![3d_printing_plans-herophoto.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/726/medium640/3d_printing_plans-herophoto.jpg?1607783176)

## Bottom Base

Use four boards to create the bottom base. Secure the boards together using basic butt joints.

![3d_printing_base-step-1.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/685/medium640/3d_printing_base-step-1.jpg?1607716867)

## Leg Frame

Use four boards to create the leg frame. Place the 28in boards down first and lay the 18in over them. Secure the boards together using nails or screws.

![3d_printing_legs-step-2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/686/medium640/3d_printing_legs-step-2.jpg?1607717085)

## Frame Supports

Use four small cutoff pieces to create the supports. Place the leg frame inside the bottom base to gauge a centered position. Secure the supports to the bottom base using nails or screws.

![3d_printing_supports-single-step-3.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/687/medium640/3d_printing_supports-single-step-3.jpg?1607717341)

![3d_printing_supports-3.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/688/medium640/3d_printing_supports-3.jpg?1607717374)

## LED Frame

Use four boards with 45 degree mitered cuts to create the LED frame. Secure the boards together using wood glue and nails.

![3d_printing_frame-step-4.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/691/medium640/3d_printing_frame-step-4.jpg?1607717662)

## LED Panel

Use a single sheet of wood 1/5in thick and cut to size.

![3d_printing_panel-step-5.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/692/medium640/3d_printing_panel-step-5.jpg?1607717818)

## Install Strip Holders

Lay a row of strip holders over the panel and align them with the edge of the wood. Position the set of holder so they're centered with the panel. Use screws to secure the holders to the panel.&nbsp;

Lay second row of strip holders and align them with the edge. Use a straight edge guide to line up the holders with the first row. Use screws to secure the second set of holders to the panel.

![3d_printing_strips-step-6.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/693/medium640/3d_printing_strips-step-6.jpg?1607717947)

Info: 

## Secure Brackets

Place the four frame brackets onto the corners of the LED frame. Then place the LED panel onto the brackets. Position the two so they're centered. Secure the frame brackets using screws.

Place the leg frame over the LED panel to gauge a good position to secure the panel brackets. Use screws to secure the&nbsp;brackets onto the LED panel.&nbsp;

![3d_printing_brackets-step-7.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/694/medium640/3d_printing_brackets-step-7.jpg?1607718256)

![3d_printing_brackets-frame-step-7.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/695/medium640/3d_printing_brackets-frame-step-7.jpg?1607718616)

## Assembled Sign

Place the leg frame into the bottom base. Then, fit the LED panel onto the leg frame. Place the LED frame onto the LED panel by fitting onto the brackets. The sign is now ready for NeoPixels and the Metro ESP32-S2 board.

![3d_printing_sign-step-8.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/696/medium640/3d_printing_sign-step-8.jpg?1607718994)

## Assembly Notes

A nail gun can be used to help speed up the assembly. Drilling pilot holes is helpful for preventing crooked screws. Material thickness and board width don't have to be exact as the design can be adapted to fit different dimensions.

# WiFi-Controlled NeoPixel Matrix LED Sign

## Building Metro Control Box

## Cable for NeoPixels

Use the 4-wire weather proof cable to connect the NeoPixel strip to the Metro board. Use a piece of silicone ribbon cable to join the weather proof cable to a 3-pin strip of headers – This makes it easy to connect to the headers on the Metro board. Use heat shrink to insulate exposed connections. The overall length of the cable is 15cm (6in).&nbsp;

![3d_printing_neopixel-cable.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/727/medium640/3d_printing_neopixel-cable.jpg?1607797686)

## USB-C Cable

Create a slim DIY USB cable to power the Metro board. The Metro is designed to fit a USB C type plug.

The other end can be any type of connector. Ideally the connector should fit an extra long USB cable for power.

The overall length of the cable is 15cm (6in).&nbsp;

![3d_printing_usb-cable.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/728/medium640/3d_printing_usb-cable.jpg?1607797706)

## Install Heat Inserts

The case uses 4x M3 heat set inserts to secure the top cover. These are installed using a soldering iron with a special heat insert tip. Inserts allow for strong joints with reliable repeatability and no wear out.&nbsp;

A [heat insert rig](https://learn.adafruit.com/heat-set-rig) can be used to make precise installations.

![3d_printing_case-heatinserts-installing.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/749/medium640/3d_printing_case-heatinserts-installing.jpg?1607872437)

![3d_printing_case-heatinserts-installed.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/750/medium640/3d_printing_case-heatinserts-installed.jpg?1607872451)

## Install Cable Gland & Cables

Insert the PG-9 cable gland into the Metro case and secure using the included hex nut.

Fit the USB-C type plug through the cable gland. Then, insert the weather proof cable, header pins first, through the cable gland.

![3d_printing_metro-case-cables-install.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/729/medium640/3d_printing_metro-case-cables-install.jpg?1607798087)

## Connect Metro

Fit the header pins from the weather proof cable to Pin 6 (white wire), GND (black wire) and VHI (red wire) pins on the Metro. Connect the USB-C plug to the port on the Metro. Double check the connections from the cable are correct.

![3d_printing_metro-connect-cables.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/730/medium640/3d_printing_metro-connect-cables.jpg?1607797794)

## Secure Metro to Case

Orient the Metro board with the mounting holes on the case. Secure the standoffs to the case, then place the metro PCB over them. Secure using machine screws. Use the following hardware to secure the Metro PCB to the case.

- 8x M3 x 6mm long screws
- 4x M3 x 10mm long FF standoffs&nbsp;

![3d_printing_metro-case-install.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/731/medium640/3d_printing_metro-case-install.jpg?1607797814)

## Secure Cover

Place the cover on top of the case. Secure using 4x M3 x 6mm long screws. Optionally use the TPU gasket to make a weather proof seal between the cover and case.

![3d_printing_metro-case-cover-installed.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/732/medium640/3d_printing_metro-case-cover-installed.jpg?1607797866)

## Secure Enclosure to Frame

Place the enclosure onto the leg frame in a desired location. The enclosue features four mounting holes for attaching. Secure the enclosure to the frame using #4-40 (M3) wooden screws.

![3d_printing_secure-case-frame.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/762/medium640/3d_printing_secure-case-frame.jpg?1607955109)

# WiFi-Controlled NeoPixel Matrix LED Sign

## Building NeoPixel Grid

## Cut NeoPixel Strips

Use flush snips to cut the NeoPixel strips. Follow the cut markings on the flexible PCB. Thoroughly count each pixel before cutting strips. This project specifically uses a 12x strips, each strip containing 12x NeoPixel LEDs.

![3d_printing_strips-cutup-edit.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/747/medium640/3d_printing_strips-cutup-edit.jpg?1607871531)

Danger: 

## Wiring NeoPixel Strips

Solder the other piece of the weather proof cable to the first NeoPixel strip in the chain.&nbsp;

Solder the 12x strips together using pieces of silicone ribbon wire. Follow the circuit diagram to reference the flow of data. Use pieces of heat shrink to insulate the exposed connections.

Each set of wires are approximately 5cm (2in) in length.&nbsp;

![3d_printing_strips-wired-edit.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/748/medium640/3d_printing_strips-wired-edit.jpg?1607871567)

## Test NeoPixel Strips

Connect the first NeoPixel strip to the Metro board. Use a 5V USB power supply to power on the Metro and strips. Thoroughly check each strip for any damaged pixels. If a dead pixel is encountered, swap out the strip with a new one.&nbsp;

Ideally use the [strandtest demo code](https://learn.adafruit.com/adafruit-neopixel-uberguide/python-circuitpython) to make all of the NeoPixel a solid color. This a great way to catch any dead pixels in the bunch.&nbsp;

![3d_printing_led-strips-test-edit.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/751/medium640/3d_printing_led-strips-test-edit.jpg?1607876348)

## Installing NeoPixel Strips

The NeoPixels are inserted into the 3D printed strip holders. The silicone sheathing is press fitted through the clips. The fitting is snug and should keep the strips nice and taught.

The first NeoPixel strip is secured to the top left corner followed by the proceeding strip in a zigzag order.&nbsp;

![3d_printing_strips-holder-closeup.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/746/medium640/3d_printing_strips-holder-closeup.jpg?1607871510)

## Install All Strips

Repeat the installation process for the remaining strips of NeoPixels. Be sure to check the flow of data in each strip so they all follow a zigzag order.&nbsp;

The NeoPixel flexible PCBs can shift during the installation and may need to be adjusted. Align all of the strips for they look straight.

&nbsp;

![3d_printing_strips-installed-sideview.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/744/medium640/3d_printing_strips-installed-sideview.jpg?1607870681)

![3d_printing_strips-installed-wideangled.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/745/medium640/3d_printing_strips-installed-wideangled.jpg?1607871039)

## Weather Proofing

If the sign is going to be used outdoors, the NeoPixels will need to be weatherproofed. An easy way to do that is to use hot glue to seal each of the strips. Make sure all of the pixels has been thoroughly tested before adding hot glue.

![3d_printing_led-matrix-blue-v2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/738/medium640/3d_printing_led-matrix-blue-v2.jpg?1607801848)

# WiFi-Controlled NeoPixel Matrix LED Sign

## Usage

## Updating Scrolling Text

Open up Adafruit IO at [https://io.adafruit.com/](https://io.adafruit.com/) on your phone, tablet, or computer.

Click or tap on the blank text input box and type in your message using a keyboard. Press the enter / return key to save the text. The enter/return key must be entered in order for the text to push to Adafruit IO.

![led_pixels_usage-edit-textbox.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/796/medium640/led_pixels_usage-edit-textbox.jpg?1607977705)

## Updating Text Color

Click or tap on the big colored circle to pull up the color picker. Drag the eye dropper around to change the shade of color. Use the slider in the color bar to adjust the hue of the color set. Optionally enter a HEX value in the text input. Click save button to save and update the text color.

![led_pixels_usage-colorpicker.jpg](https://cdn-learn.adafruit.com/assets/assets/000/097/797/medium640/led_pixels_usage-colorpicker.jpg?1607977815)


## Featured Products

### Adafruit Metro ESP32-S2

[Adafruit Metro ESP32-S2](https://www.adafruit.com/product/4775)
What's Metro shaped and has an ESP32-S2 WiFi module? What has a STEMMA QT connector for I2C devices, and a Lipoly charger circuit? What has your favorite Espressif WiFi microcontroller and lots of memory for your next IoT project?

That's right - its the new Adafruit Metro...

In Stock
[Buy Now](https://www.adafruit.com/product/4775)
[Related Guides to the Product](https://learn.adafruit.com/products/4775/guides)
### Adafruit Mini Skinny NeoPixel Digital RGB LED Strip - 30 LED/m

[Adafruit Mini Skinny NeoPixel Digital RGB LED Strip - 30 LED/m](https://www.adafruit.com/product/2949)
So thin.&nbsp;So mini.&nbsp;So teeeeeeny-tiny. It's the 'skinny' version of our classic NeoPixel strips!

These NeoPixel strips have 30 digitally-addressable pixel Mini LEDs per meter and are very affordable and are...

In Stock
[Buy Now](https://www.adafruit.com/product/2949)
[Related Guides to the Product](https://learn.adafruit.com/products/2949/guides)
### Cable Gland PG-9 size - 0.158" to 0.252" Cable Diameter

[Cable Gland PG-9 size - 0.158" to 0.252" Cable Diameter](https://www.adafruit.com/product/761)
We have some great [waterproof and weather-proof items in the adafruit shop](https://www.adafruit.com/?q=waterproof&), but once you have a project built, you'll want to enclose it. But how to keep an enclosure weather/waterproof while still attaching cables for power, data...

In Stock
[Buy Now](https://www.adafruit.com/product/761)
[Related Guides to the Product](https://learn.adafruit.com/products/761/guides)
### Waterproof Polarized 4-Wire Cable Set

[Waterproof Polarized 4-Wire Cable Set](https://www.adafruit.com/product/744)
Outdoor enthusiasts rejoice! We now have very useful 4-wire polarized cable sets in a waterproof variety. These cable sets are ideal for projects that must weather the weather: dust, water, rain, snow, tornado (not volcano proof!). Each cable has 4 color-coded conductors (red, black, white...

In Stock
[Buy Now](https://www.adafruit.com/product/744)
[Related Guides to the Product](https://learn.adafruit.com/products/744/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)
### USB Micro-B Breakout Board

[USB Micro-B Breakout Board](https://www.adafruit.com/product/1833)
Simple but effective - this breakout board has a USB Micro-B connector, with all 5 pins broken out. Great for pairing with a microcontroller with USB support, or adding USB 5V power to a project.  
  
We use a micro-B connector with through-hole shielding pads for an excellent strong...

In Stock
[Buy Now](https://www.adafruit.com/product/1833)
[Related Guides to the Product](https://learn.adafruit.com/products/1833/guides)
### Heat-Set Insert For Soldering Irons - #4-40 / M3 Inserts

[Heat-Set Insert For Soldering Irons - #4-40 / M3 Inserts](https://www.adafruit.com/product/4239)
Wanna improve the connection strength between your project's 3D-printed parts, and also have nice clean surfaces? Instead of gluing bits together, or screwing plastic screws directly into your 3D prints, use strong and reusable machine screws and heat-set inserts. Heat set inserts are only...

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/4239)
[Related Guides to the Product](https://learn.adafruit.com/products/4239/guides)
### Brass Heat-Set Inserts for Plastic - M3 x 4mm - 50 pack

[Brass Heat-Set Inserts for Plastic - M3 x 4mm - 50 pack](https://www.adafruit.com/product/4255)
Wanna improve the connection strength between your project's 3D-printed parts, and also have nice clean surfaces? Instead of gluing bits together, or screwing plastic screws directly into your 3D prints, use strong and reusable machine screws and heat-set inserts. Heat set inserts are only...

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

## Related Guides

- [Adafruit Metro ESP32-S2](https://learn.adafruit.com/adafruit-metro-esp32-s2.md)
- [TRON DISC](https://learn.adafruit.com/trondisc.md)
- [Animating Animatronics](https://learn.adafruit.com/animating-animatronics.md)
- [DotStar Fortune Necklace with Bluetooth and Touch](https://learn.adafruit.com/dotstar-fortune-necklace.md)
- [Huzzah Weather Display](https://learn.adafruit.com/huzzah-weather-display.md)
- [Adafruit NeoPixel Überguide](https://learn.adafruit.com/adafruit-neopixel-uberguide.md)
- [CAN Bus with CircuitPython: Using the canio module](https://learn.adafruit.com/using-canio-circuitpython.md)
- [Four Seasons Fairy Bottle Lanterns](https://learn.adafruit.com/four-seasons-fairy-bottle-lanterns.md)
- [HalloWing Interactive Cat Toy](https://learn.adafruit.com/hallowing-cat-toy.md)
- [Adafruit CH334F Mini USB Hub Breakouts](https://learn.adafruit.com/adafruit-ch334f-mini-4-port-usb-hub-breakout.md)
- [Adafruit TPL5110 Power Timer Breakout](https://learn.adafruit.com/adafruit-tpl5110-power-timer-breakout.md)
- [CircuitPython BLE Controlled NeoPixel Hat](https://learn.adafruit.com/circuitpython-feather-ble-neopixel-hat.md)
- [CircuitPython Sound Box](https://learn.adafruit.com/circuitpython-sound-box.md)
- [MP3 Playback with CircuitPython](https://learn.adafruit.com/mp3-playback-with-circuitpython.md)
- [Bluetooth Controlled NeoPixel Lightbox](https://learn.adafruit.com/bluetooth-neopixel-lightbox.md)
- [Micro USB Dock for Circuit Playground](https://learn.adafruit.com/micro-usb-dock-for-circuit-playground.md)
