LED Runner/Chasser with HC-05 till off Button pressed

SecondtNanoBoard.ino (13.9 KB)

Please i need an assistance want to turn off this led Chaser with the OFF button just the same way i use a button to turn it ON on the Application throught the smart phone

i use light up command to OFF the LED Chaser/Runner
and light down command to OFF the LED Chaser/Runner through the smart application

but its not turning off

Hi @joshkatech1 !

Please post your code in code tags next time ...

If you use this button in the editor menu

image

and copy the code between the tags the result looks like this (your sketch in code tags)

#include <SoftwareSerial.h>

SoftwareSerial BT ( 2, 3 ); // ( TX pin 10, RX pin 11  )

String state;


int led1 = 4; // light thirtheen
int led2 = 5; // light fourtheen
int led3 = 6; // light fifteen
int led4 = 7; // strret light one
int led5 = 8; //street light two
int led6 = 9; //pool light


int led7 = 11; // car park light
int led8 = 12; // profile light

//int led9 = A0; // unit four light
//int led10 = A1; // mall light
//int led12 = A2; // sitting area light




void setup() {
  // put your setup code here, to run once:

   BT.begin (9600);

  pinMode ( led1, OUTPUT );
  pinMode ( led2, OUTPUT );
  pinMode ( led3, OUTPUT );
  pinMode ( led4, OUTPUT );
  pinMode ( led5, OUTPUT );
  pinMode ( led6, OUTPUT );
  pinMode ( led7, OUTPUT );
  pinMode ( led8, OUTPUT );
  //pinMode ( led9, OUTPUT );
  //pinMode ( led10, OUTPUT );
  //pinMode ( led11, OUTPUT );
  //pinMode ( led12, OUTPUT );

  digitalWrite ( led1, LOW);
  digitalWrite ( led2, LOW);
  digitalWrite ( led3, LOW);
  digitalWrite ( led4, LOW);
  digitalWrite ( led5, LOW);
  digitalWrite ( led6, LOW);
  digitalWrite ( led7, LOW);
  digitalWrite ( led8, LOW);
  //digitalWrite ( led9, LOW);
  //digitalWrite ( led10, LOW);
  //digitalWrite ( led11, LOW);
  //digitalWrite ( led12, LOW);

  delay (10000);

  digitalWrite ( led1, HIGH );
  digitalWrite ( led2, HIGH );
  digitalWrite ( led3, HIGH );
  digitalWrite ( led4, HIGH );
  digitalWrite ( led5, HIGH );
  digitalWrite ( led6, HIGH );
  digitalWrite ( led7, HIGH );
  digitalWrite ( led8, HIGH );
  //digitalWrite ( led9, HIGH );
  //digitalWrite ( led10, HIGH );
  //digitalWrite ( led11, HIGH );
  //digitalWrite ( led12, HIGH );
  
}

