Why does "if...else if...else" not work, but "if...if...else" does?

Over the last couple of weeks, with help from this forum, I've put together a sketch using an Arduino Uno, which i’ll swap out later for the smaller Nano. The sketch controls Leds and their sequence using states, a small servo motor & sound effects controlled by 2 momentary buttons.

*stage1, (i put this in "else" as its the default action) When neither button is pressed, the sketch will return the the servo to the parked position, it plays sound 01 and sequences the slow speed version of the LEDs

*stage2, (i put this in "else if") When buttonA becomes pressed the servo moves to 1st position, plays sound 02 and sequences the medium speed version of the LEDs and does this until the button is released, at which point returns to stage1

*stage3, (i put this in "if") When buttonB becomes pressed the servo moves to 2nd position, plays sound 03 and sequences the fast speed version of the LEDs and does this until the button is released, at which point returns to stage1

The sketch worked perfectly with "if...else if...else" statements & i then decided i needed to add in a millis controlled delay so when i released either button the current actions would continue for 2 seconds. I found the following code and tested it to make sure it worked with the servo & leds before adding to my sketch

[code]
//Global Variables
const byte BUTTON = 2; // our button pin
const byte LED = 13; // LED (built-in on Uno)

unsigned long buttonPushedMillis; // when button was released
unsigned long ledTurnedOnAt; // when led was turned on
unsigned long turnOnDelay = 0; // wait to turn on LED
unsigned long turnOffDelay = 2000; // turn off LED after this time
bool ledReady = false; // flag for when button is let go
bool ledState = false; // for LED is on or not.

void setup() {
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
}

void loop() {
  // get the time at the start of this loop()
  unsigned long currentMillis = millis();

  // check the button
  if (digitalRead(BUTTON) == LOW) {
    // update the time when button was pushed
    buttonPushedMillis = currentMillis;
    ledReady = true;
  }

  // make sure this code isn't checked until after button has been let go
  if (ledReady) {
    //this is typical millis code here:
    if ((unsigned long)(currentMillis - buttonPushedMillis) >= turnOnDelay) {
      // okay, enough time has passed since the button was let go.
      digitalWrite(LED, HIGH);
      // setup our next "state"
      ledState = true;
      // save when the LED turned on
      ledTurnedOnAt = currentMillis;
      // wait for next button press
      ledReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) {
      ledState = false;
      digitalWrite(LED, LOW);
    }
  }
}
[/code]

I set "turnOnDelay = 0;" as i want it start the action instantly & "turnOffDelay = 2000; " to 2 secs.

The combined code worked perfectly for the "if" & "else" statements but the "else if" statement had issues with the servo moving into position for a few seconds then trying to rest, on a constant cycle, the led sequence was freezing up for seconds at time. I checked to see if my {} were in the correct place and they all seemed to be.

Luckily i tried changing "else if" to "if" and that has solved the issue, the sketch works perfectly with that simple change from "if...else if...else" to "if...if...else"

Can anyone shed any light on what i missed in the code to make "else if" behave in that way
Here is the working code.

[code]
/*
    REQUIRED Libraries to make this sketch work:

    MP3Flash16Pv2 Library https://github.com/r0ndL/MP3Flash16Pv2

    BY8x0116P Library https://github.com/r0ndL/BY8x0116Pv2

  Important Note for if...elseif...else statements
  if (condition) {
  code to be executed if this condition is true;
  } else if (condition) {
  code to be executed if first condition is false and this condition is true;
  } else {
  code to be executed if all conditions are false;
  }
  NOTE!!!!! FOR THIS SKETCH I HAD TO CHANGE "else if" to "if" to make stage 2 work!!!!!!
*/

//--------------SET AUDIO OPTIONS FOR BY8301------------------------
// NOTE:  This sketch currently supports 3 different sound modules (MP3-FLASH-16P, BY8001-16P, BY8301-16P)

#define AUDIO1  2   // 1=MP3-FLASH-16P
// 2=BY8001-16P or BY8301-16P

// INCLUDE LIBS AND DECLARE VARIABLES...
#include "AltSoftSerial.h"
AltSoftSerial MP3Serial; // SoftwareSerial port assignments (RX, TX) to communicate with sound module

#if (AUDIO1==2)
//settings for BY8001-16P or BY8301-16P module...

#include "BY8x0116Pv2.h"
BY8x0116Pv2 myPlayer(MP3Serial); // Use SoftwareSerial as the serial port

#else
//settings for MP3-FLASH-16P...

#include "MP3Flash16Pv2.h"
MP3Flash16Pv2 myPlayer(MP3Serial); // Use SoftwareSerial as the serial port

#endif

// ARDUINO PIN ASSIGNMENTS to connect to by8301...
// Default Pin Assignments - BASIC WIRING in NOTES/MANUAL FOR BY8301
#define PIN_sound_BUSY    A3  //Connect to BUSY pin on sound module

// ADDITIONAL SOUND OPTIONS...
#define number_of_sounds  3
//----------------------------------------------------------------------------------------------------


//-----------BY8301 PLAYBACK CONTROL----------------------------------------------------
void PlayTrack(int TrackToPlay)
{
  static int TrackPlaying = -1;

  if (TrackPlaying != TrackToPlay)
  { // Not playing the required track
    myPlayer.stopPlay();                    // Stop what you're doing, if anything
    myPlayer.playFile(TrackToPlay, 10);     // Play requested track, VOLUME 10 (OUT OF 30)
    TrackPlaying = TrackToPlay;             // Note the track now playing
  }
  else if (!myPlayer.isBusy())              // Track number is right but is it still playing?
  {
    myPlayer.playFile(TrackToPlay, 10);     // No, so play it again, VOLUME 10 (OUT OF 30)
  }
}
//----------------------------------------------------------------------------------------------------


//--------------------SERVO-------------------------------------
#include<ServoTimer2.h>

ServoTimer2 myservo; // create servo object to control servo CONNECT UNO TX PIN 9, RX PIN 8
//--------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
// RED LEDS wired to buttonA & B press
int ledPinRA =  A0;      // the number of the LED pin
int ledPinRB =  A1;      // the number of the LED pin
//----------------------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
// buttonA & B with Pin No
int buttonApin = 2; //ButtonA
int buttonBpin = 4; //ButtonB
//----------------------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
int pos = 0; // set initial servo position to 0
int buttonAstate = 0; // variable for reading pushbutton status
int buttonBstate = 0; // variable for reading pushbutton status
//----------------------------------------------------------------------------------------------------


//--------www.baldengineer.com millis button delay-----------
unsigned long buttonPushedMillis; // when button was released
unsigned long ledTurnedOnAt; // when led was turned on
unsigned long turnOnDelay = 0; // wait to turn on LED AFTER PRESSING BUTTON 1000=1SEC
unsigned long turnOffDelay = 2000; // turn off LED after this time ONCE BUTTON IS RELEASED 1000=1SEC
bool ledReady = false; // flag for when button is let go
bool ledState = false; // for LED is on or not.
//-----------------------------------------------------------


//----------------------------STATE CONTROL FOR LED SEQUENCE & SPEEDS---------------------------------------
/*
  by noiasca https://forum.arduino.cc/index.php?topic=666044
*/
//----SPEEDS-----
const uint16_t intervalSLOW[] {1000, 1000, 1000, 1000, 1000, 1000, 1000, 100};  // time to wait in each intervall
const uint16_t intervalMEDIUM[] {400, 400, 400, 400, 400, 400, 400, 100};
const uint16_t intervalFAST[] {100, 100, 100, 100, 100, 100, 100, 100};

//----LED PIN No.-----
const byte ledPinA = 5;
const byte ledPinB = 6;
const byte ledPinC = 7;
const byte ledPinD = A4;
const byte ledPinE = A5;
const byte ledPinF = 10;
const byte ledPinG = 11;


void handleLedsSLOW()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalSLOW[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}


void handleLedsMEDIUM()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalMEDIUM[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}


void handleLedsFAST()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalFAST[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}



void setup() {
  myservo.attach(3); // SERVO pin
  Serial.begin(9600);
  pinMode(3, OUTPUT); // initialize the SERVO pin as an output
  pinMode(buttonApin, INPUT_PULLUP); // initialize the button A pin as an input
  pinMode(buttonBpin, INPUT_PULLUP); // initialize the button B pin as an input
  pinMode(ledPinA, OUTPUT); // initialize the LED1 pin as an output
  pinMode(ledPinB, OUTPUT); // initialize the LED2 pin as an output
  pinMode(ledPinC, OUTPUT); // initialize the LED3 pin as an output
  pinMode(ledPinD, OUTPUT); // initialize the LED4 pin as an output
  pinMode(ledPinE, OUTPUT); // initialize the LED5 pin as an output
  pinMode(ledPinF, OUTPUT); // initialize the LED6 pin as an output
  pinMode(ledPinG, OUTPUT); // initialize the LED7 pin as an output

  pinMode(12, OUTPUT);     // pin 12 as output for SLIDE switch 2No.LEDS

  pinMode(ledPinRA, OUTPUT); // initialize the LED pin as an output
  pinMode(ledPinRB, OUTPUT); // initialize the LED pin as an output

  MP3Serial.begin(9600);
  myPlayer.init(PIN_sound_BUSY);      // Init the player with the MP3 BUSY pin connected to Arduino pin defined
}



