Start from first case every time called?

Hello again :slight_smile:

Nearing the end of a project. One last thing I want to change.

My sketch calls to a void () to run an animation (switch case)

I'd like the animations to always start at frame (case 0) every time it's called, vs picking up where it left off the last time the animation was called.

I've been trying to find an example of this but haven't been able to figure that out yet.

Here's an example:

void turnAnimeStep()
{
  static byte frame = 0;    // reset to replay
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;
  if (millis() - lastTime < tween)
    return;

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

    case 1 :
      RenderFrame (ledarrayt2);
      tween = 15;
      frame++;
      break;

    case 2 :
      RenderFrame (ledarrayt3);
      tween = 15;
      frame++;
      break;

    case 3 :
      RenderFrame (ledarrayt4);
      tween = 15;
      frame++;
      break;

    case 4 :
      RenderFrame (ledarrayt5);
      tween = 15;
      frame++;
      break;

    case 5 :
      RenderFrame (ledarrayt6);
      tween = 15;
      frame++;
      break;

    case 6 :
      RenderFrame (ledarrayt7);
      tween = 15;
      frame++;
      break;

    case 7 :
      RenderFrame (ledarrayt8);
      tween = 15;
      frame++;
      break;

    case 8 :
      RenderFrame (ledarrayt9);
      tween = 15;
      frame++;
      break;

    case 9 :
      RenderFrame (ledarrayt10);
      tween = 15;
      frame++;
      break;

    case 10 :
      RenderFrame (ledarrayt11);
      tween = 15;
      frame++;
      break;

    case 11 :
      RenderFrame (ledarrayt12);
      tween = 15;
      frame++;
      break;

    case 12 :
      RenderFrame (ledarrayt13);
      tween = 15;
      frame++;
      break;

    case 13 :
      RenderFrame (ledarrayt14);
      tween = 15;
      frame++;
      break;

    case 14 :
      RenderFrame (ledarrayt15);
      tween = 15;
      frame++;
      break;

    case 15 :
      RenderFrame (ledarrayt16);
      tween = 15;
      frame++;
      break;

    case 16 :
      RenderFrame (ledarrayt17);
      tween = 15;
      frame++;
      break;

    case 17 :
      RenderFrame (ledarrayt18);
      tween = 15;
      frame++;
      break;

    case 18 :
      RenderFrame (ledarrayt19);
      tween = 15;
      frame++;
      break;

    case 19 :
      RenderFrame (ledarrayt20);
      tween = 15;
      frame++;
      break;

    case 20 :
      RenderFrame (ledarrayt21);
      tween = 15;
      frame++;
      break;

    case 21 :
      RenderFrame (ledarrayt22);
      tween = 15;
      frame++;
      break;

    case 22 :
      RenderFrame (ledarrayt23);
      tween = 15;
      frame++;
      break;

    case 23 :
      RenderFrame (ledarrayt24);
      tween = 15;
      frame = 0;
      break;
  }
}

I'm not sure if a modification here is needed or in the sketch where the operation is called.

Thanks for any help! I see the finish line for this one :slight_smile:

Hello

You could add a parameter reset to the function

void turnAnimeStep( const bool reset = false )
{
  static byte frame = 0;    // reset to replay
  
  if ( reset )
  {
    frame = 0;
  }

  ...

When you want to reset the animation, call turnAnimeStep( true );

That description does not make any sense. If you always start at case 0, it would do the first pattern and then return and the next time you called it, it would do the first pattern again, ...

-or-

If you want it to just cycle threw all those patterns before returning, just call the pattern, insert a delay(), call the next pattern, ... and then return. This, of course, would defeat the purpose of this function not being a blocking function.

They are called 'functions', not 'voids'. The first word at the left is the type of variable the function returns, with void meaning it does not return anything.

In your code the variable frame is defined as static. Static means that every time the function is called the variable will hold the same value it had when the function last returned (ended). If you always want it to be 0 (or any other particular value) lose the word static.

LOL.

OK, you've got a lot to learn about this stuff. :expressionless:

But srsly, we need to see just how this function is being called. In an old version, it was called without regard to where it was in the sequence of frames.

So what condition means reset to frame zero? When does calling stepAnime mean do the next frame w/o resetting?

So you know, post your code or a small example that shows how you use the function.

a7

You could condense your code greatly by using arrays. Then you wouldn't need the switch statement and all of the code in it.

A7

The function is called at a set of input states.

All I need to do is have the animation always start at the first frame.... So if it's cut off for whatever reason, when it's called again, it starts at the first frame.

I know I have a long way to go lol, but I'm keeping at it.

Anywhere here's the monster in it's entirety

//tail lamp dev v3

#include <Adafruit_NeoPixel.h>
#include  "taillightarrays.h"

#define PIN 3

const int sensorPin1 = A0;    // select a input pin for control 1 RUN LAMP
const int sensorPin2 = A1;    // select a input pin for control 2 TURN SIGNAL
const int sensorPin3 = A2;    // select a input pin for control 3 BRAKE LIGHT
const int sensorPin4 = A3;    // select a input pin for control 4 REVERSE
const int sensorPin5 = A4;    // party light
const int sensorPin6 = A5;    // turn signal delay function
const int OUTPUT_PIN = A6;    // OUTPUT PIN

unsigned long timerPreset;
unsigned long timerVal;

const int NUM_PIXELS = 256;

 // state names
#define IDLE 0
#define ACTIVE 1
#define RELEASED 2

// current state
byte state = IDLE ;

// timer stuff
#define INTERVAL 1060
unsigned long timer ;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, PIN, NEO_GRB);


