High score doesn't always save on SD card

Greetings everyone,
In the code below, i would like to point to two sections. Specifically the final part of the "setup" function, where high score should be printed on a LCD screen when My arduino mega is plugged in to mains...and the function "void checkIfStopWasPressed", where when stop is pressed, the program would compare the current score (runningTotal) with the highscore, that would already be stored on the SD card. And if the new runningTotal is higher than the highscore on the SD card, the given high score should be deleted from the SD card and the new one should be saved...So that the high score stays saved when arduino is unplugged from power supply, and can be displayed again when the arduino powers on again...But in my case...the high score doesnt always get saved on the SD card as it should..which is not good...It only saves the high score every 10-15 events maybe...Am i doing something wrong?

  BASED ON State change detection (edge detection) changed for INPUT PULLUP
  and with a struct array
  delay()-less millis()-based pulse pin 13

#include <SD.h>
#include <SPI.h>
#include <TMRpcm.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#define SD_ChipSelectPin 53  //example uses hardware SS pin 53 on Mega2560

TMRpcm audio;   // create an object for use in this sketch

File myFile;
char line[25];
byte index = 0;
unsigned long prejsni = 0;
const long interval = 100;

// the buttons
struct buttons
  byte pin;
  byte led;
  bool state;
  bool prevState;
  byte score;
  byte pressed;
  char muzika[10];//tu dodam string ki bo vseboval ime datoteke z muziko/////lahko se znajša na manj znakov/////////////////////////////////////////////////////////////

const byte buttonPins[] = {13, 14, 15, 16, 17};  //Senz za M A R I O
const byte numberOfButtons = sizeof(buttonPins) / sizeof(buttonPins[0]);
buttons mybuttons[numberOfButtons];
const byte ledPins[] = {23, 24, 25, 26, 27};
const byte scores[] = {10, 20, 30, 40, 50};
const char *ImenaMuzik[] = {"boo.wav", "coin.wav", "opica.wav", "bomba.wav", "shyguy.wav",}; //tu dodam polje stringov ki vsebujejo imena datotek z muziko////////preimenuj v imena datotek/////////////////////////////////////////////////////////

bool reading;
const int button = 49;
bool prevState;

long highscore = 0;
long runningTotal;
byte numberOfButtonsPressed = 0;

//the pulse led
int pulseLedInterval = 500;
unsigned long previousMillisPulse;
bool pulseState = false;

//the effect led
int effectLedInterval;
int effectLedIntervalMax = 100;
int effectLedIntervalMin = 30;
unsigned long previousMillisEffect;
bool effectState;
bool doEffect = false;