void loop() {
  //--------www.baldengineer.com millis button delay-----------
  unsigned long currentMillis = millis(); // get the time at the start of this loop()
  //-----------------------------------------------------------

  digitalWrite(12, HIGH); // sets the digital pin 12 on

  buttonAstate = digitalRead(buttonApin); // read the state of button A value
  buttonBstate = digitalRead(buttonBpin); // read the state of button B value


  //-------------------------Stage 3-----------------------------------------------------------
  if (buttonBstate == LOW) {  // check if button B is pressed, if (condition) {code to be executed if this condition is true;}
    //--------www.baldengineer.com millis button delay-----------
    buttonPushedMillis = currentMillis; // update the time when button was pushed
    ledReady = true;
  }
  // make sure this code isn't checked until after button has been let go
  if (ledReady) { //this is typical millis code here:
    if ((unsigned long)(currentMillis - buttonPushedMillis) >= turnOnDelay) {
      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;
      //-----------------------------------------------------------
      myservo.write(1442); // if it is rotate servo to 83 degrees
      PlayTrack(3); // PLAY TRACK3
      handleLedsFAST();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRB, HIGH);//BUTTON B IS PRESSED SO MANUALLY LIGHT LED:
      digitalWrite(ledPinRA, LOW); //BUTTON A IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
      //--------www.baldengineer.com millis button delay-----------
      // setup our next "state"
      ledState = true;
      ledTurnedOnAt = currentMillis; // save when the LED turned on
      // wait for next button press
      ledReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) {
      ledState = false;
      // Put in all the actions you want to close them out below
      //-----------------------------------------------------------
      myservo.write(750);  // servo position
      PlayTrack(1); // PLAY TRACK1
      handleLedsSLOW();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
      digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    }
  }



  //-------------------------Stage 2-----------------------------------------------------------

  if (buttonAstate == LOW) { // check if button A is pressed, elseif (condition) {code to be executed if first condition is false and this condition is true;} changed to "if" as "else if" caused issues
    //--------www.baldengineer.com millis button delay-----------
    buttonPushedMillis = currentMillis; // update the time when button was pushed
    ledReady = true;
  }
  // make sure this code isn't checked until after button has been let go
  if (ledReady) { //this is typical millis code here:
    if ((unsigned long)(currentMillis - buttonPushedMillis) >= turnOnDelay) {
      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;
      //-----------------------------------------------------------
      myservo.write(1042); // if it is rotate servo to 35 degrees
      PlayTrack(2); // PLAY TRACK2
      handleLedsMEDIUM();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, HIGH); //BUTTON A IS PRESSED SO MANUALLY LIGHT LED:
      digitalWrite(ledPinRB, LOW); //BUTTON B IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
      //--------www.baldengineer.com millis button delay-----------
      // setup our next "state"
      ledState = true;
      ledTurnedOnAt = currentMillis; // save when the LED turned on
      // wait for next button press
      ledReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) {
      ledState = false;
      // Put in all the actions you want to close them out below
      //-----------------------------------------------------------
      myservo.write(750);  // servo position
      PlayTrack(1); // PLAY TRACK1
      handleLedsSLOW();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
      digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    }
  }



  //-------------------------Stage 1-----------------------------------------------------------
  else { // This is the stage that will play by default else {code to be executed if all conditions are false;}
    myservo.write(750);  // servo position
    PlayTrack(1); // PLAY TRACK1
    handleLedsSLOW();  // checks if something is todo with the LEDs
    digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
  }

  delay(50);                // waits for a 20th of a second, should help with any button bounce
}
[/code]

Trust that if, if-else and so forth are 99.44 % not misbehaving.

I'd put money on 100 %, but since about 20 years I'm reluctant to be 100 % sure of anything, even my DOB.

If you carefully draw a flowchart of the entire logic section you are having trouble with you will see why it operates the way it does.

Obvsly draw a flowchart for each of the two versions.

Trace through the flowchart "playing computer". Do not make any assumptions or skip over any steps.

I only say flowchart because you are having trouble it seems sorting the syntax of the if/else statements when presented as lines of codes.

For some this is always a challenge! No shame in flowcharts. :wink:

a7

1 Like

Hi,
@alto777 has good advice.
You need to draw out what you want to output for your various combinations of input.
Can you list your input hardware and your output hardware.

If your need is for certain combinations of inputs to output certain scenarios then you may be better to consider switch.. case.. function.

https://www.arduino.cc/reference/en/language/structure/control-structure/switchcase/

Tom... :smiley: :+1: :coffee: :australia:

1 Like

Thank you that is a great idea. But my issue is all I changed to make the code work as expected was change "else if" to "if". I have read multiple examples about structuring the if...else if...else statement and I am having trouble seeing what the difference is with just using if...if...else, as both statements default to else if the first 2 statements are false. And I can't find anything that says an "else if" statement will make your code act differently to using an "if" statement. Keep thinking the "else if" possibly needs additional () or {} or something similar that aren't required in an "if" statement. Is using multiple "if" statements the normal thing to do in a straight forward sketch where you want to check say just a few conditions?

Assure me that you have posted both versions (or do in a new post) and maybe I'll get so interested that I will draw some flowcharts and show you…

So may I ask, did you try to draw some flowcharts? Did you see the difference?

If/Else is common to just about every language no matter the pesky syntax differences. You must come to grips with how it works.

As to whether it works, yes, yes it does. As I said, it would be very unusual for it to not do exactly what is expressed.

Having said that, there are N number of subtle and maybe not so subtle ways for noobs to go wrong. Braces, semicolons, logic expressions oh my!

As to whether it is how to accomplish a desired computation, well that's part of learning to program…

Google

if else if else if flowchart

switch to "images" and take a look at how a graphical representation of program flow relates to lines of code in the textual version.

flow chart <-> source code

a7

1 Like

Here is the working version

[code]
/*
    REQUIRED Libraries to make this sketch work:

    MP3Flash16Pv2 Library https://github.com/r0ndL/MP3Flash16Pv2

    BY8x0116P Library https://github.com/r0ndL/BY8x0116Pv2

  Important Note for if...elseif...else statements
  if (condition) {
  code to be executed if this condition is true;
  } else if (condition) {
  code to be executed if first condition is false and this condition is true;
  } else {
  code to be executed if all conditions are false;
  }
  NOTE!!!!! FOR THIS SKETCH I HAD TO CHANGE "else if" to "if" to make stage 2 work!!!!!!
*/

//--------------SET AUDIO OPTIONS FOR BY8301------------------------
// NOTE:  This sketch currently supports 3 different sound modules (MP3-FLASH-16P, BY8001-16P, BY8301-16P)

#define AUDIO1  2   // 1=MP3-FLASH-16P
// 2=BY8001-16P or BY8301-16P

// INCLUDE LIBS AND DECLARE VARIABLES...
#include "AltSoftSerial.h"
AltSoftSerial MP3Serial; // SoftwareSerial port assignments (RX, TX) to communicate with sound module

#if (AUDIO1==2)
//settings for BY8001-16P or BY8301-16P module...

#include "BY8x0116Pv2.h"
BY8x0116Pv2 myPlayer(MP3Serial); // Use SoftwareSerial as the serial port

#else
//settings for MP3-FLASH-16P...

#include "MP3Flash16Pv2.h"
MP3Flash16Pv2 myPlayer(MP3Serial); // Use SoftwareSerial as the serial port

#endif

// ARDUINO PIN ASSIGNMENTS to connect to by8301...
// Default Pin Assignments - BASIC WIRING in NOTES/MANUAL FOR BY8301
#define PIN_sound_BUSY    A3  //Connect to BUSY pin on sound module

// ADDITIONAL SOUND OPTIONS...
#define number_of_sounds  3
//----------------------------------------------------------------------------------------------------


//-----------BY8301 PLAYBACK CONTROL----------------------------------------------------
void PlayTrack(int TrackToPlay)
{
  static int TrackPlaying = -1;

  if (TrackPlaying != TrackToPlay)
  { // Not playing the required track
    myPlayer.stopPlay();                    // Stop what you're doing, if anything
    myPlayer.playFile(TrackToPlay, 10);     // Play requested track, VOLUME 10 (OUT OF 30)
    TrackPlaying = TrackToPlay;             // Note the track now playing
  }
  else if (!myPlayer.isBusy())              // Track number is right but is it still playing?
  {
    myPlayer.playFile(TrackToPlay, 10);     // No, so play it again, VOLUME 10 (OUT OF 30)
  }
}
//----------------------------------------------------------------------------------------------------


//--------------------SERVO-------------------------------------
#include<ServoTimer2.h>

