9
9
import adafruit_imageload
10
10
import gc9a01
11
11
12
- # wiring for QT Py, should work on any QT Py or XIAO board, but ESP32-S3 is fastest
12
+ # config: behaviors
13
+ eye_twitch_time = 2 # bigger is less twitchy
14
+ eye_twitch_amount = 20 # allowable deviation from center for iris
15
+ eye_blink_time = 1.2 # bigger is slower
16
+ eye_rotation = 0 # 0 or 180, don't do 90 or 270 because too slow
17
+
18
+ # config: wiring for QT Py, should work on any QT Py or XIAO board, but ESP32-S3 is fastest
13
19
tft0_clk = board .SCK
14
20
tft0_mosi = board .MOSI
15
21
22
28
dw , dh = 240 , 240 # display dimensions
23
29
24
30
# load our eye and iris bitmaps
25
- eyeball_bitmap , eyeball_pal = adafruit_imageload .load ("imgs/eye0_ball2.bmp" )
31
+ ## static so load from disk
32
+ eyeball_bitmap = displayio .OnDiskBitmap (open ("/imgs/eye0_ball2.bmp" , "rb" ))
33
+ eyeball_pal = eyeball_bitmap .pixel_shader
34
+ ## moves aorund, so load into RAM
26
35
iris_bitmap , iris_pal = adafruit_imageload .load ("imgs/eye0_iris0.bmp" )
27
36
iris_pal .make_transparent (0 )
28
- eyelid_bitmap = displayio .OnDiskBitmap (open ("/imgs/eyelid_spritesheet2.bmp" , "rb" ))
29
- eyelid_pal = eyelid_bitmap .pixel_shader
30
- #eyelid_bitmap, eyelid_pal = adafruit_imageload.load("/imgs/eyelid_spritesheet.bmp")
37
+ ## also moves, so load into RAM (hopefully)
38
+ try :
39
+ eyelid_bitmap , eyelid_pal = adafruit_imageload .load ("/imgs/eyelid_spritesheet2.bmp" )
40
+ except Exception as e :
41
+ print ("couldn't load" ,e )
42
+ eyelid_bitmap = displayio .OnDiskBitmap (open ("/imgs/eyelid_spritesheet2.bmp" , "rb" ))
43
+ eyelid_pal = eyelid_bitmap .pixel_shader
31
44
eyelid_sprite_cnt = eyelid_bitmap .width // dw # should be 16
32
45
eyelid_pal .make_transparent (1 )
33
46
34
47
# compute or declare some useful info about the eyes
35
48
iris_w , iris_h = iris_bitmap .width , iris_bitmap .height # iris is normally 110x110
36
49
iris_cx , iris_cy = dw // 2 - iris_w // 2 , dh // 2 - iris_h // 2
37
- r = 20 # allowable deviation from center for iris
38
50
39
51
40
52
spi0 = busio .SPI (clock = tft0_clk , MOSI = tft0_mosi )
41
53
42
54
# class to help us track eye info (not needed for this use exactly, but I find it interesting)
43
55
class Eye :
44
- def __init__ (self , spi , dc , cs , rst , rot = 0 , eye_speed = 0.25 , twitch = 2 ):
56
+ def __init__ (self , spi , dc , cs , rst , rot = 0 , eye_speed = 0.25 ):
45
57
display_bus = displayio .FourWire (spi , command = dc , chip_select = cs , reset = rst )
46
58
display = gc9a01 .GC9A01 (display_bus , width = dw , height = dh , rotation = rot )
47
59
display .auto_refresh = False
@@ -56,29 +68,35 @@ def __init__(self, spi, dc, cs, rst, rot=0, eye_speed=0.25, twitch=2):
56
68
main .append (self .lids )
57
69
self .x , self .y = iris_cx , iris_cy
58
70
self .tx , self .ty = self .x , self .y
59
- self .next_time = time . monotonic ()
71
+ self .next_time = 0
60
72
self .eye_speed = eye_speed
61
- self .twitch = twitch
62
73
self .lidpos = 0
63
74
self .lidpos_inc = 1
64
75
self .lid_next_time = 0
65
76
66
77
def update (self ):
78
+ """
79
+ global variables used:
80
+ - eye_twitch_amount
81
+ - eye_twitch_time
82
+ - eye_blink_time
83
+ -
84
+ """
67
85
# make the eye twitch around
68
86
self .x = self .x * (1 - self .eye_speed ) + self .tx * self .eye_speed # "easing"
69
87
self .y = self .y * (1 - self .eye_speed ) + self .ty * self .eye_speed
70
88
self .iris .x = int ( self .x )
71
- self .iris .y = int ( self .y ) + 10
89
+ self .iris .y = int ( self .y ) + 10 # have it look down a bit FIXME
72
90
if time .monotonic () > self .next_time :
73
91
# pick a new "target" for the eye to look at
74
- t = random .uniform (0.25 ,self . twitch )
92
+ t = random .uniform (0.25 , eye_twitch_time )
75
93
self .next_time = time .monotonic () + t
76
- self .tx = iris_cx + random .uniform (- r , r )
77
- self .ty = iris_cy + random .uniform (- r , r )
78
-
79
- if time .monotonic () > self .lid_next_time :
94
+ self .tx = iris_cx + random .uniform (- eye_twitch_amount , eye_twitch_amount )
95
+ self .ty = iris_cy + random .uniform (- eye_twitch_amount , eye_twitch_amount )
96
+ # elif to minimize display changes per update
97
+ elif time .monotonic () > self .lid_next_time :
80
98
# make the eye blink its eyelids
81
- self .lid_next_time = time .monotonic () + random .uniform (1 , 3 )
99
+ self .lid_next_time = time .monotonic () + random .uniform ( eye_blink_time * 0.5 , eye_blink_time * 1.5 )
82
100
self .lidpos = self .lidpos + self .lidpos_inc
83
101
self .lids [0 ] = self .lidpos
84
102
if self .lidpos == 0 or self .lidpos == eyelid_sprite_cnt - 1 :
@@ -88,10 +106,9 @@ def update(self):
88
106
89
107
# a list of all the eyes, in this case, only one
90
108
the_eyes = [
91
- Eye ( spi0 , tft_L0_dc , tft_L0_cs , tft_L0_rst , rot = 0 ),
109
+ Eye ( spi0 , tft_L0_dc , tft_L0_cs , tft_L0_rst , rot = eye_rotation ),
92
110
]
93
111
94
112
while True :
95
113
for eye in the_eyes :
96
114
eye .update ()
97
-
0 commit comments