Skip to content

Commit d7f8814

Browse files
authored
Merge pull request #67 from dcbriccetti/gravity_pulls_pixel
Create “Gravity Pulls Pixel” program
2 parents 516d237 + 6861b08 commit d7f8814

File tree

3 files changed

+86
-1
lines changed

3 files changed

+86
-1
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ install:
2727

2828
script:
2929
- pylint adafruit_circuitplayground/*.py
30-
- ([[ ! -d "examples" ]] || pylint --disable=missing-docstring,invalid-name examples/*.py)
30+
- ([[ ! -d "examples" ]] || pylint --disable=missing-docstring,invalid-name `find ./examples -name "*.py"`)
3131
- circuitpython-build-bundles --filename_prefix adafruit-circuitpython-circuitplayground --library_location .
3232
- cd docs && sphinx-build -E -W -b html . _build/html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"""Gravity Pulls Pixel
2+
3+
This program uses the Circuit Playground Express’s accelerometer to position
4+
a white pixel as if gravity were pulling it.
5+
6+
Flip the switch left (toward the notes) to turn on debugging messages and
7+
slow down the action. See a code walkthrough here: https://youtu.be/sZ4tNOUKRpw
8+
"""
9+
import time
10+
import math
11+
from adafruit_circuitplayground.express import cpx
12+
13+
PIXEL_SPACING_ANGLE = 30
14+
STANDARD_GRAVITY = 9.81
15+
16+
BACKGROUND_COLOR = 0, 0, 64
17+
MIN_BRIGHTNESS = 15 # Minimum brightness for anti-aliasing
18+
LIGHTING_ARC_LENGTH = 45
19+
20+
21+
def compute_pixel_angles():
22+
"""Return a list of rotation angles of the ten NeoPixels.
23+
24+
On the CPX there are ten pixels arranged like the 12 hours of a clock, except that positions
25+
6 and 12 are empty. The numbers in the list are the angles from the (x, y) accelerometer
26+
values for each pixel when the CPX is rotated with that pixel at the bottom. For example,
27+
with pixel 0 at the bottom (and pixel 5 at the top), the accelerometer’s (x, y) values
28+
give an angle of 300°. Rotated clockwise 1/12 turn (30°), so that pixel 1 is at the bottom,
29+
the angle is 330°.
30+
"""
31+
return [(300 + PIXEL_SPACING_ANGLE * n) % 360 for n in range(12) if n not in (5, 11)]
32+
33+
34+
def degrees_between(a1, a2):
35+
smaller = min(a1, a2)
36+
larger = max(a1, a2)
37+
return min(larger - smaller, 360 + smaller - larger)
38+
39+
40+
def pixel_brightness(distance_from_down, accel_magnitude):
41+
"""Return the a brightness for a pixel, or None if the pixel is not in the lighting arc"""
42+
half_lighting_arc_length = LIGHTING_ARC_LENGTH / 2
43+
44+
if accel_magnitude < 0.1 or distance_from_down > half_lighting_arc_length:
45+
return None
46+
47+
normalized_nearness = 1 - distance_from_down / half_lighting_arc_length
48+
scale_factor = (255 - MIN_BRIGHTNESS) * accel_magnitude
49+
color_part = MIN_BRIGHTNESS + round(normalized_nearness * scale_factor)
50+
return color_part
51+
52+
53+
def angle_in_degrees(x, y):
54+
"""Return the angle of the point (x, y), in degrees from -180 to 180"""
55+
return math.atan2(y, x) / math.pi * 180
56+
57+
58+
def positive_degrees(angle):
59+
"""Convert -180 through 180 to 0 through 360"""
60+
return (angle + 360) % 360
61+
62+
63+
cpx.pixels.brightness = 0.1 # Adjust overall brightness as desired, between 0 and 1
64+
pixel_positions = compute_pixel_angles()
65+
66+
while True:
67+
debug = cpx.switch # True is toward the left
68+
accel_x, accel_y = cpx.acceleration[:2] # Ignore z
69+
down_angle = positive_degrees(angle_in_degrees(accel_x, accel_y))
70+
magnitude_limit = STANDARD_GRAVITY
71+
normalized_magnitude = min(math.sqrt(accel_x * accel_x + accel_y * accel_y),
72+
magnitude_limit) / magnitude_limit
73+
74+
pixels_lit = []
75+
for i, pixel_position in enumerate(pixel_positions):
76+
pe = pixel_brightness(degrees_between(pixel_position, down_angle), normalized_magnitude)
77+
cpx.pixels[i] = (pe, pe, pe) if pe else BACKGROUND_COLOR
78+
if pe:
79+
pixels_lit.append((i, pe))
80+
81+
if debug:
82+
lit_formatted = ', '.join(('{}: {:>3d}'.format(p, i) for p, i in pixels_lit))
83+
print('x: {:>6.2f}, y: {:>6.2f}, angle: {:>6.2f}, mag: {:>3.2f}, pixels: [{}]'.format(
84+
accel_x, accel_y, down_angle, normalized_magnitude, lit_formatted))
85+
time.sleep(0.5)

0 commit comments

Comments
 (0)