Program Knight Rider sequence to respond alongside existing cases and buttons

Hi,

I previously created a program (with help from the forum), which uses cases to establish when two buttons are pushed down together in order to turn on a light sequence for a set amount of time.

Button 1 (safety button) must be held down to allow Button 2 (on button) to turn on the LED’s (UV LEDS’s) for a set amount of time. If Button 1 is released before that time lights will turn off.

However, I’m trying to programme a separate row of LED’s to perform a knight rider/chase sort of sequence but only flow in one direction. So. I have 8 LED’s in this sequence, when LED 8 is reached it starts back at 1 and so on.

I need this second LED sequence to work in conjunction with the first set of LED’s.

So, the aim is:
Button 1 (safety button) must be held down to allow Button 2 (on button) to turn on the LED’s 1 (6 UV LEDS’s) & LED’s 2 (Knight Rider/Chase sequence) for a set amount of time. If Button 1 is released before that time all lights will turn off.

I’m therefore trying to avoid the delay function.

I’ve created both programmes, and have tried to merge them also, but I can’t seem to get them to work alongside each other. I’ve included the two separate codes below.

Thank you in advance!!

// CODE 1 - INDICATOR KNIGHT RIDER/CHASE
// define output pins
int outPins[] = {A5, A4, A3, A2, A1, A0, 10, 11};

// timer
long previousMillis = 0;
static long TIMER = 200;
//
int knightLight = 0;
int knightCounter = 1;

void setup()
{
  for(int p = 0; p < 8; p++) {
    pinMode(outPins[p], OUTPUT);
  }
}

void loop() {
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > TIMER) {
    previousMillis = currentMillis;
    // reset last knight light
    digitalWrite(outPins[knightLight], LOW);
    // calc new knight light
    knightLight = knightLight + knightCounter;
    if (knightLight > 7) {
      knightLight = 0;
      knightCounter = 1;
    }
    if (knightLight < 0) {
     knightLight = 0;
     knightCounter = 1;
    }
    // set new knight light
    digitalWrite(outPins[knightLight], HIGH);
  }
}








//CODE 2 - SAFETY BUTTON, ON BUTTON & UV LED's TIMED (ALSO TURNS LED'S 2 (indicators) ON)
// timed led with on and safety button

const int safetyButtonPin = 2;       // the number of the safetybutton pin
const int onButtonPin = 3;           // the number of the onbutton pin
const int uvLEDPin1 =  4;            // the number of the UV LED pin
const int uvLEDPin2 =  5;
const int uvLEDPin3 =  6;
const int uvLEDPin4 =  7;
const int uvLEDPin5 =  8;
const int uvLEDPin6 =  9;

//indicators
const int indicatorPin1 =  A5;
const int indicatorPin2 =  A4;
const int indicatorPin3 =  A3;
const int indicatorPin4 =  A2;
const int indicatorPin5 =  A1;
const int indicatorPin6 =  A0;
const int indicatorPin7 =  10;
const int indicatorPin8 =  11;


//led
unsigned long ledWentOnAt;
int ledStaysOnFor = 3000;

//states
enum {ST_idle, ST_safe, ST_on} currentState = ST_idle;