void setup()
  lcd.begin(16, 2);
  lcd.setCursor(3, 0);
  lcd.print("SUPER MARIO");
  lcd.setCursor(5, 1);

  // initialize the button pins as input with pullup so active low
  //    make sure the button is from pin to ground
  Serial.println(" ");
  Serial.print("Initialising "); Serial.print(numberOfButtons); Serial.println(" buttons");
  for (int i = 0; i < numberOfButtons; i++)
    mybuttons[i].pin = buttonPins[i];
    pinMode(mybuttons[i].pin, INPUT_PULLUP);
    mybuttons[i].led = ledPins[i];
    pinMode(mybuttons[i].led, OUTPUT);
    mybuttons[i].state = digitalRead(mybuttons[i].pin);
    mybuttons[i].prevState = mybuttons[i].state;
    mybuttons[i].score = scores[i];
    mybuttons[i].pressed = 0;
    Serial.print("Button: "); Serial.print(i);
    Serial.print(", Pin: "); Serial.print(mybuttons[i].pin);
    Serial.print(", Led: "); Serial.print(mybuttons[i].led);
    Serial.print(", Score: "); Serial.print(mybuttons[i].score);
    Serial.print(", Pressed: "); Serial.print(mybuttons[i].pressed);
    Serial.print(", State: "); Serial.print(mybuttons[i].state);
    Serial.print(", Prev state: "); Serial.println(mybuttons[i].prevState);
    strcpy(mybuttons[i].muzika, ImenaMuzik[i]);//tu vstavim ime muzike v spremenljivko za ta button////////////////////////////////////////////////////////////////////

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only

  pinMode(49, INPUT_PULLUP);

  audio.speakerPin = 6; //5,6,11 or 46 on Mega, 9 on Uno, Nano, etc
  if (!SD.begin(SD_ChipSelectPin)) {
  } else {
    Serial.println("SD OK");

  //Izpis high score-a iz SD kartice ob ponovnem zagonu.
  myFile = SD.open("test.txt");
  if (myFile) {

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      line[index] = (myFile.read());
      // check if character is '\r'
      if (line[index] == '\r')
        // add terminatin NUL character
        line[index] == '\0';
        // done
      // next character will go in next element of line
    // close the file:
    highscore = atol(line);

void loop()
  if (doEffect) blinkLedsAndMakeANoise();
  //  checkForbuttons1tateChange();
  //  if (doEffect1) blinkled1sAndMakeANoise();
} //loop

void checkForButtonStateChange()
  for (int i = 0; i < numberOfButtons; i++)
    mybuttons[i].state = digitalRead(mybuttons[i].pin);
    // compare the buttonState to its previous state
    if (mybuttons[i].state != mybuttons[i].prevState) // means it changed... but which way?
      if (mybuttons[i].state == HIGH)  // changed to pressed
        if (audio.isPlaying() == 0) { //returns 1 if music playing, 0 if not
          audio.play(mybuttons[i].muzika);//tu igra muziko za ta specifičen button/////////////////////////////////////////////////////////////////////////////
        Serial.print(" newly pressed");
        if (mybuttons[i].pressed == 0)
          mybuttons[i].pressed = 1;
          Serial.print(", Unique buttons pressed "); Serial.print(numberOfButtonsPressed);

        digitalWrite(mybuttons[i].led, HIGH);
        runningTotal = runningTotal + mybuttons[i].score;
        Serial.print(", Score "); Serial.println(runningTotal);
      // poor man's de-bounce
    // save the current state as the last state, for next time through the loop
    mybuttons[i].prevState = mybuttons[i].state;

  if (numberOfButtonsPressed == 5)
    Serial.print("All leds on, score "); Serial.println(runningTotal);
    for (int i = 0; i < numberOfButtons; i++)
      mybuttons[i].pressed = 0;
    doEffect = true;
    numberOfButtonsPressed = 0;
} // checkForButtonStateChange()

void blinkLedsAndMakeANoise()
  static byte numberOfEffects = 0;
  if (millis() - previousMillisEffect >= effectLedInterval)
    effectLedInterval = random(effectLedIntervalMin, effectLedIntervalMax);
    previousMillisEffect = millis();
    effectState = !effectState;
    for (int i = 0; i < numberOfButtons; i++)
      digitalWrite(mybuttons[i].led, effectState);

  if (numberOfEffects == 25)
    doEffect = false;
    numberOfEffects = 0;
    for (int i = 0; i < numberOfButtons; i++)
      digitalWrite(mybuttons[i].led, LOW);

void checkIfStopWasPressed()
  reading = digitalRead(49);
  if (reading == 0) { //button was pressed
    if (runningTotal > highscore) {  //check if current score > highsore
      highscore = runningTotal;      //if current score> highscore, write that score to SD card
      SD.remove("test.txt");  //izbriše file z starim rezultatom, ustvari nov file z novim high score-om.
      myFile = SD.open("test.txt", FILE_WRITE);
      if (myFile) {
        Serial.print("Writing to test.txt...");
     doEffect = true;
  numberOfButtonsPressed = 0;
  runningTotal = 0;

void text() {
  if (millis() - prejsni >= interval) {
    prejsni = millis();
    lcd.setCursor(4, 0);
    lcd.setCursor(4, 1);

It seems like you need some more debug statements in your sketch to figure out which part is failing.
Is the button push always being detected?
Is a new high score being detected?
Is the SD file successfully being removed?

what are you seeing on the Serial Monitor?

I have a LCD connected to the arduino. In the first row, the LCD displays the current score, and in the second row, the highscore is displayed.. The button is accually a IR sensor. When i put my finger in front, the mario game over theme song plays and if the runningTotal is higher than the previous score, it displays it. This has to mean that it does most of the intendend things right? But the highscore usually stays the same if I unplug the arduino...Only a few times does it accualy change..

However i do hear mulitple rattles from the speaker before the sound effect triggers when i put my finger in front of the sensor...might that have anything to do with this?

You are also doing serial prints before you call Serial.begin();

You should log to serial if either SD.begin() or SD.open() fails. If SD.begin() fails
perhaps you should simply loop forever rather than return prematurely from setup().

If the open() call for writing the high score fails, you silently ignore the fact.

Perhaps you should check that the high score table is writable in setup() too, so you
don't find out too late?

The thing is i know that the SD is working because the sound effects, which you can see in the code are dedicated to corresponding buttons, are played through the speaker when i run the code and activate the sensors...So the SD.begin event must happen...But about the SD.open....I will try add a Serial.printline("SD succesfully open") or something, so that it tells me if the writing to SD at least begins...

Will add the SD begin to the begining of setup....

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.