Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- TRIKE LIGHTS for Peacock Groove Cargo Trike. www.facebook.com/peacockgroove/
- Code by Steve McCluskey and Karl Stoerzinger
- steve.a.mccluskey@gmail.com
- kstoerz@gmail.com
- This sketch flashes 13 LEDs and has 3 digital inputs for mode and L/R turn signals.
- Revision History:
- V1.0 : Prototype release. 02/14/16
- V1.1 : Changed led0next/led1next/etc to ledNext[7] array. 02/15/16
- V1.2 : Changed led0p/led1p/etc to ledP[7] array. Karl tweaked hazard() to only blink corners and make the sides and center reds stay on. Mode 3 is now
- skipped due to lack of dedicated brake lever switch. 02/16/15
- Modes:
- ----------
- Switch off : all lights off.
- Switch on : steady on (default).
- Off/on quick 1 : normal amber, normal red.
- Off/on quick 2 : normal amber, brake red.
- Off/on quick 3 : hazards.
- Off/on quick 4 : back to steady on.
- Turn signals are always active and work with current pattern.
- Hardware:
- Using TIP102/TIP1206 NPN transistors to switch the ground of the 12v LED fixtures.
- - 1k resistor from digitial pin to left leg of TIP102.
- - middle leg of TIP102 to negative wire of LED (white, in this case!).
- - right leg of TIP102 to ground of 12v power source.
- - tie 12v ground to 5v ground!!!
- - +12v to positive wires of all LED fixtures.
- - 5v supplied to power microcontroller via appropriate LM7805 vreg circuit, etc.
- - put a suitable fuse on the 12v wire(s) going out to lights!
- ARRAY SIZES:
- https://arduino.land/FAQ/content/6/29/en/how-to-get-the-size-of-an-array.html
- number of elements in array (kludged because there is no straightforward array length function!)
- unsigned int led0el = sizeof( ledAr[0] ) / sizeof( uint16_t );
- unsigned int led1el = sizeof( ledAr[1] ) / sizeof( uint16_t );
- unsigned int led2el = sizeof( ledAr[2] ) / sizeof( uint16_t );
- Not currently used.
- Some sample patterns by Karl:
- {40,40,40,40,40,40,40,40,300,400,0}; 4 short pulses, 1 long
- {100,50,100,50,100,50,50,100,50,100,50,100,0}; alternating duty cycle (needs work)
- {10,10,20,20,30,30,40,40,50,50,60,60,70,70,80,80,90,90,100,100,0}; ramp down fast to slow (needs work)
- {50,50,50,50,50,50,50,50,50,50,50,100,100,50,100,50,100,100,0}; alternating fast and slow strobes (pretty good)
- {50,50,50,50,50,50,50,50,50,550,0} and {50,550,50,50,50,50,50,50,50,50,0} kind of alternating pairs of strobes
- {25,100,50,100,75,100,100,100,75,100,50,100,25,100,0} constant off time, ramping on time
- {50,200,50,150,50,100,50,50,50,100,50,150,50,200,50,250,0} constant on time, ramping off time
- {370,340,0} turn signal
- {20,40,20,40,20,200,20,40,20,40,20,200,20,40,20,40,20,500,0} three fast strobes and a pause (pretty good)
- On/off logic:
- 0%2 = 0
- 1%2 = 1
- 2%2 = 0
- 3%2 = 1
- element 0 1 2 3
- value 20 30 10 50
- meaning on for 20ms off for 30 on for 10 off for 50
- LEDs on trike are arranged as follows:
- Y0 Y0
- Y1 Y1
- Y2 Y2
- Y3 Y3
- R RRR R
- 0 123 4
- Output pin layout as follows:
- 0 : Serial RX (NC).
- 1 : Serial TX (NC).
- 2 : Amber Left 0 (Front facing).
- 3 ~: Amber Left 1 (Side facing).
- 4 : Amber Left 2 (Side facing).
- 5 ~: Red 0 (Rear facing).
- 6 ~: Red 1 (Rear facing).
- 7 : Amber Left 3 (Side facing).
- 8 : Amber Right 0 (Front facing).
- 9 ~: Red 2 (Rear facing).
- 10~: Red 3 (Rear facing).
- 11~: Red 4 (Rear facing).
- 12 : Amber Right 1 (Side facing).
- 13 : Amber Right 2 (Side facing).
- A5 : Amber Right 3 (Side facing).
- Inputs:
- A0 : NC.
- A1 : Ground.
- A2 : Mode.
- A3 : Left turn.
- A4 : Right turn.
- */
- // Pin declarations:
- #define amberL0 2
- #define amberL1 3
- #define amberL2 4
- #define amberL3 7
- #define amberR0 8
- #define amberR1 12
- #define amberR2 13
- #define amberR3 A5
- #define red0 5
- #define red1 6
- #define red2 9
- #define red3 10
- #define red4 11
- #define inputGnd A1
- #define modeSwitch A2
- #define lturn A3
- #define rturn A4
- #define modeSwitchTime 500 // Change to make switching modes easier or harder.
- // Current flash patterns:
- uint16_t ledAr[7][11] = {{40, 40, 40, 40, 40, 40, 40, 40, 300, 400, 0},
- {42, 42, 42, 42, 42, 42, 42, 42, 300, 400, 0},
- {44, 44, 44, 44, 44, 44, 44, 44, 300, 400, 0},
- {46, 46, 46, 46, 46, 46, 46, 46, 300, 400, 0},
- {48, 48, 48, 48, 48, 48, 48, 48, 300, 400, 0},
- {50, 50, 50, 50, 50, 50, 50, 50, 300, 400, 0},
- {54, 54, 54, 54, 54, 54, 54, 54, 400, 500, 0}};
- // Flash pattern array position pointers:
- uint8_t ledP [7] = {0, 0, 0, 0, 0, 0, 0};
- // Turn signal pattern and its position pointer:
- uint16_t turn [3] = {370, 340, 0};
- uint8_t turnP = 0;
- // Hazard pattern and its position pointer:
- uint16_t hazard[3] = {550, 400, 0};
- uint8_t hazP = 0;
- //uint8_t chaseP = 0; // Chase position.
- byte currentMode = 1;
- bool timerReset = false;
- bool modeChanged = true;
- bool modeSwitchOn = false;
- bool leftTurnOn = false;
- bool rightTurnOn = false;
- unsigned long mls = 0; // Value in which to store millis() for multiple rapid comparisons.
- unsigned long ledNext[7] = {0, 0, 0, 0, 0, 0, 0}; // Next millis() value at which LED state will change.
- unsigned long turnNext = 0; // Next turn time.
- unsigned long hazNext = 0; // Next hazard time.
- unsigned long modeTime = 0; // How long mode switch has been off.
- //unsigned long chaseNext = 0;
- void setup() {
- pinMode (amberL0, OUTPUT);
- pinMode (amberL1, OUTPUT);
- pinMode (amberL2, OUTPUT);
- pinMode (amberL3, OUTPUT);
- pinMode (amberR0, OUTPUT);
- pinMode (amberR1, OUTPUT);
- pinMode (amberR2, OUTPUT);
- pinMode (amberR3, OUTPUT);
- pinMode (red0, OUTPUT);
- pinMode (red1, OUTPUT);
- pinMode (red2, OUTPUT);
- pinMode (red3, OUTPUT);
- pinMode (red4, OUTPUT);
- pinMode (inputGnd, OUTPUT);
- digitalWrite(inputGnd, LOW); // Using as ground pin for now.
- pinMode (modeSwitch, INPUT_PULLUP);
- pinMode (lturn, INPUT_PULLUP);
- pinMode (rturn, INPUT_PULLUP);
- } //end setup().
- void loop() {
- mls = millis(); // Store millis() in a variable for many rapid comparisons.
- // Read inputs:
- if (digitalRead(modeSwitch) == LOW) { // Input defaults to HIGH. Switch on pulls it low.
- modeSwitchOn = true;
- } // end if.
- else {
- modeSwitchOn = false;
- }
- if (digitalRead(lturn) == LOW) {
- leftTurnOn = true;
- } // end if.
- else {
- leftTurnOn = false;
- } // end else.
- if (digitalRead(rturn) == LOW) {
- rightTurnOn = true;
- } // end if.
- else {
- rightTurnOn = false;
- } // end else.
- // Mode switch ON, no turn signals:
- if (modeSwitchOn && !leftTurnOn && !rightTurnOn) {
- timerReset = false; // Set to false every time switch turns on.
- if (mls - modeTime > modeSwitchTime) { // Longer than timeout?
- if (!modeChanged) { // Has mode been changed?
- currentMode = 1; // Reset back to 1.
- modeChanged = true; // Mode has been changed.
- } // end if.
- } // end if.
- else { // Shorter than timeout.
- if (!modeChanged) { // Has mode been changed?
- currentMode ++; // Next mode.
- if (currentMode > 4) { // Limit on number of modes.
- currentMode = 1; // Reset back to 1.
- } // end if.
- modeChanged = true; // Mode has been changed.
- } // end if.
- } // end else.
- switch (currentMode) { // Displays pattern.
- case 1:
- steadyOn();
- break; // end case 1.
- case 2:
- normalAmber();
- normalRed();
- break; // end case 2.
- case 3:
- currentMode = 4; // Skip past brake light mode for now due to lack of dedicated hardware. -Karl
- //normalAmber();
- //brakeRed();
- break; // end case 3.
- case 4:
- hazards();
- break; // end case 4.
- default:
- break; // end case default.
- } // end switch.
- } // end if switch ON.
- // Mode switch off, no turn signals:
- else if (!modeSwitchOn && !leftTurnOn && !rightTurnOn) {
- allOff();
- modeChanged = false;
- if (!timerReset) { // Only resets timer once per switch off.
- modeTime = mls;
- timerReset = true;
- } // end if.
- } // end else.
- // Mode switch off, left turn ON:
- else if (leftTurnOn && !modeSwitchOn && !rightTurnOn) {
- leftTurn();
- } // end if.
- // Mode switch off, right turn ON:
- else if (rightTurnOn && !modeSwitchOn && !leftTurnOn) {
- rightTurn();
- }
- // Mode switch ON, left turn ON:
- else if (modeSwitchOn && leftTurnOn && !rightTurnOn) {
- leftTurn();
- } // end else if.
- // Mode switch ON, right turn ON:
- else if (modeSwitchOn && rightTurnOn && !leftTurnOn) {
- rightTurn();
- } // end else if.
- delay(2);
- } // end loop().
- void normalAmber() {
- // Fronts L/R:
- if (mls >= ledNext[0]) { // Time to do something?
- if (ledAr[0][ledP[0]] == 0) { // Reached null value of array? Return to beginning.
- ledP[0] = 0;
- } // end if.
- digitalWrite(amberL0, ((ledP[0] + 1) % 2)); // %2 is modulus of 2. +1 inverts the result so first element (0) creates 1 for on.
- digitalWrite(amberR0, ((ledP[0] + 1) % 2));
- ledNext[0] = mls + ledAr[0][ledP[0]]; // Next time to do something.
- ledP[0] ++; // Increment pointer.
- } // end if.
- // Front side L/R:
- if (mls >= ledNext[1]) {
- if (ledAr[1][ledP[1]] == 0) {
- ledP[1] = 0;
- } // end if.
- digitalWrite(amberL1, ((ledP[1] + 1) % 2));
- digitalWrite(amberR1, ((ledP[1] + 1) % 2));
- ledNext[1] = mls + ledAr[1][ledP[1]];
- ledP[1] ++;
- } // end if.
- // Mid side L/R:
- if (mls >= ledNext[2]) {
- if (ledAr[2][ledP[2]] == 0) {
- ledP[2] = 0;
- } // end if.
- digitalWrite(amberL2, ((ledP[2] + 1) % 2));
- digitalWrite(amberR2, ((ledP[2] + 1) % 2));
- ledNext[2] = mls + ledAr[2][ledP[2]];
- ledP[2] ++;
- } // end if.
- // Rear side L/R.
- if (mls >= ledNext[3]) {
- if (ledAr[3][ledP[3]] == 0) {
- ledP[3] = 0;
- } // end if.
- digitalWrite(amberL3, ((ledP[3] + 1) % 2));
- digitalWrite(amberR3, ((ledP[3] + 1) % 2));
- ledNext[3] = mls + ledAr[3][ledP[3]];
- ledP[3] ++;
- } // end if.
- } //end normalAmber().
- void normalRed() {
- // Outer reds:
- if (mls >= ledNext[4]) {
- if (ledAr[4][ledP[4]] == 0) {
- ledP[4] = 0;
- } // end if.
- digitalWrite(red0, ((ledP[4] + 1) % 2));
- digitalWrite(red4, ((ledP[4] + 1) % 2));
- ledNext[4] = mls + ledAr[4][ledP[4]];
- ledP[4] ++;
- } // end if.
- // Center red:
- if (mls >= ledNext[5]) {
- if (ledAr[5][ledP[5]] == 0) {
- ledP[5] = 0;
- } // end if.
- digitalWrite(red2, ((ledP[5] + 1) % 2));
- ledNext[5] = mls + ledAr[5][ledP[5]];
- ledP[5] ++;
- } // end if.
- // Mid reds:
- if (mls >= ledNext[6]) {
- if (ledAr[6][ledP[6]] == 0) {
- ledP[6] = 0;
- } // end if.
- digitalWrite(red3, ((ledP[6] + 1) % 2));
- digitalWrite(red1, ((ledP[6] + 1) % 2));
- ledNext[6] = mls + ledAr[6][ledP[6]];
- ledP[6] ++;
- } // end if.
- } // end normalRed().
- void brakeRed() {
- analogWrite(red0, 100);
- analogWrite(red1, 150);
- analogWrite(red2, 255);
- analogWrite(red3, 150);
- analogWrite(red4, 100);
- } //end brakeRed();
- void leftTurn() {
- if (modeSwitchOn) {
- switch (currentMode) {
- case 1:
- break; // end case 1.
- case 2 ... 3: // Only do this if in normalAmber() and switch is on.
- if (mls >= ledNext[0]) {
- if (ledAr[0][ledP[0]] == 0) {
- ledP[0] = 0;
- } // end if.
- digitalWrite(amberR0, ((ledP[0] + 1) % 2));
- ledNext[0] = mls + ledAr[0][ledP[0]];
- ledP[0] ++;
- } // end if.
- if (mls >= ledNext[1]) {
- if (ledAr[1][ledP[1]] == 0) {
- ledP[1] = 0;
- } // end if.
- digitalWrite(amberR1, ((ledP[1] + 1) % 2));
- ledNext[1] = mls + ledAr[1][ledP[1]];
- ledP[1] ++;
- } // end if.
- if (mls >= ledNext[2]) {
- if (ledAr[2][ledP[2]] == 0) {
- ledP[2] = 0;
- } // end if.
- digitalWrite(amberR2, ((ledP[2] + 1) % 2));
- ledNext[2] = mls + ledAr[2][ledP[2]];
- ledP[2] ++;
- } // end if.
- if (mls >= ledNext[3]) {
- if (ledAr[3][ledP[3]] == 0) {
- ledP[3] = 0;
- } // end if.
- digitalWrite(amberR3, ((ledP[3] + 1) % 2));
- ledNext[3] = mls + ledAr[3][ledP[3]];
- ledP[3] ++;
- } // end if.
- break; // end case 2 or 3.
- case 4: // If in hazard mode, turn off other lights.
- digitalWrite(amberR0, LOW);
- digitalWrite(amberR1, LOW);
- digitalWrite(amberR2, LOW);
- digitalWrite(amberR3, LOW);
- digitalWrite(red4, LOW);
- digitalWrite(red3, LOW);
- digitalWrite(red2, LOW);
- break; // end case 4.
- default:
- break; // end case default.
- } // end switch
- } // end if modeSwitchOn.
- else { // Turn off other lights if mode switch off.
- digitalWrite(amberR0, LOW);
- digitalWrite(amberR1, LOW);
- digitalWrite(amberR2, LOW);
- digitalWrite(amberR3, LOW);
- digitalWrite(red2, LOW);
- digitalWrite(red3, LOW);
- digitalWrite(red4, LOW);
- } // end else.
- // Calls turn signal array pattern:
- if (mls >= turnNext) {
- if (turn[turnP] == 0) {
- turnP = 0;
- } // end if.
- digitalWrite(amberL0, ((turnP + 1) % 2));
- digitalWrite(amberL1, ((turnP + 1) % 2));
- digitalWrite(amberL2, ((turnP + 1) % 2));
- digitalWrite(amberL3, ((turnP + 1) % 2));
- digitalWrite(red0, ((turnP + 1) % 2));
- digitalWrite(red1, ((turnP + 1) % 2));
- if (modeSwitchOn && currentMode != 4) { // Ignore hazard mode.
- analogWrite (red2, 128);
- analogWrite (red3, 40);
- analogWrite (red4, 10);
- } // end if.
- else {
- digitalWrite(red2, LOW);
- digitalWrite(red3, LOW);
- digitalWrite(red4, LOW);
- } // end else.
- turnNext = mls + turn[turnP];
- turnP ++;
- } // end if.
- } // end leftTurn().
- void rightTurn() {
- if (modeSwitchOn) {
- switch (currentMode) {
- case 1:
- break; // end case 1.
- case 2 ... 3:
- if (mls >= ledNext[0]) {
- if (ledAr[0][ledP[0]] == 0) {
- ledP[0] = 0;
- } // end if.
- digitalWrite(amberL0, ((ledP[0] + 1) % 2));
- ledNext[0] = mls + ledAr[0][ledP[0]];
- ledP[0] ++;
- } // end if.
- if (mls >= ledNext[1]) {
- if (ledAr[1][ledP[1]] == 0) {
- ledP[1] = 0;
- } // end if.
- digitalWrite(amberL1, ((ledP[1] + 1) % 2));
- ledNext[1] = mls + ledAr[1][ledP[1]];
- ledP[1] ++;
- } // end if.
- if (mls >= ledNext[2]) {
- if (ledAr[2][ledP[2]] == 0) {
- ledP[2] = 0;
- } // end if.
- digitalWrite(amberL2, ((ledP[2] + 1) % 2));
- ledNext[2] = mls + ledAr[2][ledP[2]];
- ledP[2] ++;
- } // end if.
- if (mls >= ledNext[3]) {
- if (ledAr[3][ledP[3]] == 0) {
- ledP[3] = 0;
- } // end if.
- digitalWrite(amberL3, ((ledP[3] + 1) % 2));
- ledNext[3] = mls + ledAr[3][ledP[3]];
- ledP[3] ++;
- } // end if.
- break; // end case 2 or 3.
- case 4:
- digitalWrite(amberL0, LOW);
- digitalWrite(amberL1, LOW);
- digitalWrite(amberL2, LOW);
- digitalWrite(amberL3, LOW);
- digitalWrite(red0, LOW);
- digitalWrite(red1, LOW);
- digitalWrite(red2, LOW);
- break; // end case 4.
- default:
- break; // end case default.
- } // end switch.
- } // end if modeSwitchOn.
- else {
- digitalWrite(amberL0, LOW);
- digitalWrite(amberL1, LOW);
- digitalWrite(amberL2, LOW);
- digitalWrite(amberL3, LOW);
- digitalWrite(red2, LOW);
- digitalWrite(red1, LOW);
- digitalWrite(red0, LOW);
- } // end else.
- if (mls >= turnNext) {
- if (turn[turnP] == 0) {
- turnP = 0;
- } // end if.
- digitalWrite(amberR0, ((turnP + 1) % 2));
- digitalWrite(amberR1, ((turnP + 1) % 2));
- digitalWrite(amberR2, ((turnP + 1) % 2));
- digitalWrite(amberR3, ((turnP + 1) % 2));
- digitalWrite(red3, ((turnP + 1) % 2));
- digitalWrite(red4, ((turnP + 1) % 2));
- if (modeSwitchOn && currentMode != 4) {
- analogWrite (red2, 128);
- analogWrite (red1, 40);
- analogWrite (red0, 10);
- } // end if.
- else {
- digitalWrite(red0, LOW);
- digitalWrite(red1, LOW);
- digitalWrite(red2, LOW);
- } // end else.
- turnNext = mls + turn[turnP];
- turnP ++;
- } // end if.
- } // end rightTurn().
- void steadyOn() {
- digitalWrite(amberL0, HIGH);
- digitalWrite(amberL1, HIGH);
- digitalWrite(amberL2, HIGH);
- digitalWrite(amberL3, HIGH);
- digitalWrite(amberR0, HIGH);
- digitalWrite(amberR1, HIGH);
- digitalWrite(amberR2, HIGH);
- digitalWrite(amberR3, HIGH);
- analogWrite (red0, 40);
- analogWrite (red1, 40);
- analogWrite (red2, 40);
- analogWrite (red3, 40);
- analogWrite (red4, 40);
- } // end steadyOn().
- void allOff() { // All lights off.
- for (uint8_t x = 2; x < 14; x ++) {
- digitalWrite(x, LOW);
- } // end for.
- digitalWrite(A5, LOW);
- } // end allOff().
- void hazards(){
- if (mls >= hazNext) {
- if (hazard[hazP] == 0) {
- hazP = 0;
- } // end if.
- uint8_t value = ((hazP + 1) % 2); // Only do calculation once instead of each digitalWrite.
- digitalWrite(amberL0, value); // Tweak hazards to only flash the corners of the vehicle. -Karl
- digitalWrite(amberL1, value);
- digitalWrite(amberL2, 1);
- digitalWrite(amberL3, value);
- digitalWrite(amberR0, value);
- digitalWrite(amberR1, value);
- digitalWrite(amberR2, 1);
- digitalWrite(amberR3, value);
- digitalWrite(red0, value);
- digitalWrite(red1, 1);
- digitalWrite(red2, 1);
- digitalWrite(red3, 1);
- digitalWrite(red4, value);
- hazNext = mls + hazard[hazP];
- hazP ++;
- } // end if.
- } // end hazards().
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement