  Extends Bill Earl's Flasher Class

    From https://learn.adafruit.com/multi-tasking-the-arduino-part-1/a-classy-solution

  Button code excerpted from Examples -> 03.Digital -> Button


  Modified by Matthew Small - d13@dthirteen.com - May 2021


  Description:

    Most 'Blink Without Delay' tutorials only give a solution where the LED has a regular
    on, off, on, off, ..., cycle. I wanted something a little different. Imagine a status
    LED that flashes, say, 2 quick flashes every 10 seconds to show all is well (thus saving
    power), and a more 'angry' 3 long flashes every 4 seconds to show an error, etc etc. This
    code attempts to provide that ability. It also preserves the on, off, etc behaviour if
    you choose appropriate times.

    A class makes sense here as you only have to write the code once then instantiate as
    many objects as you need. That way you don't have to create and keep track of a large
    number of variables as you do with most '... without Delay' examples. This class uses
    11 variables on its own. Multiply that by how many LED objects you want and it quickly
    becomes tedious to write and maintain your code. This leads to a key aim of this class
    - to create a 'set and forget' class that can be dropped into a sketch without having to
    think about how to track LED states and a bazillion variables for each state.

    Developed on a Wemos D1 Mini and a Freetronics 'Eleven' (UNO R3 clone). These highlighted
    that different boards have different methodologies in their designs. The ESP8266 boards
    sink current to turn on the on-board LED. ie. digitalWrite(LED_BUILTIN, LOW). Meanwhile,
    a UNO R3 sources current to turn on the LED. ie. digitalWrite(LED_BUILTIN, HIGH). It is
    for this reason that the 'onLevel' argument must be given when instantiating StatusFlash
    objects. Whichever way you choose to wire your LEDs, this class can handle it without
    needing to rewrite your code around it.

    Board                    Turn on LED_BUILTIN   Pin #
    UNO R3                   HIGH                  13
    ESP32 DEVKIT V1 DOIT     HIGH                  2
    Wemos D1 Mini            LOW                   D4
    Seeeduino XIAO           LOW                   13

  Installation:
  
   Place the StatusFlash directory in your Arduino sketchbook/libraries folder.

  Usage:
  
    #include <statusflash.h>

    StatusFlash name(pin number, number of flashes, on time, off time, repeat time, LED on level)

        name               = a suitable name for the StatusFlash object.
        pin number         = the pin the LED is connected to.
        number of flashes  = the number of times the LED will flash.
        on time            = the duration the LED is ON.
        off time           = the duration the LED is OFF between ON states.
        repeat time        = after the LED has flashed the number of times, the duration until
                             the sequence starts again.
        LED on level       = either HIGH or LOW. What level for the LED to be on?
    
  NOTE:
  
    * Total time for a full cycle to complete is:
    
        (number of flashes * on time) + ((number of flashes - 1) * off time) + repeat time

    * You can instantiate multiple instances on a single LED pin. That is how you can change
      the LED status in your code when the status of your system changes. See the example
      sketch to see how you can do this.
   
  Some examples:
  
    StatusFlash led01(LED_BUILTIN, 3, 100, 400, 2000, HIGH); // On-board LED.
    StatusFlash led02(3, 5, 350, 350, 3100, LOW);            // D3 on UNO, XIAO.
    StatusFlash led02(D3, 5, 350, 350, 3100, LOW);           // D3 on Wemos D1 Mini.
    StatusFlash a1(A1, 2, 200, 200, 1000, LOW);              // A1 analog pin.
    StatusFlash ledon(LED_BUILTIN,1,1000,0,0,LOW);           // No flashing, just on.
    StatusFlash ledoff(LED_BUILTIN,1,0,1000,1000, LOW);      // No flashing, just off.

  Then, in setup(), call the begin() method. ie:

        void setup() {
          led01.begin();
          led02.begin();
        }

  Later, just call the Update() method repeatedly when you want it to run. ie:
  
        void loop { 
          if (true) { led01.Update(); }
          else if (false) { led02.Update(); } 
        }