ServoTimer2 myservo; // create servo object to control servo CONNECT UNO TX PIN 9, RX PIN 8
//--------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
// RED LEDS wired to buttonA & B press
int ledPinRA =  A0;      // the number of the LED pin
int ledPinRB =  A1;      // the number of the LED pin
//----------------------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
// buttonA & B with Pin No
int buttonApin = 2; //ButtonA
int buttonBpin = 4; //ButtonB
//----------------------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
int pos = 0; // set initial servo position to 0
int buttonAstate = 0; // variable for reading pushbutton status
int buttonBstate = 0; // variable for reading pushbutton status
//----------------------------------------------------------------------------------------------------


//--------www.baldengineer.com millis button delay-----------
unsigned long buttonPushedMillis; // when button was released
unsigned long ledTurnedOnAt; // when led was turned on
unsigned long turnOnDelay = 0; // wait to turn on LED AFTER PRESSING BUTTON 1000=1SEC
unsigned long turnOffDelay = 2000; // turn off LED after this time ONCE BUTTON IS RELEASED 1000=1SEC
bool ledReady = false; // flag for when button is let go
bool ledState = false; // for LED is on or not.
//-----------------------------------------------------------


//----------------------------STATE CONTROL FOR LED SEQUENCE & SPEEDS---------------------------------------
/*
  by noiasca https://forum.arduino.cc/index.php?topic=666044
*/
//----SPEEDS-----
const uint16_t intervalSLOW[] {1000, 1000, 1000, 1000, 1000, 1000, 1000, 100};  // time to wait in each intervall
const uint16_t intervalMEDIUM[] {400, 400, 400, 400, 400, 400, 400, 100};
const uint16_t intervalFAST[] {100, 100, 100, 100, 100, 100, 100, 100};

//----LED PIN No.-----
const byte ledPinA = 5;
const byte ledPinB = 6;
const byte ledPinC = 7;
const byte ledPinD = A4;
const byte ledPinE = A5;
const byte ledPinF = 10;
const byte ledPinG = 11;


void handleLedsSLOW()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalSLOW[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}


void handleLedsMEDIUM()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalMEDIUM[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}


void handleLedsFAST()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalFAST[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}



void setup() {
  myservo.attach(3); // SERVO pin
  Serial.begin(9600);
  pinMode(3, OUTPUT); // initialize the SERVO pin as an output
  pinMode(buttonApin, INPUT_PULLUP); // initialize the button A pin as an input
  pinMode(buttonBpin, INPUT_PULLUP); // initialize the button B pin as an input
  pinMode(ledPinA, OUTPUT); // initialize the LED1 pin as an output
  pinMode(ledPinB, OUTPUT); // initialize the LED2 pin as an output
  pinMode(ledPinC, OUTPUT); // initialize the LED3 pin as an output
  pinMode(ledPinD, OUTPUT); // initialize the LED4 pin as an output
  pinMode(ledPinE, OUTPUT); // initialize the LED5 pin as an output
  pinMode(ledPinF, OUTPUT); // initialize the LED6 pin as an output
  pinMode(ledPinG, OUTPUT); // initialize the LED7 pin as an output

  pinMode(12, OUTPUT);     // pin 12 as output for SLIDE switch 2No.LEDS

  pinMode(ledPinRA, OUTPUT); // initialize the LED pin as an output
  pinMode(ledPinRB, OUTPUT); // initialize the LED pin as an output

  MP3Serial.begin(9600);
  myPlayer.init(PIN_sound_BUSY);      // Init the player with the MP3 BUSY pin connected to Arduino pin defined
}



void loop() {
  //--------www.baldengineer.com millis button delay-----------
  unsigned long currentMillis = millis(); // get the time at the start of this loop()
  //-----------------------------------------------------------

  digitalWrite(12, HIGH); // sets the digital pin 12 on

  buttonAstate = digitalRead(buttonApin); // read the state of button A value
  buttonBstate = digitalRead(buttonBpin); // read the state of button B value


  //-------------------------Stage 3-----------------------------------------------------------
  if (buttonBstate == LOW) {  // check if button B is pressed, if (condition) {code to be executed if this condition is true;}
    //--------www.baldengineer.com millis button delay-----------
    buttonPushedMillis = currentMillis; // update the time when button was pushed
    ledReady = true;
  }
  // make sure this code isn't checked until after button has been let go
  if (ledReady) { //this is typical millis code here:
    if ((unsigned long)(currentMillis - buttonPushedMillis) >= turnOnDelay) {
      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;
      //-----------------------------------------------------------
      myservo.write(1442); // if it is rotate servo to 83 degrees
      PlayTrack(3); // PLAY TRACK3
      handleLedsFAST();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRB, HIGH);//BUTTON B IS PRESSED SO MANUALLY LIGHT LED:
      digitalWrite(ledPinRA, LOW); //BUTTON A IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
      //--------www.baldengineer.com millis button delay-----------
      // setup our next "state"
      ledState = true;
      ledTurnedOnAt = currentMillis; // save when the LED turned on
      // wait for next button press
      ledReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) {
      ledState = false;
      // Put in all the actions you want to close them out below
      //-----------------------------------------------------------
      myservo.write(750);  // servo position
      PlayTrack(1); // PLAY TRACK1
      handleLedsSLOW();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
      digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    }
  }



  //-------------------------Stage 2-----------------------------------------------------------

  if (buttonAstate == LOW) { // check if button A is pressed, elseif (condition) {code to be executed if first condition is false and this condition is true;} changed to "if" as "else if" caused issues
    //--------www.baldengineer.com millis button delay-----------
    buttonPushedMillis = currentMillis; // update the time when button was pushed
    ledReady = true;
  }
  // make sure this code isn't checked until after button has been let go
  if (ledReady) { //this is typical millis code here:
    if ((unsigned long)(currentMillis - buttonPushedMillis) >= turnOnDelay) {
      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;
      //-----------------------------------------------------------
      myservo.write(1042); // if it is rotate servo to 35 degrees
      PlayTrack(2); // PLAY TRACK2
      handleLedsMEDIUM();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, HIGH); //BUTTON A IS PRESSED SO MANUALLY LIGHT LED:
      digitalWrite(ledPinRB, LOW); //BUTTON B IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
      //--------www.baldengineer.com millis button delay-----------
      // setup our next "state"
      ledState = true;
      ledTurnedOnAt = currentMillis; // save when the LED turned on
      // wait for next button press
      ledReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) {
      ledState = false;
      // Put in all the actions you want to close them out below
      //-----------------------------------------------------------
      myservo.write(750);  // servo position
      PlayTrack(1); // PLAY TRACK1
      handleLedsSLOW();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
      digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    }
  }



  //-------------------------Stage 1-----------------------------------------------------------
  else { // This is the stage that will play by default else {code to be executed if all conditions are false;}
    myservo.write(750);  // servo position
    PlayTrack(1); // PLAY TRACK1
    handleLedsSLOW();  // checks if something is todo with the LEDs
    digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
  }

  delay(50);                // waits for a 20th of a second, should help with any button bounce
}
[/code]

And this is the version that stage2 servo and led won't perform as expected

[code]
/*
    REQUIRED Libraries to make this sketch work:

    MP3Flash16Pv2 Library https://github.com/r0ndL/MP3Flash16Pv2

    BY8x0116P Library https://github.com/r0ndL/BY8x0116Pv2

  Important Note for if...elseif...else statements
  if (condition) {
  code to be executed if this condition is true;
  } else if (condition) {
  code to be executed if first condition is false and this condition is true;
  } else {
  code to be executed if all conditions are false;
  }
  NOTE!!!!! FOR THIS SKETCH I HAD TO CHANGE "else if" to "if" to make stage 2 work!!!!!!
*/

//--------------SET AUDIO OPTIONS FOR BY8301------------------------
// NOTE:  This sketch currently supports 3 different sound modules (MP3-FLASH-16P, BY8001-16P, BY8301-16P)

#define AUDIO1  2   // 1=MP3-FLASH-16P
// 2=BY8001-16P or BY8301-16P

// INCLUDE LIBS AND DECLARE VARIABLES...
#include "AltSoftSerial.h"
AltSoftSerial MP3Serial; // SoftwareSerial port assignments (RX, TX) to communicate with sound module

#if (AUDIO1==2)
//settings for BY8001-16P or BY8301-16P module...

#include "BY8x0116Pv2.h"
BY8x0116Pv2 myPlayer(MP3Serial); // Use SoftwareSerial as the serial port

#else
//settings for MP3-FLASH-16P...

#include "MP3Flash16Pv2.h"
MP3Flash16Pv2 myPlayer(MP3Serial); // Use SoftwareSerial as the serial port

#endif

// ARDUINO PIN ASSIGNMENTS to connect to by8301...
// Default Pin Assignments - BASIC WIRING in NOTES/MANUAL FOR BY8301
#define PIN_sound_BUSY    A3  //Connect to BUSY pin on sound module

// ADDITIONAL SOUND OPTIONS...
#define number_of_sounds  3
//----------------------------------------------------------------------------------------------------