void setup()
{
  strip.begin();
  strip.setBrightness(15);
  strip.show();   // Initialize all pixels to 'off'
  pinMode(A0, INPUT_PULLUP);
  pinMode(A1, INPUT_PULLUP);
  pinMode(A2, INPUT_PULLUP);
  pinMode(A3, INPUT_PULLUP);
  pinMode(A5, INPUT_PULLUP);
  pinMode(A6, OUTPUT);
  digitalWrite (OUTPUT_PIN, HIGH);
 



}

void loop()
{


  int state1 = 0; // initialize state1 value to zero
  int state2 = 0; // initialize state2 value to zero
  int state3 = 0; // initialize state3 value to zero
  int state4 = 0; // initialize state4 value to zero
  int state5 = 0; // initialize state4 value to zero

  if (digitalRead(sensorPin1) == LOW) // read the value from the sensor1: //run
    state1 = 1;
  else state1 = 0;


  if (digitalRead(sensorPin2) == LOW) // read the value from the sensor2: //turn
    state2 = 2;
  else state2 = 0;


  if (digitalRead(sensorPin3) == LOW) // read the value from the sensor3: //brake
    state3 = 4;
  else state3 = 0;


  if (digitalRead(sensorPin4) == LOW) // read the value from the sensor4: //reverse
    state4 = 8;
  else state4 = 0;

  if (digitalRead(sensorPin5) == LOW) // read the value from the sensor4: //party lights
    state5 = 20;
  else state5 = 0;


  int totalState = state1 + state2 + state3 + state4 + state5; //total of states to a single int

  //totals of state for which frame to render


  if (totalState == 0) { //off
    RenderFrame (ledarrayoff);
  }


  if (totalState == 1) { //run
    strip.setBrightness(50);
    RenderFrame (ledarrayrun);
  }


  if (totalState == 2 or totalState == 3) { //turn anime turn run anime
    strip.setBrightness(255);
    turnAnimeStep();
  }

  if (totalState == 4) { //brake
    RenderFrame (ledarraybrake);
    strip.setBrightness(255);
  }


  if (totalState == 5) { //run brake
    strip.setBrightness(255);
    RenderFrame (ledarraybrake);
  }


  if (totalState == 6) { //turn brake
    strip.setBrightness(255);
    turnbrakeAnimeStep();
  }


  if (totalState == 8) { // reverse
    strip.setBrightness(255);
    RenderFrame (ledarrayreverse);
  }


  if (totalState == 9) { // run reverse
    RenderFrame (ledarrayrunreverse);
    strip.setBrightness(255);
  }


  if (totalState == 10 or totalState == 11) { // turn reverse and run turn reverse
    turnReverseAnimeStep();
    strip.setBrightness(255);
  }


  if (totalState == 12) { // brake reverse
    RenderFrame (ledarraybrakereverse);
    strip.setBrightness(255);
  }


  if (totalState == 13) { // run brake reverse
    RenderFrame (ledarraybrakereverse);
    strip.setBrightness(255);
  }


  if (totalState == 14 or totalState == 15) { // turn brake reverse
    turnbrakeReverseAnimeStep ();
    strip.setBrightness(255);
  }

  if (totalState == 20) { // party lights
    PARTYLIGHTS ();
  }


  switch (state)
  {
    case IDLE: // IDLE waits for sensor trigger
    if (digitalRead (sensorPin6) == LOW)
    {
      state = ACTIVE ;
      digitalWrite (OUTPUT_PIN, LOW) ; // activate output
    }
    break ;

    case ACTIVE: // ACTIVE waits for sensor to release
    if (digitalRead (sensorPin6) == HIGH)
    {
      state = RELEASED ;
      timer = millis() ;  // on release start timer
    }
    break ;

    case RELEASED:  // waits for timeout (or retrigger)
    if (millis() - timer >= INTERVAL)
    {
      state = IDLE ;
      digitalWrite (OUTPUT_PIN, HIGH) ; // deactivate output
    }
    else if (digitalRead (sensorPin6) == LOW) // retriggered before timeout
    {  
      state = ACTIVE ;
    }
    break ;
  }
}

//Anime state machines

