Greetings,
I could really use some advice to tweak this code to work exactly how I need it. The core of the code was created by someone else so its a bit beyond my knowledge to tweak it exactly.
Currently it requires a serial keyboard input to select a mode of operation for the Indicators (blinking LEDS) )function and I am trying to replace this with a randomized generator that changes the mode automatically every few seconds.
In the Indicators function (line 104) I have replaced the first line that takes the serial input with a simple switch statement that looks at Indicator_Mode and in main I periodically select a random Indicator_Mode and the switch statement in Indicators should change the Mode accordingly.
The result of my changes has failed and the indicators do not flash as expected they only stay on.
Any help would be really appreciated. thanks heaps!
/* BLOCK COMMENT
ATTENTION: This Sketch contains elements of C++.
https://www.learncpp.com/cpp-tutorial/
https://forum.arduino.cc/t/model-car-led-lighting-control-help-please/918210
*/
#define ProjectName "Model car LED lighting"
#include <FastLED.h>
#define LED_PIN 2
#define NUM_LEDS 2
#define BRIGHTNESS 200
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
#define UPDATES_PER_SECOND 100
//Input Switches
//#define Door_switch
#define Door_switch 11 //12
#define Trunk_switch 3 //11
//WS2812B LEDs x2
#define Interior 2
// Engine LEDs
#define REDLED_1 9
#define REDLED_2 8
#define REDLED_3 6
#define REDLED_4 7
#define REDLED_5 5
#define REDLED_6 4
//byte pins[6] = {9,8,6,7,5,4};
#define Headlights 10 //PWM
#define Brake_Lights 13
int Door_State = 0;
int Trunk_State = 0;
int HeadLight_State = 0;
int Indicator_Mode = 0;
unsigned long previousMillis = 0; // will store last time Engine LED was updated
unsigned long Headlight_previousMillis = 0; // will store last time LED was updated
unsigned long Indicator_previousMillis = 0; // will store last time LED was updated
unsigned long Indicator_Flash_previousMillis = 0; // will store last time LED was updated
const long engine_RPM_interval = 20; // interval at which to spin red engine LEDs
const long Headlight_interval = 2000; // interval at which to change Headlight state
const long Indicator_interval = 5000; // interval at which to change Indicator mode
const long Indicator_Flash_interval = 500; // interval at which to change Indicator state
byte pins[6] = {REDLED_6,REDLED_5,REDLED_4,REDLED_3,REDLED_2,REDLED_1};
// hardware and timer settings
constexpr byte Front_Left_Indicator {A0}; // portPin o---|220|---|LED|---GND
constexpr byte Rear_Left_Indicator1 {A1}; // portPin o---|220|---|LED|---GND
constexpr byte Rear_Left_Indicator2 {A2}; // portPin o---|220|---|LED|---GND
constexpr byte Front_Right_Indicator {A3}; // portPin o---|220|---|LED|---GND
constexpr byte Rear_Right_Indicator1 {A4}; // portPin o---|220|---|LED|---GND
constexpr byte Rear_Right_Indicator2 {A5}; // portPin o---|220|---|LED|---GND
constexpr unsigned long BlinkDuration {400}; // times in msec
constexpr unsigned long TestDuration {250}; // times in msec
// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
struct TIMER { // has the following members
unsigned long duration; // memory for interval time
bool repeat_; // control for blinking
bool control_; // control for start/stop
unsigned long stamp; // memory for actual time
};
struct FLASHER {
TIMER timer;
byte indicators[3];
} flasher [] {
{BlinkDuration, true, true, 0, {Front_Left_Indicator, Rear_Left_Indicator1, Rear_Left_Indicator2}},
{BlinkDuration, true, true, 0, {Front_Right_Indicator, Rear_Right_Indicator1, Rear_Right_Indicator2}},
};
// ------------------ USER FUNCTIONS ---------------
void startTimer(TIMER &timer) {
timer.control_ = true;
timer.stamp = currentTime;
}
void stoppTimer(TIMER &timer) {
timer.control_ = false;
}
bool checkTimer(TIMER & time_) { // generic time handler using TIME struct
if (currentTime - time_.stamp >= time_.duration && time_.control_) { // the mother of all timers
if (time_.repeat_) time_.stamp = currentTime;
else time_.control_ = false;
return true;
} else return false;
}
enum {Left, Right, All, Off};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Indicators() {
//switch ((Serial.read() & 0xf) - 1) { // use this line for keyboard control of indicators over serial...
switch (Indicator_Mode) {
case 1:
for (auto &flash : flasher) for (auto indicator : flash.indicators) digitalWrite(indicator, LOW);
for (auto indicator : flasher[Left].indicators) digitalWrite(indicator, HIGH);
startTimer(flasher[Left].timer);
stoppTimer(flasher[Right].timer);
break;
case 2:
for (auto &flash : flasher) for (auto indicator : flash.indicators) digitalWrite(indicator, LOW);
for (auto indicator : flasher[Right].indicators) digitalWrite(indicator, HIGH);
stoppTimer(flasher[Left].timer);
startTimer(flasher[Right].timer);
break;
case 3:
for (auto &flash : flasher) for (auto indicator : flash.indicators) digitalWrite(indicator, LOW);
for (auto indicator : flasher[Left].indicators) digitalWrite(indicator, HIGH);
for (auto indicator : flasher[Right].indicators) digitalWrite(indicator, HIGH);
startTimer(flasher[Left].timer);
startTimer(flasher[Right].timer);
break;
case 4:
for (auto &flash : flasher) for (auto indicator : flash.indicators) digitalWrite(indicator, LOW);
stoppTimer(flasher[Left].timer);
stoppTimer(flasher[Right].timer);
break;
}
}
// ------------------------------------------------
void setup() {
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness(BRIGHTNESS);
pinMode(Door_switch, INPUT_PULLUP);
pinMode(Trunk_switch, INPUT_PULLUP);
pinMode(REDLED_1, OUTPUT);
pinMode(REDLED_2, OUTPUT);
pinMode(REDLED_3, OUTPUT);
pinMode(REDLED_4, OUTPUT);
pinMode(REDLED_5, OUTPUT);
pinMode(REDLED_6, OUTPUT);
pinMode(Headlights, OUTPUT);
pinMode(Brake_Lights, OUTPUT);
Serial.begin(9600);
Serial.println(F("."));
Serial.print(F("File : ")), Serial.println(__FILE__);
Serial.print(F("Date : ")), Serial.println(__DATE__);
Serial.print(F("Project: ")), Serial.println(ProjectName);
//pinMode (LED_BUILTIN, OUTPUT); // used as heartbeat indicator
for (auto &flash : flasher) for (auto indicator : flash.indicators) pinMode(indicator, OUTPUT);
Serial.println(F("check flash lights"));
for (auto &flash : flasher) for (auto indicator : flash.indicators) digitalWrite(indicator, HIGH), delay(TestDuration);
for (auto &flash : flasher) for (auto indicator : flash.indicators) digitalWrite(indicator, LOW), delay(TestDuration);
Serial.println(F("[1] flash LEFT - [2] flash RIGHT - [3] flash ALL - [4] flash OFF"));
}
void loop () {
unsigned long currentMillis = millis();
currentTime = millis();
// Keep engine LEDs spinning if trunk open
if (currentMillis - previousMillis >= engine_RPM_interval){
previousMillis = currentMillis;
if (Trunk_State == LOW){
Cycle_Engine_Leds();
}
if (Trunk_State == HIGH){
Turn_Off_Engine_Leds();
}
}
// Choose Headlight State
if (currentMillis - Headlight_previousMillis >= Headlight_interval){
Headlight_previousMillis = currentMillis;
HeadLight_State = random(1,4);
//Serial.print("Headlight State = ");
//Serial.println(HeadLight_State);
}
HeadLights(); /////////////////////////////////////////////
// Choose Indicator State
if (currentMillis - Indicator_previousMillis >= Indicator_interval){
Indicator_previousMillis = currentMillis;
Indicator_Mode = random(1,5);
Serial.print("Indicator Mode = ");
Serial.println(Indicator_Mode);
}
//if (Serial.available() > 0) Indicators();
Indicators();
for (auto &flash : flasher) {
if (checkTimer(flash.timer))
for (auto indicator : flash.indicators) digitalWrite(indicator, !digitalRead(indicator));
}
// Read input switch to see if a car door is open
Door_State = digitalRead(Door_switch);
//Serial.print("Door State = ");
//Serial.println(Door_State);
// Read input switch to see if a Trunk lid is open
Trunk_State = digitalRead(Trunk_switch);
//Serial.print("Trunk State = ");
//Serial.println(Trunk_State);
InteriorLights();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Cycle_Engine_Leds(){
static byte led = 0;
digitalWrite(pins[led], LOW);
if (++led >= sizeof(pins)/sizeof(pins[0])) led = 0;{
digitalWrite(pins[led], HIGH);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Turn_Off_Engine_Leds(){
static byte led = 0;
digitalWrite(pins[led], LOW);
if (++led >= sizeof(pins)/sizeof(pins[0])) led = 0;{
digitalWrite(pins[led], LOW);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void InteriorLights(){
if (Door_State == LOW){
for( int i = 0; i < NUM_LEDS; ++i){
leds[i] = CRGB::Red;
FastLED.show();
}
}
if (Door_State == HIGH){
for( int i = 0; i < NUM_LEDS; ++i){
leds[i] = CRGB::Black;
FastLED.show();
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void HeadLights(){
if (HeadLight_State == 3){
analogWrite(Headlights, 255); // turn the LED on (HIGH is the voltage level)
digitalWrite(Brake_Lights, HIGH);
}
if (HeadLight_State == 2){
analogWrite(Headlights, 50); // turn the LED on (HIGH is the voltage level)
digitalWrite(Brake_Lights, HIGH);
}
if (HeadLight_State == 1){
analogWrite(Headlights, 0); // turn the LED on (HIGH is the voltage level)
digitalWrite(Brake_Lights, LOW);
}
}