//-----------BY8301 PLAYBACK CONTROL----------------------------------------------------
void PlayTrack(int TrackToPlay)
{
  static int TrackPlaying = -1;

  if (TrackPlaying != TrackToPlay)
  { // Not playing the required track
    myPlayer.stopPlay();                    // Stop what you're doing, if anything
    myPlayer.playFile(TrackToPlay, 10);     // Play requested track, VOLUME 10 (OUT OF 30)
    TrackPlaying = TrackToPlay;             // Note the track now playing
  }
  else if (!myPlayer.isBusy())              // Track number is right but is it still playing?
  {
    myPlayer.playFile(TrackToPlay, 10);     // No, so play it again, VOLUME 10 (OUT OF 30)
  }
}
//----------------------------------------------------------------------------------------------------


//--------------------SERVO-------------------------------------
#include<ServoTimer2.h>

ServoTimer2 myservo; // create servo object to control servo CONNECT UNO TX PIN 9, RX PIN 8
//--------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
// RED LEDS wired to buttonA & B press
int ledPinRA =  A0;      // the number of the LED pin
int ledPinRB =  A1;      // the number of the LED pin
//----------------------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
// buttonA & B with Pin No
int buttonApin = 2; //ButtonA
int buttonBpin = 4; //ButtonB
//----------------------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
int pos = 0; // set initial servo position to 0
int buttonAstate = 0; // variable for reading pushbutton status
int buttonBstate = 0; // variable for reading pushbutton status
//----------------------------------------------------------------------------------------------------


//--------www.baldengineer.com millis button delay-----------
unsigned long buttonPushedMillis; // when button was released
unsigned long ledTurnedOnAt; // when led was turned on
unsigned long turnOnDelay = 0; // wait to turn on LED AFTER PRESSING BUTTON 1000=1SEC
unsigned long turnOffDelay = 2000; // turn off LED after this time ONCE BUTTON IS RELEASED 1000=1SEC
bool ledReady = false; // flag for when button is let go
bool ledState = false; // for LED is on or not.
//-----------------------------------------------------------


//----------------------------STATE CONTROL FOR LED SEQUENCE & SPEEDS---------------------------------------
/*
  by noiasca https://forum.arduino.cc/index.php?topic=666044
*/
//----SPEEDS-----
const uint16_t intervalSLOW[] {1000, 1000, 1000, 1000, 1000, 1000, 1000, 100};  // time to wait in each intervall
const uint16_t intervalMEDIUM[] {400, 400, 400, 400, 400, 400, 400, 100};
const uint16_t intervalFAST[] {100, 100, 100, 100, 100, 100, 100, 100};

//----LED PIN No.-----
const byte ledPinA = 5;
const byte ledPinB = 6;
const byte ledPinC = 7;
const byte ledPinD = A4;
const byte ledPinE = A5;
const byte ledPinF = 10;
const byte ledPinG = 11;


void handleLedsSLOW()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalSLOW[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}


void handleLedsMEDIUM()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalMEDIUM[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}


void handleLedsFAST()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalFAST[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}



void setup() {
  myservo.attach(3); // SERVO pin
  Serial.begin(9600);
  pinMode(3, OUTPUT); // initialize the SERVO pin as an output
  pinMode(buttonApin, INPUT_PULLUP); // initialize the button A pin as an input
  pinMode(buttonBpin, INPUT_PULLUP); // initialize the button B pin as an input
  pinMode(ledPinA, OUTPUT); // initialize the LED1 pin as an output
  pinMode(ledPinB, OUTPUT); // initialize the LED2 pin as an output
  pinMode(ledPinC, OUTPUT); // initialize the LED3 pin as an output
  pinMode(ledPinD, OUTPUT); // initialize the LED4 pin as an output
  pinMode(ledPinE, OUTPUT); // initialize the LED5 pin as an output
  pinMode(ledPinF, OUTPUT); // initialize the LED6 pin as an output
  pinMode(ledPinG, OUTPUT); // initialize the LED7 pin as an output

  pinMode(12, OUTPUT);     // pin 12 as output for SLIDE switch 2No.LEDS

  pinMode(ledPinRA, OUTPUT); // initialize the LED pin as an output
  pinMode(ledPinRB, OUTPUT); // initialize the LED pin as an output

  MP3Serial.begin(9600);
  myPlayer.init(PIN_sound_BUSY);      // Init the player with the MP3 BUSY pin connected to Arduino pin defined
}



void loop() {
  //--------www.baldengineer.com millis button delay-----------
  unsigned long currentMillis = millis(); // get the time at the start of this loop()
  //-----------------------------------------------------------

  digitalWrite(12, HIGH); // sets the digital pin 12 on

  buttonAstate = digitalRead(buttonApin); // read the state of button A value
  buttonBstate = digitalRead(buttonBpin); // read the state of button B value


  //-------------------------Stage 3-----------------------------------------------------------
  if (buttonBstate == LOW) {  // check if button B is pressed, if (condition) {code to be executed if this condition is true;}
    //--------www.baldengineer.com millis button delay-----------
    buttonPushedMillis = currentMillis; // update the time when button was pushed
    ledReady = true;
  }
  // make sure this code isn't checked until after button has been let go
  if (ledReady) { //this is typical millis code here:
    if ((unsigned long)(currentMillis - buttonPushedMillis) >= turnOnDelay) {
      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;
      //-----------------------------------------------------------
      myservo.write(1442); // if it is rotate servo to 83 degrees
      PlayTrack(3); // PLAY TRACK3
      handleLedsFAST();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRB, HIGH);//BUTTON B IS PRESSED SO MANUALLY LIGHT LED:
      digitalWrite(ledPinRA, LOW); //BUTTON A IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
      //--------www.baldengineer.com millis button delay-----------
      // setup our next "state"
      ledState = true;
      ledTurnedOnAt = currentMillis; // save when the LED turned on
      // wait for next button press
      ledReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) {
      ledState = false;
      // Put in all the actions you want to close them out below
      //-----------------------------------------------------------
      myservo.write(750);  // servo position
      PlayTrack(1); // PLAY TRACK1
      handleLedsSLOW();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
      digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    }
  }



  //-------------------------Stage 2-----------------------------------------------------------
else  if (buttonAstate == LOW) { // check if button A is pressed, elseif (condition) {code to be executed if first condition is false and this condition is true;} changed to "if" as "else if" caused issues
    //--------www.baldengineer.com millis button delay-----------
    buttonPushedMillis = currentMillis; // update the time when button was pushed
    ledReady = true;
  }
  // make sure this code isn't checked until after button has been let go
  if (ledReady) { //this is typical millis code here:
    if ((unsigned long)(currentMillis - buttonPushedMillis) >= turnOnDelay) {
      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;
      //-----------------------------------------------------------
      myservo.write(1042); // if it is rotate servo to 35 degrees
      PlayTrack(2); // PLAY TRACK2
      handleLedsMEDIUM();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, HIGH); //BUTTON A IS PRESSED SO MANUALLY LIGHT LED:
      digitalWrite(ledPinRB, LOW); //BUTTON B IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
      //--------www.baldengineer.com millis button delay-----------
      // setup our next "state"
      ledState = true;
      ledTurnedOnAt = currentMillis; // save when the LED turned on
      // wait for next button press
      ledReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) {
      ledState = false;
      // Put in all the actions you want to close them out below
      //-----------------------------------------------------------
      myservo.write(750);  // servo position
      PlayTrack(1); // PLAY TRACK1
      handleLedsSLOW();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
      digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    }
  }



  //-------------------------Stage 1-----------------------------------------------------------
  else { // This is the stage that will play by default else {code to be executed if all conditions are false;}
    myservo.write(750);  // servo position
    PlayTrack(1); // PLAY TRACK1
    handleLedsSLOW();  // checks if something is todo with the LEDs
    digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
  }

  delay(50);                // waits for a 20th of a second, should help with any button bounce
}
[/code]

As I said only change between is this line changed from