//turn anime machine
void turnAnimeStep()
{
  static byte frame = 0;    // reset to replay
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;
  if (millis() - lastTime < tween)
    return;

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

    case 1 :
      RenderFrame (ledarrayt2);
      tween = 15;
      frame++;
      break;

    case 2 :
      RenderFrame (ledarrayt3);
      tween = 15;
      frame++;
      break;

    case 3 :
      RenderFrame (ledarrayt4);
      tween = 15;
      frame++;
      break;

    case 4 :
      RenderFrame (ledarrayt5);
      tween = 15;
      frame++;
      break;

    case 5 :
      RenderFrame (ledarrayt6);
      tween = 15;
      frame++;
      break;

    case 6 :
      RenderFrame (ledarrayt7);
      tween = 15;
      frame++;
      break;

    case 7 :
      RenderFrame (ledarrayt8);
      tween = 15;
      frame++;
      break;

    case 8 :
      RenderFrame (ledarrayt9);
      tween = 15;
      frame++;
      break;

    case 9 :
      RenderFrame (ledarrayt10);
      tween = 15;
      frame++;
      break;

    case 10 :
      RenderFrame (ledarrayt11);
      tween = 15;
      frame++;
      break;

    case 11 :
      RenderFrame (ledarrayt12);
      tween = 15;
      frame++;
      break;

    case 12 :
      RenderFrame (ledarrayt13);
      tween = 15;
      frame++;
      break;

    case 13 :
      RenderFrame (ledarrayt14);
      tween = 15;
      frame++;
      break;

    case 14 :
      RenderFrame (ledarrayt15);
      tween = 15;
      frame++;
      break;

    case 15 :
      RenderFrame (ledarrayt16);
      tween = 15;
      frame++;
      break;

    case 16 :
      RenderFrame (ledarrayt17);
      tween = 15;
      frame++;
      break;

    case 17 :
      RenderFrame (ledarrayt18);
      tween = 15;
      frame++;
      break;

    case 18 :
      RenderFrame (ledarrayt19);
      tween = 15;
      frame++;
      break;

    case 19 :
      RenderFrame (ledarrayt20);
      tween = 15;
      frame++;
      break;

    case 20 :
      RenderFrame (ledarrayt21);
      tween = 15;
      frame++;
      break;

    case 21 :
      RenderFrame (ledarrayt22);
      tween = 15;
      frame++;
      break;

    case 22 :
      RenderFrame (ledarrayt23);
      tween = 15;
      frame++;
      break;

    case 23 :
      RenderFrame (ledarrayt24);
      tween = 15;
      frame = 0;
      break;
  }
}

//turn brake anime machine
void turnbrakeAnimeStep()
{
  static byte frame = 0;    // reset to replay
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;

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

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

    case 1 :
      RenderFrame (ledarraytb2);
      tween = 15;
      frame++;
      break;

    case 2 :
      RenderFrame (ledarraytb3);
      tween = 15;
      frame++;
      break;

    case 3 :
      RenderFrame (ledarraytb4);
      tween = 15;
      frame++;
      break;

    case 4 :
      RenderFrame (ledarraytb5);
      tween = 15;
      frame++;
      break;

    case 5 :
      RenderFrame (ledarraytb6);
      tween = 15;
      frame++;
      break;

    case 6 :
      RenderFrame (ledarraytb7);
      tween = 15;
      frame++;
      break;

    case 7 :
      RenderFrame (ledarraytb8);
      tween = 15;
      frame++;
      break;

    case 8 :
      RenderFrame (ledarraytb9);
      tween = 15;
      frame++;
      break;

    case 9 :
      RenderFrame (ledarraytb10);
      tween = 15;
      frame++;
      break;

    case 10 :
      RenderFrame (ledarraytb11);
      tween = 15;
      frame++;
      break;

    case 11 :
      RenderFrame (ledarraytb12);
      tween = 15;
      frame++;
      break;

    case 12 :
      RenderFrame (ledarraytb13);
      tween = 15;
      frame++;
      break;

    case 13 :
      RenderFrame (ledarraytb14);
      tween = 15;
      frame++;
      break;

    case 14 :
      RenderFrame (ledarraytb15);
      tween = 15;
      frame++;
      break;

    case 15 :
      RenderFrame (ledarraytb16);
      tween = 15;
      frame++;
      break;

    case 16 :
      RenderFrame (ledarraytb17);
      tween = 15;
      frame++;
      break;

    case 17 :
      RenderFrame (ledarraytb18);
      tween = 15;
      frame++;
      break;

    case 18 :
      RenderFrame (ledarraytb19);
      tween = 15;
      frame++;
      break;

    case 19 :
      RenderFrame (ledarraytb20);
      tween = 15;
      frame++;
      break;

    case 20 :
      RenderFrame (ledarraytb21);
      tween = 15;
      frame++;
      break;

    case 21 :
      RenderFrame (ledarraytb22);
      tween = 15;
      frame++;
      break;

    case 22 :
      RenderFrame (ledarraytb23);
      tween = 15;
      frame = 0;
      break;
  }
}