void loop() {
  
  // put your main code here, to run repeatedly:
   while (BT.available()){
    delay (10);
    char jos = BT.read();
    state += jos;
  }

  if ( state.length()>0){
    Serial.println (state);

    
    if ( state == "light 13 on") {
      digitalWrite ( led1, LOW );
    }

    if ( state == "light 13 off") {
      digitalWrite ( led1, HIGH );
    }

    if ( state == "light 14 on") {
      digitalWrite ( led2, LOW );
    }

    if ( state == "light 14 off") {
      digitalWrite ( led2, HIGH);
    }

    if ( state == "light 15 on") {
      digitalWrite ( led3, LOW );
    }

    if (state == "light 15 off") {
      digitalWrite ( led3, HIGH);
    }

    if ( state == "street light one on") {
      digitalWrite ( led4, LOW );
    }

    if ( state == "street light one off") {
      digitalWrite ( led4, HIGH );
    }

    if ( state == "street light two on") {
      digitalWrite ( led5, LOW );
    }

    if ( state == "street light two off") {
      digitalWrite ( led5, HIGH );
    }

    if ( state == "pool light on") {
      digitalWrite ( led6, LOW);
    }

    if (state == "pool light off") {
      digitalWrite ( led6, HIGH );
    }

     if ( state == "carpark light on") {
      digitalWrite ( led7, LOW );
    }

    if ( state == "carpark light off") {
      digitalWrite ( led7, HIGH );
    }

    if ( state == "profile light on") {
      digitalWrite ( led8, LOW );
    }

    if ( state == "profile light off") {
      digitalWrite ( led8, HIGH);
    }


    if (( state == "light up")|| (state == "Light Up" )) {
      int A = 0;
      while(!(A == 2)) {
        
        // first

        for(int i = 0; i < 3; i++) {
          digitalWrite(led1, LOW);
          digitalWrite(led8, LOW);
          delay (200);
          digitalWrite(led1, HIGH);
          digitalWrite(led8, HIGH);
          digitalWrite(led2, LOW);
          digitalWrite(led7, LOW);
          delay (200);
          digitalWrite(led2, HIGH);
          digitalWrite(led7, HIGH);
          digitalWrite(led3, LOW);
          digitalWrite(led6, LOW);
          delay (200);
          digitalWrite(led3, HIGH);
          digitalWrite(led6, HIGH);
          digitalWrite(led4, LOW);
          digitalWrite(led5, LOW);
          delay (200);
          digitalWrite(led4, HIGH);
          digitalWrite(led5, HIGH);
          delay (200);

          
          digitalWrite(led4, LOW);
          digitalWrite(led5, LOW);
          delay (200);
          digitalWrite(led4, HIGH);
          digitalWrite(led5, HIGH);
          digitalWrite(led3, LOW);
          digitalWrite(led6, LOW);
          delay (200);
          digitalWrite(led3, HIGH);
          digitalWrite(led6, HIGH);
          digitalWrite(led2, LOW);
          digitalWrite(led7, LOW);
          delay (200);
          digitalWrite(led2, HIGH);
          digitalWrite(led7, HIGH);
          digitalWrite(led1, LOW);
          digitalWrite(led8, LOW);
          delay (200);
          digitalWrite(led1, HIGH);
          digitalWrite(led8, HIGH);
          delay (10);
        }

        // second

        for(int i = 0; i < 2; i++) {

          digitalWrite(led1, LOW);
          delay(500);
          digitalWrite(led1, HIGH);
          delay(500);
          digitalWrite(led2, LOW);
          delay(500);
          digitalWrite(led2, HIGH);
          delay(500);
          digitalWrite(led3, LOW);
          delay(500);
          digitalWrite(led3, HIGH);
          delay(500);
          digitalWrite(led4, LOW);
          delay(500);
          digitalWrite(led4, HIGH);
          delay(500);
          digitalWrite(led5, LOW);
          delay(500);
          digitalWrite(led5, HIGH);
          delay(500);
          digitalWrite(led6, LOW);
          delay(500);
          digitalWrite(led6, HIGH);
          delay(500);
          digitalWrite(led7, LOW);
          delay(500);
          digitalWrite(led7, HIGH);
          delay(500);
          digitalWrite(led8, LOW);
          delay(500);
          digitalWrite(led8, HIGH);
          
          delay(500);
          digitalWrite(led8, LOW);
          delay(500);
          digitalWrite(led8, HIGH);
          delay(500);
          digitalWrite(led7, LOW);
          delay(500);
          digitalWrite(led7, HIGH);
          delay(500);
          digitalWrite(led6, LOW);
          delay(500);
          digitalWrite(led6, HIGH);
          delay(500);
          digitalWrite(led5, LOW);
          delay(500);
          digitalWrite(led5, HIGH);
          delay(500);
          digitalWrite(led4, LOW);
          delay(500);
          digitalWrite(led4, HIGH);
          delay(500);
          digitalWrite(led3, LOW);
          delay(500);
          digitalWrite(led3, HIGH);
          delay(90);
          
          
        }

        // Third

        for(int i = 0; i < 3; i++) {
          digitalWrite(led1, LOW);
          digitalWrite(led8, LOW);
          delay (300);
          digitalWrite(led1, HIGH);
          digitalWrite(led8, HIGH);
          digitalWrite(led2, LOW);
          digitalWrite(led7, LOW);
          delay (300);
          digitalWrite(led2, HIGH);
          digitalWrite(led7, HIGH);
          digitalWrite(led3, LOW);
          digitalWrite(led6, LOW);
          delay (300);
          digitalWrite(led3, HIGH);
          digitalWrite(led6, HIGH);
          digitalWrite(led4, LOW);
          digitalWrite(led5, LOW);
          delay (300);
          digitalWrite(led4, HIGH);
          digitalWrite(led5, HIGH);
          delay (300);

          
          digitalWrite(led4, LOW);
          digitalWrite(led5, LOW);
          delay (300);
          digitalWrite(led4, HIGH);
          digitalWrite(led5, HIGH);
          digitalWrite(led3, LOW);
          digitalWrite(led6, LOW);
          delay (300);
          digitalWrite(led3, HIGH);
          digitalWrite(led6, HIGH);
          digitalWrite(led2, LOW);
          digitalWrite(led7, LOW);
          delay (300);
          digitalWrite(led2, HIGH);
          digitalWrite(led7, HIGH);
          digitalWrite(led1, LOW);
          digitalWrite(led8, LOW);
          delay (300);
          digitalWrite(led1, HIGH);
          digitalWrite(led8, HIGH);
          delay (10);
        }

        // fifth
        
        for(int i = 0; i < 2; i++) {
          digitalWrite(led1, LOW);
          delay(1000);
          digitalWrite(led2, LOW);
          delay(1000);
          digitalWrite(led3, LOW);
          delay(1000);
          digitalWrite(led4, LOW);
          delay(1000);
          digitalWrite(led5, LOW);
          delay(1000);
          digitalWrite(led6, LOW);
          delay(1000);
          digitalWrite(led7, LOW);
          delay(1000);
          digitalWrite(led8, LOW);
          delay(500);
          digitalWrite(led1, HIGH);
          digitalWrite(led2, HIGH);
          digitalWrite(led3, HIGH);
          digitalWrite(led4, HIGH);
          digitalWrite(led5, HIGH);
          digitalWrite(led6, HIGH);
          digitalWrite(led7, HIGH);
          digitalWrite(led8, HIGH);

          delay (500); 
          
          digitalWrite(led8, LOW);
          delay(1000);
          digitalWrite(led7, LOW);
          delay(1000);
          digitalWrite(led6, LOW);
          delay(1000);
          digitalWrite(led5, LOW);
          delay(1000);
          digitalWrite(led4, LOW);
          delay(1000);
          digitalWrite(led3, LOW);
          delay(1000);
          digitalWrite(led2, LOW);
          delay(1000);
          digitalWrite(led1, LOW);
          delay(500);
          digitalWrite(led1, HIGH);
          digitalWrite(led2, HIGH);
          digitalWrite(led3, HIGH);
          digitalWrite(led4, HIGH);
          digitalWrite(led5, HIGH);
          digitalWrite(led6, HIGH);
          digitalWrite(led7, HIGH);
          digitalWrite(led8, HIGH);
          
        }

        

        // seventh
        
        for(int i = 0; i < 3; i++) {
          digitalWrite(12, LOW);
          digitalWrite(11, LOW);
          digitalWrite(10, LOW);
          digitalWrite(9, LOW);
          digitalWrite(8, LOW);
          digitalWrite(7, LOW);
          digitalWrite(6, LOW);
          digitalWrite(5, LOW);
          delay(500);
          digitalWrite(12, HIGH);
          digitalWrite(11, HIGH);
          digitalWrite(10, HIGH);
          digitalWrite(9, HIGH);
          digitalWrite(8, HIGH);
          digitalWrite(7, HIGH);
          digitalWrite(6, HIGH);
          digitalWrite(5, HIGH);
          delay(500);
      }

       

        
        // ninth
        for(int p = 0; p < 2; p++) {
          digitalWrite(12, LOW);
          delay(0.05 * 1000);
          digitalWrite(11, LOW);
          delay(0.05 * 1000);
          digitalWrite(10, LOW);
          delay(0.05 * 1000);
          digitalWrite(9, LOW);
          delay(0.05 * 1000);
          digitalWrite(8, LOW);
          delay(0.05 * 1000);
          digitalWrite(7, LOW);
          delay(0.05 * 1000);
          digitalWrite(6, LOW);
          delay(0.05 * 1000);
          digitalWrite(5, LOW);
          
          digitalWrite(12, HIGH);
          delay(0.05 * 1000);
          digitalWrite(11, HIGH);
          delay(0.05 * 1000);
          digitalWrite(10, HIGH);
          delay(0.05 * 1000);
          digitalWrite(9, HIGH);
          delay(0.05 * 1000);
          digitalWrite(8, HIGH);
          delay(0.05 * 1000);
          digitalWrite(7, HIGH);
          delay(0.05 * 1000);
          digitalWrite(6, HIGH);
          delay(0.05 * 1000);
          digitalWrite(5, HIGH);
          delay(0.05 * 1000);
          digitalWrite(5, LOW);
          delay(0.05 * 1000);
          digitalWrite(6, LOW);
          delay(0.05 * 1000);
          digitalWrite(7, LOW);
          delay(0.05 * 1000);
          digitalWrite(8, LOW);
          delay(0.05 * 1000);
          digitalWrite(9, LOW);
          delay(0.05 * 1000);
          digitalWrite(10, LOW);
          delay(0.05 * 1000);
          digitalWrite(11, LOW);
          delay(0.05 * 1000);
          digitalWrite(12, LOW);
          
          digitalWrite(5, HIGH);
          delay(0.05 * 1000);
          digitalWrite(6, HIGH);
          delay(0.05 * 1000);
          digitalWrite(7, HIGH);
          delay(0.05 * 1000);
          digitalWrite(8, HIGH);
          delay(0.05 * 1000);
          digitalWrite(9, HIGH);
          delay(0.05 * 1000);
          digitalWrite(10, HIGH);
          delay(0.05 * 1000);
          digitalWrite(11, HIGH);
          delay(0.05 * 1000);
          digitalWrite(12, HIGH);
          delay(0.05 * 1000);
          A = 0;
      }
    }
  }

    if (( state == "light down")|| (state == "Light Down" )){
      digitalWrite ( led1, HIGH );
      digitalWrite ( led2, HIGH );
      digitalWrite ( led3, HIGH );
      digitalWrite ( led4, HIGH );
      digitalWrite ( led5, HIGH );
      digitalWrite ( led6, HIGH );
      digitalWrite ( led7, HIGH );
      digitalWrite ( led8, HIGH );
      //digitalWrite ( led9, HIGH );
      //digitalWrite ( led10, HIGH );
      //digitalWrite ( led11, HIGH );
      //digitalWrite ( led12, HIGH );
    }

    
    if ( state == "central light on") {
      digitalWrite ( led1, LOW);
      digitalWrite ( led2, LOW);
      digitalWrite ( led3, LOW);
      digitalWrite ( led4, LOW);
      digitalWrite ( led5, LOW);
      digitalWrite ( led6, LOW);
      digitalWrite ( led7, LOW);
      digitalWrite ( led8, LOW);
      //digitalWrite ( led9, LOW);
      //digitalWrite ( led10, LOW);
      //digitalWrite ( led11, LOW);
      //digitalWrite ( led12, LOW);
    }

    if (state == "central light off") {
      digitalWrite ( led1, HIGH );
      digitalWrite ( led2, HIGH );
      digitalWrite ( led3, HIGH );
      digitalWrite ( led4, HIGH );
      digitalWrite ( led5, HIGH );
      digitalWrite ( led6, HIGH );
      digitalWrite ( led7, HIGH );
      digitalWrite ( led8, HIGH );
      //digitalWrite ( led9, HIGH );
      //digitalWrite ( led10, HIGH );
      //digitalWrite ( led11, HIGH );
      //digitalWrite ( led12, HIGH );
    }




    

    state ="";

  }

}

