Initial commit

This commit is contained in:
Noah
2018-12-21 08:12:54 +00:00
commit 30903a207b
26 changed files with 2851 additions and 0 deletions

149
clockscene.py Executable file
View File

@@ -0,0 +1,149 @@
#!/usr/bin/env python
#
# This file implements a simple clock scene displaying the current time.
#
# While it is primarily designed to be run on the host computer, an MCU
# running MicroPython might run it to provide automatic rendering of
# the current time while the host computer is offline.
#
import time
if not hasattr(time, 'ticks_ms'):
# Emulate https://docs.pycom.io/firmwareapi/micropython/utime.html
time.ticks_ms = lambda: int(time.time() * 1000)
time.sleep_ms = lambda x: time.sleep(x/1000.0)
# Local imports
from pixelfont import PixelFont
class ClockScene:
def __init__(self, display, config):
self.name = 'Clock'
self.display = display
self.font = PixelFont()
self.button_state = 0
# delete me
self.x_pos = 4
self.y_pos = 0
self.x_vel = 1
self.y_vel = 1
self.step = 0
def reset(self):
"""
Unused in this scene
"""
pass
def input(self, button_id, button_state):
"""
Handle button input
"""
if button_state == 1:
self.button_state ^= 1
elif button_state == 2:
return False
return True # signal that we handled the button
def render(self, frame, dropped_frames, fps):
"""
Render the current time and day of week
"""
t0 = time.ticks_ms()
# This takes 0ms
print('Rendering frame {} @ {}fps after a delay of {}s, {} dropped frames'.format(frame, fps, 1.*(1+dropped_frames)/fps, dropped_frames))
display = self.display
display.clear()
x_off = 0
y_off = 0
(year, month, day, hour, minute, second, weekday, _) = time.localtime()[:8]
if not self.button_state:
time_str = '{:02d}:{:02d}'.format(hour, minute)
if (int(time.ticks_ms() // 100.0) % 10) < 4:
time_str = time_str.replace(':', ' ')
x_off = 8
else:
time_str = '{:02d}.{:02d}.{:02d}'.format(day, month, year % 100)
x_off = 2
t2 = time.ticks_ms()
alphabet = self.font.alphabet
font_data = self.font.data
font_height = self.font.height
font_width = self.font.width
for i in range(len(time_str)):
digit = time_str[i]
if digit in ':. ' or time_str[i-1] in ':. ':
# Kludge to compress rendering of colon
x_off -= 1
data_offset = alphabet.find(digit)
if data_offset < 0:
data_offset = 0
tmp = (data_offset * font_height) << 2 # optimization: multiply by font with
font_byte = tmp >> 3 # optimization: divide by number of bits
font_bit = tmp & 7 # optimization: modulo number of bits
for row in range(font_height):
for col in range(font_width):
val = 0
if font_data[font_byte] & (1 << font_bit):
val = 255
font_bit += 1
if font_bit == 8:
font_byte += 1
font_bit = 0
display.put_pixel(x_off+col, y_off+row, val, val, val)
# Per letter offset
x_off += 4
t2 = time.ticks_ms() - t2
if 0:
# Flare effect.. lame
print('Clock: kernel at {},{} to {},{}'.format(self.x_pos, self.y_pos, self.x_pos+1,self.y_pos+1))
for i in range(3):
y = self.y_pos+i
for j in range(6):
x = self.x_pos+j
colors = self.display.get_pixel_front(x, y)
if not sum(colors):
continue
if j in [0,1,4,5]:
c = colors[0]-24
else:
c = colors[0]+24
if c < 0:
c = 0
elif c > 255:
c = 255
self.display.put_pixel(x, y, c, c, 2*c//3)
if 1:
self.x_pos += self.x_vel
if self.x_pos < 1 or self.x_pos > 31-7:
self.x_vel *= -1
if (frame % 3) == 0:
self.y_pos += self.y_vel
if self.y_pos == 0 or self.y_pos >= 5:
self.y_vel *= -1
t3 = time.ticks_ms()
x_off = 2
for i in range(7):
color = 128 if i == weekday else 48
x = x_off + (i << 2)
display.put_pixel(x+0, 7, color, color, 2*color//5)
display.put_pixel(x+1, 7, color, color, 2*color//5)
display.put_pixel(x+2, 7, color, color, 2*color//5)
t3 = time.ticks_ms() - t3
t4 = time.ticks_ms()
display.render()
t4 = time.ticks_ms() - t4
print('ClockScene: Spent {}ms plotting time, {}ms plotting weekdays, {}ms updating LedMatrix+HAL, {}ms total'.format(t2, t3, t4, time.ticks_ms()-t0))
if self.button_state == 2:
self.button_state = 0
# Signal that we want to be continued to be rendered
return True