MobaTools Timerbase and Timer to Light LED

Hi Folks. I'm new to Arduino/C++ and MoBaTools. I was just working with MoBaTools' Timebase and Timer to light an LED (both are in the code below although one has been commented out). The code is supposed to wait 5 seconds after Arduino is powered on and then light the LED for 500ms. Nothing is happening when I upload the sketch. Can anyone see what I'm doing wrong?

#include <MobaTools.h>     // Include MobaTools
 
MoToSoftLed myLed;

MoToTimer myTimer1;
MoToTimer myTimer2;

MoToTimebase myBase;
MoToTimebase myBase2;

int ledPin = 13;

void setup() 
{
  Serial.begin(115200);

  myLed.attach(ledPin);

}

void loop() 
{


////////// USING BASETIME //////////
      myBase.setBasetime(5000);       // set a timer for 5 seconds after startup
      myBase.start();                 // begin timer

      if (myBase.tick() == true)      // if the timer is up...
      {
        myBase2.setBasetime(500);     // set a second timer for 500ms
        myBase2.start();              // start second timer
        myLed.on();                   // turn on led
      }

      if(myBase2.tick() == true)      // if timer 2 is up...
      {
        myLed.off();                  // turn off led
      }


////////// USING TIMER //////////      
      myTimer1.setTime(5000);             // start a 5 second timer

      if (myTimer1.expired() == true )    // if timer expires...
      {
        myTimer2.setTime(500);            // start a second 500ms timer
        myLed.on();                       // turn on the LED
      }

      if (myTimer2.expired() == true )    // if timer expires...
      {
        myLed.off();                      // turn off led
      }

}


Best,

Tony

You are restarting your timers every time through loop() so they will never expire.

@blh64 is right. Because you restart the timers over and over they will never expire.

MoToTimebase is meant to create ticks in regular intervals. Usually you set the time once in setup() and you will get timer events ( ticks ) at the set interval. You don't need to restart it.
MoToTimer is a one-time running timer ( just like a retriggerable HW MonoFlop ). You start the time and you will get a single event when the timer expires. If you set the time again before it expires it will start over.

I've shortened your sketch to a simple example with only one Timebase (myBase) and one Timer (myTimer1). The LED is switched on in regular 5 sec intervals, and every time it is switched on a timer is started to switch it off 1 sec later.

#include <MobaTools.h>     // Include MobaTools

MoToSoftLed myLed;

MoToTimer myTimer1;
MoToTimer myTimer2;

MoToTimebase myBase;
MoToTimebase myBase2;

int ledPin = 13;

void setup()
{
    Serial.begin(115200);

    myLed.attach(ledPin);
    myBase.setBasetime(5000);     // set a timer to tick every 5 seconds
    //myBase2.setBasetime(500);     // set a second timer to tick every 500ms

}

void loop()
{


    ////////// USING BASETIME //////////

    if (myBase.tick() == true)      // if the timer is up...
    {
        myLed.on();                   // turn on led
        myTimer1.setTime(1000);       // turn it off in 1 second
    }

    if (myTimer1.expired() == true)     // if timer 1 expired
    {
        myLed.off();                  // turn off led
    }

}

Thank you. I was confused. Not that it's all clear now but I'm working at it.

In my application, upon button press, I'd like to wait for 500ms, then flash the LED rapidly 3 times (20 ms on, 20 ms off, 20 ms on, 20ms off, 20 ms on and 20 ms off again), then have the LED stay on solid for 4 seconds, and then flash three times rapidly, as before, before turning off.

Is this doable with Base/Timers? I'm struggling with this one.

Tony

20ms? You will not really see them flashing.

Shurely it is. I would not use Timebase in this case, because it is not really a continous time event. MoToTimer is the right tool to do this.

blh64,