"//-------------------------Stage 2-----------------------------------------------------------
else if (buttonAstate == LOW) {"
To
"//-------------------------Stage 2-----------------------------------------------------------
if (buttonAstate == LOW) {" and that made the servo and leds work as expected

Your problem is that the 'else' and the 'else if' statements are NOT associated with the 'if's you think they are! For example, you state:

stage1, (i put this in "else" as its the default action) When neither button is pressed, the sketch will return the the servo to the parked position, it plays sound 01 and sequences the slow speed version of the LEDs

That is NOT how you have your conditionals arranged! At the outermost level you should have something like this:

  //-------------------------Stage 3-----------------------------------------------------------
  if (buttonBstate == LOW) 
  {
    ... 
  }
  //-------------------------Stage 2-----------------------------------------------------------
  else  if (buttonAstate == LOW) 
  {
    ... 
  }
  //-------------------------Stage 1-----------------------------------------------------------
  else 
  {
    ... 
  }

But look at your code closely. The following 'else if':

else if (buttonAstate == LOW)

is associated with the preceding 'if':

if (ledState)

Similarly your stage 3 'else' is actually associated with the preceding 'if':

if (ledState)

You are going to have to rearrange your logic. Make a flowchart as suggested and then code it.

Thank you @natty15d for the versions.

Thanks @ToddL1962, this might help!

Here's where the else changes the behaviour:


	if (X) {
		X STUFF
	}
	else
		if (Y) {
			if (Z) {
	 			NOT X and Y and Z STUFF
			}
		}

versus
	if (X) {
		X STUFF
	}


	if (Y) {
		if (Z) {
			Y and Z STUFF
		}
	}

The else subordinates the following if statement.

Version one: if X is true, do X stuff, if X is false and Y and Z are tue do Z stuff.

Version two: if X is true, do X stuff. Regardless, if Y and Z are tue do Z stuff.


Version two on the left.

All it took was one else dropped in there. Perfectly valid syntax both, just gotta code what you mean.

Auto format can help, but your code is pretty dense and seeing what you think it is doing or what it is really doing is hard.

Did you try yourself? Use a flowchart method to design your next program, and learn the syntax of if/else.

a7

2 Likes

I'm not a fan of writing code for other people, but your handleLed routines, which differ literally only in one line of code was low hanging fruit, I could not resist changing it, mostly as an exercise.

Multiple functions that diffe in one line of code only beg to be collapsed into one function with a passed value to select among the desired different behaviours.

I share it hoping you take some time to figure it out. It is untested; I am sure the errors will be spotted by the eagles. who fly over us in these fora. They may offer further improvements of their own, or wholesale better alternatives.

The below will makes the source code shorter, It will make your object code (memory use) lower. It will be ONE place to modify or maintain the handling of the LEDs.

switch/case is nice and has its place. Not here. In this kind of thing, arrays work better.

// Make a 2 dimensional array of delay values

const uint16_t intervalSMF[3][8] = {

	{1000, 1000, 1000, 1000, 1000, 1000, 1000, 100},	// SLOW
	{400, 400, 400, 400, 400, 400, 400, 100},			// MEDIUM
	{100, 100, 100, 100, 100, 100, 100, 100},			// FAST
};

// an array of the segment pins

const byte segment[7] = {
		ledPinA,
		ledPinB,
		ledPinC,
		ledPinD,
		ledPinE,
		ledPinF,
		ledPinG,
};

// one handler to, um, handle them all

void handleLeds(int rateSMF)
{
	static uint32_t previousMillis = 0;
	static byte state = 7;
 
	if (millis() - previousMillis < intervalSMF[rateSMF][state])
		return; // it is NOT time for next sate

	state++;
	state = state % 8;
	Serial.print(F("state=")); Serial.println(state);

	for (byte xx = 0; xx < 7; xx++)
		digitalWrite(segment[xx], LOW);
		
	if (state != 7)
		digitalWrite(segment[state], HIGH);

	previousMillis = millis();
}

Later where you give the display attention
 	      handleLeds(0);  // SLOW
// or 	      
 	      handleLeds(1);  // MEDIUM
// or 	      
 	      handleLeds(2);  // FAST

I hand you this fish, not to feed you but in the hope it helps you learn to fish.

a7

1 Like

Thankyou for the reply, thought i had understood what you meant so changed the code to have separate millis controls for each button

//--------www.baldengineer.com millis buttonA delay-----------
unsigned long buttonAPushedMillis; // when button was released
unsigned long ledATurnedOnAt; // when led was turned on
unsigned long turnOnADelay = 0; // wait to turn on LED AFTER PRESSING BUTTON 1000=1SEC
unsigned long turnOffADelay = 2000; // turn off LED after this time ONCE BUTTON IS RELEASED 1000=1SEC
bool ledAReady = false; // flag for when button is let go
bool ledAState = false; // for LED is on or not.
//-----------------------------------------------------------


//--------www.baldengineer.com millis buttonB delay-----------
unsigned long buttonBPushedMillis; // when button was released
unsigned long ledBTurnedOnAt; // when led was turned on
unsigned long turnOnBDelay = 0; // wait to turn on LED AFTER PRESSING BUTTON 1000=1SEC
unsigned long turnOffBDelay = 2000; // turn off LED after this time ONCE BUTTON IS RELEASED 1000=1SEC
bool ledBReady = false; // flag for when button is let go
bool ledBState = false; // for LED is on or not.
//-----------------------------------------------------------
  //--------www.baldengineer.com millis button delay-----------
  unsigned long currentAMillis = millis(); // get the time at the start of this loop()
  unsigned long currentBMillis = millis(); // get the time at the start of this loop()
  //-----------------------------------------------------------

But that didnt work, the servo just cycles constantly and the LEDS wont sequence correctly.

This is the code as it is now

[code]
/*
    REQUIRED Libraries to make this sketch work:

    MP3Flash16Pv2 Library https://github.com/r0ndL/MP3Flash16Pv2

    BY8x0116P Library https://github.com/r0ndL/BY8x0116Pv2

  Important Note for if...elseif...else statements
  if (condition) {
  code to be executed if this condition is true;
  } else if (condition) {
  code to be executed if first condition is false and this condition is true;
  } else {
  code to be executed if all conditions are false;
  }
  NOTE!!!!! NEED SEPERATE STATE CONTROLS FOR EACH BUTTON!!!!!!
*/

//--------------SET AUDIO OPTIONS FOR BY8301------------------------
// NOTE:  This sketch currently supports 3 different sound modules (MP3-FLASH-16P, BY8001-16P, BY8301-16P)

#define AUDIO1  2   // 1=MP3-FLASH-16P
// 2=BY8001-16P or BY8301-16P

// INCLUDE LIBS AND DECLARE VARIABLES...
#include "AltSoftSerial.h"
AltSoftSerial MP3Serial; // SoftwareSerial port assignments (RX, TX) to communicate with sound module

#if (AUDIO1==2)
//settings for BY8001-16P or BY8301-16P module...

#include "BY8x0116Pv2.h"
BY8x0116Pv2 myPlayer(MP3Serial); // Use SoftwareSerial as the serial port

#else
//settings for MP3-FLASH-16P...

#include "MP3Flash16Pv2.h"
MP3Flash16Pv2 myPlayer(MP3Serial); // Use SoftwareSerial as the serial port

#endif

// ARDUINO PIN ASSIGNMENTS to connect to by8301...
// Default Pin Assignments - BASIC WIRING in NOTES/MANUAL FOR BY8301
#define PIN_sound_BUSY    A3  //Connect to BUSY pin on sound module

// ADDITIONAL SOUND OPTIONS...
#define number_of_sounds  3
//----------------------------------------------------------------------------------------------------


//-----------BY8301 PLAYBACK CONTROL----------------------------------------------------
void PlayTrack(int TrackToPlay)
{
  static int TrackPlaying = -1;

  if (TrackPlaying != TrackToPlay)
  { // Not playing the required track
    myPlayer.stopPlay();                    // Stop what you're doing, if anything
    myPlayer.playFile(TrackToPlay, 10);     // Play requested track, VOLUME 10 (OUT OF 30)
    TrackPlaying = TrackToPlay;             // Note the track now playing
  }
  else if (!myPlayer.isBusy())              // Track number is right but is it still playing?
  {
    myPlayer.playFile(TrackToPlay, 10);     // No, so play it again, VOLUME 10 (OUT OF 30)
  }
}
//----------------------------------------------------------------------------------------------------


//--------------------SERVO-------------------------------------
#include<ServoTimer2.h>

ServoTimer2 myservo; // create servo object to control servo CONNECT UNO TX PIN 9, RX PIN 8
//--------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
// RED LEDS wired to buttonA & B press
int ledPinRA =  A0;      // the number of the LED pin
int ledPinRB =  A1;      // the number of the LED pin
//----------------------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
// buttonA & B with Pin No
int buttonApin = 2; //ButtonA
int buttonBpin = 4; //ButtonB
//----------------------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
int pos = 0; // set initial servo position to 0
int buttonAstate = 0; // variable for reading pushbutton status
int buttonBstate = 0; // variable for reading pushbutton status
//----------------------------------------------------------------------------------------------------


//--------www.baldengineer.com millis buttonA delay-----------
unsigned long buttonAPushedMillis; // when button was released
unsigned long ledATurnedOnAt; // when led was turned on
unsigned long turnOnADelay = 0; // wait to turn on LED AFTER PRESSING BUTTON 1000=1SEC
unsigned long turnOffADelay = 2000; // turn off LED after this time ONCE BUTTON IS RELEASED 1000=1SEC
bool ledAReady = false; // flag for when button is let go
bool ledAState = false; // for LED is on or not.
//-----------------------------------------------------------


//--------www.baldengineer.com millis buttonB delay-----------
unsigned long buttonBPushedMillis; // when button was released
unsigned long ledBTurnedOnAt; // when led was turned on
unsigned long turnOnBDelay = 0; // wait to turn on LED AFTER PRESSING BUTTON 1000=1SEC
unsigned long turnOffBDelay = 2000; // turn off LED after this time ONCE BUTTON IS RELEASED 1000=1SEC
bool ledBReady = false; // flag for when button is let go
bool ledBState = false; // for LED is on or not.
//-----------------------------------------------------------


//----------------------------STATE CONTROL FOR LED SEQUENCE & SPEEDS---------------------------------------
/*
  by noiasca https://forum.arduino.cc/index.php?topic=666044
*/
//----SPEEDS-----
const uint16_t intervalSLOW[] {1000, 1000, 1000, 1000, 1000, 1000, 1000, 100};  // time to wait in each intervall
const uint16_t intervalMEDIUM[] {400, 400, 400, 400, 400, 400, 400, 100};
const uint16_t intervalFAST[] {100, 100, 100, 100, 100, 100, 100, 100};

//----LED PIN No.-----
const byte ledPinA = 5;
const byte ledPinB = 6;
const byte ledPinC = 7;
const byte ledPinD = A4;
const byte ledPinE = A5;
const byte ledPinF = 10;
const byte ledPinG = 11;


void handleLedsSLOW()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalSLOW[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}


void handleLedsMEDIUM()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalMEDIUM[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}


void handleLedsFAST()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalFAST[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}



void setup() {
  myservo.attach(3); // SERVO pin
  Serial.begin(9600);
  pinMode(3, OUTPUT); // initialize the SERVO pin as an output
  pinMode(buttonApin, INPUT_PULLUP); // initialize the button A pin as an input
  pinMode(buttonBpin, INPUT_PULLUP); // initialize the button B pin as an input
  pinMode(ledPinA, OUTPUT); // initialize the LED1 pin as an output
  pinMode(ledPinB, OUTPUT); // initialize the LED2 pin as an output
  pinMode(ledPinC, OUTPUT); // initialize the LED3 pin as an output
  pinMode(ledPinD, OUTPUT); // initialize the LED4 pin as an output
  pinMode(ledPinE, OUTPUT); // initialize the LED5 pin as an output
  pinMode(ledPinF, OUTPUT); // initialize the LED6 pin as an output
  pinMode(ledPinG, OUTPUT); // initialize the LED7 pin as an output

  pinMode(12, OUTPUT);     // pin 12 as output for SLIDE switch 2No.LEDS

  pinMode(ledPinRA, OUTPUT); // initialize the LED pin as an output
  pinMode(ledPinRB, OUTPUT); // initialize the LED pin as an output

  MP3Serial.begin(9600);
  myPlayer.init(PIN_sound_BUSY);      // Init the player with the MP3 BUSY pin connected to Arduino pin defined
}



void loop() {
  //--------www.baldengineer.com millis button delay-----------
  unsigned long currentAMillis = millis(); // get the time at the start of this loop()
  unsigned long currentBMillis = millis(); // get the time at the start of this loop()
  //-----------------------------------------------------------

  digitalWrite(12, HIGH); // sets the digital pin 12 on

  buttonAstate = digitalRead(buttonApin); // read the state of button A value
  buttonBstate = digitalRead(buttonBpin); // read the state of button B value


  //-------------------------Stage 3-----------------------------------------------------------
  if (buttonBstate == LOW)
  { // check if button B is pressed, if (condition) {code to be executed if this condition is true;}
    //--------www.baldengineer.com millis button delay-----------
    buttonBPushedMillis = currentBMillis; // update the time when button was pushed
    ledBReady = true;
  }
  // make sure this code isn't checked until after button has been let go
  if (ledBReady) { //this is typical millis code here:
    if ((unsigned long)(currentBMillis - buttonBPushedMillis) >= turnOnBDelay) {
      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;
      //-----------------------------------------------------------
      myservo.write(1442); // if it is rotate servo to 83 degrees
      PlayTrack(3); // PLAY TRACK3
      handleLedsFAST();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRB, HIGH);//BUTTON B IS PRESSED SO MANUALLY LIGHT LED:
      digitalWrite(ledPinRA, LOW); //BUTTON A IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
      //--------www.baldengineer.com millis button delay-----------
      // setup our next "state"
      ledBState = true;
      ledBTurnedOnAt = currentBMillis; // save when the LED turned on
      // wait for next button press
      ledBReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledBState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentBMillis - ledBTurnedOnAt) >= turnOffBDelay) {
      ledBState = false;
      // Put in all the actions you want to close them out below
      //-----------------------------------------------------------
      myservo.write(750);  // servo position
      PlayTrack(1); // PLAY TRACK1
      handleLedsSLOW();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
      digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    }
  }


  //-------------------------Stage 2-----------------------------------------------------------

  else if (buttonAstate == LOW)
  { // check if button A is pressed, elseif (condition) {code to be executed if first condition is false and this condition is true;}
    //--------www.baldengineer.com millis button delay-----------
    buttonAPushedMillis = currentAMillis; // update the time when button was pushed
    ledAReady = true;
  }
  // make sure this code isn't checked until after button has been let go
  if (ledAReady) { //this is typical millis code here:
    if ((unsigned long)(currentAMillis - buttonAPushedMillis) >= turnOnADelay) {
      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;
      //-----------------------------------------------------------
      myservo.write(1042); // if it is rotate servo to 35 degrees
      PlayTrack(2); // PLAY TRACK2
      handleLedsMEDIUM();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, HIGH); //BUTTON A IS PRESSED SO MANUALLY LIGHT LED:
      digitalWrite(ledPinRB, LOW); //BUTTON B IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
      //--------www.baldengineer.com millis button delay-----------
      // setup our next "state"
      ledAState = true;
      ledATurnedOnAt = currentAMillis; // save when the LED turned on
      // wait for next button press
      ledAReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledAState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentAMillis - ledATurnedOnAt) >= turnOffADelay) {
      ledAState = false;
      // Put in all the actions you want to close them out below
      //-----------------------------------------------------------
      myservo.write(750);  // servo position
      PlayTrack(1); // PLAY TRACK1
      handleLedsSLOW();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
      digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    }
  }


  //-------------------------Stage 1-----------------------------------------------------------
  else { // This is the stage that will play by default else {code to be executed if all conditions are false;}
    myservo.write(750);  // servo position
    PlayTrack(1); // PLAY TRACK1
    handleLedsSLOW();  // checks if something is todo with the LEDs
    digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
  }

  delay(50);                // waits for a 20th of a second, should help with any button bounce
}
[/code]