//turn brake reverse anime machine
void turnbrakeReverseAnimeStep()
{
  static byte frame = 0;    // reset to replay
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;

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

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

    case 1 :
      RenderFrame (ledarraytbr2);
      tween = 15;
      frame++;
      break;

    case 2 :
      RenderFrame (ledarraytbr3);
      tween = 15;
      frame++;
      break;

    case 3 :
      RenderFrame (ledarraytbr4);
      tween = 15;
      frame++;
      break;

    case 4 :
      RenderFrame (ledarraytbr5);
      tween = 15;
      frame++;
      break;

    case 5 :
      RenderFrame (ledarraytbr6);
      tween = 15;
      frame++;
      break;

    case 6 :
      RenderFrame (ledarraytbr7);
      tween = 15;
      frame++;
      break;

    case 7 :
      RenderFrame (ledarraytbr8);
      tween = 15;
      frame++;
      break;

    case 8 :
      RenderFrame (ledarraytbr9);
      tween = 15;
      frame++;
      break;

    case 9 :
      RenderFrame (ledarraytbr10);
      tween = 15;
      frame++;
      break;

    case 10 :
      RenderFrame (ledarraytbr11);
      tween = 15;
      frame++;
      break;

    case 11 :
      RenderFrame (ledarraytbr12);
      tween = 15;
      frame++;
      break;

    case 12 :
      RenderFrame (ledarraytbr13);
      tween = 15;
      frame++;
      break;

    case 13 :
      RenderFrame (ledarraytbr14);
      tween = 15;
      frame++;
      break;

    case 14 :
      RenderFrame (ledarraytbr15);
      tween = 15;
      frame++;
      break;

    case 15 :
      RenderFrame (ledarraytbr16);
      tween = 15;
      frame++;
      break;

    case 16 :
      RenderFrame (ledarraytbr17);
      tween = 15;
      frame++;
      break;

    case 17 :
      RenderFrame (ledarraytbr18);
      tween = 15;
      frame++;
      break;

    case 18 :
      RenderFrame (ledarraytbr19);
      tween = 15;
      frame++;
      break;

    case 19 :
      RenderFrame (ledarraytbr20);
      tween = 15;
      frame++;
      break;

    case 20 :
      RenderFrame (ledarraytbr21);
      tween = 15;
      frame++;
      break;

    case 21 :
      RenderFrame (ledarraytbr22);
      tween = 15;
      frame++;
      break;

    case 22 :
      RenderFrame (ledarraytbr23);
      tween = 15;
      frame = 0;
      break;
  }
}



//turn reverse anime machine
void turnReverseAnimeStep()
{
  static byte frame = 0;    // reset to replay
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;

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

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

    case 1 :
      RenderFrame (ledarraytr2);
      tween = 15;
      frame++;
      break;

    case 2 :
      RenderFrame (ledarraytr3);
      tween = 15;
      frame++;
      break;

    case 3 :
      RenderFrame (ledarraytr4);
      tween = 15;
      frame++;
      break;

    case 4 :
      RenderFrame (ledarraytr5);
      tween = 15;
      frame++;
      break;

    case 5 :
      RenderFrame (ledarraytr6);
      tween = 15;
      frame++;
      break;

    case 6 :
      RenderFrame (ledarraytr7);
      tween = 15;
      frame++;
      break;

    case 7 :
      RenderFrame (ledarraytr8);
      tween = 15;
      frame++;
      break;

    case 8 :
      RenderFrame (ledarraytr9);
      tween = 15;
      frame++;
      break;

    case 9 :
      RenderFrame (ledarraytr10);
      tween = 15;
      frame++;
      break;

    case 10 :
      RenderFrame (ledarraytr11);
      tween = 15;
      frame++;
      break;

    case 11 :
      RenderFrame (ledarraytr12);
      tween = 15;
      frame++;
      break;

    case 12 :
      RenderFrame (ledarraytr13);
      tween = 15;
      frame++;
      break;

    case 13 :
      RenderFrame (ledarraytr14);
      tween = 15;
      frame++;
      break;

    case 14 :
      RenderFrame (ledarraytr15);
      tween = 15;
      frame++;
      break;

    case 15 :
      RenderFrame (ledarraytr16);
      tween = 15;
      frame++;
      break;

    case 16 :
      RenderFrame (ledarraytr17);
      tween = 15;
      frame++;
      break;

    case 17 :
      RenderFrame (ledarraytr18);
      tween = 15;
      frame++;
      break;

    case 18 :
      RenderFrame (ledarraytr19);
      tween = 15;
      frame++;
      break;

    case 19 :
      RenderFrame (ledarraytr20);
      tween = 15;
      frame++;
      break;

    case 20 :
      RenderFrame (ledarraytr21);
      tween = 15;
      frame++;
      break;

    case 21 :
      RenderFrame (ledarraytr22);
      tween = 15;
      frame++;
      break;

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


//PARTYLIGHTS
void PARTYLIGHTS()
{
  static byte frame = 0;    // reset to replay
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;

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

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


    case 1 :
      RenderFrame (PARTYLIGHT2);
      tween = 200;
      frame = 0;
      break;
  }
}