A first impression:

  • The sketch consists of a lot of code repetitions.
  • The "linear structure" of the sketch is not very helpful for improvements.

In general software developers are lazy, they try to avoid typing or copying the same procedures several times: They love functions and loops to handle repetetive tasks,

They also love meaningful variable names and arrays! Arrays are wonderful features of programming languages to handle several items of the same type and function!

The use of these features will make it much easier to solve your intention ...

There are quite a number of problematic issues in your sketch:

  • The intensive use of delay() makes your sketch less responsive to any commands given by SoftwareSerial (quite likely a bluetooth connection?).
  • To make sure that the commands is read completely you use a delay(10) inside the while() loop. It's much better to use the ending character of a message (e.g. New Line or Carriage Return) to identify that a message has been received completely.
  • Instead of writing a lot of if() statements it might be easier to read and follow the program flow to use a switch/case construct ...

As your topic does not relate directly to the installation or operation of the IDE it has been moved to the Programming category of the forum

Is the Arduino receiving:

light 13 off

or

l
i
g
h
t

1
3

o
f
f

Just as a quick workaround you may make these changes to your sketch and give it a try:

// ...
boolean msgComplete = false;   

void loop() {
  
  // put your main code here, to run repeatedly:
  while (!msgComplete){  
   if (BT.available()){
    char jos = BT.read();
    if (jos >= ' ') {
      state += jos;
    } else {
      msgComplete = true;
    }
  }
}

  if ( msgComplete){
    msgComplete = false;
    Serial.println (state);
    
    if ( state == "light 13 on") {
      digitalWrite ( led1, LOW );
    }
// ...

It won't be able to break out of the chaser sequence unless he changes this first.

int A = 0;
while(!(A == 2)) {
    // "A" never changes its value, so the loop is infinite.
    // The only one subsequent assignment confirms it as 0.

At the very least, you should read from the serial port inside the while() loop to check whether you need to exit. :wink:

Yes

Noted thans,
So whats the solution or way forward?

Okay

Haha. Same to you.

The way forward would be to re-write the whole sketch using arrays, enumerations and separate functions where applicable.

The target would be to make the program flow better maintainable...

I'll give you examples as soon as I've got some time.

In the meantime you might check @MaximoEsfuerzo 's observation ... ;-)

As promised here a possibility to solve the issues; it's not the cleanest solution but should be much easier to expand and maintain ...

Usually String() objects should be avoided, I still use one object to gather and evaluate the commands but reserve 40 bytes for this in setup().

You can check it out on Wokwi: https://wokwi.com/projects/451136500457875457

/*
   Forum: https://forum.arduino.cc/t/led-runner-chasser-with-hc-05-till-off-button-pressed/1421148
   Wokwi: https://wokwi.com/projects/451136500457875457

   2025/12/23
   ec2021

*/

struct myLights {
  byte pin;
  char name[20];
};

enum LIGHTS {
  light13   = 4,
  light14   = 5,
  light15   = 6,
  streetL1  = 7,
  streetL2  = 8,
  poolL     = 9,
  carparkL  = 11,
  profileL = 12
};

myLights lights[] = {
  {light13, "light 13"},
  {light14, "light 14"},
  {light15, "light 15"},
  {streetL1, "street light one"},
  {streetL2, "street light two"},
  {poolL,  "pool light"},
  {carparkL, "carpark light"},
  {profileL, "profile light"}
};

constexpr int noOfLights = sizeof(lights) / sizeof(lights[0]);

char effects[][20] = {
  "light up",
  "central light on",
  "light down",
  "central light off"
};

constexpr int noOfEffects = sizeof(effects) / sizeof(effects[0]);

boolean msgComplete = false;
String command;
int runEffectNo = -1;


void setup() {
  Serial.begin(9600);
  Serial.println("Start");
  Serial.println(noOfLights);
  command.reserve(40);
  command = "";
  for (int i = 0; i < noOfLights; i++) {
    pinMode(lights[i].pin, OUTPUT );
  }
  setAllLightsTo(LOW);
  delay (2000);
  setAllLightsTo(HIGH);

}

void loop() {
  if ( commandReceived()) {
    Serial.println (command);
    evaluateCommand();
  }
  runEffects();
}
boolean commandReceived() {
  if (Serial.available()) {
    char jos = Serial.read();
    if (jos >= ' ') {
      command += jos;
    } else {
      command.toLowerCase();
      return true;
    }
  }
  return false;
}

void evaluateCommand() {
  if (!isDirectCommand()) {
    checkEffectCommand();
  };
  command = "";
}

boolean isDirectCommand() {
  boolean cmdFound = false;
  int lightNo = 0;
  while (!cmdFound && lightNo < noOfLights) {
    if (command.startsWith(lights[lightNo].name)) {
      cmdFound = true;
    } else {
      lightNo++;
    }
  }
  if (cmdFound) {
    if (command.endsWith("on")) {
      digitalWrite(lights[lightNo].pin, LOW);
    }
    if (command.endsWith("off")) {
      digitalWrite(lights[lightNo].pin, HIGH);
    }
    runEffectNo = -1;
  }
  return cmdFound;
}

void checkEffectCommand() {
  boolean cmdFound = false;
  int effectNo = 0;
  while (!cmdFound && effectNo < noOfEffects) {
    if (command.startsWith(effects[effectNo])) {
      cmdFound = true;
    } else {
      effectNo++;
    }
  }
  if (cmdFound) {
    runEffectNo = effectNo;
  }
}

void setAllLightsTo(byte aState) {
  for (int i = 0; i < noOfLights; i++) {
    digitalWrite(lights[i].pin, aState);
  }
}

void runEffects() {
  if (runEffectNo < 0) {
    return;
  }
  switch (runEffectNo) {
    case 0:  // light up
      lightUp();
      break;
    case 1:  // central light on
      centralLightOn();
      break;
    case 2: // light down
    case 3: // central light off
      lightDown();
      break;
  }
}

void centralLightOn() {
  setAllLightsTo(LOW);
  runEffectNo = -1;
}

void lightDown() {
  setAllLightsTo(HIGH);
  runEffectNo = -1;
}

void lightUp() {
  if (!FirstDone()) {
    return;
  }
  if (!SecondDone()) {
    return;
  }
  if (!ThirdDone()) {
    return;
  }
  runEffectNo = -1;
}

boolean FirstDone() {
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < noOfLights / 2; j++) {
      switchPair(j, noOfLights - j - 1, 200);
      if (breakOnSerial()) {
        return false;
      };
    }
    for (int j = 1; j < noOfLights / 2; j++) {
      switchPair(noOfLights - j - 1, j, 200);
      if (breakOnSerial()) {
        return false;
      };
    }
    delay (10);
  }
  return true;
}

boolean SecondDone() {
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < noOfLights; j++) {
      switchSingle(j, 500);
      if (breakOnSerial()) {
        return false;
      };
    }
    for (int j = 0; j < noOfLights; j++) {
      switchSingle(noOfLights - j - 1, 500);
      if (breakOnSerial()) {
        return false;
      };
    }
    delay(90);
  }
  return true;
}

