Skip to content

Commit de48394

Browse files
helgibbonsGadgetoid
authored andcommitted
port GFX pack examples
1 parent 259bad7 commit de48394

File tree

2 files changed

+360
-0
lines changed

2 files changed

+360
-0
lines changed
Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
'''
2+
sunrise.py
3+
This example is for Interstate 75 W, connected up to two chained 64 x 64 panels.
4+
It displays information from the Sunrise Sunset API:
5+
Find out more here - https://sunrise-sunset.org/api
6+
Also shows how to use a 16x16 animated sprite.
7+
'''
8+
import WIFI_CONFIG
9+
import time
10+
from math import radians, sin, cos
11+
from random import randint
12+
from interstate75 import Interstate75
13+
from network_manager import NetworkManager
14+
import ntptime
15+
import urequests
16+
import uasyncio
17+
import machine
18+
19+
20+
# Helper class so that the different formats of time can be converted into one comparable format
21+
# Makes up for the lack of a datetime module in MicroPython
22+
class TimeObj:
23+
def __init__(self):
24+
self.secs = 0
25+
self.mins = 0
26+
self.hours = 0
27+
self.PM = False
28+
29+
# Returns time variables as a tuple (h, m, s)
30+
def get_time(self):
31+
pm_hrs = 0
32+
if self.PM:
33+
pm_hrs = 12
34+
return (self.hours + pm_hrs, self.mins, self.secs)
35+
36+
# Returns time variables as a single string
37+
def get_str(self):
38+
h, m, s = self.get_time()
39+
return "{0:02d}:{1:02d}:{2:02d}".format(h, m, s)
40+
41+
# Set time variables from the sunrise-sunset API
42+
def parse_api(self, apiStr):
43+
strsplit = apiStr.split()
44+
if strsplit[1] == 'PM':
45+
self.PM = True
46+
timesplit = strsplit[0].split(':')
47+
self.hours = int(timesplit[0])
48+
self.mins = int(timesplit[1])
49+
self.secs = int(timesplit[2])
50+
51+
# Set time variables form
52+
def parse_localtime(self, localtpl):
53+
yr, mo, dy, self.hours, self.mins, self.secs, un1, un2 = localtpl
54+
55+
# Returns number of seconds since midnight
56+
def get_total_secs(self):
57+
seconds = 0
58+
if self.PM:
59+
seconds += 43200 # seconds in the first 12 hours
60+
seconds += (self.hours * 3600)
61+
seconds += (self.mins * 60)
62+
seconds += self.secs
63+
return seconds
64+
65+
66+
# Instances of TimeObj helper class defined above
67+
sunrise_obj = TimeObj()
68+
sunset_obj = TimeObj()
69+
currenttime = TimeObj()
70+
71+
# Coordinates for Sheffield-on-Sea, UK
72+
lng = -1.4659
73+
lat = 53.3829
74+
# Coordinates for LA, USA
75+
# lng = -118.2437
76+
# lat = 34.0522
77+
URL = 'https://api.sunrise-sunset.org/json?lat={0}&lng={1}&date=today'.format(lat, lng)
78+
rtc = machine.RTC()
79+
80+
i75 = Interstate75(display=Interstate75.DISPLAY_INTERSTATE75_128X64)
81+
graphics = i75.display
82+
sys_status = "Starting"
83+
WIDTH, HEIGHT = graphics.get_bounds()
84+
85+
BLACK = graphics.create_pen(0, 0, 0)
86+
WHITE = graphics.create_pen(200, 200, 200)
87+
HILLS_COLOUR_1 = graphics.create_pen(100, 100, 0)
88+
HILLS_COLOUR_2 = graphics.create_pen(100, 150, 0)
89+
HILLS_COLOUR_3 = graphics.create_pen(50, 150, 0)
90+
SUN_COLOUR = graphics.create_pen(255, 0, 0)
91+
92+
# Generate hill heights
93+
hills1 = [randint(10, 18), randint(10, 18), randint(10, 18), randint(10, 18), randint(10, 18)]
94+
hills2 = [randint(10, 18), randint(10, 18)]
95+
hills3 = [randint(10, 18), randint(10, 18)]
96+
97+
# Sprite information for sun icon
98+
sun = [
99+
[
100+
0b0000000100000000,
101+
0b0000000000000000,
102+
0b0010011111001000,
103+
0b0000100000100000,
104+
0b0001000000010000,
105+
0b0010000000001000,
106+
0b0010010001001000,
107+
0b0010000100001000,
108+
0b0010000000001000,
109+
0b0010000000001000,
110+
0b0001001110010000,
111+
0b0000100000100000,
112+
0b0010011111001000,
113+
0b0000000000000000,
114+
0b0000000100000000,
115+
0b0000000000000000
116+
],
117+
[
118+
0b0000000000000000,
119+
0b0100000000000100,
120+
0b0000011111000000,
121+
0b0000100000100000,
122+
0b0001000000010000,
123+
0b0010010001001000,
124+
0b0010010001001000,
125+
0b1010000100001010,
126+
0b0010000000001000,
127+
0b0010010001001000,
128+
0b0001001110010000,
129+
0b0000100000100000,
130+
0b0000011111000000,
131+
0b0100000000000100,
132+
0b0000000000000000,
133+
0b0000000000000000
134+
],
135+
[
136+
0b0000000100000000,
137+
0b0100000000000100,
138+
0b0010011111001000,
139+
0b0000100000100000,
140+
0b0001000000010000,
141+
0b0010010001001000,
142+
0b0010010001001000,
143+
0b1010000100001010,
144+
0b0010000000001000,
145+
0b0010010001001000,
146+
0b0001001110010000,
147+
0b0000100000100000,
148+
0b0010011111001000,
149+
0b0100000000000100,
150+
0b0000000100000000,
151+
0b0000000000000000
152+
]
153+
]
154+
155+
156+
def get_data():
157+
# open the json file
158+
print(f'Requesting URL: {URL}')
159+
r = urequests.get(URL)
160+
# open the json data
161+
j = r.json()
162+
print('Data obtained!')
163+
r.close()
164+
return j
165+
166+
167+
def get_sunrise():
168+
sun_json = get_data()
169+
sunrise = sun_json['results']['sunrise']
170+
sunrise_obj.parse_api(sunrise)
171+
sunset = sun_json['results']['sunset']
172+
sunset_obj.parse_api(sunset)
173+
174+
175+
def display_status():
176+
global sys_status
177+
graphics.set_pen(BLACK)
178+
graphics.clear()
179+
graphics.set_pen(WHITE)
180+
graphics.text(sys_status, 2, 0, WIDTH, 1)
181+
i75.update(graphics)
182+
183+
184+
def status_handler(mode, status, ip):
185+
# reports wifi connection status
186+
global sys_status
187+
print(mode, status, ip)
188+
sys_status = 'Mode: {0} Connected: {1} IP: {2}'.format(mode, status, ip)
189+
display_status()
190+
i75.update(graphics)
191+
print('Connecting to wifi...')
192+
if status is not None:
193+
if status:
194+
print('Wifi connection successful!')
195+
else:
196+
print('Wifi connection failed!')
197+
198+
199+
def calc_circle_points(ori_x, ori_y, r, deg):
200+
rads = radians(deg - 180)
201+
x = int(cos(rads) * r) + ori_x
202+
y = int(sin(rads) * r) + ori_y
203+
return x, y
204+
205+
206+
def to_seconds(hour, mins, secs, isPM=False):
207+
seconds = 0
208+
if isPM:
209+
seconds += 43200 # Seconds in the first 12 hours
210+
seconds += (hour * 3600)
211+
seconds += (mins * 60)
212+
seconds += secs
213+
return seconds
214+
215+
216+
def draw_hills():
217+
graphics.set_pen(HILLS_COLOUR_1)
218+
for x in range(5):
219+
graphics.circle(30 * x, 64, hills1[x])
220+
graphics.set_pen(HILLS_COLOUR_2)
221+
for x in range(2):
222+
graphics.circle(60 * x + 15, 64, hills2[x])
223+
graphics.set_pen(HILLS_COLOUR_3)
224+
for x in range(2):
225+
graphics.circle(60 * x + 30 + 15, 64, hills3[x])
226+
227+
228+
def draw_text():
229+
graphics.set_pen(WHITE)
230+
graphics.text("Sun Rise-Set API demo", 2, 0, WIDTH, 1)
231+
graphics.text("Sunrise: {0}".format(sunrise_obj.get_str()), 2, 8, WIDTH, 1)
232+
graphics.text("Sunset: {0}".format(sunset_obj.get_str()), 2, 16, WIDTH, 1)
233+
graphics.text("{0}".format(currenttime.get_str()), 2, 24, WIDTH, 1)
234+
235+
236+
def draw_sun(sunrise, sunset, time, cycle):
237+
global SUN_COLOUR
238+
sunlight_range = sunset - sunrise
239+
angle = int((180 / sunlight_range) * (time - sunrise)) % 360
240+
pos_x, pos_y = calc_circle_points(64 - 16, 54, 50, angle)
241+
graphics.set_pen(SUN_COLOUR)
242+
if angle > 180:
243+
SUN_COLOUR = graphics.create_pen(0, 0, 0)
244+
elif angle < 90:
245+
r = 255
246+
g = int(((angle / 100) * 90))
247+
b = 0
248+
SUN_COLOUR = graphics.create_pen(r, g, b)
249+
elif angle > 90:
250+
r = 255
251+
g = int(100 - (((angle - 90) / 100) * 90))
252+
b = 0
253+
SUN_COLOUR = graphics.create_pen(r, g, b)
254+
for y in range(16):
255+
for x in range(16):
256+
if sun[cycle][y] & (1 << x):
257+
graphics.pixel(x + pos_x, int((y + pos_y)))
258+
259+
260+
try:
261+
network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler)
262+
uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK))
263+
except Exception as e:
264+
print(f'Wifi connection failed! {e}')
265+
266+
get_sunrise()
267+
ntptime.settime()
268+
currenttime.parse_localtime(time.localtime())
269+
270+
count = 0 # Counter for animation
271+
272+
while True:
273+
# Update current time class instance from RTC
274+
currenttime.parse_localtime(time.localtime())
275+
count += 1
276+
277+
graphics.set_pen(BLACK)
278+
graphics.clear()
279+
280+
# Uncomment for the animation
281+
# draw_sun(0, 180, count % 180, count % 3)
282+
draw_sun(sunrise_obj.get_total_secs(), sunset_obj.get_total_secs(), currenttime.get_total_secs(), count % 3)
283+
draw_hills()
284+
draw_text()
285+
i75.update(graphics)
286+
time.sleep(0.2)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import time
2+
import machine
3+
from breakout_bme68x import BreakoutBME68X, STATUS_HEATER_STABLE
4+
from interstate75 import Interstate75
5+
6+
"""
7+
Interstate75 Temp DEMO
8+
This demo uses a BME680 or BME688 attached to the QWST connector to
9+
measure temperature, pressure, and humidity and display it on the Interstate75 display.
10+
The internal temperature sensor can be used in place of the BME68x breakout -
11+
just change use_bme68x_breakout to False
12+
13+
This example is designed for use on 2 chained 64x64 panels.
14+
"""
15+
16+
# Settings
17+
lower_temp_bound = 15
18+
upper_temp_bound = 30
19+
use_bme68x_breakout = True
20+
21+
sensor_temp = machine.ADC(4)
22+
conversion_factor = 3.3 / (65535) # used for calculating a temperature from the raw sensor reading
23+
24+
i75 = Interstate75(display=Interstate75.DISPLAY_INTERSTATE75_128X64)
25+
graphics = i75.display
26+
27+
BLACK = graphics.create_pen(0, 0, 0)
28+
TEMP_COLOUR = graphics.create_pen(255, 255, 255)
29+
30+
if use_bme68x_breakout:
31+
bmp = BreakoutBME68X(i75.i2c)
32+
33+
graphics.set_pen(BLACK)
34+
graphics.clear()
35+
graphics.set_font("bitmap14_outline")
36+
37+
while True:
38+
# Clear display
39+
graphics.set_pen(BLACK)
40+
graphics.clear()
41+
42+
graphics.set_pen(TEMP_COLOUR)
43+
graphics.text("Interstate75 Temp demo", 2, 2, scale=0.1)
44+
45+
if use_bme68x_breakout:
46+
temperature, pressure, humidity, gas, status, _, _ = bmp.read()
47+
graphics.text("Temp: {:0.2f}c".format(temperature), 2, 20, scale=0.2)
48+
graphics.text("Press: {:0.2f}Pa".format(pressure), 2, 35, scale=0.2)
49+
graphics.text("Humid: {:0.2f}%".format(humidity), 2, 50, scale=0.2)
50+
51+
heater = "Stable" if status & STATUS_HEATER_STABLE else "Unstable"
52+
print("{:0.2f}c, {:0.2f}Pa, {:0.2f}%, {:0.2f} Ohms, Heater: {}".format(
53+
temperature, pressure, humidity, gas, heater))
54+
55+
else:
56+
reading = sensor_temp.read_u16() * conversion_factor
57+
temperature = 27 - (reading - 0.706) / 0.001721
58+
graphics.text("Temperature", 25, 15, scale=0.2)
59+
graphics.text("{:0.2f}c".format(temperature), 25, 30, scale=2)
60+
61+
if temperature < lower_temp_bound:
62+
r = 0
63+
b = 255
64+
elif temperature > upper_temp_bound:
65+
r = 255
66+
b = 0
67+
else:
68+
r = int((temperature - lower_temp_bound) / (upper_temp_bound - lower_temp_bound) * 255)
69+
b = int(255 - ((temperature - lower_temp_bound) / (upper_temp_bound - lower_temp_bound) * 255))
70+
71+
TEMP_COLOUR = graphics.create_pen(r, 0, b)
72+
i75.update(graphics)
73+
74+
time.sleep(0.2)

0 commit comments

Comments
 (0)