Nano acting weird when using SD module. Can't get anything to work! [SOLVED]

Update: I hate Strings. They cause havoc everywhere they go. The solution was to just not use them.

Hey all, I'm making a small project that takes a button press (interrupt), increases a number in an array on a memory card, and prints that new array below the last, using the SD library. My issues are all over and random, just before making this post I had one issue and now I have a different one completely without changing code. Anyway, on to the specifics:

What I'm trying to do now, is just open the SD card, read all the "lines" (really just separated by \n) and store the data in an array at the end. I've gotten that all to work, as well as the code I added after. But now the nano seems to break before even doing any of that.

What happens now is when I press a button to activate an interrupt, it opens the interrupt function, prints half a message to the serial monitor, and then nothing, it's frozen and stops there.

Here's the code: (large portion is commented out because it normally works but the new issue prevents this)

[code]
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
DS1307 rtc;
int CS_PIN = 10;
File file;
const int commonPin = 2;
const int buttonPins[] = {3, 4, 5, 6, 7, 8, 9}; //only 4 pins are used; 3-6 for testing purposes
unsigned long lastFire = 0;
char names[] = {'D', 'S', 'C', 'H'}; //ignore, for later use
int total[] = {0, 0, 0, 0};



void setup() {
  Serial.begin(57600);

  //Serial.println("Initializing SD card...");
  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("Ready");



  configureCommon(); // Setup pins for interrupt
  attachInterrupt(digitalPinToInterrupt(commonPin), pressInterrupt, FALLING);
}
void loop() {
}



//main function is here
void press(int button) {
  Serial.print("you pressed: "); //just to tell me which button was pressed, not necessary anymore since I know it's always correct
  Serial.println(button);

  file = SD.open("Test.txt", FILE_READ);
  Serial.println("begin reading");

  String totals = ""; //String to store the numbers in each individual array, should replace this with something that isn't a String though
  char beef; //character that is added to the string totals in the function below

  //Here we read all the values in the text file and only the last line is saved in the array total[]
  while (file.available()) {
    for (int i = 0; i <= 3; i++) {
      beef = file.read();
      Serial.print("I see: " + beef);
      while (beef != '/') {
        //Serial.print('.');
        totals += beef;
        beef = file.read();
      }
      total[i] = totals.toInt();
      totals = "";

    }
  }
  file.close();

  /*

    //here a switch case checks which button was pressed and updates the array
    switch (button){
      case 0:
      ++total[0];
      //Serial.println("increased 0");
        break;
      case 1:
      --total[0];
     // Serial.println("decreased 0");
        break;
      case 2:
      ++total[1];
        break;
      case 3:
      --total[1];
        break;
    }



    file = SD.open("Test.txt",FILE_WRITE);
    if (file){
    file.print('\n'); //at the end of the last line put a newline so a human boy can read this shit
    for (int i = 0; i<=3; i++){
    file.print(total[i]);
    file.print('/');

    }
    }
    file.close();

    for (int i = 0;i<4;i++){
    Serial.print(total[i]);
    }
    Serial.println();
  */
}








//Interrupt things//////////////////////////////////////////////////////////////////////////

void pressInterrupt() { // ISR
  if (millis() - lastFire < 200) { // Debounce
    return;
  }
  lastFire = millis();

  configureDistinct(); // Setup pins for testing individual buttons

  for (int i = 0; i < sizeof(buttonPins) / sizeof(int); i++) { // Test each button for press
    if (!digitalRead(buttonPins[i])) {
      press(i);
    }
  }

  configureCommon(); // Return to original state
}

void configureCommon() {
  pinMode(commonPin, INPUT_PULLUP);

  for (int i = 0; i < sizeof(buttonPins) / sizeof(int); i++) {
    pinMode(buttonPins[i], OUTPUT);
    digitalWrite(buttonPins[i], LOW);
  }
}

void configureDistinct() {
  pinMode(commonPin, OUTPUT);
  digitalWrite(commonPin, LOW);

  for (int i = 0; i < sizeof(buttonPins) / sizeof(int); i++) {
    pinMode(buttonPins[i], INPUT_PULLUP);
  }
}

[/code]

Now when I upload this, run it, and open the serial monitor. I get this:

10:53:04.409 -> Ready
10:53:04.923 -> yo

The second line appears after I press a button

Also, the nano is connected to an SD card module here
The only other thing connected is a button that shorts between D2 and D3 for the interrupt

I think I've covered everything, but correct me if I'm wrong.
Any help is greatly appreciated. Thank you

All your code is executed within an interrupt. That's not going to go well. I don't see why you need to use one at all.

wildbill:
All your code is executed within an interrupt. That's not going to go well. I don't see why you need to use one at all.

So update, I replaced the String with an alternative and now things are running much better and I'm onto another issue. But what would you recommend? That the interrupt triggers a function? or something else?

Usually, for reading buttons, polling is responsive enough as long as you don't use delay for anything other than debouncing. If you must use interrupts, just have it set a flag and poll that. Make it volatile.

wildbill:
Usually, for reading buttons, polling is responsive enough as long as you don't use delay for anything other than debouncing. If you must use interrupts, just have it set a flag and poll that. Make it volatile.

So I just figured how to get the rest to work finally, but I'm curious in doing what you said. I have never used polling/flags/volatile before so I'll have to do some research. I more or less understand the purpose, not why interrupts are bad but I'll do my best to avoid this in the future. Thanks for the advice!

Interrupts are very useful when appropriate. But in an interrupt routine, interrupts are disabled which means that trying to do anything that uses them like millis or serial output will either fail or at least act in an unexpected way. If your routine is long, you risk missing other interrupts which will likely have unpleasant results.

wildbill:
Interrupts are very useful when appropriate. But in an interrupt routine, interrupts are disabled which means that trying to do anything that uses them like millis or serial output will either fail or at least act in an unexpected way. If your routine is long, you risk missing other interrupts which will likely have unpleasant results.

Ahhhh I see. That makes total sense. Well thankfully I think it works perfectly with this project because I don't want any other buttons to be triggered while one is still being logged. But I will have to remember it works that way for the future for sure