I tried adding in { just after the button state designators and } at the end of the statement for both "if" & "else if" to close of the statements, this made the servo, leds & sound work but the button delay stop working!

//-------------------------Stage 3-----------------------------------------------------------
  if (buttonBstate == LOW){
  { // check if button B is pressed, if (condition) {code to be executed if this condition is true;}
    //--------www.baldengineer.com millis button delay-----------
    buttonBPushedMillis = currentBMillis; // update the time when button was pushed
    ledBReady = true;
  }
  // make sure this code isn't checked until after button has been let go
  if (ledBReady) { //this is typical millis code here:
    if ((unsigned long)(currentBMillis - buttonBPushedMillis) >= turnOnBDelay) {
      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;
      //-----------------------------------------------------------
      myservo.write(1442); // if it is rotate servo to 83 degrees
      PlayTrack(3); // PLAY TRACK3
      handleLedsFAST();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRB, HIGH);//BUTTON B IS PRESSED SO MANUALLY LIGHT LED:
      digitalWrite(ledPinRA, LOW); //BUTTON A IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
      //--------www.baldengineer.com millis button delay-----------
      // setup our next "state"
      ledBState = true;
      ledBTurnedOnAt = currentBMillis; // save when the LED turned on
      // wait for next button press
      ledBReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledBState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentBMillis - ledBTurnedOnAt) >= turnOffBDelay) {
      ledBState = false;
      // Put in all the actions you want to close them out below
      //-----------------------------------------------------------
      myservo.write(750);  // servo position
      PlayTrack(1); // PLAY TRACK1
      handleLedsSLOW();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
      digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    }
  }
  }

  //-------------------------Stage 2-----------------------------------------------------------

  else if (buttonAstate == LOW){
  { // check if button A is pressed, elseif (condition) {code to be executed if first condition is false and this condition is true;}
    //--------www.baldengineer.com millis button delay-----------
    buttonAPushedMillis = currentAMillis; // update the time when button was pushed
    ledAReady = true;
  }
  // make sure this code isn't checked until after button has been let go
  if (ledAReady) { //this is typical millis code here:
    if ((unsigned long)(currentAMillis - buttonAPushedMillis) >= turnOnADelay) {
      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;
      //-----------------------------------------------------------
      myservo.write(1042); // if it is rotate servo to 35 degrees
      PlayTrack(2); // PLAY TRACK2
      handleLedsMEDIUM();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, HIGH); //BUTTON A IS PRESSED SO MANUALLY LIGHT LED:
      digitalWrite(ledPinRB, LOW); //BUTTON B IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
      //--------www.baldengineer.com millis button delay-----------
      // setup our next "state"
      ledAState = true;
      ledATurnedOnAt = currentAMillis; // save when the LED turned on
      // wait for next button press
      ledAReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledAState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentAMillis - ledATurnedOnAt) >= turnOffADelay) {
      ledAState = false;
      // Put in all the actions you want to close them out below
      //-----------------------------------------------------------
      myservo.write(750);  // servo position
      PlayTrack(1); // PLAY TRACK1
      handleLedsSLOW();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
      digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    }
  }
  }

  //-------------------------Stage 1-----------------------------------------------------------
  else { // This is the stage that will play by default else {code to be executed if all conditions are false;}
    myservo.write(750);  // servo position
    PlayTrack(1); // PLAY TRACK1
    handleLedsSLOW();  // checks if something is todo with the LEDs
    digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
  }

  delay(50);                // waits for a 20th of a second, should help with any button bounce
}