boolean ThirdDone() {
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < noOfLights; j++) {
      switchSingle(j, 300);
      if (breakOnSerial()) {
        return false;
      };
    }
    delay(300);
    for (int j = 0; j < noOfLights; j++) {
      switchSingle(noOfLights - j - 1, 300);
      if (breakOnSerial()) {
        return false;
      };
    }
    delay(10);
  }
  return true;
}

void switchSingle(byte lOne, uint16_t dly) {
  digitalWrite(lights[lOne].pin, LOW);
  delay(dly);
  digitalWrite(lights[lOne].pin, HIGH);
}

void switchPair(byte lOne, byte lTwo, uint16_t dly) {
  digitalWrite(lights[lOne].pin, LOW);
  digitalWrite(lights[lTwo].pin, LOW);
  delay(dly);
  digitalWrite(lights[lOne].pin, HIGH);
  digitalWrite(lights[lTwo].pin, HIGH);
}

boolean breakOnSerial() {
  if (Serial.available()) {
    setAllLightsTo(HIGH);
    runEffectNo = -1;
    return true;
  }
  return false;
}

To add further lights:

  • add an individual name in enum LIGHTS and assign the correct pin number
  • add a line to the struct lights[] with the new enumeration and the string how ro call it (in lower letters!)
    To add further effects
  • add an effect command to the char array effects[]
  • add a case in the function runEffects()
  • create a function that is called from that specific case

