You need to maintain more state information to have 'case 3' work like a KITT-style back and forth LED scanner. I think you can do it with three state variables, j for which pair of LEDs is active, backwardsScan to say which way to go, and timer4 to remember where in the 91ms cycle we are with the active pair of LEDs.

Try something like this:

...
int backwardsScan = 0;
...

case 3: // KITT-like scanning back and forth 90us/1us
  // j remembers which LED pair is active
  // backwardsScan remembers which direction to scan
  // timer4 handles the 90ms/1ms on-off cycle.
  // 
  // reset output leds appropriately for (j,timer4):
  for(int ii=0;ii<=5;ii++){
    digitalWrite(ledArray[ii],( (ii==j) && (timer4 <90))); 
  }
  // update KITT state based on (j,backwardsScan,timer4)
  if(timer4 > 91){ 
     j += backwardsScan? -1 : 1 ;
     if (j > 5){
        backwardsScan = 1;
        j = 5;
        }
     if (j < 0) {
        backwardsScan = 0;
        j = 0;
        }
     timer4 = 0;
     }

  break;

The main trick with state machines is being able to fully determine the complete state from what you are keeping track of--It should be memoryless, in that the state variable(s) fully specify the state, and you don't need to remember the prior state. If you find you need to know more than one thing, you might need a vector or set of state variables. One could map the whole led-backwardsScan-timer4 state vector into a single state variable (timer4, modulo 182ms for example,) but that would be unnecessarily complicated. Recognizing all the variables required to fully specify the state is important.

Answer from Dave X on Stack Exchange
🌐
PJRC
pjrc.com › teensy › td_timing_elaspedMillis.html
Using elapsedMillis & elapsedMicros
In this example, a pushbutton has quick response, but a task is performed every 2.5 seconds. #include <Bounce.h> Bounce myButton = Bounce(2, 10); // pushbutton on pin 2 elapsedMillis sincePrint; void setup() { Serial.begin(9600); pinMode(2, INPUT_PULLUP); } void loop() { myButton.update(); ...
🌐
Codebender
codebender.cc › example › elapsedMillis › timingComparison
Library example: elapsedMillis : timingComparison
<iframe style="height: 510px; width: 100%; margin: 10px 0 10px;" allowTransparency="true" src="https://codebender.cc/embed/example/elapsedMillis/timingComparison" frameborder="0"></iframe> You can also embed the Serial Monitor section! Just use this HTML code.
🌐
GitHub
github.com › pfeerick › elapsedMillis
GitHub - pfeerick/elapsedMillis: Arduino 'port' of the elapsedMillis library · GitHub
Initial code derived from Paul Stoffregen's elapsedMillis and elapsedMicros helper code for the Teensy USB developer board. Code contributes and initial examples created by John Plocher.
Starred by 89 users
Forked by 26 users
Languages   C++
🌐
Rip Tutorial
riptutorial.com › measure how long something took, using elapsedmillis and elapsedmicros
arduino Tutorial => Measure how long something took, using...
#include <elapsedMillis.h> void ... example, an elapsedMillis object and an elapsedMicros object are used to measure how long something took, by creating them just before the expression we want to time is executed, and getting their values afterwards...
🌐
GitHub
github.com › pfeerick › elapsedMillis › blob › master › examples › timingComparison › timingComparison.ino
elapsedMillis/examples/timingComparison/timingComparison.ino at master · pfeerick/elapsedMillis
elapsedmillis em1; elapsedmicros em2; · All the standard operations are supported on them. · There are 3 examples below that blink a LED every second. · * The first is the venerable blink sketch that uses delay() to · "do nothing" while waiting for time to pass.
Author   pfeerick
🌐
Codebender
codebender.cc › example › elapsedMillis › GettingStarted
Library example: elapsedMillis : GettingStarted
<iframe style="height: 510px; width: 100%; margin: 10px 0 10px;" allowTransparency="true" src="https://codebender.cc/embed/example/elapsedMillis/GettingStarted" frameborder="0"></iframe> You can also embed the Serial Monitor section! Just use this HTML code. <iframe style="height: 510px; width: 100%; margin: 10px 0 10px;" allowTransparency="true" src="https://codebender.cc/embed/serialmonitor" frameborder="0"></iframe> 2015-11-20 codebender ·
Top answer
1 of 1
2