void RenderFrame(const uint32_t *arr)
{
  for (uint16_t t = 0; t < 256; t++)
  {
    strip.setPixelColor(t, arr[t]);
  }
  strip.show();

}

What board are you using? If it is a Nano, A6 and A7 can only be used as analog inputs, not digital pins.

With the help of arrays, you can also simplify your code. I believe you need to differentiate between when a new totalState happens (reset your animation) vs. just continuing. The easiest is to do something like @guix suggested

//tail lamp dev v3

#include <Adafruit_NeoPixel.h>
#include  "taillightarrays.h"

#define PIN 3
/*
const int sensorPin1 = A0;    // select a input pin for control 1 RUN LAMP
const int sensorPin2 = A1;    // select a input pin for control 2 TURN SIGNAL
const int sensorPin3 = A2;    // select a input pin for control 3 BRAKE LIGHT
const int sensorPin4 = A3;    // select a input pin for control 4 REVERSE
const int sensorPin5 = A4;    // party light
const int sensorPin6 = A5;    // turn signal delay function
const int OUTPUT_PIN = A6;    // OUTPUT PIN
*/

const byte pinSensor[] = { A0, A1, A2, A3, A4 };
const byte sensorPinCount = sizeof( pinSensor ) / sizeof( pinSensor[0] );

const byte pinTurnSignalDelay = A5;
const int OUTPUT_PIN = A6;    // OUTPUT PIN

unsigned long timerPreset;
unsigned long timerVal;

const int NUM_PIXELS = 256;

// state names
#define IDLE 0
#define ACTIVE 1
#define RELEASED 2

// current state
byte state = IDLE ;

// timer stuff
#define INTERVAL 1060
unsigned long timer ;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, PIN, NEO_GRB);


void setup()
{
  strip.begin();
  strip.setBrightness(15);
  strip.show();   // Initialize all pixels to 'off'
  /*
  pinMode(A0, INPUT_PULLUP);
  pinMode(A1, INPUT_PULLUP);
  pinMode(A2, INPUT_PULLUP);
  pinMode(A3, INPUT_PULLUP);
  pinMode(A5, INPUT_PULLUP);
  pinMode(A6, OUTPUT);
  */
  for( int i=0; i < sensorPinCount; ++i ) {
    pinMode( pinSensor[i], INPUT_PULLUP );
  }
  pinMode( pinTurnSignalDelay, INPUT_PULLUP);
  digitalWrite (OUTPUT_PIN, HIGH);
}

int prevTotalState = -1;

void loop() {

  int totalState = 0; // initialize state1 value to zero

  for( int i = 0; i < sensorPinCount; ++i ) {
    if (digitalRead(pinSensor[i]) == LOW) {
    bitSet(totalState, i );
    }
  }

  if ( prevTotalState != totalState ) {
    // we have a new state
    newState( totalState );
    prevTotalState = totalState;
  }
  else {
    // same state
    currentState( totalState );
  }
  
  switch (state)
  {
    case IDLE: // IDLE waits for sensor trigger
      if (digitalRead (pinTurnSignalDelay) == LOW)
      {
        state = ACTIVE;
        digitalWrite (OUTPUT_PIN, LOW) ; // activate output
      }
      break ;

    case ACTIVE: // ACTIVE waits for sensor to release
      if (digitalRead (pinTurnSignalDelay) == HIGH)
      {
        state = RELEASED ;
        timer = millis() ;  // on release start timer
      }
      break ;

    case RELEASED:  // waits for timeout (or retrigger)
      if (millis() - timer >= INTERVAL)
      {
        state = IDLE;
        digitalWrite (OUTPUT_PIN, HIGH) ; // deactivate output
      }
      else if (digitalRead (pinTurnSignalDelay) == LOW) // retriggered before timeout
      {
        state = ACTIVE;
      }
      break;
  }
}

