Skip to content

Commit 8d3236e

Browse files
authored
Merge pull request #984 from adafruit/TheKitty-patch-114
Create appropriate readme for new guide
2 parents 647be29 + 2544db4 commit 8d3236e

File tree

4 files changed

+4501
-0
lines changed

4 files changed

+4501
-0
lines changed

PyPortal_MQTT_Control/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
## The PyPortal MQTT Sensor Node/Control Pad tutorial on the Adafruit Learning System
2+
3+
The code in this repo accompanies the Adafruit tutorial
4+
PyPortal MQTT Sensor Node/Control Pad
5+
https://learn.adafruit.com/pyportal-mqtt-sensor-node-control-pad
6+
7+
The *appropriate code file file should be copied onto the **CIRCUITPY** flash drive as **code.py** that appears
8+
when you plug the CircuitPlayground Express into your computer via a known good USB cable.
9+
10+
If the only drive name you get is named **CPLAYBOOT**, CircuitPython may not be loaded
11+
on the board. You can load CircuitPython [per this guide](https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-quickstart). Then you should be able to see the **CIRCUITPY** drive when connected via USB.
12+
13+
CircuitPython resources may be found at https://CircuitPython.Org/
14+
15+
Learning Guide by Richard Albritton for Adafruit Industries, January, 2020
16+
17+
MIT License, include all this text in any redistribution
18+
19+
Support Open Source development by buying your materials at [Adafruit.com](https://www.adafruit.com/).

PyPortal_MQTT_Control/code.py

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
import board
2+
import displayio
3+
import busio
4+
from digitalio import DigitalInOut
5+
from analogio import AnalogIn
6+
import neopixel
7+
import adafruit_adt7410
8+
from adafruit_esp32spi import adafruit_esp32spi
9+
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
10+
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
11+
from adafruit_bitmap_font import bitmap_font
12+
from adafruit_display_text.label import Label
13+
from adafruit_button import Button
14+
import adafruit_touchscreen
15+
from adafruit_minimqtt import MQTT
16+
17+
# ------------- WiFi ------------- #
18+
19+
# Get wifi details and more from a secrets.py file
20+
try:
21+
from secrets import secrets
22+
except ImportError:
23+
print("WiFi secrets are kept in secrets.py, please add them there!")
24+
raise
25+
26+
# If you are using a board with pre-defined ESP32 Pins:
27+
esp32_cs = DigitalInOut(board.ESP_CS)
28+
esp32_ready = DigitalInOut(board.ESP_BUSY)
29+
esp32_reset = DigitalInOut(board.ESP_RESET)
30+
31+
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
32+
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
33+
status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2)
34+
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)
35+
36+
# ------- Sensor Setup ------- #
37+
# init. the temperature sensor
38+
i2c_bus = busio.I2C(board.SCL, board.SDA)
39+
adt = adafruit_adt7410.ADT7410(i2c_bus, address=0x48)
40+
adt.high_resolution = True
41+
temperature = "blaa"
42+
# init. the light sensor
43+
light_sensor = AnalogIn(board.LIGHT)
44+
45+
# init. the motion sensor
46+
movement_sensor = DigitalInOut(board.D3)
47+
48+
button1_state = 0
49+
button2_state = 0
50+
51+
# ------------- Screen eliments ------------- #
52+
53+
display = board.DISPLAY
54+
55+
# Backlight function
56+
def set_backlight(val):
57+
"""Adjust the TFT backlight.
58+
:param val: The backlight brightness. Use a value between ``0`` and ``1``, where ``0`` is
59+
off, and ``1`` is 100% brightness.
60+
"""
61+
val = max(0, min(1.0, val))
62+
board.DISPLAY.auto_brightness = False
63+
board.DISPLAY.brightness = val
64+
65+
# Touchscreen setup
66+
ts = adafruit_touchscreen.Touchscreen(board.TOUCH_XL, board.TOUCH_XR,
67+
board.TOUCH_YD, board.TOUCH_YU,
68+
calibration=((5200, 59000), (5800, 57000)),
69+
size=(320, 240))
70+
71+
# ---------- Set the font and preload letters ----------
72+
# Be sure to put your font into a folder named "fonts".
73+
font = bitmap_font.load_font("/fonts/Helvetica-Bold-16.bdf")
74+
# This will preload the text images.
75+
font.load_glyphs(b'abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890- ()')
76+
77+
# ------------- User Inretface Eliments ------------- #
78+
79+
# Make the display context
80+
splash = displayio.Group(max_size=200)
81+
board.DISPLAY.show(splash)
82+
83+
# Make a background color fill
84+
color_bitmap = displayio.Bitmap(320, 240, 1)
85+
color_palette = displayio.Palette(1)
86+
color_palette[0] = 0x3D0068
87+
bg_sprite = displayio.TileGrid(color_bitmap, x=0, y=0,
88+
pixel_shader=color_palette)
89+
splash.append(bg_sprite)
90+
91+
buttons = []
92+
# Default button styling:
93+
BUTTON_WIDTH = 100
94+
BUTTON_HEIGHT = 100
95+
BUTTON_MARGIN = 10
96+
97+
# Button Objects
98+
button_1 = Button(x=BUTTON_MARGIN, y=BUTTON_MARGIN,
99+
width=BUTTON_WIDTH, height=BUTTON_HEIGHT,
100+
label="Button 1", label_font=font,
101+
style=Button.SHADOWROUNDRECT, label_color=0x505050,
102+
fill_color=0x9e9e9e, outline_color=0x464646)
103+
buttons.append(button_1)
104+
105+
button_2 = Button(x=BUTTON_MARGIN, y=BUTTON_MARGIN*2+BUTTON_HEIGHT,
106+
width=BUTTON_WIDTH, height=BUTTON_HEIGHT,
107+
label="Button 2", label_font=font,
108+
style=Button.SHADOWROUNDRECT, label_color=0x505050,
109+
fill_color=0x9e9e9e, outline_color=0x464646)
110+
buttons.append(button_2)
111+
112+
for b in buttons:
113+
splash.append(b.group)
114+
115+
# Text Label Objects
116+
temperature_label = Label(font, text="temperature", color=0xE300D2, max_glyphs=40)
117+
temperature_label.x = 130
118+
temperature_label.y = 20
119+
splash.append(temperature_label)
120+
121+
light_label = Label(font, text="lux", color=0xE300D2, max_glyphs=40)
122+
light_label.x = 130
123+
light_label.y = 40
124+
splash.append(light_label)
125+
126+
motion_label = Label(font, text="motion", color=0xE300D2, max_glyphs=40)
127+
motion_label.x = 130
128+
motion_label.y = 60
129+
splash.append(motion_label)
130+
131+
feed1_label = Label(font, text="MQTT feed1", color=0xE39300, max_glyphs=100)
132+
feed1_label.x = 130
133+
feed1_label.y = 130
134+
splash.append(feed1_label)
135+
136+
feed2_label = Label(font, text="MQTT feed2", color=0x00DCE3, max_glyphs=100)
137+
feed2_label.x = 130
138+
feed2_label.y = 200
139+
splash.append(feed2_label)
140+
141+
# ------------- MQTT Topic Setup ------------- #
142+
143+
mqtt_topic = 'test/topic'
144+
mqtt_temperature = 'pyportal/temperature'
145+
mqtt_lux = 'pyportal/lux'
146+
mqtt_PIR = 'pyportal/pir'
147+
mqtt_button1 = 'pyportal/button1'
148+
mqtt_button2 = 'pyportal/button2'
149+
mqtt_feed1 = 'pyportal/feed1'
150+
mqtt_feed2 = 'pyportal/feed2'
151+
152+
# ------------- MQTT Functions ------------- #
153+
154+
# Define callback methods which are called when events occur
155+
# pylint: disable=unused-argument, redefined-outer-name
156+
def connect(client, userdata, flags, rc):
157+
# This function will be called when the client is connected
158+
# successfully to the broker.
159+
print('Connected to MQTT Broker!')
160+
print('Flags: {0}\n RC: {1}'.format(flags, rc))
161+
162+
def disconnected(client, userdata, rc):
163+
# This method is called when the client is disconnected
164+
print('Disconnected from MQTT Broker!')
165+
166+
def subscribe(client, userdata, topic, granted_qos):
167+
# This method is called when the client subscribes to a new feed.
168+
print('Subscribed to {0} with QOS level {1}'.format(topic, granted_qos))
169+
170+
def publish(client, userdata, topic, pid):
171+
# This method is called when the client publishes data to a feed.
172+
print('Published to {0} with PID {1}'.format(topic, pid))
173+
174+
def message(client, topic, message):
175+
"""Method callled when a client's subscribed feed has a new
176+
value.
177+
:param str topic: The topic of the feed with a new value.
178+
:param str message: The new value
179+
"""
180+
print('New message on topic {0}: {1}'.format(topic, message))
181+
if topic == "pyportal/feed1":
182+
feed1_label.text = 'Next Bus: {}'.format(message)
183+
if topic == "pyportal/feed2":
184+
feed2_label.text = 'Weather: \n {}'.format(message)
185+
if topic == "pyportal/button1":
186+
if message == "1":
187+
buttons[0].label="ON"
188+
buttons[0].selected = False
189+
print("Button 1 ON")
190+
else:
191+
buttons[0].label="OFF"
192+
buttons[0].selected = True
193+
print("Button 1 OFF")
194+
195+
# ------------- Network Connection ------------- #
196+
197+
# Connect to WiFi
198+
wifi.connect()
199+
200+
# Set up a MiniMQTT Client
201+
client = MQTT(socket,
202+
broker = secrets['broker'],
203+
port = 1883,
204+
username = secrets['user'],
205+
password = secrets['pass'],
206+
network_manager = wifi)
207+
208+
# Connect callback handlers to client
209+
client.on_connect = connect
210+
client.on_disconnect = disconnected
211+
client.on_subscribe = subscribe
212+
client.on_publish = publish
213+
client.on_message = message
214+
215+
print('Attempting to connect to %s' % client.broker)
216+
client.connect()
217+
218+
print('Subscribing to %s, %s, %s, and %s' % (mqtt_feed1, mqtt_feed2, mqtt_button1, mqtt_button2))
219+
client.subscribe(mqtt_feed1)
220+
client.subscribe(mqtt_feed2)
221+
client.subscribe(mqtt_button1)
222+
client.subscribe(mqtt_button2)
223+
224+
# ------------- Code Loop ------------- #
225+
while True:
226+
# Poll the message queue
227+
client.loop()
228+
229+
# Read sensor data and format
230+
light_value = lux = light_sensor.value
231+
light_label.text = 'Light Sensor: {}'.format(light_value)
232+
temperature = round(adt.temperature)
233+
temperature_label.text = 'Temp Sensor: {}'.format(temperature)
234+
movement_value = movement_sensor.value
235+
motion_label.text = 'PIR Sensor: {}'.format(movement_value)
236+
237+
# Read display button press
238+
touch = ts.touch_point
239+
if touch:
240+
for i, b in enumerate(buttons):
241+
if b.contains(touch):
242+
print('Sending button%d pressed' % i)
243+
if i == 0:
244+
# Toggle switch button type
245+
if button1_state == 0:
246+
button1_state = 1
247+
b.label = "ON"
248+
b.selected = False
249+
print("Button 1 ON")
250+
else:
251+
button1_state = 0
252+
b.label = "OFF"
253+
b.selected = True
254+
print("Button 1 OFF")
255+
print('Sending button 1 state: ')
256+
client.publish(mqtt_button1, button1_state)
257+
# for debounce
258+
while ts.touch_point:
259+
print("Button 1 Pressed")
260+
if i == 1:
261+
# Momentary button type
262+
b.selected = True
263+
print('Sending button 2 state: ')
264+
client.publish(mqtt_button2, 1)
265+
# for debounce
266+
while ts.touch_point:
267+
print("Button 2 Pressed")
268+
print("Button 2 reliced")
269+
print('Sending button 2 state: ')
270+
client.publish(mqtt_button2, 0)
271+
b.selected = False
272+
273+
# Publish sensor data to MQTT
274+
print('Sending light sensor value: %d' % light_value)
275+
client.publish(mqtt_lux, light_value)
276+
277+
print('Sending temperature value: %d' % temperature)
278+
client.publish(mqtt_temperature, temperature)
279+
280+
print('Sending motion sensor value: %d' % movement_value)
281+
client.publish(mqtt_PIR, '{}'.format(movement_value))

0 commit comments

Comments
 (0)