You need to maintain more state information to have 'case 3' work like a KITT-style back and forth LED scanner. I think you can do it with three state variables, j for which pair of LEDs is active, backwardsScan to say which way to go, and timer4 to remember where in the 91ms cycle we are with the active pair of LEDs.

Try something like this:

...
int backwardsScan = 0;
...

case 3: // KITT-like scanning back and forth 90us/1us
  // j remembers which LED pair is active
  // backwardsScan remembers which direction to scan
  // timer4 handles the 90ms/1ms on-off cycle.
  // 
  // reset output leds appropriately for (j,timer4):
  for(int ii=0;ii<=5;ii++){
    digitalWrite(ledArray[ii],( (ii==j) && (timer4 <90))); 
  }
  // update KITT state based on (j,backwardsScan,timer4)
  if(timer4 > 91){ 
     j += backwardsScan? -1 : 1 ;
     if (j > 5){
        backwardsScan = 1;
        j = 5;
        }
     if (j < 0) {
        backwardsScan = 0;
        j = 0;
        }
     timer4 = 0;
     }

  break;

The main trick with state machines is being able to fully determine the complete state from what you are keeping track of--It should be memoryless, in that the state variable(s) fully specify the state, and you don't need to remember the prior state. If you find you need to know more than one thing, you might need a vector or set of state variables. One could map the whole led-backwardsScan-timer4 state vector into a single state variable (timer4, modulo 182ms for example,) but that would be unnecessarily complicated. Recognizing all the variables required to fully specify the state is important.

🌐
PlatformIO
platformio.org › lib › show › 1002 › elapsedMillis › examples
PlatformIO is a professional collaborative platform for embedded development
Open source, cross-platform IDE and Unified Debugger. Static Code Analyzer and Remote Unit Testing. Multi-platform and Multi-architecture Build System. Firmware File Explorer and Memory Inspection.
Find elsewhere
🌐
Particle
community.particle.io › firmware › libraries
elapsedMillis and elapsedMicros library - Libraries - Particle
February 7, 2014 - This codes required NO adaptation for the Spark so I take no credit :smile: Here it is with an simple LED blink example. Cheers! // -------- elapsedMillis.h -------- /* Elapsed time types - for easy-to-use measurements of elapsed time * http://www.pjrc.com/teensy/ * Copyright (c) 2011 PJRC.COM, ...
🌐
GitHub
github.com › pfeerick › elapsedMillis › blob › master › elapsedMillis.h
elapsedMillis/elapsedMillis.h at master · pfeerick/elapsedMillis
elapsedMillis(void) { ms = millis(); } elapsedMillis(unsigned long val) { ms = millis() - val; } elapsedMillis(const elapsedMillis &orig) { ms = orig.ms; } operator unsigned long () const { return millis() - ms; } elapsedMillis & operator ...
Author   pfeerick
🌐
Arduino
docs.arduino.cc › libraries › elapsedmillis
elapsedMillis | Arduino Documentation
August 1, 2024 - elapsedMillis · Home / Programming / Library / elapsedMillis · Timing · MIT License · V1.0.6 · Paul Stoffregen · 08/01/2024 · Peter Feerick <peter.feerick@gmail.com> http://github.com/pfeerick/elapsedMillis/wiki · peter.feerick@gmail.com · Makes coding responsive sketches easier.
🌐
Reddit
reddit.com › r/arduino › millis() vs. elapsedmillis ?
r/arduino on Reddit: millis() vs. elapsedMillis ?
March 16, 2021 -

I'm thinking about writing an article* about how to implement cooperative multi-tasking on Arduino-compatible microcontrollers. Working title: Beyond "Blink without Delay". Much of the article will talk about ways structure a program to simplify the handling of multiple concurrent "tasks" with different timing requirements, based on my own experience.

At a lower level, I'd like to discuss the pros and cons of the various methods to measure task time intervals. At minimum I'll cover the blink-without-delay method based on millis(), as well as the elapsedMillis library. I've tried a few different methods, including the Ticker library, but have come to rely exclusively on elapsedMillis for all my projects. But before I go off and profess my love for elapsedMillis, I'd like to get your input.

