LED matrix control using arrays and state machine?

I understand the aesthetics.

What happens with “real” sequencing turn lights? I might bet they just get chopped off in midst cycle if the turn signal is removed.

But there is no real trouble with making sure things run to a good stopping point before doing.

Your animations cycle continuously because as long as conditions merit, you call the stepping function:

What you can do in a case like this is cede some control to the animation function, so

  • the input signals are used to initiate a sequence

  • the sequence will terminate when the input signals change AND the sequence is at step 0 or wherever stopping makes sense.

I did something like that with my version, the below are untested but should give an idea of an approach. The essence is that machines should be callable at all times - if they aren't busy, they just don't do anything.

If you write the step function to return a value saying if it is busy or not

// command 0 - initialise this machine.
// command 1 - normal step this machine, return 0 when done/no longer busy

unsigned char turnMachineStep(unsigned char command)
{
  static byte frame = 0;
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;

  static unsigned char busy = 0;		// not busy!
  static unsigned char returnValue = 0; // not done - will change if not

  if (command == 0) {
    frame = 0;
    lastChange = millis();
    tween = 1;		// next call gets immediate enough attention.
    busy = 1;
    return (1);
  }

  if (!busy)
    return (0);

  if (millis() - lastTime < tween)
    return;

  lastTime = millis();
  switch (frame) {
    case 0 :
      RenderFrame (ledarraytr1);
      tween = 200;
      frame++;
      break;

    case 1 : /* case 1 - 21 elided here */

    case 22 :
      RenderFrame (ledarraytr23);
      tween = 15;
      frame = 0;

      returnVal = 1;		// we done
      busy = 0;				// we not
      
      break;
  }

  return returnVal;
}

and call it like this:

  if (!turnMachineStep(1) and (totalState == 2 or totalState == 3)) {
  	turnMachineStep(0);
  }

it should finish any animation it started, and cycle if the signals remain valid.

Observe: the machine is called every time you loop(), whether or not you are animating.

If it is called AND is finished AND you want the animation to run, the (re)initialising call is made.

I have always said I launched you on a bad path… sometimes only when you see something working do you realize a little detail was left out of the design. Sometime a hack can be squeezed in; sometimes it will make sense to take a breath and start writing version 2. :expressionless:

I'd test the above code but I am off to see Rick Wakeman. YES, that Rick Wakeman. :wink:

a7