/* Sequential taillight turn signal and brake light and DRL
This project is to get a sequential indicator light in combination with a brake light.
I want the circuit to be small so I opted for the ATtiny84.
The programm however is build with an Arduino Nano.
The indicator lights are sequential from all on to all off.
When the brake is hit, all led's turn on.
When the brake is hit and one of the indictor switches is triggered, one side stay's on
and the other is a sequential running turn light.
Work to do;
one of the led's on each side should blink in a in a preset morse code message when no
indicator is used and no brake is applied -> use of an interrupt or no delay morse code?
LICENCE
Copyright November 2022 Robert de Beer
Licensed under the Apache License, Version 2.0 ( the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For an AtTiny84:
program uses 2598 ( 31%) bytes program storage space
variables use 52 ( 10%) bytes of dynamic memory
*/
#define dbounceMs 10 // debounce time 5+ ms is usual enough
#define numBtns sizeof( btnPin)
#define numLeds sizeof( ledPin)
byte lia;
byte ria;
byte liri;
byte brkeState = 0;
byte leftState = 0;
byte rghtState = 0;
//byte currBrkeState = 0; // assume switch open because of input_pullup
//byte currLeftState = 0; // assume switch open because of input_pullup
//byte currRghtState = 0; // assume switch open because of input_pullup
byte lastBrkeState = 0; // assume switch open because of input_pullup
byte lastLeftState = 0; // assume switch open because of input_pullup
byte lastRghtState = 0; // assume switch open because of input_pullup
byte btnPin[] = {6, 7, 8}; // array that holds the button port numbers [NANO]
byte ledPin[] = {4, 3, 2, 10, 11, 12}; // array that holds the led port numbers [NANO]
//byte btnPin[] = {8, 9, 10}; // button port numbers array [ATtiny84] Brk, Lind, Rind
//byte ledPin[] = {4, 3, 2, 5, 6, 7}; // led port numbers array [ATtiny84] L(L1, L2, L3), R(L1, L2, L3)
byte pinNum;
byte nextStep;
byte state;
byte turnInd;
static byte stepInterval = 120;
unsigned long currMs;
unsigned long nextMs;
unsigned long waitMs;
unsigned long brkePressMs;
unsigned long rghtPressMs;
unsigned long leftPressMs;
void setup() {
// Serial.begin( 115200);
for( byte i = 0; i < numBtns; i++){
pinMode( btnPin[i], INPUT_PULLUP);
}
for( byte i = 0; i < numLeds; i++) {
pinMode( ledPin[i], OUTPUT);
pinMode( 14, OUTPUT);
pinMode( 15, OUTPUT);
digitalWrite( ledPin[i], 1);
digitalWrite( 14, 1);
digitalWrite( 15, 1);
}
for( byte j = 0; j < 3; j++){ // repeat 3 times
for( byte i = 0; i < numLeds / 2; i++) { // all leds on from center to edge
digitalWrite( ledPin[i + lia], 0);
digitalWrite( ledPin[i + ria], 0);
digitalWrite( 14,0);
digitalWrite( 15,0);
delay( stepInterval / 2);
}
delay( stepInterval);
for( byte i = 0; i < numLeds / 2; i++) { // all leds off from center to edge
digitalWrite( ledPin[i + lia], 1);
digitalWrite( ledPin[i + ria], 1);
digitalWrite( 14,1);
digitalWrite( 15,1);
delay( stepInterval / 2);
}
delay( stepInterval);
}
}
void loop() {
currMs = millis();
byte brkeReading = digitalRead( btnPin[0]);
byte leftReading = digitalRead( btnPin[1]);
byte rghtReading = digitalRead( btnPin[2]);
if( brkeReading == 1 && leftReading == 1 && rghtReading == 1) {
state = 0;
}
if ( brkeReading != lastBrkeState) { // has it changed?
brkePressMs = currMs; // reset the deboncing timer
}
if (( currMs - brkePressMs) > dbounceMs) { // debounce
if ( brkeState != lastBrkeState) { // has it changed?
brkeState = brkeReading;
if ( brkeState == LOW) { // only set flag if the new state is LOW
state = 1;
}
}
}
lastBrkeState = brkeReading;
if (leftReading != lastLeftState) {
leftPressMs = currMs;
}
if (( currMs - leftPressMs) > dbounceMs) {
if ( leftState != lastLeftState) {
leftState = leftReading;
if (leftState == LOW) {
state = 2;
liri = 0;
}
}
}
lastLeftState = leftReading;
if (rghtReading != lastRghtState) {
rghtPressMs = currMs;
}
if (( currMs - rghtPressMs) > dbounceMs) {
if ( rghtState != lastRghtState) {
rghtState = rghtReading;
if (rghtState == LOW) {
state = 3;
liri = 3;
}
}
}
lastRghtState = rghtReading;
switch( state){
case 0: // daytime running lights
drlSequence( ledPin[1], ledPin[4]);
break;
case 1: // brake lights left right
// statements
break;
case 2: // turn signal left
// statements
break;
case 3: // turn signal right
// statements
break;
case 4: // brake AND left turn signal
// statements
break;
case 5: // brake AND right turn signal
// statements
break;
default:
state = 0;
break;
}
}
void drlSequence( byte drl1, byte drl2) {
if( currMs > nextMs) {
digitalWrite(drl1, !digitalRead( drl1));
digitalWrite(drl2, digitalRead( drl1));
waitMs = random( 40, 240);
nextMs = currMs + waitMs;
}
}