In the function lightUp() I have realized the first three functions as provided in your sketch. As the maximum single delay is around 1 second I refrained from rewriting everything using the millis() function, instead of this I added a function that allows to interrupt the process at certain positions. Not nice and not "foolproof", but the quickest way for now ...

To show how to add an effect command see https://wokwi.com/projects/451148665794671617

Sketch
/*
   Forum: https://forum.arduino.cc/t/led-runner-chasser-with-hc-05-till-off-button-pressed/1421148
   Wokwi: https://wokwi.com/projects/451148665794671617

   2025/12/23
   ec2021

   Effect "blink all" and function blinkAll() added

*/

struct myLights {
  byte pin;
  char name[20];
};

enum LIGHTS {
  light13   = 4,
  light14   = 5,
  light15   = 6,
  streetL1  = 7,
  streetL2  = 8,
  poolL     = 9,
  carparkL  = 11,
  profileL = 12
};

myLights lights[] = {
  {light13, "light 13"},
  {light14, "light 14"},
  {light15, "light 15"},
  {streetL1, "street light one"},
  {streetL2, "street light two"},
  {poolL,  "pool light"},
  {carparkL, "carpark light"},
  {profileL, "profile light"}
};

constexpr int noOfLights = sizeof(lights) / sizeof(lights[0]);

