|
| 1 | +import time |
| 2 | +import math |
| 3 | +from adafruit_circuitplayground import cp |
| 4 | + |
| 5 | +brightness = 0 |
| 6 | + |
| 7 | +# List that holds the last 10 z-axis acceleration values read from the accelerometer. |
| 8 | +# Used for the n=10 moving average |
| 9 | +last10 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] |
| 10 | + |
| 11 | +# List that holds the last 50 z-axis acceleration values read from the accelerometer. |
| 12 | +# Used for the n=50 moving average |
| 13 | +last50 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 14 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 15 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 16 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 17 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] |
| 18 | + |
| 19 | +consecutive_triggers = 0 |
| 20 | +cp.pixels.fill((255, 0, 0)) |
| 21 | + |
| 22 | +light_on = False |
| 23 | + |
| 24 | +while True: |
| 25 | + x, y, z = cp.acceleration |
| 26 | + |
| 27 | + # moving average n=10, not super smooth, but it substantially lowers the amount of noise |
| 28 | + last10.append(z) |
| 29 | + last10.pop(0) |
| 30 | + avg10 = sum(last10)/10 |
| 31 | + |
| 32 | + # moving average n=50, very smooth |
| 33 | + last50.append(z) |
| 34 | + last50.pop(0) |
| 35 | + avg50 = sum(last50)/50 |
| 36 | + |
| 37 | + # If the difference between the moving average of the last 10 points and the moving average of |
| 38 | + # the last 50 points is greater than 1 m/s^2, this is true |
| 39 | + if avg10 - avg50 > 1: |
| 40 | + if consecutive_triggers > 3: # Is true when avg10-avg50 > 1m/s^2 at least 3 times in a row |
| 41 | + # Detects shake. Due to the very low shake threshold, this alone would have very low |
| 42 | + # specificity. This was mitigated by having it only run when the acceleration |
| 43 | + # difference is greater than 1 m/s^2 at least 3 times in a row. |
| 44 | + if not cp.shake(shake_threshold=10): |
| 45 | + # Set brightness to max, timestamp when it was set to max, and set light_on to true |
| 46 | + cp.pixels.brightness = 1 |
| 47 | + start = time.monotonic() |
| 48 | + light_on = True |
| 49 | + consecutive_triggers += 1 # increase it whether or not the light is turned on |
| 50 | + |
| 51 | + # light_on variable is for short circuiting. Not really necessary, just makes things run faster |
| 52 | + elif not light_on or time.monotonic() - start > 0.4: |
| 53 | + # Sine wave used for the color breathing effect. |
| 54 | + # Max brightness can be adjusted with the coefficient. |
| 55 | + cp.pixels.brightness = abs(math.sin(brightness)) * 0.5 |
| 56 | + brightness += 0.05 |
| 57 | + consecutive_triggers = 0 |
| 58 | + light_on = False |
| 59 | + |
| 60 | + time.sleep(0.02) |
0 commit comments