Sorry for not getting this, i really am trying to grasp the concept, but i'mjust not there yet :confused:

thank you thats fantastic, i now get the sublte difference between the if...if...else sketch and the if...else if...sketch

Thank you that is amazing, i will have a look at that and try to figure out what is going on in your proposed change :slight_smile:

Latest version of the code. Ive put the buttonA & B functions as wrapper function that are called into action in the "if" & "else if" parts of the sketch.
It works, BUT, the delay function on the buttons release has stopped working. What am i missing with this code, i feel i've almost got it but i'm just overlooking one small key part.
The issue is the button delay code, because of the way it was originally written i cant put it inside a statement because it stops the millis delay coding from working.
Any help would fantastic :slight_smile:

[code]
/*
    REQUIRED Libraries to make this sketch work:

    MP3Flash16Pv2 Library https://github.com/r0ndL/MP3Flash16Pv2

    BY8x0116P Library https://github.com/r0ndL/BY8x0116Pv2

  Important Note for if...elseif...else statements
  if (condition) {
  code to be executed if this condition is true;
  } else if (condition) {
  code to be executed if first condition is false and this condition is true;
  } else {
  code to be executed if all conditions are false;
  }
  NOTE!!!!! NEED SEPERATE STATE CONTROLS FOR EACH BUTTON!!!!!!
*/

//--------------SET AUDIO OPTIONS FOR BY8301------------------------
// NOTE:  This sketch currently supports 3 different sound modules (MP3-FLASH-16P, BY8001-16P, BY8301-16P)

#define AUDIO1  2   // 1=MP3-FLASH-16P
// 2=BY8001-16P or BY8301-16P

// INCLUDE LIBS AND DECLARE VARIABLES...
#include "AltSoftSerial.h"
AltSoftSerial MP3Serial; // SoftwareSerial port assignments (RX, TX) to communicate with sound module

#if (AUDIO1==2)
//settings for BY8001-16P or BY8301-16P module...

#include "BY8x0116Pv2.h"
BY8x0116Pv2 myPlayer(MP3Serial); // Use SoftwareSerial as the serial port

#else
//settings for MP3-FLASH-16P...

#include "MP3Flash16Pv2.h"
MP3Flash16Pv2 myPlayer(MP3Serial); // Use SoftwareSerial as the serial port

#endif

// ARDUINO PIN ASSIGNMENTS to connect to by8301...
// Default Pin Assignments - BASIC WIRING in NOTES/MANUAL FOR BY8301
#define PIN_sound_BUSY    A3  //Connect to BUSY pin on sound module

// ADDITIONAL SOUND OPTIONS...
#define number_of_sounds  3
//----------------------------------------------------------------------------------------------------




//-----------BY8301 PLAYBACK CONTROL----------------------------------------------------
void PlayTrack(int TrackToPlay)
{
  static int TrackPlaying = -1;

  if (TrackPlaying != TrackToPlay)
  { // Not playing the required track
    myPlayer.stopPlay();                    // Stop what you're doing, if anything
    myPlayer.playFile(TrackToPlay, 10);     // Play requested track, VOLUME 10 (OUT OF 30)
    TrackPlaying = TrackToPlay;             // Note the track now playing
  }
  else if (!myPlayer.isBusy())              // Track number is right but is it still playing?
  {
    myPlayer.playFile(TrackToPlay, 10);     // No, so play it again, VOLUME 10 (OUT OF 30)
  }
}
//----------------------------------------------------------------------------------------------------


//--------------------SERVO-------------------------------------
#include<ServoTimer2.h>

ServoTimer2 myservo; // create servo object to control servo CONNECT UNO TX PIN 9, RX PIN 8
//--------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
// RED LEDS wired to buttonA & B press
int ledPinRA =  A0;      // the number of the LED pin
int ledPinRB =  A1;      // the number of the LED pin
//----------------------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
// buttonA & B with Pin No
int buttonApin = 2; //ButtonA
int buttonBpin = 4; //ButtonB
//----------------------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------
int pos = 0; // set initial servo position to 0
int buttonAstate = 0; // variable for reading pushbutton status
int buttonBstate = 0; // variable for reading pushbutton status
int lastbuttonAstate = 0; // variable for reading pushbutton status
int lastbuttonBstate = 0; // variable for reading pushbutton status
//----------------------------------------------------------------------------------------------------


//--------www.baldengineer.com millis buttonA delay-----------
unsigned long buttonAPushedMillis; // when button was released
unsigned long ledATurnedOnAt; // when led was turned on
unsigned long turnOnADelay = 0; // wait to turn on LED AFTER PRESSING BUTTON 1000=1SEC
unsigned long turnOffADelay = 2000; // turn off LED after this time ONCE BUTTON IS RELEASED 1000=1SEC
bool ledAReady = false; // flag for when button is let go
bool ledAState = false; // for LED is on or not.
//-----------------------------------------------------------
unsigned long currentAMillis = millis(); // get the time at the start of this loop()
unsigned long currentBMillis = millis(); // get the time at the start of this loop()

//--------www.baldengineer.com millis buttonB delay-----------
unsigned long buttonBPushedMillis; // when button was released
unsigned long ledBTurnedOnAt; // when led was turned on
unsigned long turnOnBDelay = 0; // wait to turn on LED AFTER PRESSING BUTTON 1000=1SEC
unsigned long turnOffBDelay = 2000; // turn off LED after this time ONCE BUTTON IS RELEASED 1000=1SEC
bool ledBReady = false; // flag for when button is let go
bool ledBState = false; // for LED is on or not.
//-----------------------------------------------------------

//----------------------------STATE CONTROL FOR LED SEQUENCE & SPEEDS---------------------------------------
/*
  by noiasca https://forum.arduino.cc/index.php?topic=666044
*/
//----SPEEDS-----
const uint16_t intervalSLOW[] {1000, 1000, 1000, 1000, 1000, 1000, 1000, 100};  // time to wait in each intervall
const uint16_t intervalMEDIUM[] {400, 400, 400, 400, 400, 400, 400, 100};
const uint16_t intervalFAST[] {100, 100, 100, 100, 100, 100, 100, 100};

//----LED PIN No.-----
const byte ledPinA = 5;
const byte ledPinB = 6;
const byte ledPinC = 7;
const byte ledPinD = A4;
const byte ledPinE = A5;
const byte ledPinF = 10;
const byte ledPinG = 11;


void handleLedsSLOW()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalSLOW[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}


void handleLedsMEDIUM()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalMEDIUM[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}


void handleLedsFAST()
{
  static uint32_t previousMillis = 0;
  static byte state = 7;
  if (millis() - previousMillis >= intervalFAST[state])
  {
    // it's time for next state
    state++;
    state = state % 8;
    Serial.print(F("state=")); Serial.println(state);

    // act according state
    switch (state)
    {
      case 0:
        digitalWrite(ledPinA, HIGH);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 1:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, HIGH);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 2:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, HIGH);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 3:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, HIGH);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 4:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, HIGH);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
      case 5:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, HIGH);
        digitalWrite(ledPinG, LOW);
        break;
      case 6:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, HIGH);
        break;
      case 7:
        digitalWrite(ledPinA, LOW);
        digitalWrite(ledPinB, LOW);
        digitalWrite(ledPinC, LOW);
        digitalWrite(ledPinD, LOW);
        digitalWrite(ledPinE, LOW);
        digitalWrite(ledPinF, LOW);
        digitalWrite(ledPinG, LOW);
        break;
    }
    previousMillis = millis();
  }
}

void buttonAactions() {
  { // check if button A is pressed, elseif (condition) {code to be executed if first condition is false and this condition is true;}
    //--------www.baldengineer.com millis button delay-----------
    buttonAPushedMillis = currentAMillis; // update the time when button was pushed
    ledAReady = true;
  }
  // make sure this code isn't checked until after button has been let go
  if (ledAReady) { //this is typical millis code here:
    if ((unsigned long)(currentAMillis - buttonAPushedMillis) >= turnOnADelay) {
      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;
      //-----------------------------------------------------------
      myservo.write(1042); // if it is rotate servo to 35 degrees
      PlayTrack(2); // PLAY TRACK2
      handleLedsMEDIUM();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, HIGH); //BUTTON A IS PRESSED SO MANUALLY LIGHT LED:
      digitalWrite(ledPinRB, LOW); //BUTTON B IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
      //--------www.baldengineer.com millis button delay-----------
      // setup our next "state"
      ledAState = true;
      ledATurnedOnAt = currentAMillis; // save when the LED turned on
      // wait for next button press
      ledAReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledAState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentAMillis - ledATurnedOnAt) >= turnOffADelay) {
      ledAState = false;
      // Put in all the actions you want to close them out below
      //-----------------------------------------------------------
      myservo.write(750);  // servo position
      PlayTrack(1); // PLAY TRACK1
      handleLedsSLOW();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
      digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    }
  }
}