char effects[][20] = {
  "light up",
  "central light on",
  "light down",
  "central light off",
  "blink all"
};

constexpr int noOfEffects = sizeof(effects) / sizeof(effects[0]);

boolean msgComplete = false;
String command;
int runEffectNo = -1;


void setup() {
  Serial.begin(9600);
  Serial.println("Start");
  Serial.println(noOfLights);
  command.reserve(40);
  command = "";
  for (int i = 0; i < noOfLights; i++) {
    pinMode(lights[i].pin, OUTPUT );
  }
  setAllLightsTo(LOW);
  delay (2000);
  setAllLightsTo(HIGH);

}

void loop() {
  if ( commandReceived()) {
    Serial.println (command);
    evaluateCommand();
  }
  runEffects();
}
boolean commandReceived() {
  if (Serial.available()) {
    char jos = Serial.read();
    if (jos >= ' ') {
      command += jos;
    } else {
      command.toLowerCase();
      return true;
    }
  }
  return false;
}

void evaluateCommand() {
  if (!isDirectCommand()) {
    checkEffectCommand();
  };
  command = "";
}

boolean isDirectCommand() {
  boolean cmdFound = false;
  int lightNo = 0;
  while (!cmdFound && lightNo < noOfLights) {
    if (command.startsWith(lights[lightNo].name)) {
      cmdFound = true;
    } else {
      lightNo++;
    }
  }
  if (cmdFound) {
    if (command.endsWith("on")) {
      digitalWrite(lights[lightNo].pin, LOW);
    }
    if (command.endsWith("off")) {
      digitalWrite(lights[lightNo].pin, HIGH);
    }
    runEffectNo = -1;
  }
  return cmdFound;
}

