Here is the code from a couple of the examples that are included with the library. To run the examples, you will need to have your FunHouse set up with CircuitPython and a settings.toml file created. You can find detailed instructions in the Adafruit FunHouse guide. You will also need all of the libraries included in this project bundle:
Simple Test
This example uses of the top level FunHouse layer and makes use of the graphics and peripherals. The focus of this example is the usage of the attached peripherals. The code starts out with a few imports.
import board from digitalio import DigitalInOut, Direction, Pull from adafruit_funhouse import FunHouse
After that, the FunHouse library is initialized with a couple of parameters. The DotStars could have been supplied for status, but then we wouldn't have the DotStar available for programmatic use. You could also provide an external NeoPixel, DotStar or RGB LED.
The parameters given were the default background color to use and the scale so everything can automatically scale up.
funhouse = FunHouse( default_bg=0x0F0F00, scale=2, )
Next up is a convenience function to allow setting all the DotStar LED colors in a single line.
funhouse.peripherals.set_dotstars(0x800000, 0x808000, 0x008000, 0x000080, 0x800080)
After that is the external sensor setup for ports A0 through A2. This sets them to be digital inputs using digitalio, but analogio could have been used as well.
# sensor setup sensors = [] for p in (board.A0, board.A1, board.A2): sensor = DigitalInOut(p) sensor.direction = Direction.INPUT sensor.pull = Pull.DOWN sensors.append(sensor)
Here's a function to set the color of a specific label index to an on or off color depending on the conditional value. This makes the code much shorter and easier to read.
def set_label_color(conditional, index, on_color): if conditional: funhouse.set_text_color(on_color, index) else: funhouse.set_text_color(0x606060, index)
The following section creates all the labels and stores the index of the labels in variables. This will make accessing specific labels very easy further down in the program. A new parameter that was recently added is the ability to set the initial text of the label, but that comes at a cost. The library will attempt to draw each label as the value is filled in and this has the appearance of if sluggishly initializing. To get around that, the root_group
property of the funhouse.display
object is set.
By setting None
as the value, this informs displayio to not show any layers. At the end, setting this to funhouse.splash
, which is the layer that everything is drawn to, causes displayio to draw all the newly created labels at the same time.
# Create the labels funhouse.display.root_group = None slider_label = funhouse.add_text( text="Slider:", text_position=(50, 30), text_color=0x606060 ) capright_label = funhouse.add_text( text="Touch", text_position=(85, 10), text_color=0x606060 ) pir_label = funhouse.add_text(text="PIR", text_position=(60, 10), text_color=0x606060) capleft_label = funhouse.add_text( text="Touch", text_position=(25, 10), text_color=0x606060 ) onoff_label = funhouse.add_text(text="OFF", text_position=(10, 25), text_color=0x606060) up_label = funhouse.add_text(text="UP", text_position=(10, 10), text_color=0x606060) sel_label = funhouse.add_text(text="SEL", text_position=(10, 60), text_color=0x606060) down_label = funhouse.add_text( text="DOWN", text_position=(10, 100), text_color=0x606060 ) jst1_label = funhouse.add_text( text="SENSOR 1", text_position=(40, 80), text_color=0x606060 ) jst2_label = funhouse.add_text( text="SENSOR 2", text_position=(40, 95), text_color=0x606060 ) jst3_label = funhouse.add_text( text="SENSOR 3", text_position=(40, 110), text_color=0x606060 ) temp_label = funhouse.add_text( text="Temp:", text_position=(50, 45), text_color=0xFF00FF ) pres_label = funhouse.add_text( text="Pres:", text_position=(50, 60), text_color=0xFF00FF ) funhouse.display.root_group = funhouse.splash
Finally, is the main loop. We'll break this down into a couple of different sections.
First calling the funhouse.set_text()
function will set the text. You can just pass in the indices that were stored a bit earlier to make it easy to read. This changes the labels for a couple of the environmental sensors and also prints out some values to the console output.
funhouse.set_text("Temp %0.1F" % funhouse.peripherals.temperature, temp_label) funhouse.set_text("Pres %d" % funhouse.peripherals.pressure, pres_label) print(funhouse.peripherals.temperature, funhouse.peripherals.relative_humidity)
In the next section, the set_label_color
function that was defined above is used to highlight any sensors that are considered on or True.
There is also a section that reads the slider value, which is between 0-1.0
when touched and None
if it is not touched. The slider value is used to set the brightness of the DotStar LEDs.
set_label_color(funhouse.peripherals.captouch6, onoff_label, 0x00FF00) set_label_color(funhouse.peripherals.captouch7, capleft_label, 0x00FF00) set_label_color(funhouse.peripherals.captouch8, capright_label, 0x00FF00) slider = funhouse.peripherals.slider if slider is not None: funhouse.peripherals.dotstars.brightness = slider funhouse.set_text("Slider: %1.1f" % slider, slider_label) set_label_color(slider is not None, slider_label, 0xFFFF00) set_label_color(funhouse.peripherals.button_up, up_label, 0xFF0000) set_label_color(funhouse.peripherals.button_sel, sel_label, 0xFFFF00) set_label_color(funhouse.peripherals.button_down, down_label, 0x00FF00) set_label_color(funhouse.peripherals.pir_sensor, pir_label, 0xFF0000) set_label_color(sensors[0].value, jst1_label, 0xFFFFFF) set_label_color(sensors[1].value, jst2_label, 0xFFFFFF) set_label_color(sensors[2].value, jst3_label, 0xFFFFFF)
Go ahead and click Download Project Bundle to download the full example and the required libraries. Rename funhouse_simpletest.py to code.py and copy all the files over to your FunHouse to run the Simple Test example.
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries # SPDX-FileCopyrightText: Copyright (c) 2021 Melissa LeBlanc-Williams for Adafruit Industries # # SPDX-License-Identifier: Unlicense import board from digitalio import DigitalInOut, Direction, Pull from adafruit_funhouse import FunHouse funhouse = FunHouse( default_bg=0x0F0F00, scale=2, ) funhouse.peripherals.set_dotstars(0x800000, 0x808000, 0x008000, 0x000080, 0x800080) # sensor setup sensors = [] for p in (board.A0, board.A1, board.A2): sensor = DigitalInOut(p) sensor.direction = Direction.INPUT sensor.pull = Pull.DOWN sensors.append(sensor) def set_label_color(conditional, index, on_color): if conditional: funhouse.set_text_color(on_color, index) else: funhouse.set_text_color(0x606060, index) # Create the labels funhouse.display.root_group = None slider_label = funhouse.add_text( text="Slider:", text_position=(50, 30), text_color=0x606060 ) capright_label = funhouse.add_text( text="Touch", text_position=(85, 10), text_color=0x606060 ) pir_label = funhouse.add_text(text="PIR", text_position=(60, 10), text_color=0x606060) capleft_label = funhouse.add_text( text="Touch", text_position=(25, 10), text_color=0x606060 ) onoff_label = funhouse.add_text(text="OFF", text_position=(10, 25), text_color=0x606060) up_label = funhouse.add_text(text="UP", text_position=(10, 10), text_color=0x606060) sel_label = funhouse.add_text(text="SEL", text_position=(10, 60), text_color=0x606060) down_label = funhouse.add_text( text="DOWN", text_position=(10, 100), text_color=0x606060 ) jst1_label = funhouse.add_text( text="SENSOR 1", text_position=(40, 80), text_color=0x606060 ) jst2_label = funhouse.add_text( text="SENSOR 2", text_position=(40, 95), text_color=0x606060 ) jst3_label = funhouse.add_text( text="SENSOR 3", text_position=(40, 110), text_color=0x606060 ) temp_label = funhouse.add_text( text="Temp:", text_position=(50, 45), text_color=0xFF00FF ) pres_label = funhouse.add_text( text="Pres:", text_position=(50, 60), text_color=0xFF00FF ) funhouse.display.root_group = funhouse.splash while True: funhouse.set_text("Temp %0.1F" % funhouse.peripherals.temperature, temp_label) funhouse.set_text("Pres %d" % funhouse.peripherals.pressure, pres_label) print(funhouse.peripherals.temperature, funhouse.peripherals.relative_humidity) set_label_color(funhouse.peripherals.captouch6, onoff_label, 0x00FF00) set_label_color(funhouse.peripherals.captouch7, capleft_label, 0x00FF00) set_label_color(funhouse.peripherals.captouch8, capright_label, 0x00FF00) slider = funhouse.peripherals.slider if slider is not None: funhouse.peripherals.dotstars.brightness = slider funhouse.set_text("Slider: %1.1f" % slider, slider_label) set_label_color(slider is not None, slider_label, 0xFFFF00) set_label_color(funhouse.peripherals.button_up, up_label, 0xFF0000) set_label_color(funhouse.peripherals.button_sel, sel_label, 0xFFFF00) set_label_color(funhouse.peripherals.button_down, down_label, 0x00FF00) set_label_color(funhouse.peripherals.pir_sensor, pir_label, 0xFF0000) set_label_color(sensors[0].value, jst1_label, 0xFFFFFF) set_label_color(sensors[1].value, jst2_label, 0xFFFFFF) set_label_color(sensors[2].value, jst3_label, 0xFFFFFF)
Once it is running, start touching the capacitive touch pads, buttons, and whatever else you can think of to see the example in action.
MQTT Example
The next example demonstrates how to use the new built-in MQTT functionality with Adafruit IO, though the MQTT functionality can be used with a standard MQTT server as well. To run this, make sure you have added your Adafruit IO information to your settings.toml file. If you're not sure how, you can check out this page in the Adafruit FunHouse guide.
For this example, you'll want to create 2 feeds named buzzer and neopixels on your Adafruit IO Feeds page. You can also create a Dashboard and add a Color Picker block to associate with the neopixels feed and a Momentary Button to associate with the buzzer feed. To learn more about how to do this, check out the Getting Started with Adafruit IO guide.
This time for imports, there's just the top level FunHouse
object and the time module.
import time from adafruit_funhouse import FunHouse
For initializing the FunHouse library, by passing None
as the default background, this causes displayio to keep the console up on the display.
funhouse = FunHouse(default_bg=None) funhouse.peripherals.set_dotstars(0x800000, 0x808000, 0x008000, 0x000080, 0x800080)
Next up are the handler functions. These allow the script to tell the library what to do when certain events occur. The different events are the connect
, disconnect
, subscribe
, unsubscribe
, and message
events. These are the events common to both the Mini MQTT library and the Adafruit IO MQTT library.
In the connect handler, it will subscribe to the buzzer
and neopixel
topics. You can change these to whatever suits you, but make sure the names match the feed IDs in the message handler.
Subscribing to a topic will cause the library to listen to the MQTT server for these topics and respond with the message handler whenever it hears something. The library will listen during the loop()
function, which will be covered in more detail a little lower in the code. To read more about MQTT Topics, you can check out the MQTT Topics section of our All the Internet of Things Protocols guide.
def connected(client): print("Connected to Adafruit IO! Subscribing...") client.subscribe("buzzer") client.subscribe("neopixels") def subscribe(client, userdata, topic, granted_qos): print("Subscribed to {0} with QOS level {1}".format(topic, granted_qos)) def disconnected(client): print("Disconnected from Adafruit IO!") def message(client, feed_id, payload): print("Feed {0} received new value: {1}".format(feed_id, payload)) if feed_id == "buzzer": if int(payload) == 1: funhouse.peripherals.play_tone(2000, 0.25) if feed_id == "neopixels": print(payload) color = int(payload[1:], 16) funhouse.peripherals.dotstars.fill(color)
The next section will initialize the MQTT library. If you are using Adafruit IO, you will want to call the init_io_mqtt()
, otherwise you will want to call the init_mqtt()
function. To work properly, one of the two functions must be called, which tells the library which underlying libraries to use.
The remaining lines assign the above handlers to their respective properties.
# Initialize a new MQTT Client object funhouse.network.init_io_mqtt() funhouse.network.on_mqtt_connect = connected funhouse.network.on_mqtt_disconnect = disconnected funhouse.network.on_mqtt_subscribe = subscribe funhouse.network.on_mqtt_message = message
The next section will connect to the MQTT server. The library does not automatically connect, so you will need to do this. The reason it doesn't automatically connect is to give you the opportunity to set up whatever you want prior to this.
The next couple of lines set the initial state of the sensorwrite_timestamp
and last_pir
state variables. The reason the last_pir variable is set to None as opposed to the initial value of the PIR sensor is so that it will always publish it's state on connection regardless of the value.
print("Connecting to Adafruit IO...") funhouse.network.mqtt_connect() sensorwrite_timestamp = time.monotonic() last_pir = None
The last block of code is the main loop. We'll break this up into sections as well. As part of the loop, the mqtt_loop()
will get called during each iteration. This allows the MQTT library to respond appropriately to any messages. By default it has a 1 second timeout, but you can shorten that for your needs. This will make your script more responsive, but it may also fail to respond to all messages if the traffic is pretty busy.
Right after the loop, we read the temperature and barometric pressure and print that to the serial console.
funhouse.network.mqtt_loop() print("Temp %0.1F" % funhouse.peripherals.temperature) print("Pres %d" % funhouse.peripherals.pressure)
During the main loop, we check that 10 seconds has elapsed. If it has, then we publish the temperature, humidity, and pressure to their respective feeds on Adafruit IO.
We also check to see if the PIR sensor has either changed since the last time we checked or if we haven't checked at all. In either case, we publish the current value to its feed and update the last_pir
variable.
# every 10 seconds, write temp/hum/press if (time.monotonic() - sensorwrite_timestamp) > 10: funhouse.peripherals.led = True print("Sending data to adafruit IO!") funhouse.network.mqtt_publish("temperature", funhouse.peripherals.temperature) funhouse.network.mqtt_publish( "humidity", int(funhouse.peripherals.relative_humidity) ) funhouse.network.mqtt_publish("pressure", int(funhouse.peripherals.pressure)) sensorwrite_timestamp = time.monotonic() # Send PIR only if changed! if last_pir is None or last_pir != funhouse.peripherals.pir_sensor: last_pir = funhouse.peripherals.pir_sensor funhouse.network.mqtt_publish("pir", "%d" % last_pir) funhouse.peripherals.led = False
Go ahead and click Download Project Bundle to download the full example and the required libraries. Rename funhouse_adafruit_io_mqtt.py to code.py and copy all the files over to your FunHouse to run the Simple Test example. Make sure your settings.toml file includes your Adafruit IO information.
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries # SPDX-FileCopyrightText: Copyright (c) 2021 Melissa LeBlanc-Williams for Adafruit Industries # # SPDX-License-Identifier: MIT import time from adafruit_funhouse import FunHouse funhouse = FunHouse(default_bg=None) funhouse.peripherals.set_dotstars(0x800000, 0x808000, 0x008000, 0x000080, 0x800080) # pylint: disable=unused-argument def connected(client): print("Connected to Adafruit IO! Subscribing...") client.subscribe("buzzer") client.subscribe("neopixels") def subscribe(client, userdata, topic, granted_qos): print("Subscribed to {0} with QOS level {1}".format(topic, granted_qos)) def disconnected(client): print("Disconnected from Adafruit IO!") def message(client, feed_id, payload): print("Feed {0} received new value: {1}".format(feed_id, payload)) if feed_id == "buzzer": if int(payload) == 1: funhouse.peripherals.play_tone(2000, 0.25) if feed_id == "neopixels": print(payload) color = int(payload[1:], 16) funhouse.peripherals.dotstars.fill(color) # pylint: enable=unused-argument # Initialize a new MQTT Client object funhouse.network.init_io_mqtt() funhouse.network.on_mqtt_connect = connected funhouse.network.on_mqtt_disconnect = disconnected funhouse.network.on_mqtt_subscribe = subscribe funhouse.network.on_mqtt_message = message print("Connecting to Adafruit IO...") funhouse.network.mqtt_connect() sensorwrite_timestamp = time.monotonic() last_pir = None while True: funhouse.network.mqtt_loop() print("Temp %0.1F" % funhouse.peripherals.temperature) print("Pres %d" % funhouse.peripherals.pressure) # every 10 seconds, write temp/hum/press if (time.monotonic() - sensorwrite_timestamp) > 10: funhouse.peripherals.led = True print("Sending data to adafruit IO!") funhouse.network.mqtt_publish("temperature", funhouse.peripherals.temperature) funhouse.network.mqtt_publish( "humidity", int(funhouse.peripherals.relative_humidity) ) funhouse.network.mqtt_publish("pressure", int(funhouse.peripherals.pressure)) sensorwrite_timestamp = time.monotonic() # Send PIR only if changed! if last_pir is None or last_pir != funhouse.peripherals.pir_sensor: last_pir = funhouse.peripherals.pir_sensor funhouse.network.mqtt_publish("pir", "%d" % last_pir) funhouse.peripherals.led = False
Once it is running, you will notice it printing the temperature and pressure to the display. Every 10 seconds it should say Sending data to adafruit IO! If you log into Adafruit IO and create a couple of feeds called buzzer and neopixels, you can try out the subscribe functionality.
To get it to react, you add a 1
to the buzzer feed or add a color value such as #FF0000
for Red to the neopixels feed. You should hear a tone played for a brief period for the buzzer feed and you should see the DotStars all light up to the color value you provided.
Page last edited January 29, 2025
Text editor powered by tinymce.