void newState( int totalState ) {
  
  if (totalState == 0) { //off
    RenderFrame (ledarrayoff);
  }

  if (totalState == 1) { //run
    strip.setBrightness(50);
    RenderFrame (ledarrayrun);
  }

  if (totalState == 2 or totalState == 3) { //turn anime turn run anime
    strip.setBrightness(255);
    turnAnimeStep(true);
  }

  if (totalState == 4) { //brake
    RenderFrame (ledarraybrake);
    strip.setBrightness(255);
  }

  if (totalState == 5) { //run brake
    strip.setBrightness(255);
    RenderFrame (ledarraybrake);
  }

  if (totalState == 6) { //turn brake
    strip.setBrightness(255);
    turnbrakeAnimeStep(true);
  }

  if (totalState == 8) { // reverse
    strip.setBrightness(255);
    RenderFrame (ledarrayreverse);
  }

  if (totalState == 9) { // run reverse
    RenderFrame (ledarrayrunreverse);
    strip.setBrightness(255);
  }

  if (totalState == 10 or totalState == 11) { // turn reverse and run turn reverse
    turnReverseAnimeStep(true);
    strip.setBrightness(255);
  }

  if (totalState == 12) { // brake reverse
    RenderFrame (ledarraybrakereverse);
    strip.setBrightness(255);
  }

  if (totalState == 13) { // run brake reverse
    RenderFrame (ledarraybrakereverse);
    strip.setBrightness(255);
  }

  if (totalState == 14 or totalState == 15) { // turn brake reverse
    turnbrakeReverseAnimeStep(true);
    strip.setBrightness(255);
  }

  if (totalState == 16) { // party lights
    PARTYLIGHTS(true);
  }
}

void currentState( int totalState ) {
  
  if (totalState == 0) { //off
    //RenderFrame (ledarrayoff);
  }

  if (totalState == 1) { //run
    //strip.setBrightness(50);
    //RenderFrame (ledarrayrun);
  }

  if (totalState == 2 or totalState == 3) { //turn anime turn run anime
    //strip.setBrightness(255);
    turnAnimeStep(false);
  }

  if (totalState == 4) { //brake
    //RenderFrame (ledarraybrake);
    //strip.setBrightness(255);
  }

  if (totalState == 5) { //run brake
    //strip.setBrightness(255);
    //RenderFrame (ledarraybrake);
  }

  if (totalState == 6) { //turn brake
    //strip.setBrightness(255);
    turnbrakeAnimeStep(true);
  }

  if (totalState == 8) { // reverse
    //strip.setBrightness(255);
    //RenderFrame (ledarrayreverse);
  }

  if (totalState == 9) { // run reverse
    //RenderFrame (ledarrayrunreverse);
    //strip.setBrightness(255);
  }

  if (totalState == 10 or totalState == 11) { // turn reverse and run turn reverse
    turnReverseAnimeStep(false);
    //strip.setBrightness(255);
  }

  if (totalState == 12) { // brake reverse
    //RenderFrame (ledarraybrakereverse);
    //strip.setBrightness(255);
  }

  if (totalState == 13) { // run brake reverse
    //RenderFrame (ledarraybrakereverse);
    //strip.setBrightness(255);
  }

  if (totalState == 14 or totalState == 15) { // turn brake reverse
    turnbrakeReverseAnimeStep(false);
    //strip.setBrightness(255);
  }

  if (totalState == 16) { // party lights
    PARTYLIGHTS(false);
  }
}

//Anime state machines

//turn anime machine
void turnAnimeStep(bool reset)
{
  if ( reset ) frame = 0;
  static byte frame = 0;    // reset to replay
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;
  if (millis() - lastTime < tween)
    return;

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

    case 1 :
      RenderFrame (ledarrayt2);
      tween = 15;
      frame++;
      break;

    case 2 :
      RenderFrame (ledarrayt3);
      tween = 15;
      frame++;
      break;

    case 3 :
      RenderFrame (ledarrayt4);
      tween = 15;
      frame++;
      break;

    case 4 :
      RenderFrame (ledarrayt5);
      tween = 15;
      frame++;
      break;

    case 5 :
      RenderFrame (ledarrayt6);
      tween = 15;
      frame++;
      break;

    case 6 :
      RenderFrame (ledarrayt7);
      tween = 15;
      frame++;
      break;

    case 7 :
      RenderFrame (ledarrayt8);
      tween = 15;
      frame++;
      break;

    case 8 :
      RenderFrame (ledarrayt9);
      tween = 15;
      frame++;
      break;

    case 9 :
      RenderFrame (ledarrayt10);
      tween = 15;
      frame++;
      break;

    case 10 :
      RenderFrame (ledarrayt11);
      tween = 15;
      frame++;
      break;

    case 11 :
      RenderFrame (ledarrayt12);
      tween = 15;
      frame++;
      break;

    case 12 :
      RenderFrame (ledarrayt13);
      tween = 15;
      frame++;
      break;

    case 13 :
      RenderFrame (ledarrayt14);
      tween = 15;
      frame++;
      break;

    case 14 :
      RenderFrame (ledarrayt15);
      tween = 15;
      frame++;
      break;

    case 15 :
      RenderFrame (ledarrayt16);
      tween = 15;
      frame++;
      break;

    case 16 :
      RenderFrame (ledarrayt17);
      tween = 15;
      frame++;
      break;

    case 17 :
      RenderFrame (ledarrayt18);
      tween = 15;
      frame++;
      break;

    case 18 :
      RenderFrame (ledarrayt19);
      tween = 15;
      frame++;
      break;

    case 19 :
      RenderFrame (ledarrayt20);
      tween = 15;
      frame++;
      break;

    case 20 :
      RenderFrame (ledarrayt21);
      tween = 15;
      frame++;
      break;

    case 21 :
      RenderFrame (ledarrayt22);
      tween = 15;
      frame++;
      break;

    case 22 :
      RenderFrame (ledarrayt23);
      tween = 15;
      frame++;
      break;

    case 23 :
      RenderFrame (ledarrayt24);
      tween = 15;
      frame = 0;
      break;
  }
}