void checkEffectCommand() {
  boolean cmdFound = false;
  int effectNo = 0;
  while (!cmdFound && effectNo < noOfEffects) {
    if (command.startsWith(effects[effectNo])) {
      cmdFound = true;
    } else {
      effectNo++;
    }
  }
  if (cmdFound) {
    runEffectNo = effectNo;
  }
}

void setAllLightsTo(byte aState) {
  for (int i = 0; i < noOfLights; i++) {
    digitalWrite(lights[i].pin, aState);
  }
}

void runEffects() {
  if (runEffectNo < 0) {
    return;
  }
  switch (runEffectNo) {
    case 0:  // light up
      lightUp();
      break;
    case 1:  // central light on
      centralLightOn();
      break;
    case 2: // light down
    case 3: // central light off
      lightDown();
      break;
    case 4: //blink all
      blinkAll();
      break;
  }
}

void centralLightOn() {
  setAllLightsTo(LOW);
  runEffectNo = -1;
}

void blinkAll() {
  static int count = 0;
  if (count > 10) {
    count = 0;
    runEffectNo = -1;
  } else {
    count++;
    setAllLightsTo(LOW);
    delay(300);
    setAllLightsTo(HIGH);
    delay(300);
    if (breakOnSerial()) {
      return;
    }
  }
}

