Last active
May 30, 2022 17:56
-
-
Save rupl/bf05d1ad40131a21f16fb24fbef9c0e3 to your computer and use it in GitHub Desktop.
Code to power an Arduino biking jacket. Build details here: https://chrisruppel.com/blog/lilypad-arduino-biking-jacket/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* LilyPad Arduino Biking Jacket | |
* | |
* Each sleeve has a button and indicator light near the cuff. | |
* - Pressing the a button turns the blinker on for a few cycles. | |
* - Hold the same button to stop it sooner. | |
* - Pressing both buttons turns on hazard mode. | |
* - Hold one button to disable hazard mode. | |
* | |
* Made with <3 for Karin :) | |
* | |
* @license GPL 2.0 | |
* @see https://chrisruppel.com/blog/lilypad-arduino-biking-jacket/ | |
*/ | |
const int left = 9; | |
const int minus = 10; | |
const int right = 11; | |
const int leftHand = 2; | |
const int leftButton = 3; | |
const int rightHand = A3; | |
const int rightButton = A2; | |
const int RESET = 5; | |
int leftCounter = RESET; | |
int rightCounter = RESET; | |
int hazardMode = 0; | |
int hazardModeJustDisabled = 0; | |
/////////////////////////// | |
// Setup | |
/////////////////////////// | |
void setup() { | |
pinMode(left, OUTPUT); | |
pinMode(right, OUTPUT); | |
pinMode(leftHand, OUTPUT); | |
pinMode(rightHand, OUTPUT); | |
pinMode(minus, OUTPUT); | |
digitalWrite(minus, LOW); | |
pinMode(leftButton, INPUT_PULLUP); | |
pinMode(rightButton, INPUT_PULLUP); | |
} | |
/////////////////////////// | |
// Main Loop | |
/////////////////////////// | |
void loop() { | |
// IF hazardMode is enabled, | |
// AND no buttons are being pressed, | |
// THEN do another cycle of hazardMode | |
if (hazardMode == 1) { | |
hazard(); | |
} | |
// IF left button is pressed, | |
// THEN listen and respond. | |
if (digitalRead(leftButton) == LOW) { | |
// Listen for additional input until button is released. | |
while(digitalRead(leftButton) == LOW) { | |
// IF other signal is detected, | |
// THEN toggle hazard mode. | |
if (digitalRead(rightButton) == LOW) { | |
hazardMode = 1 - hazardMode; | |
if (hazardMode == 0) { | |
hazardModeJustDisabled = 1; | |
} | |
return; | |
} | |
} | |
// IF blink cycle is active | |
// THEN reset and end it prematurely | |
if (leftCounter < RESET) { | |
leftCounter = RESET; | |
return; | |
} else { | |
// Trigger blinker once button is released | |
// with no other input detected. | |
blink(left, leftHand); | |
} | |
} | |
// IF right button is pressed, | |
// THEN listen and respond. | |
if (digitalRead(rightButton) == LOW) { | |
// Listen for additional input until button is released. | |
while(digitalRead(rightButton) == LOW) { | |
// IF other signal is detected, | |
// THEN toggle hazard mode. | |
if (digitalRead(leftButton) == LOW) { | |
hazardMode = 1 - hazardMode; | |
if (hazardMode == 0) { | |
hazardModeJustDisabled = 1; | |
} | |
return; | |
} | |
} | |
// IF blink cycle is active | |
// THEN reset and end it prematurely | |
if (rightCounter < RESET) { | |
rightCounter = RESET; | |
return; | |
} else { | |
// Trigger blinker once button is released | |
// with no other input detected. | |
blink(right, rightHand); | |
} | |
} | |
// IF leftCounter is not at default | |
// THEN trigger a blink cycle. | |
if (leftCounter != RESET) { | |
blink(left, leftHand); | |
} | |
// IF rightCounter is not at default | |
// THEN trigger a blink cycle. | |
if (rightCounter != RESET) { | |
blink(right, rightHand); | |
} | |
} | |
/////////////////////////// | |
// Blink | |
// | |
// Runs one full cycle of the blinking pattern on the specified side. | |
// Requires a blinker side and hand signal as input. | |
/////////////////////////// | |
void blink(int blinker, int hand) { | |
int x; | |
// IF hazard mode is enabled, | |
// OR hazardMode was disabled last cycle, | |
// THEN do nothing. | |
if (hazardMode == 1 || hazardModeJustDisabled == 1) { | |
hazardModeJustDisabled = 0; | |
return; | |
} | |
// State management | |
if (blinker == left) { | |
// Don't allow both blinkers to cycle down at the same time. | |
rightCounter = RESET; | |
// Continue with blink cycle. | |
leftCounter--; | |
// When cycle is finished, reset to default. | |
if (leftCounter <= 0) { | |
leftCounter = RESET; | |
} | |
} | |
// State management | |
if (blinker == right) { | |
// Don't allow both blinkers to cycle down at the same time. | |
leftCounter = RESET; | |
// Continue with blink cycle. | |
rightCounter--; | |
// When cycle is finished, reset to default. | |
if (rightCounter <= 0) { | |
rightCounter = RESET; | |
} | |
} | |
// Enable indicator light for driver. | |
digitalWrite(hand, HIGH); | |
// Fade in blinker. | |
for (x = 0; x <= 255; x += 6) { | |
analogWrite(blinker, x); | |
delay(2); | |
} | |
// Blink rapidly a few times | |
digitalWrite(blinker, HIGH); | |
delay(100); | |
digitalWrite(blinker, LOW); | |
delay(75); | |
digitalWrite(blinker, HIGH); | |
delay(100); | |
digitalWrite(blinker, LOW); | |
delay(75); | |
digitalWrite(blinker, HIGH); | |
delay(100); | |
digitalWrite(blinker, LOW); | |
delay(75); | |
digitalWrite(blinker, HIGH); | |
delay(100); | |
digitalWrite(blinker, LOW); | |
delay(75); | |
digitalWrite(blinker, HIGH); | |
delay(100); | |
// Fade out blinker. | |
for (x = 255; x >= 0; x--) { | |
analogWrite(blinker, x); | |
delay(3); | |
} | |
// Blinker off completely. | |
digitalWrite(blinker, LOW); | |
// Disable indicator light for driver. | |
digitalWrite(hand, LOW); | |
// Pause before continuing. | |
delay(250); | |
} | |
/////////////////////////// | |
// Hazard | |
// | |
// Runs one cycle of the hazard blinking pattern on both sides of the jacket. | |
/////////////////////////// | |
void hazard() { | |
hazardMode = 1; | |
leftCounter = RESET; | |
rightCounter = RESET; | |
digitalWrite(left, HIGH); | |
digitalWrite(right, HIGH); | |
digitalWrite(leftHand, HIGH); | |
digitalWrite(rightHand, HIGH); | |
// Check for interrupt while lights are on | |
delay(300); | |
if (digitalRead(leftButton) == LOW || digitalRead(rightButton) == LOW) { | |
hazardMode = 0; | |
hazardModeJustDisabled = 1; | |
} | |
delay(300); | |
digitalWrite(left, LOW); | |
digitalWrite(right, LOW); | |
digitalWrite(leftHand, LOW); | |
digitalWrite(rightHand, LOW); | |
delay(400); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment