Skip to content

Commit bc70338

Browse files
authored
Merge pull request #2180 from adafruit/feather_tft_azure
Adding files for azure tutorial
2 parents 306839e + e4ec3a3 commit bc70338

File tree

3 files changed

+7908
-0
lines changed

3 files changed

+7908
-0
lines changed

Feather_ESP32-S2_TFT_Azure/bmeTFT.bmp

31.7 KB
Binary file not shown.

Feather_ESP32-S2_TFT_Azure/code.py

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
4+
import time
5+
import json
6+
import simpleio
7+
import vectorio
8+
import board
9+
import terminalio
10+
import rtc
11+
import socketpool
12+
import wifi
13+
import displayio
14+
import adafruit_ntp
15+
from adafruit_display_text import bitmap_label, wrap_text_to_lines
16+
from adafruit_bitmap_font import bitmap_font
17+
from adafruit_azureiot import IoTCentralDevice
18+
import adafruit_bme680
19+
from adafruit_lc709203f import LC709203F, PackSize
20+
21+
22+
# Get wifi details and more from a secrets.py file
23+
try:
24+
from secrets import secrets
25+
except ImportError:
26+
print("WiFi secrets are kept in secrets.py, please add them there!")
27+
raise
28+
29+
print("Connecting to WiFi...")
30+
wifi.radio.connect(secrets["ssid"], secrets["password"])
31+
32+
print("Connected to WiFi!")
33+
34+
# ntp clock - update tz_offset to your timezone
35+
pool = socketpool.SocketPool(wifi.radio)
36+
ntp = adafruit_ntp.NTP(pool, tz_offset=-4)
37+
rtc.RTC().datetime = ntp.datetime
38+
39+
if time.localtime().tm_year < 2022:
40+
print("Setting System Time in UTC")
41+
rtc.RTC().datetime = ntp.datetime
42+
43+
else:
44+
print("Year seems good, skipping set time.")
45+
46+
cal = ntp.datetime
47+
year = cal[0]
48+
mon = cal[1]
49+
day = cal[2]
50+
hour = cal[3]
51+
minute = cal[4]
52+
53+
# To use Azure IoT Central, you will need to create an IoT Central app.
54+
# You can either create a free tier app that will live for 7 days without an Azure subscription,
55+
# Or a standard tier app that will last for ever with an Azure subscription.
56+
# The standard tiers are free for up to 2 devices
57+
#
58+
# If you don't have an Azure subscription:
59+
#
60+
# If you are a student, head to https://aka.ms/FreeStudentAzure and sign up, validating with your
61+
# student email address. This will give you $100 of Azure credit and free tiers of a load of
62+
# service, renewable each year you are a student
63+
#
64+
# If you are not a student, head to https://aka.ms/FreeAz and sign up to get $200 of credit for 30
65+
# days, as well as free tiers of a load of services
66+
#
67+
# Create an Azure IoT Central app by following these
68+
# instructions: https://aka.ms/CreateIoTCentralApp
69+
# Add a device template with telemetry, properties and commands, as well as a view to visualize the
70+
# telemetry and execute commands, and a form to set properties.
71+
#
72+
# Next create a device using the device template, and select Connect to get the
73+
# device connection details.
74+
# Add the connection details to your secrets.py file, using the following values:
75+
#
76+
# 'id_scope' - the devices ID scope
77+
# 'device_id' - the devices device id
78+
# 'device_sas_key' - the devices primary key
79+
#
80+
# The adafruit-circuitpython-azureiot library depends on the following libraries:
81+
#
82+
# From the Adafruit CircuitPython Bundle
83+
# (https://github.com/adafruit/Adafruit_CircuitPython_Bundle):
84+
# * adafruit-circuitpython-minimqtt
85+
# * adafruit-circuitpython-requests
86+
# Create sensor object, communicating over the board's default I2C bus
87+
i2c = board.I2C() # uses board.SCL and board.SDA
88+
bme680 = adafruit_bme680.Adafruit_BME680_I2C(i2c, debug=False)
89+
90+
# change this to match the location's pressure (hPa) at sea level
91+
bme680.sea_level_pressure = 1013.25
92+
93+
# Create an IoT Hub device client and connect
94+
esp = None
95+
pool = socketpool.SocketPool(wifi.radio)
96+
device = IoTCentralDevice(
97+
pool, esp, secrets["id_scope"], secrets["device_id"], secrets["device_primary_key"]
98+
)
99+
100+
print("Connecting to Azure IoT Central...")
101+
device.connect()
102+
103+
print("Connected to Azure IoT Central!")
104+
105+
temperature_offset = -5
106+
107+
# Create sensor object, using the board's default I2C bus.
108+
battery_monitor = LC709203F(board.I2C())
109+
110+
# Update to match the mAh of your battery for more accurate readings.
111+
# Can be MAH100, MAH200, MAH400, MAH500, MAH1000, MAH2000, MAH3000.
112+
# Choose the closest match. Include "PackSize." before it, as shown.
113+
battery_monitor.pack_size = PackSize.MAH2000
114+
115+
temp = int((bme680.temperature * 9/5) + (32 + temperature_offset))
116+
humidity = int(bme680.relative_humidity)
117+
pressure = int(bme680.pressure)
118+
battery = battery_monitor.cell_percent
119+
120+
# display setup
121+
display = board.DISPLAY
122+
123+
palette0 = displayio.Palette(2)
124+
palette0[0] = 0x00FF00
125+
palette0[1] = 0xFF0000
126+
127+
# load bitmap
128+
bitmap = displayio.OnDiskBitmap("/bmeTFT.bmp")
129+
tile_grid = displayio.TileGrid(bitmap, pixel_shader=bitmap.pixel_shader)
130+
group = displayio.Group()
131+
group.append(tile_grid)
132+
# rectangle for battery life monitor
133+
# vectorio allows for resizing in the loop
134+
rect = vectorio.Rectangle(pixel_shader=palette0, width=22, height=10, x=12, y=116, color_index = 0)
135+
group.append(rect)
136+
# bitmap font
137+
font_file = "/roundedHeavy-26.bdf"
138+
font = bitmap_font.load_font(font_file)
139+
# text elements
140+
temp_text = bitmap_label.Label(font, text="%0.1f° F" % temp, color=0xFFFFFF)
141+
temp_text.x = 20
142+
temp_text.y = 80
143+
humid_text = bitmap_label.Label(font, text="%0.1f %%" % humidity, color=0xFFFFFF)
144+
humid_text.x = 95
145+
humid_text.y = 80
146+
press_text = bitmap_label.Label(font, text="%0.2f" % pressure, color=0xFFFFFF)
147+
press_text.x = 170
148+
press_text.y = 80
149+
time_text = bitmap_label.Label(terminalio.FONT,
150+
text="\n".join(wrap_text_to_lines
151+
("Data sent on %s/%s/%s at %s:%s" % (mon,day,year,hour,minute), 20)),
152+
color=0xFFFFFF)
153+
time_text.x = 125
154+
time_text.y = 105
155+
group.append(temp_text)
156+
group.append(humid_text)
157+
group.append(press_text)
158+
group.append(time_text)
159+
display.show(group)
160+
161+
# clock to count down to sending data to Azure
162+
azure_clock = 500
163+
# clock to count down to updating TFT
164+
feather_clock = 30
165+
166+
167+
while True:
168+
try:
169+
# read BME sensor
170+
temp = int((bme680.temperature * 9/5) + (32 + temperature_offset))
171+
humidity = int(bme680.relative_humidity)
172+
pressure = int(bme680.pressure)
173+
# log battery %
174+
battery = battery_monitor.cell_percent
175+
# map range of battery charge to rectangle size on screen
176+
battery_display = round(simpleio.map_range(battery, 0, 100, 0, 22))
177+
# update rectangle to reflect battery charge
178+
rect.width = int(battery_display)
179+
# if below 20%, change rectangle color to red
180+
if battery_monitor.cell_percent < 20:
181+
rect.color_index = 1
182+
# when the azure clock runs out
183+
if azure_clock > 500:
184+
print("getting msg")
185+
# pack message
186+
message = {"Temperature": temp,
187+
"Humidity": humidity,
188+
"Pressure": pressure,
189+
"BatteryPercent": battery}
190+
print("sending json")
191+
device.send_telemetry(json.dumps(message))
192+
print("data sent")
193+
print("getting ntp date/time")
194+
cal = ntp.datetime
195+
year = cal[0]
196+
mon = cal[1]
197+
day = cal[2]
198+
hour = cal[3]
199+
minute = cal[4]
200+
time.sleep(2)
201+
clock_view = "%s:%s" % (hour, minute)
202+
if minute < 10:
203+
clock_view = "%s:0%s" % (hour, minute)
204+
print("updating time text")
205+
time_text.text="\n".join(wrap_text_to_lines
206+
("Data sent on %s/%s/%s at %s" % (mon,day,year,clock_view), 20))
207+
# reset azure clock
208+
azure_clock = 0
209+
# when the feather clock runs out
210+
if feather_clock > 30:
211+
print("updating screen")
212+
temp_text.text = "%0.1f° F" % temp
213+
humid_text.text = "%0.1f %%" % humidity
214+
press_text.text = "%0.2f" % pressure
215+
# reset feather clock
216+
feather_clock = 0
217+
# if no clocks are running out
218+
# increase counts by 1
219+
else:
220+
feather_clock += 1
221+
azure_clock += 1
222+
# ping azure
223+
device.loop()
224+
# if something disrupts the loop, reconnect
225+
# pylint: disable=broad-except
226+
except (ValueError, RuntimeError, OSError, Exception) as e:
227+
print("Connection error, reconnecting\n", str(e))
228+
wifi.radio.enabled = False
229+
wifi.radio.enabled = True
230+
wifi.radio.connect(secrets["ssid"], secrets["password"])
231+
device.reconnect()
232+
continue
233+
# delay
234+
time.sleep(1)
235+
print(azure_clock)

0 commit comments

Comments
 (0)