void lightDown() {
  setAllLightsTo(HIGH);
  runEffectNo = -1;
}

void lightUp() {
  if (!FirstDone()) {
    return;
  }
  if (!SecondDone()) {
    return;
  }
  if (!ThirdDone()) {
    return;
  }
  runEffectNo = -1;
}

boolean FirstDone() {
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < noOfLights / 2; j++) {
      switchPair(j, noOfLights - j - 1, 200);
      if (breakOnSerial()) {
        return false;
      };
    }
    for (int j = 1; j < noOfLights / 2; j++) {
      switchPair(noOfLights - j - 1, j, 200);
      if (breakOnSerial()) {
        return false;
      };
    }
    delay (10);
  }
  return true;
}

boolean SecondDone() {
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < noOfLights; j++) {
      switchSingle(j, 500);
      if (breakOnSerial()) {
        return false;
      };
    }
    for (int j = 0; j < noOfLights; j++) {
      switchSingle(noOfLights - j - 1, 500);
      if (breakOnSerial()) {
        return false;
      };
    }
    delay(90);
  }
  return true;
}

boolean ThirdDone() {
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < noOfLights; j++) {
      switchSingle(j, 300);
      if (breakOnSerial()) {
        return false;
      };
    }
    delay(300);
    for (int j = 0; j < noOfLights; j++) {
      switchSingle(noOfLights - j - 1, 300);
      if (breakOnSerial()) {
        return false;
      };
    }
    delay(10);
  }
  return true;
}

void switchSingle(byte lOne, uint16_t dly) {
  digitalWrite(lights[lOne].pin, LOW);
  delay(dly);
  digitalWrite(lights[lOne].pin, HIGH);
}

void switchPair(byte lOne, byte lTwo, uint16_t dly) {
  digitalWrite(lights[lOne].pin, LOW);
  digitalWrite(lights[lTwo].pin, LOW);
  delay(dly);
  digitalWrite(lights[lOne].pin, HIGH);
  digitalWrite(lights[lTwo].pin, HIGH);
}

boolean breakOnSerial() {
  if (Serial.available()) {
    setAllLightsTo(HIGH);
    runEffectNo = -1;
    return true;
  }
  return false;
}

BTW: The "blink all" function is an example that an effect doesn't have to be processed "linear" but can be called several times from loop() until it is finished.

[Edit] If you watch carefully you'll see that if you restart "blink all" after breaking it with a Serial transmission it will perform only the missing number of blinks. That's on purpose. If you want it to always perform the full number of blinks you have to reset count to zero before the "return" statement in the blinkAll() function is called ... ;-)

Thanks will follow suit and get back