//---------

void buttonBactions() {
  {
    //--------www.baldengineer.com millis button delay-----------
    buttonBPushedMillis = currentBMillis; // update the time when button was pushed
    ledBReady = true;
  }
  // make sure this code isn't checked until after button has been let go
  if (ledBReady) { //this is typical millis code here:
    if ((unsigned long)(currentBMillis - buttonBPushedMillis) >= turnOnBDelay) {
      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;
      //-----------------------------------------------------------
      myservo.write(1442); // if it is rotate servo to 83 degrees
      PlayTrack(3); // PLAY TRACK3
      handleLedsFAST();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRB, HIGH);//BUTTON B IS PRESSED SO MANUALLY LIGHT LED:
      digitalWrite(ledPinRA, LOW); //BUTTON A IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
      //--------www.baldengineer.com millis button delay-----------
      // setup our next "state"
      ledBState = true;
      ledBTurnedOnAt = currentBMillis; // save when the LED turned on
      // wait for next button press
      ledBReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledBState) {
    // okay, led on, check for now long
    if ((unsigned long)(currentBMillis - ledBTurnedOnAt) >= turnOffBDelay) {
      ledBState = false;
      // Put in all the actions you want to close them out below
      //-----------------------------------------------------------
      myservo.write(750);  // servo position
      PlayTrack(1); // PLAY TRACK1
      handleLedsSLOW();  // checks if something is todo with the LEDs
      digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
      digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    }
  }
}


void setup() {
  myservo.attach(3); // SERVO pin
  Serial.begin(9600);
  pinMode(3, OUTPUT); // initialize the SERVO pin as an output
  pinMode(buttonApin, INPUT_PULLUP); // initialize the button A pin as an input
  pinMode(buttonBpin, INPUT_PULLUP); // initialize the button B pin as an input
  pinMode(ledPinA, OUTPUT); // initialize the LED1 pin as an output
  pinMode(ledPinB, OUTPUT); // initialize the LED2 pin as an output
  pinMode(ledPinC, OUTPUT); // initialize the LED3 pin as an output
  pinMode(ledPinD, OUTPUT); // initialize the LED4 pin as an output
  pinMode(ledPinE, OUTPUT); // initialize the LED5 pin as an output
  pinMode(ledPinF, OUTPUT); // initialize the LED6 pin as an output
  pinMode(ledPinG, OUTPUT); // initialize the LED7 pin as an output

  pinMode(12, OUTPUT);     // pin 12 as output for SLIDE switch 2No.LEDS

  pinMode(ledPinRA, OUTPUT); // initialize the LED pin as an output
  pinMode(ledPinRB, OUTPUT); // initialize the LED pin as an output

  MP3Serial.begin(9600);
  myPlayer.init(PIN_sound_BUSY);      // Init the player with the MP3 BUSY pin connected to Arduino pin defined

}




void loop() {
  //--------www.baldengineer.com millis button delay-----------
  unsigned long currentAMillis = millis(); // get the time at the start of this loop()
  unsigned long currentBMillis = millis(); // get the time at the start of this loop()
  //-----------------------------------------------------------

  digitalWrite(12, HIGH); // sets the digital pin 12 on

  buttonAstate = digitalRead(buttonApin); // read the state of button A value
  buttonBstate = digitalRead(buttonBpin); // read the state of button B value




  //-------------------------Stage 3-----------------------------------------------------------
  if (buttonBstate == LOW)
  {
    buttonBactions();
  }


  //-------------------------Stage 2-----------------------------------------------------------

  else if (buttonAstate == LOW)
  {
    buttonAactions();
  }

  //-------------------------Stage 1-----------------------------------------------------------
  else { // This is the stage that will play by default else {code to be executed if all conditions are false;}
    myservo.write(750);  // servo position
    PlayTrack(1); // PLAY TRACK1
    handleLedsSLOW();  // checks if something is todo with the LEDs
    digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
    digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
  }
  lastbuttonAstate = buttonAstate;
  lastbuttonBstate = buttonBstate;
  delay(50);                // waits for a 20th of a second, should help with any button bounce
}
[/code]

Here is why your delay is not working:

void buttonAactions() {
  { // check if button A is pressed, elseif (condition) {code to be executed if first condition is false and this condition is true;}
    //--------www.baldengineer.com millis button delay-----------
    buttonAPushedMillis = currentAMillis; // update the time when button was pushed
    ledAReady = true;
  }

Every time you enter the function you reset the time and the flag.

I'm very confused in that how you say you want the buttons, LEDs, and servos to operate vs. the way it is coded vs. the way your code is commented are 3 different things!

Your buttonAactions() and buttonBactions() are only called WHILE the button is pressed. As soon as you release the button then those are no longer called. However, the following comment leads me to believe that you assume the button has already been let go:

      // okay, enough time has passed since the button was let go.
      // Put in all the actions you want to perform below, remember to close them out at ledState = false;

I really believe your code would benefit by detecting when a button BECOMES pressed and when it BECOMES released. Then you have more precise control of the system. However, I'm not clear on how you want it to actually operate.

TBH your code is so full of comments, not all as dumb as the one I’m picking on you about above, that it is hard to read the actual code.

And if @ToddL1962 is correct, the comments are misleading, we spend more time trying to figure out what you trying to do.

At a glance it looks like there may still be a stray if or else rattling around in there messing with you.

Srsly, draw a flowchart of what you want to have happen using your prose description. Then code to the flowchart.

a7

I'm using button A as an example. Is the following what you want to happen WHILE button A is pressed or when Button A BECOMES depressed no matter when the button is released?

  1. delay turnOnADelay ms
  2. move servo 1042, Play track 2, light LED
  3. delay turnOffADelay ms
  4. move servo 750, play track 1, turn off LED

Do you want the release of button A to interrupt the above sequence or should it complete?

If we can define this clearly then a solution should be pretty simple!

Thank you, everyones help is really appreciated.
I figured the best way to show you what i need the sketch to do is to actually show you.
I have made a video of the working if...if...else sketch to show you how it should function.
Hopefully this clears up how the sketch works.

This is how i think the code should work in bold italics when you press & hold down the buttonA (stage2) "else if"

else if (buttonAstate == LOW) checks buttonA state, if high and "if" is high it will default to "else", if buttonA state is LOW it performs the actions below
{
buttonAactions();
}

void buttonAactions() Checks buttonA {
{ // check if button A is pressed, elseif (condition) {code to be executed if first condition is false and this condition is true;}
//--------www.baldengineer.com millis button delay-----------
buttonAPushedMillis = currentAMillis; // update the time when button was pushed
ledAReady = true; starts the state to control the release timer i dont use the delay function of the first part of the code its for a button you press & release to start a function & press second time to stop, i just use the second part to monitor when i release the button and close the state and go to default settings
}
// make sure this code isn't checked until after button has been let go
if (ledAReady) { //this is typical millis code here:
if ((unsigned long)(currentAMillis - buttonAPushedMillis) >= turnOnADelay) {see above notes on this timer
// okay, enough time has passed since the button was let go.
// Put in all the actions you want to perform below, remember to close them out at ledState = false;
//-----------------------------------------------------------
these following actions all happen, and loop, while the button is HELD down & will stop, after the specified time, on release of the button
myservo.write(1042); // if it is rotate servo to 35 degrees
PlayTrack(2); // PLAY TRACK2
handleLedsMEDIUM(); // checks if something is todo with the LEDs
digitalWrite(ledPinRA, HIGH); //BUTTON A IS PRESSED SO MANUALLY LIGHT LED:
digitalWrite(ledPinRB, LOW); //BUTTON B IS NOT PRESSED SO DO NOT MANUALLY LIGHT LED:
//--------www.baldengineer.com millis button delay-----------
// setup our next "state"
ledAState = true;
ledATurnedOnAt = currentAMillis; // save when the LED turned on
// wait for next button press
ledAReady = false; looks for next state that happens when the buttons released
}
}

// see if we are watching for the time to turn off LED
if (ledAState) {
// okay, led on, check for now long
if ((unsigned long)(currentAMillis - ledATurnedOnAt) >= turnOffADelay) { this is the important part of the dely code for me, button release detected and delay timer of a second or so starts
ledAState = false;
// Put in all the actions you want to close them out below
//-----------------------------------------------------------
delay timer ends and the following state changes to the default actions
myservo.write(750); // servo position
PlayTrack(1); // PLAY TRACK1
handleLedsSLOW(); // checks if something is todo with the LEDs
digitalWrite(ledPinRA, LOW); //BUTTON A NOT PRESSED SO DO NOT MANUALLY LIGHT LED
digitalWrite(ledPinRB, LOW); //BUTTON B NOT PRESSED SO DO NOT MANUALLY LIGHT LED
}
}
}

Ah right, how would I set that up to only read once? I am really trying to figure this one out to better my understanding and try to improve my code's and I know its stupid but the fact I can't get it working is really starting to annoy me.