I can't figure out why declaring strings in my state machine stops it from switching states.

I am using QWIIC microSD card to record data from 4 sensors.

State 0is idle and blinks the onboard LED

State 1 generates a file and filename. Ideally I would like it to name it according to String2 but that doesn’t seem to be happening. no LED function because its only here for microseconds.

State 2 records until the switch is flipped. It also turns on the onboard LED so I know its recording.

I’m not sure if I should post my entire code and other states. With the quoted code below (state 1), it will do exactly what its suppose to and then stop. It won’t go to state 2 (records sensor values below headers in state 1 in txt file). Onboard LED stays off. I think its stateless. If it’s still in state 1, it’s not looping because if I add a function to mess with the LED, nothing happens.

When I delete those string functions though, the entire program works exactly as intended (aside from being able to generate custom names for data files) and goes a to the next state and records data. Onboard LED turns on.

What exactly do those functions do?

myLog.begin();
      String String1 = String(switchcount);         // number of times switch is flipped
      String String2 = String("test" + String1 + ".txt");   //custom file name
      myLog.append("test.txt");                      // Create file
      myLog.println("Date, V1, V2, V3, V4");
      myLog.syncFile();
      Serial.println("Date, V1, V2, V3, V4");
      Serial.println(1);            // prints what state its in
      state = 2;
      break;

Full code:

#include <Wire.h>
#include "SparkFun_Qwiic_OpenLog_Arduino_Library.h"
OpenLog myLog; //Create instance

int ledPin = 13; //Status LED connected to digital pin 13

#include <SparkFun_RV8803.h>

RV8803 rtc;

const int sensorPin0 = A0;
const int sensorPin1 = A1;
const int sensorPin2 = A2;
const int sensorPin3 = A3;

int switchState = 0;           //switch to start datalogging
int state = 0;

int switchcount = 0;                // number of times switch is flipped
int resolutiontime = 500;         // measure every X millseconds
int testtime = 600000;             // test length in milliseconds

void setup() {
  Serial.begin(9600);
  Wire.begin();
  pinMode(10, INPUT);             // switch with 10k pull down resistor
  pinMode(ledPin, OUTPUT);
  if (rtc.begin() == false) {                           // check rtc
    Serial.println("Something went wrong, check wiring");
  }
  else
  {
    Serial.println("RTC online!");
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  sm();         //state machine
}

void sm() {
  switch (state) {
    case 0: //Idle wait for input
      switchState = digitalRead(10);        //condition is switch, on=start datalogging, off=do nothing/stay in state 0
      if (switchState == HIGH) {
        state = 1;
      }
      else {
        state = 0;
      }
      // eventually put LCD print "IDLE" here
      digitalWrite(ledPin, HIGH);
      delay(250);
      digitalWrite(ledPin, LOW);
      delay(250);
      break;

    case 1:       //start new file and add header
      myLog.begin();
      String String1 = String(switchcount);         // number of times switch is flipped
      String String2 = String("test" + String1 + ".txt");   //custom file name
      myLog.append("test.txt");                      // Create file
      myLog.println("Date, V1, V2, V3, V4");
      myLog.syncFile();
      Serial.println("Date, V1, V2, V3, V4");
      Serial.println(1);            // prints what state its in
      state = 2;
      break;

    case 2:        //start datalogging and append to file from case 1
      int sensorVal0 = analogRead(sensorPin0);
      int sensorVal1 = analogRead(sensorPin1);
      int sensorVal2 = analogRead(sensorPin2);
      int sensorVal3 = analogRead(sensorPin3);
      float volts0 = (sensorVal0 / 1024.0) * 5.0;
      float volts1 = (sensorVal1 / 1024.0) * 5.0;
      float volts2 = (sensorVal2 / 1024.0) * 5.0;
      float volts3 = (sensorVal3 / 1024.0) * 5.0;
      Serial.print(" , ");
      Serial.print(volts0);
      Serial.print(" , ");
      Serial.print(volts1);
      Serial.print(" , ");
      Serial.print(volts2);
      Serial.print(" , ");
      Serial.println(volts3);
      switchState = digitalRead(10);
      if (rtc.updateTime() == false)
      {
        Serial.print("RTC failed to update");
      }
      String currentDate = rtc.stringDateUSA();
      String timestamp = rtc.stringTime();
      myLog.begin();
      myLog.print(currentDate);
      myLog.print(" ");
      myLog.print(timestamp);
      myLog.print(" , ");
      myLog.print(volts0);
      myLog.print(" , ");
      myLog.print(volts1);
      myLog.print(" , ");
      myLog.print(volts2);
      myLog.print(" , ");
      myLog.println(volts3);
      myLog.syncFile();
      if (switchState == LOW) {
        state = 0;
      }
      else {
        state = 2;
      }
      delay(resolutiontime);
      digitalWrite(ledPin, HIGH); 
      break;
  }
}

Maybe create the file first (like example3) and then append (like example2).

Doesn’t seem to help. If I remove the Strings entirely I get a new file generated named test and the next state will successfully log data into the created file. Only issue it it will keep writing to the same file everytime the switch is flipped because that’s what the code tells it to do.

Those two lines of code are interfering somehow and I can’t figure it out. Is there a memory overflow bug I’m unaware of here?

Even when the strings are isolated and nothing depends on them, they somehow still crash the code.

Is there another way to generate sequential filenames everytime the switch is flipped without using those functions? The craziest part is I call strings in state 2 and have no problems with them messing things up.

I rewrote it as thanks to reddit user truetofiction

char buffer[40];

sprintf(buffer, "text%d.txt", switchcount);

myLog.append(buffer); // Create file

And now it works perfect.