Estudio Roble
Published © CC BY-SA

Brake Light and Turn Signals for Backpacks

Accelerometer autodetects Braking. The Turn signals are commanded by a 315MHz module. 78 neopixels. Based on Adafruit CPX.

BeginnerFull instructions provided5 hours684
Brake Light and Turn Signals for Backpacks

Things used in this project

Hardware components

Complete kit
Everything needed is included.
×1
PCBWay Custom PCB
PCBWay Custom PCB
×1
Circuit Playground Express
Adafruit Circuit Playground Express
×1

Software apps and online services

mueditor

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

base_v16_eyebull_3x10_99lK54vBLY.FCStd

soporte_mando_v3_ajm2oczywj.FCStd

Schematics

tbo_v6_z4g0hkXot4.zip

Scheme

Code

17 TBO.py

Python
Code at the CPX
# SPDX-FileCopyrightText: 2020 Eva Herrada for Adafruit Industries
#
# SPDX-License-Identifier: MIT
#
# Modified: 2022 atreyu for Estudio Roble

import time
import math
import board
import neopixel
import digitalio
from adafruit_circuitplayground import cp

boton_A = digitalio.DigitalInOut(board.A6)
boton_A.switch_to_input(pull=digitalio.Pull.UP)
boton_B = digitalio.DigitalInOut(board.A7)
boton_B.switch_to_input(pull=digitalio.Pull.UP)
boton_C = digitalio.DigitalInOut(board.A5)
boton_C.switch_to_input(pull=digitalio.Pull.UP)
boton_D = digitalio.DigitalInOut(board.A4)
boton_D.switch_to_input(pull=digitalio.Pull.UP)

OFF = (0, 0, 0)
BLANCO = (255, 255, 255)
AZUL = (0, 0, 255)
VERDE = (0, 255, 0)
ROJO = (255, 0, 0)
NARANJA = (255, 30, 0)

tone_int_freq = 3062
tone_int_dur = 0.1

if not cp.switch:
    brillo = 0.02
else:
    brillo = 1

cp.pixels.brightness = brillo
strip = neopixel.NeoPixel(
    board.A3, 72, brightness = brillo, auto_write=False, pixel_order=neopixel.GRB
)

k_alman_fast = 0.3
k_alman_slow = 0.1

acc_fast = 0
acc_slow = 0
consecutive_triggers = 0
breaks_on = False
start_brake = time.monotonic()

def dch():
    strip.fill(OFF)
    cp.pixels.fill(OFF)
    for i in range(34, 68):
        strip[i] = (NARANJA)
    for i in range(0, 5):
        cp.pixels[i] = (NARANJA)
    strip.show()

def izq():
    strip.fill(OFF)
    cp.pixels.fill(OFF)
    for i in range(0, 34):
        strip[i] = (NARANJA)
    for i in range(5, 10):
        cp.pixels[i] = (NARANJA)
    strip.show()
def azul():
    strip.fill(AZUL)
    cp.pixels.fill(AZUL)
    strip.show()
def rojo():
    for i in range(0, 68):
        strip[i] = (ROJO)
    for i in range(0, 10):
        cp.pixels[i] = (ROJO)
    strip.show()

def apaga():
    cp.pixels.fill(OFF)
    for i in range(0,17):
        strip[i] = (OFF)
        strip[33-i] = (OFF)
        strip[67-i] = (OFF)
        strip[34+i] = (OFF)
        strip.show()
        time.sleep(0.01)

def boton_pulsado():
    if boton_A.value or boton_B.value or boton_C.value or boton_D.value:
        cp.red_led = True
        #que_boton()
        return True
    else:
        cp.red_led = False
        return False

def que_boton():
        if boton_A.value:
            print('A')
        if boton_B.value:
            print('B')
        if boton_C.value:
            print('C')
        if boton_D.value:
            print('D')

def scale(x):
    return max(min(int(68*x/10), 71), 0)

def lee_acceleration():
    global acc_fast
    global acc_slow
    global shakiness
    x, y, z = cp.acceleration
    acceleration = z

    acc_fast = k_alman_fast * acceleration + (1 - k_alman_fast) * acc_fast
    acc_slow= k_alman_slow * acceleration + (1 - k_alman_slow) * acc_slow

    shakiness =  acc_slow - acc_fast

    #Recuerda que al imprimir por el serial, la sensibilidad del freno aumenta
    #print((x, y, z))
    #print((acc_slow, acc_fast))
    #print((shakiness, ))
    #time.sleep(0.01)

time_minimum = 3.0
bps = 2
beat_time = 1 / bps
blink_number0 = 1 # to start blinking with ligth, not dark

mST = 0
apaga()
RUN = True

cp.pixels.fill(ROJO)
cp.pixels.brightness = brillo
maximo = 0
z_pixel = 0

while RUN:
    while mST == 0:
        azul()
        boton_pulsado()
        if boton_A.value or boton_C.value:
            mST = 10
        if boton_B.value or boton_D.value:
            mST = 20

        lee_acceleration()

        if shakiness  > 0.8:
            if consecutive_triggers > 3:
                if not cp.shake(shake_threshold=10):
                    start_brake = time.monotonic()
                    mST = 3
                    rojo()
                    #cp.start_tone(800)
            consecutive_triggers += 1

    while mST == 3:
        lee_acceleration()
        if time.monotonic() - start_brake > 0.4:
            azul()
            cp.stop_tone()
            consecutive_triggers = 0
            acc_slow = acc_fast
            mST = 0

    while mST == 10:
        begin_time = time.monotonic()
        end_time = begin_time + time_minimum
        blink_number0 = 1
        mST = 11
    while mST == 11:
        now = time.monotonic()
        time_elapsed = now - begin_time
        time_remaining = end_time - now
        blink_number = int(time_elapsed / beat_time) % 2
        if blink_number != blink_number0:
            blink_number0 = blink_number
            if blink_number:
                apaga()
            else:
                dch()
                cp.play_tone(tone_int_freq, tone_int_dur)
        if boton_pulsado():
            if boton_B.value or boton_D.value:
                mST = 20
            if boton_A.value or boton_C.value:
                end_time = now + time_minimum
        if time_remaining < 0:
            apaga()
            mST = 0
        time.sleep(0.1)
    while mST == 20:
        begin_time = time.monotonic()
        end_time = begin_time + time_minimum
        blink_number0 = 1
        mST = 21
    while mST == 21:
        now = time.monotonic()
        time_elapsed = now - begin_time
        time_remaining = end_time - now
        blink_number = int(time_elapsed / beat_time) % 2
        if blink_number != blink_number0:
            blink_number0 = blink_number
            if blink_number:
                apaga()
            else:
                izq()
                cp.play_tone(tone_int_freq, tone_int_dur)
        if boton_pulsado():
            if boton_A.value or boton_C.value:
                mST = 10
            if boton_B.value or boton_D.value:
                end_time = now + time_minimum
        if time_remaining < 0:
            apaga()
            mST = 0
        time.sleep(0.1)

Credits

Estudio Roble

Estudio Roble

2 projects • 1 follower

Comments