//turn brake anime machine
void turnbrakeAnimeStep(bool reset)
{
  if ( reset ) frame = 0;
  static byte frame = 0;    // reset to replay
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;

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

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

    case 1 :
      RenderFrame (ledarraytb2);
      tween = 15;
      frame++;
      break;

    case 2 :
      RenderFrame (ledarraytb3);
      tween = 15;
      frame++;
      break;

    case 3 :
      RenderFrame (ledarraytb4);
      tween = 15;
      frame++;
      break;

    case 4 :
      RenderFrame (ledarraytb5);
      tween = 15;
      frame++;
      break;

    case 5 :
      RenderFrame (ledarraytb6);
      tween = 15;
      frame++;
      break;

    case 6 :
      RenderFrame (ledarraytb7);
      tween = 15;
      frame++;
      break;

    case 7 :
      RenderFrame (ledarraytb8);
      tween = 15;
      frame++;
      break;

    case 8 :
      RenderFrame (ledarraytb9);
      tween = 15;
      frame++;
      break;

    case 9 :
      RenderFrame (ledarraytb10);
      tween = 15;
      frame++;
      break;

    case 10 :
      RenderFrame (ledarraytb11);
      tween = 15;
      frame++;
      break;

    case 11 :
      RenderFrame (ledarraytb12);
      tween = 15;
      frame++;
      break;

    case 12 :
      RenderFrame (ledarraytb13);
      tween = 15;
      frame++;
      break;

    case 13 :
      RenderFrame (ledarraytb14);
      tween = 15;
      frame++;
      break;

    case 14 :
      RenderFrame (ledarraytb15);
      tween = 15;
      frame++;
      break;

    case 15 :
      RenderFrame (ledarraytb16);
      tween = 15;
      frame++;
      break;

    case 16 :
      RenderFrame (ledarraytb17);
      tween = 15;
      frame++;
      break;

    case 17 :
      RenderFrame (ledarraytb18);
      tween = 15;
      frame++;
      break;

    case 18 :
      RenderFrame (ledarraytb19);
      tween = 15;
      frame++;
      break;

    case 19 :
      RenderFrame (ledarraytb20);
      tween = 15;
      frame++;
      break;

    case 20 :
      RenderFrame (ledarraytb21);
      tween = 15;
      frame++;
      break;

    case 21 :
      RenderFrame (ledarraytb22);
      tween = 15;
      frame++;
      break;

    case 22 :
      RenderFrame (ledarraytb23);
      tween = 15;
      frame = 0;
      break;
  }
}

//turn brake reverse anime machine
void turnbrakeReverseAnimeStep(bool reset)
{
  if ( reset ) frame = 0;
  static byte frame = 0;    // reset to replay
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;

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

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

    case 1 :
      RenderFrame (ledarraytbr2);
      tween = 15;
      frame++;
      break;

    case 2 :
      RenderFrame (ledarraytbr3);
      tween = 15;
      frame++;
      break;

    case 3 :
      RenderFrame (ledarraytbr4);
      tween = 15;
      frame++;
      break;

    case 4 :
      RenderFrame (ledarraytbr5);
      tween = 15;
      frame++;
      break;

    case 5 :
      RenderFrame (ledarraytbr6);
      tween = 15;
      frame++;
      break;

    case 6 :
      RenderFrame (ledarraytbr7);
      tween = 15;
      frame++;
      break;

    case 7 :
      RenderFrame (ledarraytbr8);
      tween = 15;
      frame++;
      break;

    case 8 :
      RenderFrame (ledarraytbr9);
      tween = 15;
      frame++;
      break;

    case 9 :
      RenderFrame (ledarraytbr10);
      tween = 15;
      frame++;
      break;

    case 10 :
      RenderFrame (ledarraytbr11);
      tween = 15;
      frame++;
      break;

    case 11 :
      RenderFrame (ledarraytbr12);
      tween = 15;
      frame++;
      break;

    case 12 :
      RenderFrame (ledarraytbr13);
      tween = 15;
      frame++;
      break;

    case 13 :
      RenderFrame (ledarraytbr14);
      tween = 15;
      frame++;
      break;

    case 14 :
      RenderFrame (ledarraytbr15);
      tween = 15;
      frame++;
      break;

    case 15 :
      RenderFrame (ledarraytbr16);
      tween = 15;
      frame++;
      break;

    case 16 :
      RenderFrame (ledarraytbr17);
      tween = 15;
      frame++;
      break;

    case 17 :
      RenderFrame (ledarraytbr18);
      tween = 15;
      frame++;
      break;

    case 18 :
      RenderFrame (ledarraytbr19);
      tween = 15;
      frame++;
      break;

    case 19 :
      RenderFrame (ledarraytbr20);
      tween = 15;
      frame++;
      break;

    case 20 :
      RenderFrame (ledarraytbr21);
      tween = 15;
      frame++;
      break;

    case 21 :
      RenderFrame (ledarraytbr22);
      tween = 15;
      frame++;
      break;

    case 22 :
      RenderFrame (ledarraytbr23);
      tween = 15;
      frame = 0;
      break;
  }
}



