This example is not designed to run on the FunHouse. It is an example of a device you could connect to Adafruit IO and then display the connected feed on your FunHouse IoT hub.

This example uses a PyPortal Titano as a remote control for NeoPixels. It uses HTTP which is pretty slow, but MQTT on PyPortals is a bit unreliable at the moment.

For this project, you need:

Hand holding PyPortal Titano development board with SAMD51, ESP32 Wifi, and 3.5" touchscreen TFT display.
The PyPortal Titano is the big sister to our popular PyPortal now with twice as many pixels! The PyPortal...
$59.95
In Stock
Angled shot of a Adafruit Feather M4 Express.
It's what you've been waiting for, the Feather M4 Express featuring ATSAMD51. This Feather is fast like a swift, smart like an owl, strong like a ox-bird (it's half ox,...
$22.95
In Stock
Angled shot of Adafruit AirLift FeatherWing.
Give your Feather project a lift with the Adafruit AirLift FeatherWing - a FeatherWing that lets you use the powerful ESP32 as a WiFi co-processor. You probably have your...
$12.95
In Stock
Triple prototyping feather wing PCB with socket headers installed
This is the FeatherWing Tripler - a prototyping add-on and more for all Feather boards. This is similar to our
$8.50
In Stock

If the FeatherWing tripler is out of stock, you can also use a FeatherWing Doubler and put Stacking Headers on either the Feather M4 or the AirLift FeatherWing.

Adafruit NeoPixel Digital RGB LED Strip wired to a microcontroller, with all the LEDs in a rainbow
You can't bake a cake without flour, sugar, and baking soda? Cream cheese? Muscadet? Ok - to be honest we don't do much cake baking.  But we do light up a TON of...
$24.95
In Stock

PyPortal Setup

First click Download Project Bundle below. This zip file will contain everything you need for this example. However, the files are also in the zip file you downloaded for the FunHouse, so you can get them from either one, just make sure you take the files from the neopixel_remote directory.

# SPDX-FileCopyrightText: 2021 Eva Herrada for Adafruit Industries
# SPDX-License-Identifier: MIT

"""
NeoPixel remote control using PyPortal Titano.

Colors used are taken from Adafruit_CircuitPython_LED_Animation library
"""

import time
import math
import board
import busio
from digitalio import DigitalInOut
import displayio
from adafruit_display_shapes.rect import Rect
import adafruit_imageload
import adafruit_touchscreen

# ESP32 SPI
from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager

# Import NeoPixel Library
import neopixel

# Import Adafruit IO HTTP Client
from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError

ts = adafruit_touchscreen.Touchscreen(
    board.TOUCH_XL,
    board.TOUCH_XR,
    board.TOUCH_YD,
    board.TOUCH_YU,
    calibration=((5200, 59000), (5800, 57000)),
    size=(480, 320),
)
RED = 0xFF0000
YELLOW = 0xFF9600
ORANGE = 0xFF2800
GREEN = 0x00FF00
TEAL = 0x00FF78
CYAN = 0x00FFFF
BLUE = 0x0000FF
PURPLE = 0xB400FF
MAGENTA = 0xFF0014
WHITE = 0xFFFFFF
BLACK = 0x000000

GOLD = 0xFFDE1E
PINK = 0xF15AFF
AQUA = 0x32FFFF
JADE = 0x00FF28
AMBER = 0xFF6400

colors = [
    None,
    None,
    GREEN,
    PURPLE,
    GOLD,
    AMBER,
    None,
    None,
    ORANGE,
    BLUE,
    BLACK,
    JADE,
    None,
    None,
    YELLOW,
    CYAN,
    WHITE,
    AQUA,
    None,
    None,
    RED,
    TEAL,
    MAGENTA,
    PINK,
]

print(colors)
group = displayio.Group()
# pyportal_setter.xcf has been included so you can edit the colors used in GIMP, just make sure to
# change them here as well
background, palette = adafruit_imageload.load(
    "bmps/pyportal_setter.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette
)
tile_grid = displayio.TileGrid(background, pixel_shader=palette)
group.append(tile_grid)
rect = Rect(0, 0, 160, 320, fill=0x000000)
group.append(rect)
print(len(group))

# Get wifi details and more from a secrets.py file
try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise

# PyPortal ESP32 Setup
esp32_cs = DigitalInOut(board.ESP_CS)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2)
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)

# Set your Adafruit IO Username and Key in secrets.py
# (visit io.adafruit.com if you need to create an account,
# or if you need your Adafruit IO key.)
ADAFRUIT_IO_USER = secrets["aio_username"]
ADAFRUIT_IO_KEY = secrets["aio_key"]

# Create an instance of the Adafruit IO HTTP client
io = IO_HTTP(ADAFRUIT_IO_USER, ADAFRUIT_IO_KEY, wifi)

try:
    # Get the 'temperature' feed from Adafruit IO
    neopixel_feed = io.get_feed("neopixel")
except AdafruitIO_RequestError:
    neopixel_feed = io.create_new_feed("neopixel")