void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
  Serial.println("setup() ... ");
  Serial.println("timed led with on and safety button");
  Serial.print("Compiler: ");
  Serial.print(__VERSION__);
  Serial.print(", Arduino IDE: ");
  Serial.println(ARDUINO);
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(__FILE__);

  pinMode(uvLEDPin1, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  pinMode(uvLEDPin2, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  pinMode(uvLEDPin3, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  pinMode(uvLEDPin4, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  pinMode(uvLEDPin5, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  pinMode(uvLEDPin6, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  
  pinMode(indicatorPin1, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  pinMode(indicatorPin2, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  pinMode(indicatorPin3, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  pinMode(indicatorPin4, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  pinMode(indicatorPin5, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  pinMode(indicatorPin6, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  pinMode(indicatorPin7, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);
  pinMode(indicatorPin8, OUTPUT);
  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);


  Serial.println("setup() done");
  Serial.println(" ");
  Serial.println("starting in state: idle");
}



void loop(){
  switch (currentState) //ST_idle, ST_safe, ST_on
  {
    case ST_idle:
      digitalWrite(uvLEDPin1, LOW);
      digitalWrite(uvLEDPin2, LOW);
      digitalWrite(uvLEDPin3, LOW);
      digitalWrite(uvLEDPin4, LOW);
      digitalWrite(uvLEDPin5, LOW);
      digitalWrite(uvLEDPin6, LOW);

      digitalWrite(indicatorPin1, LOW);
      digitalWrite(indicatorPin2, LOW);
      digitalWrite(indicatorPin3, LOW);
      digitalWrite(indicatorPin4, LOW);
      digitalWrite(indicatorPin5, LOW);
      digitalWrite(indicatorPin6, LOW);
      digitalWrite(indicatorPin7, LOW);
      digitalWrite(indicatorPin8, LOW);
      
      //wait for safety ...
      if (!digitalRead(safetyButtonPin))
      {
        Serial.println("state: safe");
        currentState = ST_safe;
      }

      break;

    case ST_safe:
      //check it's still safe...
      if (digitalRead(safetyButtonPin)) //it's not, so:
      {
        currentState = ST_idle;
        Serial.println("unsafe, returning to state: idle");
      }

      //wait for the on
      if (!digitalRead(onButtonPin))
      {
        Serial.println("state: on");
        currentState = ST_on;
        ledWentOnAt = millis(); //capture start time
        digitalWrite(uvLEDPin1, HIGH);
        digitalWrite(uvLEDPin2, HIGH);
        digitalWrite(uvLEDPin3, HIGH);
        digitalWrite(uvLEDPin4, HIGH);
        digitalWrite(uvLEDPin5, HIGH);
        digitalWrite(uvLEDPin6, HIGH);

        digitalWrite(indicatorPin1, HIGH);
        digitalWrite(indicatorPin2, HIGH);
        digitalWrite(indicatorPin3, HIGH);
        digitalWrite(indicatorPin4, HIGH);
        digitalWrite(indicatorPin5, HIGH);
        digitalWrite(indicatorPin6, HIGH);
        digitalWrite(indicatorPin7, HIGH);
        digitalWrite(indicatorPin8, HIGH);
      }

      break;

    case ST_on:
      //check it's still safe...
      if (digitalRead(safetyButtonPin)) //it's not, so:
      {
        currentState = ST_idle;
        Serial.println("unsafe, returning to state: idle");
      }
      //wait for the timer
      if (millis() - ledWentOnAt >= (unsigned long) ledStaysOnFor)
      {
        currentState = ST_idle;
        Serial.println("time up, returning to state: idle");
      }

      break;

  }//switch
}//manageStates

you presumably know you can't have two functions with the same name (e.g. loop()). rename the first loop() and call it from the other one.

in that first loop(), when knightLight > 7, shouldn't knightCounter be set to -1, not 1?

in setup(), why are you repeatedly doing pinMode (onButtonPin, INPUT_PULLUP), it only needs to be done once. the same for others

in the 2nd loop(), it would be better practice to read and capture the button states outside the switch() instead of having multiple reads.

Hi, thanks for this!

So, I’ve combined the two codes - it almost does what I need it to do but the indicator lights seem to only move one along everytime the on button is pushed rather than carrying out a sequence.

On its own - prior the incorporating the indicators - the rest of the sequence does exactly what I need it to - it’s just now incorporating the second sequence to run in conjunction that sequence isn’t doing the chase sort of function.

See the code below, but how can I get ‘indicator()’ to respond in the same way to the buttons as the UV LED’s, while carrying out its sequence.

Thanks!

// timed led with on and safety button

const int safetyButtonPin = 2;       // the number of the safetybutton pin
const int onButtonPin = 3;           // the number of the onbutton pin
const int uvLEDPin1 =  4;            // the number of the UV LED pin
const int uvLEDPin2 =  5;
const int uvLEDPin3 =  6;
const int uvLEDPin4 =  7;
const int uvLEDPin5 =  8;
const int uvLEDPin6 =  9;

//indicators
const int indicatorPin1 =  A5;
const int indicatorPin2 =  A4;
const int indicatorPin3 =  A3;
const int indicatorPin4 =  A2;
const int indicatorPin5 =  A1;
const int indicatorPin6 =  A0;
const int indicatorPin7 =  10;
const int indicatorPin8 =  11;


//led
unsigned long ledWentOnAt;
int ledStaysOnFor = 3000;

//states
enum {ST_idle, ST_safe, ST_on} currentState = ST_idle;


// define output pins
int outPins[] = {A5, A4, A3, A2, A1, A0, 10, 11};

// timer
long previousMillis = 0;
static long TIMER = 200;
//
int knightLight = 0;
int knightCounter = 1;



void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
  Serial.println("setup() ... ");
  Serial.println("timed led with on and safety button");
  Serial.print("Compiler: ");
  Serial.print(__VERSION__);
  Serial.print(", Arduino IDE: ");
  Serial.println(ARDUINO);
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(__FILE__);

  pinMode(uvLEDPin1, OUTPUT);
  pinMode(uvLEDPin2, OUTPUT);
  pinMode(uvLEDPin3, OUTPUT);
  pinMode(uvLEDPin4, OUTPUT);
  pinMode(uvLEDPin5, OUTPUT);
  pinMode(uvLEDPin6, OUTPUT);

  pinMode(safetyButtonPin, INPUT_PULLUP);
  pinMode(onButtonPin, INPUT_PULLUP);


  Serial.println("setup() done");
  Serial.println(" ");
  Serial.println("starting in state: idle");

  for(int p = 0; p < 8; p++) {
    pinMode(outPins[p], OUTPUT);
  }
}



void loop(){
  switch (currentState) //ST_idle, ST_safe, ST_on
  {
    case ST_idle:
      digitalWrite(uvLEDPin1, LOW);
      digitalWrite(uvLEDPin2, LOW);
      digitalWrite(uvLEDPin3, LOW);
      digitalWrite(uvLEDPin4, LOW);
      digitalWrite(uvLEDPin5, LOW);
      digitalWrite(uvLEDPin6, LOW);

      digitalWrite(indicatorPin1, LOW);
      digitalWrite(indicatorPin2, LOW);
      digitalWrite(indicatorPin3, LOW);
      digitalWrite(indicatorPin4, LOW);
      digitalWrite(indicatorPin5, LOW);
      digitalWrite(indicatorPin6, LOW);
      digitalWrite(indicatorPin7, LOW);
      digitalWrite(indicatorPin8, LOW);
     
      //wait for safety ...
      if (!digitalRead(safetyButtonPin))
      {
        Serial.println("state: safe");
        currentState = ST_safe;
      }

      break;

    case ST_safe:
      //check it's still safe...
      if (digitalRead(safetyButtonPin)) //it's not, so:
      {
        currentState = ST_idle;
        Serial.println("unsafe, returning to state: idle");
      }

      //wait for the on
      if (!digitalRead(onButtonPin))
      {
        Serial.println("state: on");
        currentState = ST_on;
        ledWentOnAt = millis(); //capture start time
        digitalWrite(uvLEDPin1, HIGH);
        digitalWrite(uvLEDPin2, HIGH);
        digitalWrite(uvLEDPin3, HIGH);
        digitalWrite(uvLEDPin4, HIGH);
        digitalWrite(uvLEDPin5, HIGH);
        digitalWrite(uvLEDPin6, HIGH);
        indicator();
      }

      break;

    case ST_on:
      //check it's still safe...
      if (digitalRead(safetyButtonPin)) //it's not, so:
      {
        currentState = ST_idle;
        Serial.println("unsafe, returning to state: idle");
      }
      //wait for the timer
      if (millis() - ledWentOnAt >= (unsigned long) ledStaysOnFor)
      {
        currentState = ST_idle;
        Serial.println("time up, returning to state: idle");
      }

      break;

}//switch
}//manageStates


void indicator() {
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > TIMER) {
    previousMillis = currentMillis;
    // reset last knight light
    digitalWrite(outPins[knightLight], LOW);
    // calc new knight light
    knightLight = knightLight + knightCounter;
    if (knightLight > 7) {
      knightLight = 0;
      knightCounter = -1;
    }
    if (knightLight < 0) {
     knightLight = 0;
     knightCounter = 1;
    }
    // set new knight light
    digitalWrite(outPins[knightLight], HIGH);
  }
}