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 , style = Button .SHADOWROUNDRECT , label_color = 0x505050 ,
101+ fill_color = 0x9e9e9e , outline_color = 0x464646 )
102+ buttons .append (button_1 )
103+
104+ button_2 = Button (x = BUTTON_MARGIN , y = BUTTON_MARGIN * 2 + BUTTON_HEIGHT ,
105+ width = BUTTON_WIDTH , height = BUTTON_HEIGHT ,
106+ label = "Button 2" , label_font = font , style = Button .SHADOWROUNDRECT , label_color = 0x505050 ,
107+ fill_color = 0x9e9e9e , outline_color = 0x464646 )
108+ buttons .append (button_2 )
109+
110+ for b in buttons :
111+ splash .append (b .group )
112+
113+ # Text Label Objects
114+ temperature_label = Label (font , text = "temperature" , color = 0xE300D2 , max_glyphs = 40 )
115+ temperature_label .x = 130
116+ temperature_label .y = 20
117+ splash .append (temperature_label )
118+
119+ light_label = Label (font , text = "lux" , color = 0xE300D2 , max_glyphs = 40 )
120+ light_label .x = 130
121+ light_label .y = 40
122+ splash .append (light_label )
123+
124+ motion_label = Label (font , text = "motion" , color = 0xE300D2 , max_glyphs = 40 )
125+ motion_label .x = 130
126+ motion_label .y = 60
127+ splash .append (motion_label )
128+
129+ feed1_label = Label (font , text = "MQTT feed1" , color = 0xE39300 , max_glyphs = 100 )
130+ feed1_label .x = 130
131+ feed1_label .y = 130
132+ splash .append (feed1_label )
133+
134+ feed2_label = Label (font , text = "MQTT feed2" , color = 0x00DCE3 , max_glyphs = 100 )
135+ feed2_label .x = 130
136+ feed2_label .y = 200
137+ splash .append (feed2_label )
138+
139+ # ------------- MQTT Topic Setup ------------- #
140+
141+ mqtt_topic = 'test/topic'
142+ mqtt_temperature = 'pyportal/temperature'
143+ mqtt_lux = 'pyportal/lux'
144+ mqtt_PIR = 'pyportal/pir'
145+ mqtt_button1 = 'pyportal/button1'
146+ mqtt_button2 = 'pyportal/button2'
147+ mqtt_feed1 = 'pyportal/feed1'
148+ mqtt_feed2 = 'pyportal/feed2'
149+
150+ # ------------- MQTT Functions ------------- #
151+
152+ # Define callback methods which are called when events occur
153+ # pylint: disable=unused-argument, redefined-outer-name
154+ def connect (client , userdata , flags , rc ):
155+ # This function will be called when the client is connected
156+ # successfully to the broker.
157+ print ('Connected to MQTT Broker!' )
158+ print ('Flags: {0}\n RC: {1}' .format (flags , rc ))
159+
160+ def disconnected (client , userdata , rc ):
161+ # This method is called when the client is disconnected
162+ print ('Disconnected from MQTT Broker!' )
163+
164+ def subscribe (client , userdata , topic , granted_qos ):
165+ # This method is called when the client subscribes to a new feed.
166+ print ('Subscribed to {0} with QOS level {1}' .format (topic , granted_qos ))
167+
168+ def publish (client , userdata , topic , pid ):
169+ # This method is called when the client publishes data to a feed.
170+ print ('Published to {0} with PID {1}' .format (topic , pid ))
171+
172+ def message (client , topic , message ):
173+ """Method callled when a client's subscribed feed has a new
174+ value.
175+ :param str topic: The topic of the feed with a new value.
176+ :param str message: The new value
177+ """
178+ print ('New message on topic {0}: {1}' .format (topic , message ))
179+ if topic == "pyportal/feed1" :
180+ feed1_label .text = 'Next Bus: {}' .format (message )
181+ if topic == "pyportal/feed2" :
182+ feed2_label .text = 'Weather: \n {}' .format (message )
183+ if topic == "pyportal/button1" :
184+ if message == "1" :
185+ buttons [0 ].label = "ON"
186+ buttons [0 ].selected = False
187+ print ("Button 1 ON" )
188+ else :
189+ buttons [0 ].label = "OFF"
190+ buttons [0 ].selected = True
191+ print ("Button 1 OFF" )
192+
193+ # ------------- Network Connection ------------- #
194+
195+ # Connect to WiFi
196+ wifi .connect ()
197+
198+ # Set up a MiniMQTT Client
199+ client = MQTT (socket ,
200+ broker = secrets ['broker' ],
201+ port = 1883 ,
202+ username = secrets ['user' ],
203+ password = secrets ['pass' ],
204+ network_manager = wifi )
205+
206+ # Connect callback handlers to client
207+ client .on_connect = connect
208+ client .on_disconnect = disconnected
209+ client .on_subscribe = subscribe
210+ client .on_publish = publish
211+ client .on_message = message
212+
213+ print ('Attempting to connect to %s' % client .broker )
214+ client .connect ()
215+
216+ print ('Subscribing to %s, %s, %s, and %s' % (mqtt_feed1 , mqtt_feed2 , mqtt_button1 , mqtt_button2 ))
217+ client .subscribe (mqtt_feed1 )
218+ client .subscribe (mqtt_feed2 )
219+ client .subscribe (mqtt_button1 )
220+ client .subscribe (mqtt_button2 )
221+
222+ # ------------- Code Loop ------------- #
223+ while True :
224+ # Poll the message queue
225+ client .loop ()
226+
227+ # Read sensor data and format
228+ light_value = lux = light_sensor .value
229+ light_label .text = 'Light Sensor: {}' .format (light_value )
230+ temperature = round (adt .temperature )
231+ temperature_label .text = 'Temp Sensor: {}' .format (temperature )
232+ movement_value = movement_sensor .value
233+ motion_label .text = 'PIR Sensor: {}' .format (movement_value )
234+
235+ # Read display button press
236+ touch = ts .touch_point
237+ if touch :
238+ for i , b in enumerate (buttons ):
239+ if b .contains (touch ):
240+ print ('Sending button%d pressed' % i )
241+ if i == 0 :
242+ # Toggle switch button type
243+ if button1_state == 0 :
244+ button1_state = 1
245+ b .label = "ON"
246+ b .selected = False
247+ print ("Button 1 ON" )
248+ else :
249+ button1_state = 0
250+ b .label = "OFF"
251+ b .selected = True
252+ print ("Button 1 OFF" )
253+ print ('Sending button 1 state: ' )
254+ client .publish (mqtt_button1 , button1_state )
255+ # for debounce
256+ while ts .touch_point :
257+ print ("Button 1 Pressed" )
258+ if i == 1 :
259+ # Momentary button type
260+ b .selected = True
261+ print ('Sending button 2 state: ' )
262+ client .publish (mqtt_button2 , 1 )
263+ # for debounce
264+ while ts .touch_point :
265+ print ("Button 2 Pressed" )
266+ print ("Button 2 reliced" )
267+ print ('Sending button 2 state: ' )
268+ client .publish (mqtt_button2 , 0 )
269+ b .selected = False
270+
271+ # Publish sensor data to MQTT
272+ print ('Sending light sensor value: %d' % light_value )
273+ client .publish (mqtt_lux , light_value )
274+
275+ print ('Sending temperature value: %d' % temperature )
276+ client .publish (mqtt_temperature , temperature )
277+
278+ print ('Sending motion sensor value: %d' % movement_value )
279+ client .publish (mqtt_PIR , '{}' .format (movement_value ))
0 commit comments