board.DISPLAY.show(group)
print("ready")
last_color = 257
last_index = 0
while True:
    p = ts.touch_point
    if p:
        x = math.floor(p[0] / 80)
        y = math.floor(p[1] / 80)
        index = 6 * y + x
        # Used to prevent the touchscreen sending incorrect results
        if last_index == index:
            color = colors[index]
            if colors[index]:
                group[1].fill = color
                if last_color != color:
                    color_str = "#{:06x}".format(color)
                    print(color_str)
                    io.send_data(neopixel_feed["key"], color_str)
                    last_color = color
        last_index = index
    time.sleep(0.1)

First, you'll need to copy over the following libraries to your PyPortal Titano:

  • adafruit_display_shapes/
  • adafruit_imageload/
  • adafruit_io/
  • adafruit_esp32spi/
  • adafruit_requests.mpy
  • adafruit_touchscreen.mpy
  • neopixel.mpy

After you've done that, rename neopixel_remote.py to code.py and put it on the PyPortal.

Next, make a new folder on your PyPortal named bmps and put pyportal_setter.bmp inside it.

Finally, copy over your secrets.py file.

After you've done all that, this is what your CIRCUITPY drive should look like:

When you've done all this, your PyPortal should look like this and you should be able to tap a square and have the top of the display turn that color as well as see the Adafruit IO color indicator turn that color.

Feather Setup

# SPDX-FileCopyrightText: 2021 Dylan Herrada for Adafruit Industries
# SPDX-License-Identifier: MIT

"""
Sets NeoPixel color based on an Adafruit IO feed.
Uses:
    * https://www.adafruit.com/product/3811
    * Feather board
    * https://www.adafruit.com/product/4264
    * https://www.adafruit.com/product/2890

If your Feather board has STEMMA QT, you'll need one of these:
    * https://www.adafruit.com/product/4209

But if it doesn't, use stacking headers on either the Feather or the AirLift FeatherWing
"""

import board
import busio
from adafruit_esp32spi import adafruit_esp32spi
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
import neopixel
import adafruit_minimqtt.adafruit_minimqtt as MQTT
from adafruit_io.adafruit_io import IO_MQTT
from digitalio import DigitalInOut

### WiFi ###

# Get wifi details and more from a secrets.py file
try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise

# Change the first number to the pin the data line is plugged in to and the second number
# to the number of pixels
pixels = neopixel.NeoPixel(board.D5, 300)

# If you are using a board with pre-defined ESP32 Pins:
esp32_cs = DigitalInOut(board.D13)
esp32_ready = DigitalInOut(board.D11)
esp32_reset = DigitalInOut(board.D12)

spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
"""Use below for Most Boards"""
status_light = neopixel.NeoPixel(
    board.NEOPIXEL, 1, brightness=0.2
)  # Uncomment for Most Boards
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)

# Define callback functions which will be called when certain events happen.
# pylint: disable=unused-argument
def connected(client):
    client.subscribe("neopixel")


def subscribe(client, userdata, topic, granted_qos):
    # This method is called when the client subscribes to a new feed.
    print("Subscribed to {0} with QOS level {1}".format(topic, granted_qos))


def on_neopixel(client, topic, message):
    print(message)
    colors = [
        int(message.split("#")[1][i : i + 2], 16) for i in range(0, len(message) - 1, 2)
    ]
    print(colors)
    pixels.fill(colors)


# Connect to WiFi
print("Connecting to WiFi...")
wifi.connect()
print("Connected!")

# Initialize MQTT interface with the esp interface
MQTT.set_socket(socket, esp)

# Initialize a new MQTT Client object
mqtt_client = MQTT.MQTT(
    broker="io.adafruit.com",
    username=secrets["aio_username"],
    password=secrets["aio_key"],
)


# Initialize an Adafruit IO MQTT Client
io = IO_MQTT(mqtt_client)

io.add_feed_callback("neopixel", on_neopixel)
# Connect the callback methods defined above to Adafruit IO
io.on_connect = connected
io.on_subscribe = subscribe

# Connect to Adafruit IO
print("Connecting to Adafruit IO...")
io.connect()

io.get("neopixel")

while True:
    io.loop()

First, copy over the required libraries:

  • adafruit_esp32spi/
  • adafruit_io/
  • adafruit_minimqtt/
  • adafruit_requests.mpy
  • neopixel.mpy

The code above should already be downloaded. Rename it to code.py and copy it over to your Feather.

After you've copied all that over, copy your secrets.py over and you should be set as far as the files are concerned.

Assembly

Solder the headers that came with each device. Then put the Feather and the AirLift FeatherWing in the FeatherWing Tripler and attach the data wire from the NeoPixel strip (often green. I used one of these to make it a bit easier) to pin D5 (third pin from the end furthest from the USB port of the header with less pins) on the Tripler and then connect the ground wire (usually white or black) to a GND pin on the Tripler.

Afer you've done all this it should look something like this:

Now, connect the NeoPixel strip to a power source. If you have a lot of pixels, use a power supply but if you only have a few, you can get away with connecting it to the USB pin (note: this only works if you're powering the board through USB. If you're powering it with a LiPo this won't work).

Usage

To use the remote, just press one of the colored squares and it will send that to Adafruit IO. Then, the Feather will update the NeoPixels accordingly.

This guide was first published on May 26, 2021. It was last updated on 2021-05-26 10:50:53 -0400.

This page (NeoPixel Remote Example) was last updated on May 24, 2022.

Text editor powered by tinymce.