Skip to content

Commit 6bd5a44

Browse files
Merge pull request #809 from makosa-irvin/main
Added light sensor example to the cosmic and stellar unicorns
2 parents d0c40af + 6306d5e commit 6bd5a44

File tree

6 files changed

+367
-15
lines changed

6 files changed

+367
-15
lines changed

micropython/examples/cosmic_unicorn/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- [Feature Test With Audio](#feature-test-with-audio)
1010
- [Fire Effect](#fire-effect)
1111
- [Lava Lamp](#lava-lamp)
12+
- [Light Sensor](#light-sensor)
1213
- [Nostalgia Prompt](#nostalgia-prompt)
1314
- [Rainbow](#rainbow)
1415
- [Scrolling Text](#scrolling-text)
@@ -85,6 +86,14 @@ A pretty, procedural fire effect. Switch between landscape fire and vertical fir
8586

8687
A 70s-tastic, procedural rainbow lava lamp. You can adjust the brightness with LUX + and -.
8788

89+
### Light Sensor
90+
91+
[light_sensor.py](light_sensor.py)
92+
93+
Reads data from the on board light sensor and displays the brightness level of the environment. The display is by default set to auto brightness i.e reacts to the brightness of the environment.
94+
- Button A turns auto brightness off
95+
- Button B turns auto brightness on
96+
8897
### Nostalgia Prompt
8998

9099
[nostalgia_prompt.py](nostalgia_prompt.py)
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import time
2+
from cosmic import CosmicUnicorn
3+
from picographics import PicoGraphics, DISPLAY_COSMIC_UNICORN as DISPLAY
4+
5+
"""
6+
Light sensoring feature for the cosmic unicorn
7+
Uses the onboard light sensor to detect the light in the environment
8+
The brightness level is displayed as percentage.
9+
Brightness of the display is auto adjusted to the brightness level of the environment
10+
Press A to turn auto brightness on
11+
Press B to turn auto brightness off
12+
"""
13+
# set up unicorn and drawing variables
14+
cu = CosmicUnicorn()
15+
graphics = PicoGraphics(DISPLAY)
16+
17+
WIDTH, HEIGHT = graphics.get_bounds()
18+
BLACK = graphics.create_pen(0, 0, 0)
19+
WHITE = graphics.create_pen(255, 255, 255)
20+
GREY = graphics.create_pen(20, 20, 20)
21+
HUE_START = 0
22+
HUE_END = 100
23+
graphics.set_font("bitmap8")
24+
25+
# Text display sleep time in ms
26+
TEXT_SLEEP = 500
27+
28+
29+
# the onboard light sensor has a wide range from 0 t0 4095
30+
# It is therefore needed to set a lower max and a higher minimum
31+
MIN_LS_VALUE = 10
32+
MAX_LS_VALUE = 295 # 4095 to use the full range
33+
MIN_RANGE = 0.1
34+
MAX_RANGE = 1
35+
36+
# Rate of display change i.e the lower the value the slower the transition
37+
TRANSITION_RATE = 1.0 / 72.0
38+
39+
# perform linear interpolation to map a range of values to discrete
40+
def map_range(
41+
x,
42+
min_input=MIN_LS_VALUE,
43+
max_input=MAX_LS_VALUE,
44+
min_output=MIN_RANGE,
45+
max_output=MAX_RANGE,
46+
):
47+
return (x - min_input) * (max_output - min_output) / (
48+
max_input - min_input
49+
) + min_output
50+
51+
52+
# gets the light sensor value from onboard sensor and interpolates it
53+
# clamps the brightness value it outside the ranges specified
54+
def calculate_brightness(prev_brightness_val):
55+
current_lsv = cu.light()
56+
current_brightness_val = map_range(current_lsv)
57+
58+
# uses the previous value to smooth out display changes reducing flickering
59+
brightness_diff = current_brightness_val - prev_brightness_val
60+
brightness_val = prev_brightness_val + (brightness_diff * TRANSITION_RATE)
61+
if brightness_val > 1:
62+
brightness_val = 1
63+
elif brightness_val < 0.1:
64+
brightness_val = 0.1
65+
66+
return brightness_val
67+
68+
69+
# sets up a handy function we can call to clear the screen
70+
def clear():
71+
graphics.set_pen(BLACK)
72+
graphics.clear()
73+
74+
75+
def draw_percentage(x, y):
76+
graphics.rectangle(x + 1, y + 1, 2, 2)
77+
graphics.line(x + 1, y + 5, x + 6, y)
78+
graphics.rectangle(x + 4, y + 4, 2, 2)
79+
80+
81+
# draws a sun icon
82+
def draw_sun(x, y, r):
83+
circle_x = x + 3 + r
84+
circle_y = y + 3 + r
85+
graphics.circle(circle_x, circle_y, r)
86+
graphics.line(circle_x, y, circle_x, y + 2)
87+
graphics.line(x, circle_y, x + 2, circle_y)
88+
graphics.line(circle_x, (y + 5 + 2 * r), circle_x, (y + 5 + 2 * r) + 2)
89+
graphics.line((x + 5 + 2 * r), circle_y, (x + 5 + 2 * r) + 2, circle_y)
90+
graphics.line(
91+
circle_x + 1 + r, circle_y - 1 - r, circle_x + 3 + r, circle_y - 3 - r
92+
)
93+
graphics.line(
94+
circle_x + 1 + r, circle_y + 1 + r, circle_x + 3 + r, circle_y + 3 + r
95+
)
96+
graphics.line(
97+
circle_x - 1 - r, circle_y - 1 - r, circle_x - 3 - r, circle_y - 3 - r
98+
)
99+
graphics.line(
100+
circle_x - 1 - r, circle_y + 1 + r, circle_x - 3 - r, circle_y + 3 + r
101+
)
102+
103+
104+
mode = "auto"
105+
last = time.ticks_ms()
106+
107+
brightness_value = MIN_RANGE # set the initial brightness level to the minimum
108+
while True:
109+
current = time.ticks_ms()
110+
111+
# set the display brightness
112+
brightness_value = calculate_brightness(brightness_value)
113+
cu.set_brightness(brightness_value)
114+
115+
bp = (brightness_value / MAX_RANGE) * 100 # gets brightness value in percentage relative to the MAX_LS_VALUE set
116+
117+
# deactivate auto brightness by pressing A
118+
if cu.is_pressed(CosmicUnicorn.SWITCH_A):
119+
print("Auto brightness off")
120+
mode = "off"
121+
122+
# reactivate auto brightness by pressing A
123+
if cu.is_pressed(CosmicUnicorn.SWITCH_B):
124+
print("Auto brightness on")
125+
mode = "auto"
126+
127+
# set brightness to default value if off
128+
if mode == "off":
129+
cu.set_brightness(0.5)
130+
131+
# set text update rate after a certain time to reduce flickering
132+
if current - last >= TEXT_SLEEP:
133+
clear()
134+
135+
# calculate colour from the brightness value
136+
hue = max(0, HUE_START + ((bp - 0) * (HUE_END - HUE_START) / (100 - 0)))
137+
138+
# create pens with this colour (and with the high / low colours)
139+
CURRENT_COLOUR = graphics.create_pen_hsv(hue / 360, 1.0, 0.8)
140+
HIGH_COLOUR = graphics.create_pen_hsv(HUE_END / 360, 1.0, 0.8)
141+
LOW_COLOUR = graphics.create_pen_hsv(HUE_START / 360, 1.0, 0.8)
142+
143+
# draw the text
144+
graphics.set_pen(CURRENT_COLOUR)
145+
graphics.text("BRT: ", 0, 1, scale=1)
146+
graphics.text(f"{bp:.0f}", 7, 23, scale=1)
147+
draw_percentage((WIDTH - 10), 23)
148+
149+
# draw sun icon
150+
draw_sun(0, 10, 2)
151+
152+
# draw a bar for the background
153+
bar_width = WIDTH - 12
154+
graphics.set_pen(GREY)
155+
graphics.rectangle(13, 10, bar_width, 11)
156+
157+
# draw a bar for the current brightness percentage
158+
graphics.set_pen(CURRENT_COLOUR)
159+
graphics.rectangle(13, 10, int((bp / 100) * bar_width), 11)
160+
161+
last = current
162+
163+
# time to update the display
164+
cu.update(graphics)

micropython/examples/galactic_unicorn/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- [Feature Test With Audio](#feature-test-with-audio)
1111
- [Fire Effect](#fire-effect)
1212
- [Lava Lamp](#lava-lamp)
13+
- [Light Sensor](#light-sensor)
1314
- [Nostalgia Prompt](#nostalgia-prompt)
1415
- [Rainbow](#rainbow)
1516
- [Scrolling Text](#scrolling-text)
@@ -88,6 +89,14 @@ A pretty, procedural fire effect. Switch between landscape fire and vertical fir
8889

8990
A 70s-tastic, procedural rainbow lava lamp. You can adjust the brightness with LUX + and -.
9091

92+
### Light Sensor
93+
94+
[light_sensor.py](light_sensor.py)
95+
96+
Reads data from the on board light sensor and displays the brightness level of the environment. The display is by default set to auto brightness i.e reacts to the brightness of the environment.
97+
- Button A turns auto brightness off
98+
- Button B turns auto brightness on
99+
91100
### Nostalgia Prompt
92101

93102
[nostalgia_prompt.py](nostalgia_prompt.py)

micropython/examples/galactic_unicorn/light_sensor.py

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
from picographics import PicoGraphics, DISPLAY_GALACTIC_UNICORN as DISPLAY
44

55
"""
6-
Auto brightness feature for the galactic unicorn
7-
Uses the onboard light sensor to detect the light
8-
The brightness percentage is displayed with brightness auto adjusted
6+
Light sensoring feature for the galactic unicorn
7+
Uses the onboard light sensor to detect the light in the environment
8+
The brightness level is displayed as percentage.
9+
Brightness of the display is auto adjusted to the brightness level of the environment
10+
Press A to turn auto brightness on
11+
Press B to turn auto brightness off
912
"""
1013
# set up unicorn and drawing variables
1114
gu = GalacticUnicorn()
@@ -30,6 +33,9 @@
3033
MIN_RANGE = 0.1
3134
MAX_RANGE = 1
3235

36+
# Rate of display change i.e the lower the value the slower the transition
37+
TRANSITION_RATE = 1.0 / 72.0
38+
3339

3440
# perform linear interpolation to map a range of values to discrete
3541
def map_range(
@@ -45,9 +51,14 @@ def map_range(
4551

4652

4753
# gets the light sensor value from onboard sensor and interpolates it
48-
# clamps the brightness values
49-
def calculate_brightness(current_lsv):
50-
brightness_val = map_range(current_lsv)
54+
# clamps the brightness value it outside the ranges specified
55+
def calculate_brightness(prev_brightness_val):
56+
current_lsv = gu.light()
57+
current_brightness_val = map_range(current_lsv)
58+
59+
# uses the previous value to smooth out display changes reducing flickering
60+
brightness_diff = current_brightness_val - prev_brightness_val
61+
brightness_val = prev_brightness_val + (brightness_diff * TRANSITION_RATE)
5162
if brightness_val > 1:
5263
brightness_val = 1
5364
elif brightness_val < 0.1:
@@ -56,23 +67,30 @@ def calculate_brightness(current_lsv):
5667
return brightness_val
5768

5869

70+
# draws percentage icon
71+
def draw_percentage(x, y):
72+
graphics.rectangle(x + 1, y + 1, 2, 2)
73+
graphics.line(x + 1, y + 5, x + 6, y)
74+
graphics.rectangle(x + 4, y + 4, 2, 2)
75+
76+
5977
# sets up a handy function we can call to clear the screen
6078
def clear():
6179
graphics.set_pen(BLACK)
6280
graphics.clear()
6381

6482

65-
mode = "auto"
83+
mode = "auto" # set auto brightness on
6684
last = time.ticks_ms()
85+
brightness_value = MIN_RANGE # set the initial brightness level to the specified minimum
6786
while True:
6887
current = time.ticks_ms()
6988

70-
# get light sensor value from the sensor
71-
ls_value = gu.light()
72-
brightness_value = calculate_brightness(ls_value)
89+
# set the display brightness
90+
brightness_value = calculate_brightness(brightness_value)
7391
gu.set_brightness(brightness_value)
74-
# calculate brightness percentage
75-
bp = (brightness_value / MAX_RANGE) * 100
92+
93+
bp = (brightness_value / MAX_RANGE) * 100 # gets brightness value in percentage relative to the MAX_LS_VALUE set
7694

7795
# deactivate auto brightness by pressing A
7896
if gu.is_pressed(GalacticUnicorn.SWITCH_A):
@@ -103,9 +121,11 @@ def clear():
103121
# draw the text
104122
graphics.set_pen(CURRENT_COLOUR)
105123
graphics.text("BRT: ", 0, 1, scale=1)
124+
106125
# measure the rest of the text before drawing to right align it
107-
text_width = graphics.measure_text(f"{bp:.0f}/°", scale=1)
108-
graphics.text(f"{bp:.0f}%", WIDTH - text_width, 1, scale=1)
126+
text_width = graphics.measure_text(f"{bp:.0f} ", scale=1)
127+
graphics.text(f"{bp:.0f}", WIDTH - text_width, 1, scale=1)
128+
draw_percentage((WIDTH - 8), 1)
109129

110130
# draw a bar for the background
111131
graphics.set_pen(GREY)
@@ -118,4 +138,3 @@ def clear():
118138

119139
# time to update the display
120140
gu.update(graphics)
121-
# time.sleep(1)

micropython/examples/stellar_unicorn/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- [Feature Test With Audio](#feature-test-with-audio)
1010
- [Fire Effect](#fire-effect)
1111
- [Lava Lamp](#lava-lamp)
12+
- [Light Sensor](#light-sensor)
1213
- [Nostalgia Prompt](#nostalgia-prompt)
1314
- [Rainbow](#rainbow)
1415
- [Scrolling Text](#scrolling-text)
@@ -91,6 +92,14 @@ A pretty, procedural fire effect. Switch between landscape fire and vertical fir
9192

9293
A 70s-tastic, procedural rainbow lava lamp. You can adjust the brightness with LUX + and -.
9394

95+
### Light Sensor
96+
97+
[light_sensor.py](light_sensor.py)
98+
99+
Reads data from the on board light sensor and displays the brightness level of the environment. The display is by default set to auto brightness i.e reacts to the brightness of the environment.
100+
- Button A turns auto brightness off
101+
- Button B turns auto brightness on
102+
94103
### Nostalgia Prompt
95104

96105
[nostalgia_prompt.py](nostalgia_prompt.py)

0 commit comments

Comments
 (0)