Overall, though, this was a lot of fun to code, and it is a project that I will continue to tinker with until I am happy with the results. Here is the code that I came up with, and how it works.
You'll need to download and install the Adafruit_LSM303 library - we have a tutorial on installing arduino libraries here
Select Download Project Zip to get the Flora_Brakelight_Backpack.ino file.
// SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries // // SPDX-License-Identifier: MIT #include <Wire.h> #include <Adafruit_LSM303.h> #include <SPI.h> #include <Adafruit_WS2801.h> Adafruit_LSM303 lsm; #define BRAKETHRESHOLD 350 #define BRAKETIMETHRESHOLD 200 int dataPin = 2; // Yellow wire on Adafruit Pixels int clockPin = 3; // Green wire on Adafruit Pixels const int cPin = 11; const int dPin = 6; // Set the first variable to the NUMBER of pixels. 32 = 32 pixels in a row // The LED strips are 32 LEDs per meter but you can extend/cut the strip Adafruit_WS2801 strip = Adafruit_WS2801(36,dataPin,clockPin); int start = 0; int prevX = 0; int currentX = 0; int cState = 0; int dState = 0; long brakeTime = 0; void setup() { Serial.begin(9600); // Start up the LED strip strip.begin(); // Update the strip, to start they are all 'off' strip.show(); // Try to initialise and warn if we couldn't detect the chip if (!lsm.begin()) { Serial.println("Oops ... unable to initialize the LSM303. Check your wiring!"); while (1); } pinMode(cPin, INPUT); pinMode(dPin, INPUT); } void loop() { check_switches(); // when we check the switches we'll get the current state lsm.read(); currentX = abs(lsm.accelData.x); if (start == 0){ prevX = currentX; start = 1; } int i = currentX - prevX; if (abs(i) > BRAKETHRESHOLD) { brakeTime = millis(); int strikes = 0; while ((abs(i) > BRAKETHRESHOLD) && (strikes < 3)) { if (abs(i) < BRAKETHRESHOLD) { strikes = strikes + 1; } lsm.read(); currentX = abs(lsm.accelData.x); i = currentX - prevX; if ((millis() - brakeTime) > BRAKETIMETHRESHOLD) { brakeLights(Color(255,0,0),250); while (abs(i) > BRAKETHRESHOLD) { lsm.read(); currentX = abs(lsm.accelData.x); i = currentX - prevX; Serial.println(i); delay(100); } hideAll(); brakeTime = millis(); i = 0; lsm.read(); currentX = abs(lsm.accelData.x); } } } prevX = currentX; delay(200); } void check_switches() { cState = digitalRead(cPin); dState = digitalRead(dPin); if (cState == HIGH) { // left blinker Serial.println("left blink on"); hideAll(); leftTurn(Color(255,63,0),250); delay(300); Serial.println("left blink off"); hideAll(); delay(300); } if (dState == HIGH) { // right blinker Serial.println("right blink on"); hideAll(); rightTurn(Color(255,63,0),250); delay(300); Serial.println("right blink off"); hideAll(); delay(300); } } void leftTurn(uint32_t c,uint8_t wait){ innerLeftBottom(c); innerLeftTop(c); strip.show(); delay(wait); hideAll(); outerLeftTop(c); outerLeftBottom(c); strip.show(); delay(wait); hideAll(); } void rightTurn(uint32_t c,uint8_t wait){ innerRightBottom(c); innerRightTop(c); strip.show(); delay(wait); hideAll(); outerRightTop(c); outerRightBottom(c); strip.show(); delay(wait); hideAll(); } void brakeLights(uint32_t c, uint8_t wait){ innerRightBottom(c); innerRightTop(c); innerLeftBottom(c); innerLeftTop(c); strip.show(); delay(wait); hideAll(); outerLeftTop(c); outerLeftBottom(c); outerRightTop(c); outerRightBottom(c); strip.show(); delay(wait); hideAll(); } /* Helper functions */ //Input a value 0 to 384 to get a color value. //The colours are a transition r - g - b - back to r void outerRightBottom(uint32_t c){ for (int i=0; i < 5; i++) { strip.setPixelColor(i, c); } } void outerRightTop(uint32_t c){ for (int i=5; i < 10; i++) { strip.setPixelColor(i, c); } } void innerRightTop(uint32_t c){ for (int i=10; i < 14; i++) { strip.setPixelColor(i, c); } } void innerRightBottom(uint32_t c){ for (int i=14; i < 18; i++) { strip.setPixelColor(i, c); } } void innerLeftBottom(uint32_t c){ for (int i=18; i < 22; i++) { strip.setPixelColor(i, c); strip.show(); } } void innerLeftTop(uint32_t c){ for (int i=22; i < 26; i++) { strip.setPixelColor(i, c); } } void outerLeftTop(uint32_t c){ for (int i=26; i < 31; i++) { strip.setPixelColor(i, c); } } void outerLeftBottom(uint32_t c){ for (int i=31; i < 36; i++) { strip.setPixelColor(i, c); } } void hideAll(){ for(int i = 0; i > strip.numPixels();i++){ strip.setPixelColor(i,Color(0,0,0)); } strip.show(); } // Create a 24 bit color value from R,G,B uint32_t Color(byte r, byte g, byte b) { uint32_t c; c = r; c <<= 8; c |= g; c <<= 8; c |= b; return c; }
#include <Wire.h> #include <Adafruit_LSM303.h> #include <SPI.h> #include <Adafruit_WS2801.h> Adafruit_LSM303 lsm; #define BRAKETHRESHOLD 350 #define BRAKETIMETHRESHOLD 200
The most important part of the code is the LSM303 library, the WS2801 library, and the BRAKETHRESHOLD
, and BRAKETIMETHRESHOLD
values. You will need to install the LSM303 library, which can be found here, and the WS2801 library, which can be found here.
The BRAKETHRESHOLD
value will need to be tweaked to your liking. This value looks at the amount of force the accelerometer measures before it considers it worth investigating further. Similarly, the BRAKETIMETHRESHOLD
value is the amount of time that the force exists before it will trigger the brake lights. This is an important part of the code, as it allows us to ignore things like big bumps in the road.
From there, the code is quite simple. If you press and hold the C button on the remote, the left blinker will activate on the backpack. If you press and hold the D button on the remote, the right blinker will activate on the backpack. Release either button to stop blinking. You could easily modify the sketch to press the button to turn on, and press again to turn off....or simply use the toggle type RF receiver which you can buy here.
Page last edited January 20, 2025
Text editor powered by tinymce.