Thank you. I was truly befuddled (which is easy as I'm just starting out). I'm going to play around with the code for a bit a see if I can get something together that works.

Best,

Tony

Since you are new to all this. I would set aside this sketch and the MobaTools library and start off much more basic.

look at the Button and Debounce examples (File->examples->02.basic...) to learn about buttons.
After you have that working, you can simply use delay() to make your LED do what you want.

After you have mastered that, then look at the BlinkWithoutDelay example to see how to remove your delay() calls so your program can be more responsive all the time (e.g. another button press). At that point, you can start to work with the MobaTools library.

Good luck

Am I getting closer to the solution or farther away? Code doesn't. Seems to run everything concurrently, not sequentially.

#include <MobaTools.h>     // Include MobaTools
 
MoToSoftLed myLed;

MoToTimer myTimer1; // wait 500ms
MoToTimer myTimer2; // blink 50ms
MoToTimer myTimer3; // wait 50ms
MoToTimer myTimer4; // blink 50ms
MoToTimer myTimer5; // wait 50ms
MoToTimer myTimer6; // blink 50ms
MoToTimer myTimer7; // wait 50ms
MoToTimer myTimer8; // blink 4 seconds


int ledPin = 13;

void setup() 
{
  Serial.begin(115200);

  myLed.attach(ledPin);

}

void loop() 
{

      ////////// USING TIMER //////////      
      myTimer1.setTime(500);

      if (myTimer1.expired() == true )    
      {
        myLed.on();
        myTimer2.setTime(50);
      
            if (myTimer2.expired() == true )
            {
              myLed.off(); 
              myTimer3.setTime(50);


                  if (myTimer3.expired() == true )
                  {
                    myLed.on();
                    myTimer4.setTime(50);
                  

                        if (myTimer4.expired() == true )
                        {
                          myLed.off();
                          myTimer5.setTime(50);
                        

                              if (myTimer5.expired() == true )
                              {
                                myLed.on();
                                myTimer6.setTime(50);
                              

                                    if (myTimer6.expired() == true )
                                    {
                                      myLed.off();
                                      myTimer7.setTime(50);
                                    

                                          if (myTimer7.expired() == true )
                                          {
                                            myLed.on();
                                            myTimer8.setTime(4000);
                                          

                                                if (myTimer8.expired() == true )
                                                {
                                                  myLed.off();
                                                }

                                          }

                                    }

                              }

                        }

                  }

            }

      }


}

You are still setting your timer every time through loop() so it will never expire which means all the code in your nested if() statements will never execute.

Even if that is fixed, how do you think setting a timer and then immediately testing it for expiration will ever succeed?

I would suggest reading my previous post - set this project aside while you are coming up the learning curve.

Thank you. I took one more stab at the MoBaTools but I'm afraid its not working and I'm further afraid that I'm not even close to the solution. I posted the code for comments.

I'll take a peek at blink without delay. I had hoped to stay away from delay() as it would block other aspects of the sketch.

Thanks again,

Best,

Tony

A good goal but based on your current understanding level, start out with delay() and get the sketch to at least run exactly how you want (blinking, etc.) and then worry about removing delay(). The sketch you posted doesn't have "any other code" that needs to be running. If this is the start of a larger sketch, you still can have individual sketches to understand how things work.

Hi Tony,
you don't need that much timer to blink one LED. One is sufficent.
You should study how a FSM (finite-state-machine) works. This programming technique is a great solution for many problems and nonblocking programming.

Hi Tony

Here is an a little bit simplified solution ( only one sequence of fast blinking ) with a state machine. It is not really easy to understand at first how a FSM works, but it's worth learning it. The start button must be connected between pin 2 and Gnd.

#include <MobaTools.h>     // Include MobaTools
// blink sketch using a FSM

MoToSoftLed myLed;

MoToTimer myTimer;

// 'const' are all values that never change in the sketch
const byte maxBlink     = 3;  // blinking 3 times
const int  waitTime     = 500;
const int  blinkTime    = 50;
const int  solidOnTime  = 4000;
const byte ledPin = 13;
const byte startPin = 2; // The sequence starts, if this pin is connected
                         // to Gnd ( e.g. by a button )

// our FSM needs  the following states:
// Later that should be defined with an enum
const byte IDLE       = 1; // waiting for the button press
const byte WAIT1      = 2; // first delay until blinking
const byte BLINK_ON   = 3; // Blink ON state
const byte BLINK_OFF  = 4; // Blink off state
const byte WAIT2      = 5; // last ON time
byte blinkState = IDLE;    // FSM starts in first state
byte blinkCount;    // count the number of blink cycles

void setup()
{
    Serial.begin(115200);
    myLed.attach(ledPin);
    pinMode( startPin, INPUT_PULLUP );
}

void loop()
{
  // within every loop() cycle only the statements of the active
  // FSM state ( = switch case ) are executed, all others are ignored
  switch ( blinkState ) {
    case IDLE: // here we are waiting for the button press
      if ( digitalRead(startPin) == LOW ) {
        // Start button has been pressed
        Serial.println("Start button pressed, wait a moment ... ");
        myTimer.setTime( waitTime );
        blinkState=WAIT1; // now we only wait for the timer to expire
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    case WAIT1: // waiting the first delaytime
      if ( myTimer.expired() ) {
        Serial.println("Start blinking now...");
        blinkCount= maxBlink; // counting the blinking
        myLed.on();
        myTimer.setTime(blinkTime); // start time for on time
        blinkState=BLINK_ON;
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    case BLINK_ON: // Led is on, wait until on time is over
      if ( myTimer.expired() ) {
        // now switch off and wait off time
        myLed.off();
        myTimer.setTime(blinkTime); // start time for off time
        blinkState=BLINK_OFF;
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    case BLINK_OFF: // Led is off, wait until off time is over
      if ( myTimer.expired() ) {
        myLed.on();
        // now we must decide wether there have been enough blink cycles
        blinkCount--; // decrement counter
        if ( blinkCount > 0 ) {
          // still blinking ... so switch to BLINK_ON again
          myTimer.setTime(blinkTime); // start time for on time
          blinkState=BLINK_ON;
        } else {
          // blinking finished, switch to solid on
          Serial.println("Blinking finished, now solid on");
          myTimer.setTime(solidOnTime);
          blinkState = WAIT2;
        }
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    case WAIT2: // Led is solid on, wait until everything is finished
      if ( myTimer.expired() ) {
        Serial.println("full sequence finished, wait for button press again");
        myLed.off();
       blinkState = IDLE;
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  } // End of FSM

}

The FSM code is not blocking, so it is easy to expand the sketch ( with other nonblocking code - e.g. another FSM :wink: ).
I tried to include some comments that hopefully make it more understandable. But feel free to ask...
Have fun,
F-P

it seems that almost all people that have understood non-blocking timing become blind for that one thing that makes it difficult to understand:

NOT

explaining
the fundamental difference between delay() and non-blocking timing.

Any kind of non-blocking timer works with the same principle.
And this principle is

very different

from delay() it could be seen almost as the

OPPOSITE of delay()

delay()

completely freezes code-execution

delay() = UNconditionally STOP ALL code-execution

.
.

non-blocking timing = GO ON with code-execution

combined with TIME-conditional code-execution

delay: stop all
versus
non-blocking timing: go on with main code
combined with
execute timing-code TIME-conditional

Hi Tony,
because I just enjoyed it :sunglasses:, I wrote a class with which an arbitrary blinking pattern can be realised. You can simply copy the blinksequence.h file into your sketch directory to use it.
blinksequence.h:

/* BlinkSequence
    A class for realizing arbitrary blink sequences.
    The sequence is defined by an array of data triplets:
    repeatCount, ontime, offtime
    The end of the sequence is marked by setting repeatCount to 0
    e.g.
   blkPatten_h blkSq[] = {
                      { 1,0,500 },      // because onTime = 0 here, sequence starts with led off
                      { 3,50,50 },      // 3 times on/off 50ms
                      { 1,4000,0 },
                      { 0,0,0}          // if onTime is >0 in last pattern, the sequence loops forever
                      }

   Class methods:
   init( blkPatten_h *sequence, byte ledPin, int riseTime ); // riseTime is optional and 0 by default
   void process()    // must be called frequently in loop
   void start() // start the sequence
    void stop()  // stop the sequence at any time
   bool running() // returns true while the sequence is running
*/
#include<MobaTools.h>
struct blkPatten_h {
  byte repeat;
  uint16_t onTime;
  uint16_t offTime;
};

class BlinkSequence {
  public:
    BlinkSequence() {
    }

    void init( blkPatten_h *sequence, byte ledPin, int bulbTime = 0 ) {
      _sequence = sequence;
      _blkLed.attach(ledPin);
      _blkLed.riseTime( bulbTime );
    }

    void start() {
      // start a blink sequence
      _seqIx = 0;
      // start first step
      _startPattern();
    }

    void stop() {
      _seqRunning = false;
    }

    bool running() {
        return _seqRunning;
    }

    void process() {
      // process the sequence
      if ( _seqRunning ) {
        if ( !_blkTimer.running() ) {
          if ( _ledOn ) {
            _blkLed.off();
            _ledOn = false;
            _blkTimer.setTime( _sequence[_seqIx].offTime );
          } else {
            // Led was off - checking if we should still blink in this pattern entry
            if ( --_blkCount > 0 ) {
              // switch led on in same pattern
              _ledOn = true;
              _blkLed.on();
              _blkTimer.setTime( _sequence[_seqIx].onTime );
            } else {
              // no, switch to next pattern entry
              _seqIx++;
              _blkCount = _sequence[_seqIx].repeat;
              // Check for end of sequence
              if ( _sequence[_seqIx].repeat == 0 ) {
                // is last entry, check for endless repaet
                if (_sequence[_seqIx].onTime > 0 ) {
                  // is endless, start over
                  _seqIx = 0;
                  _startPattern();
                } else {
                  _seqRunning = false;
                }
              } else {
                // no end, start pattern
                _startPattern();
              }
            }
          }
        }
      }
    }

  private:
    MoToTimer _blkTimer;
    MoToSoftLed _blkLed;
    blkPatten_h *_sequence;
    byte _blkCount;        // to count the blinking in one sequenc entry
    byte _seqIx;            // Index in sequence array
    bool _seqRunning;
    bool _ledOn;
    void _startPattern () {
      // start actual pattern
      _seqRunning = true;
      _blkCount = _sequence[_seqIx].repeat;
      if ( _blkCount == 0 ) _blkCount = 1;  // must be greater 0
      _blkTimer.setTime( _sequence[_seqIx].onTime );
      if (  _sequence[_seqIx].onTime > 0 ) {
        // don't really switch on, if on time is 0
        _blkLed.on();
      }
      _ledOn = true;


    }
};

And here an example sketch to use the class:

#include "blinksequence.h"

// example for using class BlinkSequence
blkPatten_h blkSq[] = {
  { 1, 0, 1000 },
  { 3, 50, 50 },
  { 1, 4000, 50 },
  { 3, 50, 50 },
  { 3, 300, 600 },
  { 0, 0, 0}        // this sequence stops here
};

// Flashing pattern of a lighthouse
blkPatten_h lightHouse[] = {
  { 3, 500, 1000 },
  { 2, 1000, 2000 },
  { 1, 1000, 5000 },
  { 0, 1, 0}        // if ontime is > 0 in last pattern, the sequence loops forever
};

BlinkSequence myBlink;
BlinkSequence myLh;
byte buttonOn = 2;
byte buttonOff = 3;

void setup() {
  Serial.begin(115200);
  myBlink.init( blkSq, 13 );
  myLh.init( lightHouse, 12, 400 );
  pinMode(buttonOn, INPUT_PULLUP);
  pinMode(buttonOff, INPUT_PULLUP);
  delay(1000);
  myLh.start();         // Lighthouse sequnce runs forever
}

void loop() {
  myBlink.process();
  myLh.process();

  if ( digitalRead(buttonOn) == LOW && myBlink.running() == false ) {
    myBlink.start();
  }

  if ( digitalRead(buttonOff) == LOW && myBlink.running() == true ) {
    myBlink.stop();
  }
}

Perhaps it is also useful for others :wink:

[Edit] As it is now, max on and off time is limited to about 64 seconds. If you need longer times you must change the uint16_t in struct blkPatten_h to uint32_t. But this needs considerable more memory - especially if you define many or long sequences.

Stefan,

Great millis explanation.

If the code I saw this…

boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod)

What does the ampersand mean?

Best,

Tony

Mirco,

Thank you. I’ve been digesting your code and I think I’m making sound progress. I may have a couple questions for you but I’m waiting until I think I understand it as much as possible.

Again, thank you for spending some of your time on my. It’s very much appreciated.

Best,

Tony

You are a very good detail-reader.

The ampersand means that the value that is "handed over" to the function as the first parameter is not only used inside the function

The function can modify this value and if the function is exited the new value will update the global variable that is used in the function-call.

The ampersand will automatically updating the global variable

You should be able to use the BlinkSequence class without diving deeper into it's internals. ( as it is with most libraries :wink: ). But of course you can have a closer look and try to understand how it works. Feel free to ask if something is unclear :sunglasses:

Micro,

I think I've mentioned the project I'm working on. A dinosaur that will have a few features, such as moving legs, eyes that light up, a jaw that moves (hopefully I've left enough room in the model for this), and lights on his spine that blink (the same ones you helped me with by creating a FSM).

Over the weekend I've been working on converting my leg movement code to a FSM. I thought my logic was sound but I'm not getting any movement. Honestly, I was super excited at the prospect that I might have worked it out on my own. Alas, I think I need a little nudge in the right direction.

Would you please take a peek at it to see anything obviously wrong with the code?

#include <MobaTools.h>      // Include MobaTools
#include <ezButton.h>

MoToSoftLed myLed;        
MoToTimer myTimer;        
MoToServo myServoLeft;    
MoToServo myServoRight;   
MoToServo myServoJaw;     

ezButton legsButton(4);
ezButton jawButton(5);
ezButton ledsButton(7);


//******************************* LED FSM *********************************

// LEDs on Dinosaur's back light up
// 'const' are all values that never change in the sketch
const byte maxBlink     = 8;      // blinking 3 times
const int  waitTime     = 250;    // wait 250ms
const int  blinkTime    = 50;     // time on for blinks
const int  solidOnTime  = 4000;   // solid state
const int  ledPin       = 12;     // led pin


// our FSM needs  the following states:
// Later that should be defined with an enum
const byte IDLE         = 1;  // waiting for the button press
const byte WAIT1        = 2;  // first delay until blinking
const byte BLINK_ON     = 3;  // Blink ON state
const byte BLINK_OFF    = 4;  // Blink off state
const byte BLINK_OFF2   = 5;  // Off
const byte BLINK_AGAIN  = 6;  // Series of short blinks
const byte WAIT2        = 7;  // 
byte blinkState = IDLE;       // FSM starts in first state
byte blinkCount;              // count the number of blink cycles
byte blinkCount2;


//******************************* MOTOR FSM *******************************

// Legs on Dinosaur move
const int servoLeftLegMinPos      = 90;   //set initial Left Leg pos as 90
const int servoRightLegMinPos     = 90;   //set initial Right Leg pos as 90
const int servoLeftLegMaxPos      = 130;  //set max position of Left Leg as 130 deg
const int servoRightLegMaxPos     = 130;  //set max position of Right Leg as 130 deg
const int servoLeftLegInitialPos  = 110;  //set Left Leg initial pos at 110 deg
const int servoRightLegInitialPos = 110;  //set Right Leg initial pos at 110 deg
const int legServoSpeed           = 5;


const byte IDLE2              = 1; // waiting for the button press, move from resting pos
const byte SWING1             = 2; // leg swings back
const byte SWING2             = 3; // leg swings forward
const byte SWING3             = 4; // leg swings back
const byte SWING4             = 5; // leg swings forward
const byte SWING5             = 6; // leg swings back
const byte BACK_TO_START      = 9; // leg swings to initial/resting pos

byte motorState = IDLE2;    // FSM starts in first state

//*************************************************************************




//******************************* SETUP ***********************************

void setup() {
  // set the digital pin as output:


Serial.begin(115200);             // serial monitor for debugging
myLed.attach(ledPin);             // led pin attach


legsButton.setDebounceTime(50);   // debounce button
jawButton.setDebounceTime(50);    // debounce button
ledsButton.setDebounceTime(50);   // debounce button


myServoLeft.attach(9);            // attach left servo motor
myServoRight.attach(10);          // attach right servo motor
myServoJaw.attach(8);             // attach jaw motor


}



//******************************* LOOP ************************************


void loop() {

legsButton.loop();  // call button function legs
ledsButton.loop();  // call button function leds


//*************************************************************************
//******************************* MOTOR FSM *******************************

// The objective is to move a servo motor back and forth.  It will have a leg attached and
// is supposed to look like the dinosaur is walking.  The legs will hanging straight down to start
// and then swing back and forth with servo motor between certain angles (min and max).  The angles I'm using are
// just starting points.
  switch ( motorState ) {
    case IDLE2: 
      if ( legsButton.isPressed() ) { 
        Serial.println("Move from resting/initial pos");
        myServoLeft.setSpeedTime(legServoSpeed);
        myServoLeft.write(servoLeftLegMaxPos);
        motorState=SWING1;
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    case SWING1:
      if ( myServoLeft.read() == servoLeftLegMaxPos) {
        Serial.println("Swing forward 1");
        myServoLeft.setSpeedTime(legServoSpeed);
        myServoLeft.write(servoLeftLegMinPos);
        motorState=SWING2;
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    case SWING2: 
      if ( myServoLeft.read() == servoLeftLegMinPos) {
        Serial.println("Swing back 1");
        myServoLeft.setSpeedTime(legServoSpeed);
        myServoLeft.write(servoLeftLegMaxPos);
        motorState=SWING3;
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    case SWING3:
      if ( myServoLeft.read() == servoLeftLegMaxPos) {
        Serial.println("Swing forward 2");
        myServoLeft.setSpeedTime(legServoSpeed);
        myServoLeft.write(servoLeftLegMinPos); 
        motorState=SWING4;
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    case SWING4:
      if ( myServoLeft.read() == servoLeftLegMinPos) {
        Serial.println("Swing back 2");
        myServoLeft.setSpeedTime(legServoSpeed);
        myServoLeft.write(servoLeftLegMaxPos);
        motorState=SWING5;
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    case SWING5:
      if ( myServoLeft.read() == servoLeftLegMaxPos) {
        Serial.println("Swing forward 3");
        myServoLeft.setSpeedTime(legServoSpeed);
        myServoLeft.write(servoLeftLegInitialPos);
        motorState=BACK_TO_START;
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      
    case BACK_TO_START:
      if ( myServoLeft.read() == servoLeftLegInitialPos) {
        Serial.println("Return to resting/initial pos.  Goto Idle2");
        myServoLeft.setSpeedTime(legServoSpeed);
        motorState=IDLE2;
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  }


//*************************************************************************
//******************************* LED FSM *********************************


  // within every loop() cycle only the statements of the active
  // FSM state ( = switch case ) are executed, all others are ignored
  switch ( blinkState ) {
    case IDLE: // here we are waiting for the button press
      if ( ledsButton.isPressed() ) {    // if ( digitalRead(ledsButton) == LOW ) { 
        // Start button has been pressed
        Serial.println("Start button pressed, wait a moment ... ");
        myTimer.setTime( waitTime );
        blinkState=WAIT1; // now we only wait for the timer to expire
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    case WAIT1: // waiting the first delaytime
      if ( myTimer.expired() ) {
        Serial.println("Start blinking now...");
        blinkCount= maxBlink; // counting the blinking
        blinkCount2 = maxBlink;
        myLed.on();
        myTimer.setTime(blinkTime); // start time for on time
        blinkState=BLINK_ON;
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    case BLINK_ON: // Led is on, wait until on time is over
      if ( myTimer.expired() ) {
        // now switch off and wait off time
        myLed.off();
        myTimer.setTime(blinkTime); // start time for off time
        blinkState=BLINK_OFF;
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    case BLINK_OFF: // Led is off, wait until off time is over
      if ( myTimer.expired() ) {
        myLed.on();
        // now we must decide wether there have been enough blink cycles
        blinkCount--; // decrement counter
        if ( blinkCount > 0 ) {
          // still blinking ... so switch to BLINK_ON again
          myTimer.setTime(blinkTime); // start time for on time
          blinkState=BLINK_ON;
        } else {
          // blinking finished, switch to solid on
          Serial.println("Blinking finished, now solid on");
          myTimer.setTime(solidOnTime);
          blinkState = BLINK_OFF2;
        }
      }
      break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    case BLINK_OFF2: // Led is solid on, wait until everything is finished
      if ( myTimer.expired() ) {
        Serial.println("Solid on over");
        myLed.off();
        myTimer.setTime(blinkTime);
        blinkState = BLINK_AGAIN;
		}
		break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

	  case BLINK_AGAIN: // Led is off, wait until off time is over
      if ( myTimer.expired() ) {
        myLed.on();
        // now we must decide wether there have been enough blink cycles
        blinkCount2--; // decrement counter
        if ( blinkCount2 > 0 ) {
          // still blinking ... so switch to BLINK_ON again
          myTimer.setTime(blinkTime); // start time for on time
          blinkState=BLINK_OFF2;
        } else {
          // blinking finished, wait for next button press
          Serial.println("Blinking finished, now wait for button press.");
          myLed.off();
          blinkState = IDLE; //
        }
      }
		break; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


  }  //end FSM

//*************************************************************************


}


Oh, I also modified your FSM Led code and added an extra sequence of rapid blinks at the end. And I'll be looking to see about implementing your BlinkSequence Library soon. I did look at the code in there and as you surmised it's pretty heavy stuff for me. I'm going to stick to working on developing my knowledge and use of FSMs.

Again, thank you for your help.

Best,

Tony