Skip to content

Instantly share code, notes, and snippets.

@benevpi
Created April 16, 2020 20:14
Show Gist options
  • Save benevpi/fa085e3ba16094aeebe696e386542eec to your computer and use it in GitHub Desktop.
Save benevpi/fa085e3ba16094aeebe696e386542eec to your computer and use it in GitHub Desktop.
guage test circuit python
"""CLUE Spirit Level Demo"""
import board
from adafruit_clue import clue
from adafruit_display_shapes.triangle import Triangle
import displayio
import time
import math
display = board.DISPLAY
#basics working.
#TodDo -- graphical niceties
### Add a circle at the bottom
### Add a text number display
### Maybe some options for coloured backgrounds
### Maybe a warning threshold?
# speed optimisations
#test at different sizes
## current fps @ 240x240 circa 6
### at 120x120 circa 15 -- much nicer
#Do an arc-style one
#problem -- aliasing gives is a dip in the middle. Not too sure what I can do about this.
# not too sure about the best thing here. Could detect this and boost the length at exactly the mid point
## Could put a little triangle on the end as an arrow
class GuageGroup(displayio.Group):
def __init__(self, min_val, max_val, width, height, base_size=16, zero_angle=45, colour=0xFFFFFF):
super().__init__(max_size=4)
self.pivot1=[(width//2)-(base_size//2), 0]
self.pivot2=[(width//2)+(base_size//2), 0]
self.mid=width//2
self.zero_angle = zero_angle
self.min_val = min_val
self.max_val = max_val
self.colour = colour
#should be able to work this out from the zero angle and hitting the edge of the screen.
#just base it on a 45 deg zero angle for now
#rough approximation of square root (2* width^2
self.length = int(1.4*(width/2))
self.arrow = Triangle(self.pivot1[0],0, self.pivot2[0], 0, self.mid,
self.length, fill=self.colour)
super().append(self.arrow)
def update(self, val):
#need to calculate the position of the top point
#first work out the proportion it is through the value range.
#then convert this into angles
#then the do the trig to find the angle.
#OR precompute a certain set of value ranges, and find where the current value fits.
max_angle = 180-(self.zero_angle)
if val<self.min_val: angle = self.zero_angle
elif val> self.max_val: angle = max_angle
else:
angle = ((((val-self.min_val)/(self.max_val-self.min_val)))*
(max_angle-self.zero_angle)+self.zero_angle)
top_point_x = self.mid-int(math.cos(math.radians(angle))*self.length)
top_point_y = int(math.sin(math.radians(angle))*self.length)
self.arrow = Triangle(self.pivot1[0],0, self.pivot2[0], 0, top_point_x,
top_point_y, fill=self.colour)
super().pop()
super().append(self.arrow)
class Guage(displayio.TileGrid):
def __init__(self, max_val, min_val):
# Create a bitmap with heatmap colors
self.bitmap = displayio.Bitmap(display.width, display.height, len(palette))
self.max_val = max_val
self.min_val = min_val
self.prev_point = [0,0]
super().__init__(self.bitmap, pixel_shader=palette)
for x in range(0, display.width):
for y in range(0, display.height):
self.bitmap[x,y] = 0
def show(self, val):
bitmap = self.bitmap
board.DISPLAY.auto_refresh = False
#need an efficent way of blanking the screen?
#map the value to the range
x_pos = ((val-self.min_val)/(self.max_val-self.min_val)) * display.width
x_range = display.width
y_range = display.height
#blank bitmap -- this is super slow. Need to remember previous point
#for x in range(0, x_range * y_range):
#self.bitmap[x] = 0
#track previous points -- this is super fast
bitmap[self.prev_point] = 0
bitmap[int(x_pos),100] = 1
self.prev_point = [int(x_pos),100]
board.DISPLAY.auto_refresh = True
guage = GuageGroup(-10,10, 120, 120,zero_angle=10)
group = displayio.Group(scale=1)
group.append(guage)
display.show(group)
board.DISPLAY.auto_refresh = True
while True:
x, y, _ = clue.acceleration
start = time.monotonic()
guage.update(x)
print(time.monotonic()-start)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment