Hey Tom.
Can you please let us know any error messages that you’re getting, and what the STDOUT and behaviour currently is so that we can diagnose what is going wrong?
I’ve refactored and reformatted your code to make it a bit more readable/memory-efficient and added some # TODO
items to double check in your implementation, a number of the changes were made with automated formatting extensions and tools I use in my personal workflows. It may have broken if the patterns you follow in your implementation don’t line up with it although at a glance this looks alright:
import board
import displayio
import busio
from digitalio import DigitalInOut
from analogio import AnalogIn
import neopixel
import adafruit_adt7410 # TODO: unused, remove this line
from adafruit_esp32spi import adafruit_esp32spi
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from adafruit_bitmap_font import bitmap_font
from adafruit_display_text.label import Label # TODO: unused, remove this line
from adafruit_button import Button
import adafruit_touchscreen
import adafruit_minimqtt.adafruit_minimqtt as MQTT
try:
from secrets import secrets
except ImportError:
print("WiFi secrets are kept in secrets.py, please add them there!")
raise
BUTTON_WIDTH = 225
BUTTON_HEIGHT = 140
BUTTON_MARGIN = 10
MQTT_TOPIC = "test/topic"
MQTT_LUX = "pyportal/lux"
MQTT_PIR = "pyportal/pir"
MQTT_BUTTON_ONE = "pyportal/button1"
MQTT_BUTTON_TWO = "pyportal/button2"
MQTT_FEED_ONE = "pyportal/feed1"
MQTT_FEED_TWO = "pyportal/feed2"
ESP = adafruit_esp32spi.ESP_SPIcontrol(
busio.SPI(board.SCK, board.MOSI, board.MISO),
DigitalInOut(board.ESP_CS),
DigitalInOut(board.ESP_BUSY),
DigitalInOut(board.ESP_RESET),
)
LIGHT_SENSOR = AnalogIn(board.LIGHT)
MOVEMENT_SENSOR = DigitalInOut(board.D3)
button_states = [True, True, True]
display = board.DISPLAY # TODO: unused
TOUCHSCREEN = adafruit_touchscreen.Touchscreen(
board.TOUCH_XL,
board.TOUCH_XR,
board.TOUCH_YD,
board.TOUCH_YU,
calibration=((5200, 59000), (5800, 57000)),
size=(480, 320),
)
FONT = bitmap_font.load_font("/fonts/Helvetica-Bold-16.bdf")
FONT.load_glyphs(b"abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890- ()")
SPLASH = displayio.Group()
board.DISPLAY.root_group = SPLASH
color_palette = displayio.Palette(1)
color_palette[0] = 0x000000
bg_sprite = displayio.TileGrid(
displayio.Bitmap(480, 320, 1), x=0, y=0, pixel_shader=color_palette
)
SPLASH.append(bg_sprite)
buttons = [
Button(
x=BUTTON_MARGIN,
y=BUTTON_MARGIN,
width=BUTTON_WIDTH,
height=BUTTON_HEIGHT,
label="Button One",
label_font=FONT,
style=Button.SHADOWROUNDRECT,
label_color=0x505050,
fill_color=0xE08B2F,
outline_color=0x464646,
),
Button(
x=BUTTON_MARGIN,
y=BUTTON_MARGIN * 2 + BUTTON_HEIGHT,
width=BUTTON_WIDTH,
height=BUTTON_HEIGHT,
label="Button Two",
label_font=FONT,
style=Button.SHADOWROUNDRECT,
label_color=0x505050,
fill_color=0x40E34A,
outline_color=0x464646,
),
Button(
x=BUTTON_MARGIN * 2 + BUTTON_WIDTH,
y=BUTTON_MARGIN,
width=BUTTON_WIDTH,
height=BUTTON_HEIGHT,
label="Button Three",
label_font=FONT,
style=Button.SHADOWROUNDRECT,
label_color=0x505050,
fill_color=0x9E9E9E,
outline_color=0x464646,
),
Button(
x=BUTTON_MARGIN * 2 + BUTTON_WIDTH,
y=BUTTON_MARGIN * 2 + BUTTON_HEIGHT,
width=BUTTON_WIDTH,
height=BUTTON_HEIGHT,
label="Button Four",
label_font=FONT,
style=Button.SHADOWROUNDRECT,
label_color=0x505050,
fill_color=0x9E9E9E,
outline_color=0x464646,
),
]
for button in buttons:
SPLASH.append(button.group)
# TODO: remove unused code
# feed_one_label = Label(FONT, text="MQTT1", color=0xE39300)
# feed_one_label.x = 240
# feed_one_label.y = 70
# SPLASH.append(feed_one_label)
# feed_two_label = Label(FONT, text="MQTT2", color=0x00DCE3)
# feed_two_label.x = 240
# feed_two_label.y = 230
# SPLASH.append(feed_two_label)
def set_backlight(val):
"""Adjust the TFT backlight.
:param val: The backlight brightness. Use a value between ``0`` and ``1``, where ``0`` is
off, and ``1`` is 100% brightness.
"""
try:
board.DISPLAY.auto_brightness = False
except AttributeError:
pass
board.DISPLAY.brightness = max(0, min(1.0, val))
def connect(client, userdata, flags, rc):
print("Connected to MQTT Broker!")
print("Flags: {0}\n RC: {1}".format(flags, rc))
def disconnected(client, userdata, rc):
print("Disconnected from MQTT Broker!")
def subscribe(client, userdata, topic, granted_qos):
print("Subscribed to {0} with QOS level {1}".format(topic, granted_qos))
def publish(client, userdata, topic, pid):
print("Published to {0} with PID {1}".format(topic, pid))
def message(client, topic, message):
"""Method callled when a client's subscribed feed has a new
value.
:param str topic: The topic of the feed with a new value.
:param str message: The new value
"""
print("New message on topic {0}: {1}".format(topic, message))
try: # TODO: can remove this try-except if feed_one_label and feed_two_label get defined
if topic == "pyportal/feed1":
feed_one_label.text = "Next Bus: {}".format(
message
) # TODO: ensure this gets defined
if topic == "pyportal/feed2":
feed_two_label.text = "Weather: \n {}".format(
message
) # TODO: ensure this gets defined
if topic == "pyportal/button1":
if message == "1":
buttons[0].label = "ON"
buttons[0].selected = False
print("Button 1 ON")
else:
buttons[0].label = "OFF"
buttons[0].selected = True
print("Button 1 OFF")
except Exception as exception: # TODO: see try
print(f"Exception on message: {exception}")
def wifi_connect():
print("Connecting to WiFi...")
adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(
ESP, secrets, neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2)
).connect()
print("Connected to WiFi!")
wifi_connect()
MQTT.set_socket(socket, ESP)
client = MQTT.MQTT(
broker=secrets["broker"],
port=1883,
username=secrets["user"],
password=secrets["pass"],
)
client.on_connect = connect
client.on_disconnect = disconnected
client.on_subscribe = subscribe
client.on_publish = publish
client.on_message = message
print(f"Attempting to connect to {client.broker}")
client.connect()
print(
f"Subscribing to {MQTT_FEED_ONE}, {MQTT_FEED_TWO}, {MQTT_BUTTON_ONE}, and {MQTT_BUTTON_TWO}"
)
client.subscribe(MQTT_FEED_ONE)
client.subscribe(MQTT_FEED_TWO)
client.subscribe(MQTT_BUTTON_ONE)
client.subscribe(MQTT_BUTTON_TWO)
while True:
client.loop()
# TODO: remove unused code
# light_label.text = "Light Sensor: {}".format(light_value)
# temperature = round(adt.temperature)
# temperature_label.text = "Temp Sensor: {}".format(temperature)
# motion_label.text = "PIR Sensor: {}".format(movement_value)
touch = TOUCHSCREEN.touch_point
if touch:
for i, b in enumerate(buttons):
if b.contains(touch):
print(f"Sending button {i + 1} pressed")
if button_states[i]:
button_states[i] = False
b.label = "OFF"
b.selected = True
print(f"Button {i + 1} OFF")
print(f"Sending button {i + 1} state")
else:
button_states[i] = True
b.label = "ON"
b.selected = False
print(f"Button {i + 1} ON")
if i == 0:
client.publish(MQTT_BUTTON_ONE, button_states[0])
elif i == 1:
client.publish(MQTT_BUTTON_TWO, button_states[1])
while TOUCHSCREEN.touch_point:
print(f"Button {i} Pressed")
print(f"Sending light sensor value: {LIGHT_SENSOR.value}")
client.publish(MQTT_LUX, LIGHT_SENSOR.value)
print(f"Sending motion sensor value: {MOVEMENT_SENSOR.value}")
client.publish(MQTT_PIR, "{}".format(MOVEMENT_SENSOR.value))
If possible, I also almost always recommend formatting your modules to be called by:
if __name__ == "__main__":
main()
and define your implementation in classes/functions accordingly based on your personal style, although it isn’t that important in this case.
Are any unhandled exceptions coming up when you try running this on your Titano?
By the way, just going to throw a couple book recommendations out there in case anyone is interested, figured I may as well:
Robert (Uncle Bob) Martin - Clean Code: A Handbook of Agile Software Craftsmanship
Andy Hunt and Dave Thomas - The Pragmatic Programmer