//turn reverse anime machine
void turnReverseAnimeStep(bool reset)
{
  if ( reset ) frame = 0;
  static byte frame = 0;    // reset to replay
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;

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

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

    case 1 :
      RenderFrame (ledarraytr2);
      tween = 15;
      frame++;
      break;

    case 2 :
      RenderFrame (ledarraytr3);
      tween = 15;
      frame++;
      break;

    case 3 :
      RenderFrame (ledarraytr4);
      tween = 15;
      frame++;
      break;

    case 4 :
      RenderFrame (ledarraytr5);
      tween = 15;
      frame++;
      break;

    case 5 :
      RenderFrame (ledarraytr6);
      tween = 15;
      frame++;
      break;

    case 6 :
      RenderFrame (ledarraytr7);
      tween = 15;
      frame++;
      break;

    case 7 :
      RenderFrame (ledarraytr8);
      tween = 15;
      frame++;
      break;

    case 8 :
      RenderFrame (ledarraytr9);
      tween = 15;
      frame++;
      break;

    case 9 :
      RenderFrame (ledarraytr10);
      tween = 15;
      frame++;
      break;

    case 10 :
      RenderFrame (ledarraytr11);
      tween = 15;
      frame++;
      break;

    case 11 :
      RenderFrame (ledarraytr12);
      tween = 15;
      frame++;
      break;

    case 12 :
      RenderFrame (ledarraytr13);
      tween = 15;
      frame++;
      break;

    case 13 :
      RenderFrame (ledarraytr14);
      tween = 15;
      frame++;
      break;

    case 14 :
      RenderFrame (ledarraytr15);
      tween = 15;
      frame++;
      break;

    case 15 :
      RenderFrame (ledarraytr16);
      tween = 15;
      frame++;
      break;

    case 16 :
      RenderFrame (ledarraytr17);
      tween = 15;
      frame++;
      break;

    case 17 :
      RenderFrame (ledarraytr18);
      tween = 15;
      frame++;
      break;

    case 18 :
      RenderFrame (ledarraytr19);
      tween = 15;
      frame++;
      break;

    case 19 :
      RenderFrame (ledarraytr20);
      tween = 15;
      frame++;
      break;

    case 20 :
      RenderFrame (ledarraytr21);
      tween = 15;
      frame++;
      break;

    case 21 :
      RenderFrame (ledarraytr22);
      tween = 15;
      frame++;
      break;

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


//PARTYLIGHTS
void PARTYLIGHTS(bool reset)
{
  if ( reset ) frame = 0;
  static byte frame = 0;    // reset to replay
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;

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

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


    case 1 :
      RenderFrame (PARTYLIGHT2);
      tween = 200;
      frame = 0;
      break;
  }
}


void RenderFrame(const uint32_t *arr)
{
  for (uint16_t t = 0; t < 256; t++)
  {
    strip.setPixelColor(t, arr[t]);
  }
  strip.show();
}

If have created two functions newState and currentState that do what needs to get done depending on if the current sensors change or not. i deliberately left in, but commented out, much of the work in the currentState function since you don't have to repeat yourself unless you are doing animation.

This code

  if (totalState == 14 or totalState == 15) { // turn brake reverse
    turnbrakeReverseAnimeStep ();
    strip.setBrightness(255);
  }

moves turnbrakeReverseAnimeStep along from wherever it left off.

You must reset any machinery that is not running, I suggest

  if (totalState == 14 or totalState == 15) { // turn brake reverse
      turnbrakeReverseAnimeStep ();
      strip.setBrightness(255);
  }
  else  // machine not running, so reset it
      turnbrakeReverseAnimeStep(true);

And use @guix's plausible modification to add a reset functionality, adjusted here to provide only a reset call.

void turnAnimeStep( const bool reset = false )
{
  static byte frame = 0;    // reset to replay
  
  if ( reset )
  {
    frame = 0;
    return;        // that's all, folks!
  }

  ...

It'll get reset quite a bit, if reset was at all costly you could flag and do it only once as necessary. It isn't costly, however, so.

Also, you could change 20 to 16: I've breen exploiting the bit-coded nature of that variable, so 16 fits in with using 1, 2, 4, and 8 elsewhere.

a7