For reference, here's a brief synopsis of the blink-without-delay/millis() method:

unsigned long currentTime, previousTime;
unsigned int taskDelay = 300;
void loop() {
  currentTime = millis();
  if ((currentTime - previousTime) > taskDelay) {
    previousTime = currentTime;    
    // Perform task 
  }
}  

And here's the elapsedMillis equivalent:

elapsedMillis taskTimer;
unsigned int taskDelay = 300;
void loop() {
  if (taskTimer > taskDelay) {
    taskTimer = 0;
    // Perform task
  }
}

The key advantage of the elapsedMillis method is that the code is more concise and readable. It also eliminates any perceived issue with millis() rollover (which isn't really an issue with unsigned variables).

A disadvantage is the minor "time slippage" that occurs in the delay between the compare if (TaskTimer > TaskDelay) and resetting the timer taskTimer = 0. This is only an issue if the cumulative delays need to maintain long-term timing accuracy (a rare situation I think).

In addition to "going deep" on the two methods shown above, I'l also provide a brief survey of other timing methods, including Ticker and also the EVERY_N_MILLISECONDS method provided by the FastLED library.

What do you folks think? What's your preferred method, and why?

*If you want to see examples of my other articles, check here.

🌐
Codebender
codebender.cc › example › elapsedMillis › timeouts
Library example: elapsedMillis : timeouts
<iframe style="height: 510px; width: 100%; margin: 10px 0 10px;" allowTransparency="true" src="https://codebender.cc/embed/example/elapsedMillis/timeouts" frameborder="0"></iframe> You can also embed the Serial Monitor section! Just use this HTML code. <iframe style="height: 510px; width: 100%; margin: 10px 0 10px;" allowTransparency="true" src="https://codebender.cc/embed/serialmonitor" frameborder="0"></iframe> 2015-11-20 codebender ·
🌐
GitHub
github.com › pfeerick › elapsedMillis › wiki
Home · pfeerick/elapsedMillis Wiki · GitHub
When elapsedMillis is created as a local variable (inside the function), it automatically starts at zero each time the function executes.
Author   pfeerick
🌐
Rip Tutorial
riptutorial.com › non-blocking blinky with the elapsedmillis library (and class)
arduino Tutorial => Non-blocking blinky with the elapsedMillis...
#include <elapsedMillis.h> #define ... 0; } // do other stuff here } You can see in the example that the ledTime object is assigned zero when the LED pin was toggled....
🌐
Thekurks
thekurks.net › blog › 2016 › 4 › 8 › tutorial-delay-vs-timer
Tutorial: How and Why to use Timers instead of the Delay() Function — The Arduino Maker Man
March 14, 2018 - Now download Timer_demo2 and upload it to your Arduino Uno. This sketch uses the elapsedMillis library. You see that the code is more complex but the button functions whenever you press it.
Address   Vancouver, BC Canada
🌐
GitHub
github.com › PaulStoffregen › cores › blob › master › teensy › elapsedMillis.h
cores/teensy/elapsedMillis.h at master · PaulStoffregen/cores
elapsedMillis(void) { ms = millis(); } elapsedMillis(unsigned long val) { ms = millis() - val; } elapsedMillis(const elapsedMillis &orig) { ms = orig.ms; } operator unsigned long () const { return millis() - ms; } elapsedMillis & operator ...
Author   PaulStoffregen
🌐
Google Groups
groups.google.com › a › arduino.cc › g › developers › c › FAw_W0Vn7kg
Request to have elapsedMillis/elapsedMicros data-type added to standard Arduino
> Initial stub article has been ... you have to copy-paste the code or download a zip without version history. On nitpick about the example: elapsedMillis em; Perhaps call this variable "elapsed" instead?...
🌐
Arduino Libraries
arduinolibraries.info › libraries › elapsed-millis
elapsedMillis - Arduino Libraries
December 2, 2019 - https://github.com/pfeerick/elapsedMillis/wiki · Github · https://github.com/pfeerick/elapsedMillis · Category · Timing · License · MIT · Library Type · Contributed · Architectures · Any · When using delay(), your code can not (easily) respond to user input while the delay is happening (unless you use interrupts or complex timer code).