Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Øyvind Kolås
firmware
Commits
05ba8877
Commit
05ba8877
authored
Sep 06, 2020
by
schneider
Browse files
chore(g-watch): Use Unix line endings
parent
8bb4d35f
Changes
2
Hide whitespace changes
Inline
Side-by-side
preload/apps/g_watch/README.md
View file @
05ba8877
#G-Watch
A gesture controlled power-saving digital clock. It can replace main.py as standard watch.
###How to use:
Hold your arm roughly straight and turn your wrist quickly. The digital clock will appear on the screen and fade out after a few seconds.
###Features:
*
Gesture controlled
*
Screen brightness adapts to environment brightness
#G-Watch
A gesture controlled power-saving digital clock. It can replace main.py as standard watch.
###How to use:
Hold your arm roughly straight and turn your wrist quickly. The digital clock will appear on the screen and fade out after a few seconds.
###Features:
*
Gesture controlled
*
Screen brightness adapts to environment brightness
Uses code from watch++
\ No newline at end of file
preload/apps/g_watch/__init__.py
View file @
05ba8877
import
buttons
import
display
import
ledfx
import
leds
import
math
import
bhi160
import
utime
import
power
import
light_sensor
disp
=
display
.
open
()
sensor
=
0
sensors
=
[{
"sensor"
:
bhi160
.
BHI160Orientation
(
sample_rate
=
8
),
"name"
:
"Orientation"
}]
DIGITS
=
[
(
True
,
True
,
True
,
True
,
True
,
True
,
False
),
(
False
,
True
,
True
,
False
,
False
,
False
,
False
),
(
True
,
True
,
False
,
True
,
True
,
False
,
True
),
(
True
,
True
,
True
,
True
,
False
,
False
,
True
),
(
False
,
True
,
True
,
False
,
False
,
True
,
True
),
(
True
,
False
,
True
,
True
,
False
,
True
,
True
),
(
True
,
False
,
True
,
True
,
True
,
True
,
True
),
(
True
,
True
,
True
,
False
,
False
,
False
,
False
),
(
True
,
True
,
True
,
True
,
True
,
True
,
True
),
(
True
,
True
,
True
,
True
,
False
,
True
,
True
)
]
DOW
=
[
'Mo'
,
'Tu'
,
'We'
,
'Th'
,
'Fr'
,
'Sa'
,
'Su'
]
led_count
=
11
b7
=
255
# brightness of 7-segment display 0...255
def
ceil_div
(
a
,
b
):
return
(
a
+
(
b
-
1
))
//
b
def
tip_height
(
w
):
return
ceil_div
(
w
,
2
)
-
1
def
draw_tip
(
x
,
y
,
w
,
c
,
invert
=
False
,
swapAxes
=
False
):
h
=
tip_height
(
w
)
for
dy
in
range
(
h
):
for
dx
in
range
(
dy
+
1
,
w
-
1
-
dy
):
px
=
x
+
dx
py
=
y
+
dy
if
not
invert
else
y
+
h
-
1
-
dy
if
swapAxes
:
px
,
py
=
py
,
px
disp
.
pixel
(
px
,
py
,
col
=
c
)
def
draw_seg
(
x
,
y
,
w
,
h
,
c
,
swapAxes
=
False
):
tip_h
=
tip_height
(
w
)
body_h
=
h
-
2
*
tip_h
draw_tip
(
x
,
y
,
w
,
c
,
invert
=
True
,
swapAxes
=
swapAxes
)
px1
,
px2
=
x
,
x
+
(
w
-
1
)
py1
,
py2
=
y
+
tip_h
,
y
+
tip_h
+
(
body_h
-
1
)
if
swapAxes
:
px1
,
px2
,
py1
,
py2
=
py1
,
py2
,
px1
,
px2
disp
.
rect
(
px1
,
py1
,
px2
,
py2
,
col
=
c
)
draw_tip
(
x
,
y
+
tip_h
+
body_h
,
w
,
c
,
invert
=
False
,
swapAxes
=
swapAxes
)
def
draw_Vseg
(
x
,
y
,
w
,
l
,
c
):
draw_seg
(
x
,
y
,
w
,
l
,
c
)
def
draw_Hseg
(
x
,
y
,
w
,
l
,
c
):
draw_seg
(
y
,
x
,
w
,
l
,
c
,
swapAxes
=
True
)
def
draw_grid_seg
(
x
,
y
,
w
,
l
,
c
,
swapAxes
=
False
):
sw
=
w
-
2
tip_h
=
tip_height
(
sw
)
x
=
x
*
w
y
=
y
*
w
l
=
(
l
-
1
)
*
w
draw_seg
(
x
+
1
,
y
+
tip_h
+
3
,
sw
,
l
-
3
,
c
,
swapAxes
=
swapAxes
)
def
draw_grid_Vseg
(
x
,
y
,
w
,
l
,
c
):
draw_grid_seg
(
x
,
y
,
w
,
l
,
c
)
def
draw_grid_Hseg
(
x
,
y
,
w
,
l
,
c
):
draw_grid_seg
(
y
,
x
,
w
,
l
,
c
,
swapAxes
=
True
)
def
draw_grid
(
x1
,
y1
,
x2
,
y2
,
w
,
c
):
for
x
in
range
(
x1
*
w
,
x2
*
w
):
for
y
in
range
(
y1
*
w
,
y2
*
w
):
if
x
%
w
==
0
or
x
%
w
==
w
-
1
or
y
%
w
==
0
or
y
%
w
==
w
-
1
:
disp
.
pixel
(
x
,
y
,
col
=
c
)
def
draw_grid_7seg
(
x
,
y
,
w
,
segs
,
c
):
if
segs
[
0
]:
draw_grid_Hseg
(
x
,
y
,
w
,
4
,
c
)
if
segs
[
1
]:
draw_grid_Vseg
(
x
+
3
,
y
,
w
,
4
,
c
)
if
segs
[
2
]:
draw_grid_Vseg
(
x
+
3
,
y
+
3
,
w
,
4
,
c
)
if
segs
[
3
]:
draw_grid_Hseg
(
x
,
y
+
6
,
w
,
4
,
c
)
if
segs
[
4
]:
draw_grid_Vseg
(
x
,
y
+
3
,
w
,
4
,
c
)
if
segs
[
5
]:
draw_grid_Vseg
(
x
,
y
,
w
,
4
,
c
)
if
segs
[
6
]:
draw_grid_Hseg
(
x
,
y
+
3
,
w
,
4
,
c
)
def
render_num
(
num
,
x
):
draw_grid_7seg
(
x
,
1
,
7
,
DIGITS
[
num
//
10
],
(
b7
,
b7
,
b7
))
draw_grid_7seg
(
x
+
5
,
1
,
7
,
DIGITS
[
num
%
10
],
(
b7
,
b7
,
b7
))
def
render_colon
():
draw_grid_Vseg
(
11
,
2
,
7
,
2
,
(
b7
,
b7
,
b7
))
draw_grid_Vseg
(
11
,
4
,
7
,
2
,
(
b7
,
b7
,
b7
))
def
render7segment
():
year
,
month
,
mday
,
hour
,
min
,
sec
,
wday
,
yday
=
utime
.
localtime
()
render_num
(
hour
,
1
)
render_num
(
min
,
13
)
if
sec
%
2
==
0
:
render_colon
()
with
display
.
open
()
as
disp
:
disp
.
clear
().
update
()
bri
=
0
threshold_angle
=
35
zn
=
0
yo
=
0
#old y value
yn
=
0
#new y value
yd
=
0
#y difference
ydl
=
0
#yd lpf
clock_on
=
utime
.
monotonic_ms
()
#time in ms when clock is turned on
timeout
=
7000
#time in ms how long clock will be displayed
clock_off
=
clock_on
+
timeout
#time in ms when clock is turned off
fade_time
=
0
#fade out counter
leds
.
dim_top
(
2
)
leds_on
=
0
p_leds_on
=
0
while
True
:
millis
=
utime
.
monotonic_ms
()
lt
=
utime
.
localtime
()
dow
=
lt
[
6
]
#---------------------------------------- read brightness sensor
bri
=
light_sensor
.
get_reading
()
bri
=
int
(
fade_time
*
100
/
1000
*
bri
/
200
)
# calculate display brightness in percent (bri)
if
(
bri
>
100
):
bri
=
100
if
(
bri
<
0
):
bri
=
0
ledbri
=
((
bri
/
2
)
+
50
)
/
100
# calculate led bar brightness (ledbri = 0...1)
#---------------------------------------- read buttons
pressed
=
buttons
.
read
(
buttons
.
BOTTOM_LEFT
|
buttons
.
BOTTOM_RIGHT
)
p_leds_on
=
leds_on
if
pressed
&
buttons
.
BOTTOM_LEFT
!=
0
:
leds_on
=
0
disp
.
clear
()
disp
.
print
(
'LEDS OFF'
,
posx
=
40
,
posy
=
30
,
font
=
2
)
disp
.
update
()
disp
.
backlight
(
brightness
=
50
)
utime
.
sleep_ms
(
500
)
disp
.
backlight
(
brightness
=
0
)
for
led
in
range
(
led_count
):
leds
.
prep_hsv
(
led
,
[
0
,
0
,
0
])
disp
.
update
()
if
pressed
&
buttons
.
BOTTOM_RIGHT
!=
0
:
leds_on
=
1
disp
.
clear
()
disp
.
print
(
'LEDS ON'
,
posx
=
40
,
posy
=
30
,
font
=
2
)
disp
.
update
()
disp
.
backlight
(
brightness
=
50
)
utime
.
sleep_ms
(
500
)
disp
.
backlight
(
brightness
=
0
)
#---------------------------------------- read orientation sensor
samples
=
sensors
[
sensor
][
"sensor"
].
read
()
if
len
(
samples
)
>
0
:
#get orientation sensor samples
sample
=
samples
[
0
]
yo
=
yn
#calculate absolute wrist rotation since last check
yn
=
sample
.
y
+
360
yd
=
abs
(
yn
-
yo
)
yd
=
yd
%
180
yd
=
yd
*
22
#multiply rotation with amplifier
if
abs
(
sample
.
z
)
>
50
:
#if arm is hanging:
yd
=
0
#do not regard wrist rotation
ydl
=
ydl
*
.
9
ydl
=
(
yd
+
ydl
*
9
)
/
10
#low pass filter wrist rotation
if
ydl
>
100
:
#check rottion against threshold and limit value
ydl
=
100
if
clock_on
+
timeout
<
millis
:
clock_on
=
millis
clock_off
=
timeout
+
clock_on
#.................................... display rotation bargraph on leds // full bar == hitting threshold
if
(
leds_on
==
1
):
hour
=
lt
[
3
]
hue
=
360
-
(
hour
/
24
*
360
)
for
led
in
range
(
led_count
):
if
(
led
<
int
(
ydl
/
100
*
12
)
-
1
)
or
millis
<
clock_off
-
1500
-
((
10
-
led
)
*
15
)
+
300
:
leds
.
prep_hsv
(
10
-
led
,
[
hue
,
100
,
ledbri
])
#led=0
else
:
leds
.
prep_hsv
(
10
-
led
,
[
0
,
0
,
0
])
#---------------------------------------- display clock
disp
.
clear
()
if
clock_off
>=
millis
:
#.................................... time
lt
=
utime
.
localtime
()
year
=
lt
[
0
]
month
=
lt
[
1
]
day
=
lt
[
2
]
hour
=
lt
[
3
]
mi
=
lt
[
4
]
sec
=
lt
[
5
]
dow
=
lt
[
6
]
fade_time
=
clock_off
-
millis
-
1000
#calculate fade out
if
fade_time
<
0
:
fade_time
=
0
if
fade_time
>
1000
:
fade_time
=
1000
disp
.
backlight
(
brightness
=
bri
)
render7segment
()
#render time in 7-segment digiclock style
disp
.
print
(
'{:02d}-{:02d}-{} {}'
.
format
(
day
,
month
,
year
,
DOW
[
dow
]),
posx
=
10
,
posy
=
67
,
font
=
2
)
# display date
#.................................... power
pwr
=
math
.
sqrt
(
power
.
read_battery_voltage
())
#disp.print("%f" % power.read_battery_voltage(), posx=25, posy=58, font=2) # display battery voltage
full
=
2.0
empty
=
math
.
sqrt
(
3.4
)
pwr
=
pwr
-
empty
full
=
full
-
empty
pwrpercent
=
pwr
*
(
100.0
/
full
)
#disp.print("%f" % pwrpercent, posx=25, posy=67, font=2) # display battery percent
if
pwrpercent
<
0
:
pwrpercent
=
0
if
pwrpercent
>
100
:
pwrpercent
=
100
disp
.
rect
(
8
,
60
,
153
,
63
,
col
=
[
100
,
100
,
100
])
# draw battery bar
c
=
[
255
,
0
,
0
]
#red=empty
if
pwrpercent
>
10
:
c
=
[
255
,
255
,
0
]
#yellow=emptyish
if
pwrpercent
>
25
:
c
=
[
0
,
255
,
0
]
#green=ok
disp
.
rect
(
8
,
60
,
int
(
pwrpercent
*
1.43
+
8
),
63
,
col
=
c
)
# draw charge bar in battery bar
#---------------------------------------- do not display clock
leds
.
update
()
disp
.
update
()
import
buttons
import
display
import
ledfx
import
leds
import
math
import
bhi160
import
utime
import
power
import
light_sensor
disp
=
display
.
open
()
sensor
=
0
sensors
=
[{
"sensor"
:
bhi160
.
BHI160Orientation
(
sample_rate
=
8
),
"name"
:
"Orientation"
}]
DIGITS
=
[
(
True
,
True
,
True
,
True
,
True
,
True
,
False
),
(
False
,
True
,
True
,
False
,
False
,
False
,
False
),
(
True
,
True
,
False
,
True
,
True
,
False
,
True
),
(
True
,
True
,
True
,
True
,
False
,
False
,
True
),
(
False
,
True
,
True
,
False
,
False
,
True
,
True
),
(
True
,
False
,
True
,
True
,
False
,
True
,
True
),
(
True
,
False
,
True
,
True
,
True
,
True
,
True
),
(
True
,
True
,
True
,
False
,
False
,
False
,
False
),
(
True
,
True
,
True
,
True
,
True
,
True
,
True
),
(
True
,
True
,
True
,
True
,
False
,
True
,
True
)
]
DOW
=
[
'Mo'
,
'Tu'
,
'We'
,
'Th'
,
'Fr'
,
'Sa'
,
'Su'
]
led_count
=
11
b7
=
255
# brightness of 7-segment display 0...255
def
ceil_div
(
a
,
b
):
return
(
a
+
(
b
-
1
))
//
b
def
tip_height
(
w
):
return
ceil_div
(
w
,
2
)
-
1
def
draw_tip
(
x
,
y
,
w
,
c
,
invert
=
False
,
swapAxes
=
False
):
h
=
tip_height
(
w
)
for
dy
in
range
(
h
):
for
dx
in
range
(
dy
+
1
,
w
-
1
-
dy
):
px
=
x
+
dx
py
=
y
+
dy
if
not
invert
else
y
+
h
-
1
-
dy
if
swapAxes
:
px
,
py
=
py
,
px
disp
.
pixel
(
px
,
py
,
col
=
c
)
def
draw_seg
(
x
,
y
,
w
,
h
,
c
,
swapAxes
=
False
):
tip_h
=
tip_height
(
w
)
body_h
=
h
-
2
*
tip_h
draw_tip
(
x
,
y
,
w
,
c
,
invert
=
True
,
swapAxes
=
swapAxes
)
px1
,
px2
=
x
,
x
+
(
w
-
1
)
py1
,
py2
=
y
+
tip_h
,
y
+
tip_h
+
(
body_h
-
1
)
if
swapAxes
:
px1
,
px2
,
py1
,
py2
=
py1
,
py2
,
px1
,
px2
disp
.
rect
(
px1
,
py1
,
px2
,
py2
,
col
=
c
)
draw_tip
(
x
,
y
+
tip_h
+
body_h
,
w
,
c
,
invert
=
False
,
swapAxes
=
swapAxes
)
def
draw_Vseg
(
x
,
y
,
w
,
l
,
c
):
draw_seg
(
x
,
y
,
w
,
l
,
c
)
def
draw_Hseg
(
x
,
y
,
w
,
l
,
c
):
draw_seg
(
y
,
x
,
w
,
l
,
c
,
swapAxes
=
True
)
def
draw_grid_seg
(
x
,
y
,
w
,
l
,
c
,
swapAxes
=
False
):
sw
=
w
-
2
tip_h
=
tip_height
(
sw
)
x
=
x
*
w
y
=
y
*
w
l
=
(
l
-
1
)
*
w
draw_seg
(
x
+
1
,
y
+
tip_h
+
3
,
sw
,
l
-
3
,
c
,
swapAxes
=
swapAxes
)
def
draw_grid_Vseg
(
x
,
y
,
w
,
l
,
c
):
draw_grid_seg
(
x
,
y
,
w
,
l
,
c
)
def
draw_grid_Hseg
(
x
,
y
,
w
,
l
,
c
):
draw_grid_seg
(
y
,
x
,
w
,
l
,
c
,
swapAxes
=
True
)
def
draw_grid
(
x1
,
y1
,
x2
,
y2
,
w
,
c
):
for
x
in
range
(
x1
*
w
,
x2
*
w
):
for
y
in
range
(
y1
*
w
,
y2
*
w
):
if
x
%
w
==
0
or
x
%
w
==
w
-
1
or
y
%
w
==
0
or
y
%
w
==
w
-
1
:
disp
.
pixel
(
x
,
y
,
col
=
c
)
def
draw_grid_7seg
(
x
,
y
,
w
,
segs
,
c
):
if
segs
[
0
]:
draw_grid_Hseg
(
x
,
y
,
w
,
4
,
c
)
if
segs
[
1
]:
draw_grid_Vseg
(
x
+
3
,
y
,
w
,
4
,
c
)
if
segs
[
2
]:
draw_grid_Vseg
(
x
+
3
,
y
+
3
,
w
,
4
,
c
)
if
segs
[
3
]:
draw_grid_Hseg
(
x
,
y
+
6
,
w
,
4
,
c
)
if
segs
[
4
]:
draw_grid_Vseg
(
x
,
y
+
3
,
w
,
4
,
c
)
if
segs
[
5
]:
draw_grid_Vseg
(
x
,
y
,
w
,
4
,
c
)
if
segs
[
6
]:
draw_grid_Hseg
(
x
,
y
+
3
,
w
,
4
,
c
)
def
render_num
(
num
,
x
):
draw_grid_7seg
(
x
,
1
,
7
,
DIGITS
[
num
//
10
],
(
b7
,
b7
,
b7
))
draw_grid_7seg
(
x
+
5
,
1
,
7
,
DIGITS
[
num
%
10
],
(
b7
,
b7
,
b7
))
def
render_colon
():
draw_grid_Vseg
(
11
,
2
,
7
,
2
,
(
b7
,
b7
,
b7
))
draw_grid_Vseg
(
11
,
4
,
7
,
2
,
(
b7
,
b7
,
b7
))
def
render7segment
():
year
,
month
,
mday
,
hour
,
min
,
sec
,
wday
,
yday
=
utime
.
localtime
()
render_num
(
hour
,
1
)
render_num
(
min
,
13
)
if
sec
%
2
==
0
:
render_colon
()
with
display
.
open
()
as
disp
:
disp
.
clear
().
update
()
bri
=
0
threshold_angle
=
35
zn
=
0
yo
=
0
#old y value
yn
=
0
#new y value
yd
=
0
#y difference
ydl
=
0
#yd lpf
clock_on
=
utime
.
monotonic_ms
()
#time in ms when clock is turned on
timeout
=
7000
#time in ms how long clock will be displayed
clock_off
=
clock_on
+
timeout
#time in ms when clock is turned off
fade_time
=
0
#fade out counter
leds
.
dim_top
(
2
)
leds_on
=
0
p_leds_on
=
0
while
True
:
millis
=
utime
.
monotonic_ms
()
lt
=
utime
.
localtime
()
dow
=
lt
[
6
]
#---------------------------------------- read brightness sensor
bri
=
light_sensor
.
get_reading
()
bri
=
int
(
fade_time
*
100
/
1000
*
bri
/
200
)
# calculate display brightness in percent (bri)
if
(
bri
>
100
):
bri
=
100
if
(
bri
<
0
):
bri
=
0
ledbri
=
((
bri
/
2
)
+
50
)
/
100
# calculate led bar brightness (ledbri = 0...1)
#---------------------------------------- read buttons
pressed
=
buttons
.
read
(
buttons
.
BOTTOM_LEFT
|
buttons
.
BOTTOM_RIGHT
)
p_leds_on
=
leds_on
if
pressed
&
buttons
.
BOTTOM_LEFT
!=
0
:
leds_on
=
0
disp
.
clear
()
disp
.
print
(
'LEDS OFF'
,
posx
=
40
,
posy
=
30
,
font
=
2
)
disp
.
update
()
disp
.
backlight
(
brightness
=
50
)
utime
.
sleep_ms
(
500
)
disp
.
backlight
(
brightness
=
0
)
for
led
in
range
(
led_count
):
leds
.
prep_hsv
(
led
,
[
0
,
0
,
0
])
disp
.
update
()
if
pressed
&
buttons
.
BOTTOM_RIGHT
!=
0
:
leds_on
=
1
disp
.
clear
()
disp
.
print
(
'LEDS ON'
,
posx
=
40
,
posy
=
30
,
font
=
2
)
disp
.
update
()
disp
.
backlight
(
brightness
=
50
)
utime
.
sleep_ms
(
500
)
disp
.
backlight
(
brightness
=
0
)
#---------------------------------------- read orientation sensor
samples
=
sensors
[
sensor
][
"sensor"
].
read
()
if
len
(
samples
)
>
0
:
#get orientation sensor samples
sample
=
samples
[
0
]
yo
=
yn
#calculate absolute wrist rotation since last check
yn
=
sample
.
y
+
360
yd
=
abs
(
yn
-
yo
)
yd
=
yd
%
180
yd
=
yd
*
22
#multiply rotation with amplifier
if
abs
(
sample
.
z
)
>
50
:
#if arm is hanging:
yd
=
0
#do not regard wrist rotation
ydl
=
ydl
*
.
9
ydl
=
(
yd
+
ydl
*
9
)
/
10
#low pass filter wrist rotation
if
ydl
>
100
:
#check rottion against threshold and limit value
ydl
=
100
if
clock_on
+
timeout
<
millis
:
clock_on
=
millis
clock_off
=
timeout
+
clock_on
#.................................... display rotation bargraph on leds // full bar == hitting threshold
if
(
leds_on
==
1
):
hour
=
lt
[
3
]
hue
=
360
-
(
hour
/
24
*
360
)
for
led
in
range
(
led_count
):
if
(
led
<
int
(
ydl
/
100
*
12
)
-
1
)
or
millis
<
clock_off
-
1500
-
((
10
-
led
)
*
15
)
+
300
:
leds
.
prep_hsv
(
10
-
led
,
[
hue
,
100
,
ledbri
])
#led=0
else
:
leds
.
prep_hsv
(
10
-
led
,
[
0
,
0
,
0
])
#---------------------------------------- display clock
disp
.
clear
()
if
clock_off
>=
millis
:
#.................................... time
lt
=
utime
.
localtime
()