Sd card and lcd issue

Hi there

I wrote a code for a vending machine.
There are menus with options so that a service person can change stuff like price, amount etc...
I m using a atmega with lcd 2*16 and sd card module a nfc reader a thermostat and some buttons.
the problem is that my program gets stuck at the menus when it gets back to the main screen and as you can see on the serial monitor sd card reading also fails ??????????????
sometimes the lcd will go blank as well when i get back to main menu screen.

see below my code

many thanks

#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SD.h>
#define BUTTON_UP 19
#define BUTTON_DOWN 18
#define BUTTON_ENTER 8
#define NOKEY    0
#define KEYUP    1
#define KEYDOWN  2
#define KEYENTER 3
//menu's
#define MAXMENUOPTIONS 8
#define MAINMENU 0
#define CREATEGROUPMENU 1
#define PRICEMENU 2
#define AMOUNTMENU 3
#define UNITFORSALEFORSUBSCRIBERMENU 5
#define PRICEFORSUBSCRIBERMENU 6
#define PRICEPERUNITFORGROUPS 7

//define error codes
#define NO_MILK 1
#define HIGH_TEMP 2
#define LOW_TEMP 3
#define NO_CHANGE 4


//thermostat
#define ONE_WIRE_BUS 25
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#define MIN_ALOWED_TEMP 12
#define MAX_ALOWED_TEMP 30
#define MAX_ALOWED_TIME_AT_EXTREME_TEMP 60000
bool onceTempTimer;

int globalPrice = 5;//globalPrice for one vend of milk (1 unit equals 10 agurot)
int amount = 0;//amount in msec dispenced in one vend
int globalPriceForSubscribers;
int globalUnitsForSaleForSubscribers;
int pricePerUnitForGroups;

LiquidCrystal lcd(12, 11, 5, 4, 23, 22);
int menuPosition = 0;

byte upSign[8] = {
  0b00000,
  0b00000,
  0b00100,
  0b00100,
  0b01110,
  0b01110,
  0b11111,
  0b00000
};
byte downSign[8] = {
  0b00000,
  0b11111,
  0b01110,
  0b01110,
  0b00100,
  0b00100,
  0b00000,
  0b00000
};

byte enterSign[8] = {
  0b00001,
  0b00001,
  0b00001,
  0b00101,
  0b01101,
  0b11111,
  0b01100,
  0b00100
};

byte celciusSign[8] = {
  0b00111,
  0b00101,
  0b00111,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};

void setup() {
  // put your setup code here, to run once:
  sensors.begin();
  lcd.begin(16, 2);// set up the LCD's number of columns and rows:
  lcd.createChar(0, celciusSign);
  lcd.createChar(1, downSign);
  lcd.createChar(2, upSign);
  lcd.createChar(3, enterSign);
  lcd.clear();
  Serial.begin(115200);
  pinMode(BUTTON_UP, INPUT);
  pinMode(BUTTON_DOWN, INPUT);
  pinMode(BUTTON_ENTER, INPUT);
 
  if (!SD.begin(53)) {
    Serial.println("initialization SD failed!");
    // while (1);
  }
  Serial.println("initialization SD done.");
}

void loop() {

  menu();
}
void menu() {
  switch (key()) {
    case KEYUP:
      menuPosition++;
      if (menuPosition >= MAXMENUOPTIONS) {
        menuPosition = 0;
      }
      break;
    case KEYDOWN:
      menuPosition--;
      if (menuPosition < 0) {
        menuPosition = MAXMENUOPTIONS - 1;
      }
      break;
    case KEYENTER:
      bool hitEnter = false;
      switch (menuPosition) {
        case PRICEPERUNITFORGROUPS:
          do {
            lcd.setCursor(15, 0);
            lcd.rightToLeft();
            printHeb("קבע מחיר לקבוצות");
            lcd.leftToRight();
            lcd.setCursor(9, 1);
            lcd.print(pricePerUnitForGroups * 10);
            switch (key()) {
              case KEYUP:
                if (pricePerUnitForGroups < 1000) {//price cant be more then 100 shekel
                  pricePerUnitForGroups++;
                }
                break;
              case KEYDOWN:
                if (pricePerUnitForGroups > 1) {//globalPrice cant be less then 1
                  pricePerUnitForGroups--;
                }
                break;
              case KEYENTER:
                hitEnter = true;
                break;
            }
          } while (!hitEnter);
          break;
        case PRICEFORSUBSCRIBERMENU:
          do {
            lcd.setCursor(15, 0);
            lcd.rightToLeft();
            printHeb("קבע מחיר למנוים ");
            lcd.leftToRight();
            lcd.setCursor(9, 1);
            lcd.print(globalPriceForSubscribers * 10);
            switch (key()) {
              case KEYUP:
                if (globalPriceForSubscribers < 1000) {//price cant be more then 100 shekel
                  globalPriceForSubscribers++;
                }
                break;
              case KEYDOWN:
                if (globalPriceForSubscribers > 1) {//Price cant be less then 1
                  globalPriceForSubscribers--;
                }
                break;
              case KEYENTER:
                hitEnter = true;
                break;
            }
          } while (!hitEnter);
          break;
        case PRICEMENU:
          do {
            lcd.setCursor(15, 0);
            lcd.rightToLeft();
            printHeb("קבע מחיר באגורות");
            lcd.leftToRight();
            lcd.setCursor(9, 1);
            lcd.print(globalPrice * 10);
            switch (key()) {
              case KEYUP:
                if (globalPrice < 1000) {//price cant be more then 100 shekel
                  globalPrice++;
                }
                break;
              case KEYDOWN:
                if (globalPrice > 1) {//price cant be less then 1
                  globalPrice--;
                }
                break;
              case KEYENTER:
                hitEnter = true;
                break;
            }
          } while (!hitEnter);
          break;
        case AMOUNTMENU:
          do {
            lcd.setCursor(15, 0);
            lcd.rightToLeft();
            printHeb("כמות: cesm ");
            lcd.leftToRight();
            lcd.setCursor(0, 0);
            lcd.print(amount * 100);
            if (amount < 99) {
              lcd.setCursor(4, 0);
              lcd.print(" ");
            }
            switch (key()) {
              case KEYUP:
                if (amount < 200) {//amount cant be more then 20 sec
                  amount++;
                }
                break;
              case KEYDOWN:
                if (amount > 1) {//price cant be less then 1
                  amount--;
                }
                break;
              case KEYENTER:
                hitEnter = true;
                break;
            }
          } while (!hitEnter);
          break;
        case UNITFORSALEFORSUBSCRIBERMENU:
          do {
            lcd.setCursor(15, 0);
            lcd.rightToLeft();
            printHeb("יחידות למכירה:  ");
            lcd.leftToRight();
            lcd.setCursor(9, 1);
            lcd.print(globalUnitsForSaleForSubscribers);
            switch (key()) {
              case KEYUP:
                if (globalUnitsForSaleForSubscribers < 500) {//amount cant be more then 1 byte
                  globalUnitsForSaleForSubscribers++;
                }
                break;
              case KEYDOWN:
                if (globalUnitsForSaleForSubscribers > 1) {//price cant be less then 1
                  globalUnitsForSaleForSubscribers--;
                }
                break;
              case KEYENTER:
                hitEnter = true;
                break;
            }
          } while (!hitEnter);
          break;
        case CREATEGROUPMENU:
          int groupName[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
          int currentposition = 12;
          static int enterPressed = 0;
          int letter = 221;
          bool clearOnce = false;
          static long lastTimeOff;
          do {
            if (!clearOnce) {
              clearOnce = true;
              lcd.setCursor(15, 0);
              lcd.rightToLeft();
              printHeb("שם:             ");
            }
            lcd.setCursor(currentposition, 0);
            unsigned long currentMillis = millis();
            static long previousMillis;
            static bool letterOn;
            if (currentMillis - previousMillis >= 500) {
              previousMillis = currentMillis;// save the last time you blinked the letter
              if (!letterOn) {// if the letter is off turn it on and vice-versa:
                lcd.write(letter);
                groupName[currentposition] = letter;
                letterOn = true;
              } else {
                lcd.write(159);
                letterOn = false;
              }
            }
            switch (key()) {
              case KEYUP:
                enterPressed = 0;
                if (letter == 221) {
                  letter = 159;
                }
                if (letter == 186) {
                  letter = 159;
                }
                if (letter < 186) {//taf 187
                  letter++;
                }
                Serial.println(letter);
                break;
              case KEYDOWN:
                enterPressed = 0;
                if (letter == 221) {
                  letter = 187;
                }
                if (letter == 160) {
                  letter = 187;
                }
                if (letter > 160) {//alef 159
                  letter--;
                }
                Serial.println(letter);
                break;
              case KEYENTER:
                if (!letterOn) {
                  lcd.write(letter);
                }
                if (currentposition > 0) {
                  currentposition--;
                }
                letter = 221;
                enterPressed++;
                if (enterPressed == 2 ) {
                  hitEnter = true;
                }
                break;
            }
          } while (!hitEnter);
          long timer = millis() +10000;
          do {
            lcd.setCursor(15, 0);
            lcd.rightToLeft();
            printHeb("הצג כרתיס לשמור");
            //if (IsthereATagToRead()) {AddNewUidToGroup(globalUid,1,createNewGroup(groupName));
            //printHeb("נוסף קבוצה חדש");delay(1500);brake;
          } while (timer > millis());
          menuPosition = MAINMENU;
          break;
      }
  }


  switch (menuPosition) {
    case MAINMENU:
      lcd.setCursor(15, 0);
      lcd.rightToLeft();
      printHeb("מחיר:       ");
      lcd.leftToRight();
      if (globalPrice < 10) {
        lcd.setCursor(0, 0);
        lcd.print("0.");
        lcd.print(globalPrice);
        lcd.print("0 ");
      }
      else {
        int aftercomma = globalPrice % 10;
        int beforecomma = globalPrice / 10;
        lcd.setCursor(0, 0);
        lcd.print(beforecomma);
        lcd.print(".");
        lcd.print(aftercomma);
        lcd.print("0 ");
      }
      lcd.setCursor(0, 1);
      lcd.leftToRight();
      lcd.print("       ");
      static long displayTimer;
      if (displayTimer <  millis()) {
        thermostat();
        Serial.println("thermostat()");
        displayTimer = millis() + 3000;
      }
      break;
    case PRICEMENU:
      //lcd.clear();
      lcd.setCursor(15, 0);
      lcd.rightToLeft();
      printHeb("    קבע מחיר    ");
      displayButtons();
      break;
    case AMOUNTMENU:
      //lcd.clear();
      lcd.setCursor(15, 0);
      lcd.rightToLeft();
      printHeb("    קבע כמות    ");
      displayButtons();
      break;
    case CREATEGROUPMENU:
      //lcd.clear();
      lcd.setCursor(15, 0);
      lcd.rightToLeft();
      printHeb("  הוספת קבוצה   ");
      displayButtons();
      break;
    case   UNITFORSALEFORSUBSCRIBERMENU:
      lcd.setCursor(15, 0);
      lcd.rightToLeft();
      printHeb("קבע כמות  למנוים");
      displayButtons();
      break;
    case   PRICEFORSUBSCRIBERMENU:
      lcd.setCursor(15, 0);
      lcd.rightToLeft();
      printHeb("קבע מחיר  למנוים");
      displayButtons();
      break;
    case   PRICEPERUNITFORGROUPS:
      lcd.setCursor(15, 0);
      lcd.rightToLeft();
      printHeb("קבע מחיר לקבוצות");
      displayButtons();
      break;
  }

}
void displayButtons() {
  lcd.setCursor(0, 1);
  lcd.write(byte(1));
  lcd.setCursor(3, 1);
  lcd.write(byte(2));
  lcd.setCursor(6, 1);
  lcd.write(byte(3));
  lcd.setCursor(7, 1);
  lcd.leftToRight();
  printHeb("          ");
}

int key() {
  static long lastTimeSButtonA;
  static long lastTimeSButtonB;
  static long lastTimeSButtonC;
  if (digitalRead(BUTTON_UP) == LOW && millis() - lastTimeSButtonA > 200) { // left
    lastTimeSButtonA = millis();
    Serial.println("<up>");
    return KEYUP;
  } else if (digitalRead(BUTTON_DOWN) == LOW && millis() - lastTimeSButtonB > 200) { // right
    lastTimeSButtonB = millis();
    Serial.println("<down>");
    return KEYDOWN;
  } else if (digitalRead(BUTTON_ENTER) == LOW && millis() - lastTimeSButtonC > 200) { // enter
    lastTimeSButtonC = millis();
    Serial.println("<enter>");
    return KEYENTER;
  } else {
    return NOKEY;
  }

}
void printHeb(char *str)
{
  byte i;    // Input
  byte k = 0; // Output
  char arr[15]={0,0,0,0,  0,0,0,0,  0,0,0,0,  0,0,0};

  for (i = 0; i < strlen(str); i++)
  {
    if ((byte)str[i] < 127)
    {
      arr[k++] = (byte)(str[i]);
    }
    else
    {
      arr[k++] = (byte)(str[i + 1]) + 16; // -144+160;
      i++;
    }
  }

  arr[k] = 0;
  //Serial.println(strlen(str));
  lcd.print(arr);
  //  lcd.print(arr[1]);
  //for (int positionn = 0; positionn < strlen(str) - 14; positionn++) {
  //   for (int y = positionn; y < positionn+16; y++) {
  //    lcd.print(arr[y]);
  //    Serial.println(y);

  //  }
  //  delay(1000);
  //   lcd.setCursor(15, 0);
  // }
}

void thermostat() {

File myFile;
  myFile = SD.open("members.txt");
  if (myFile) {
    Serial.println("members.txt");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening members.txt");
  }

  myFile = SD.open("groups.txt");
  if (myFile) {
    Serial.println("groups.txt");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening groups.txt");
  }
  
  /* Serial.print("Celsius temperature: ");
    // Why "byIndex"? You can have more than one IC on the same bus. 0 refers to the first IC on the wire
    Serial.println(sensors.getTempCByIndex(0));*/
  sensors.requestTemperatures();
  //char tempForScreen[] = {'-', 3, 1, '.', 3, 0};
  //dtostrf(sensors.getTempCByIndex(0), 6, 2, tempForScreen);
  lcd.leftToRight();
  lcd.setCursor(9, 1);
  //for (int x = 0; x < 5; x++) {
  lcd.print(sensors.getTempCByIndex(0) );
  //lcd.print(tempForScreen[1] );
  //lcd.print(tempForScreen[2] );
  //lcd.print(tempForScreen[3] );
  // }
  lcd.setCursor(13, 1);
  lcd.write(byte(0));
  lcd.print("C");
  static float LastTimeTempRead;
  if (sensors.getTempCByIndex(0) < MIN_ALOWED_TEMP) {
    if (onceTempTimer) {
      LastTimeTempRead = millis();
      onceTempTimer = false;
    }
    if (sensors.getTempCByIndex(0) < MIN_ALOWED_TEMP && millis() - LastTimeTempRead > MAX_ALOWED_TIME_AT_EXTREME_TEMP) {
      error(LOW_TEMP);
    }
  }
  if (sensors.getTempCByIndex(0) > MAX_ALOWED_TEMP) {
    if (onceTempTimer) {
      LastTimeTempRead = millis();
      onceTempTimer = false;
    }
    if (sensors.getTempCByIndex(0) > MAX_ALOWED_TEMP && millis() - LastTimeTempRead > MAX_ALOWED_TIME_AT_EXTREME_TEMP) {
      error(HIGH_TEMP);
    }
  }
  if (sensors.getTempCByIndex(0) > MIN_ALOWED_TEMP && sensors.getTempCByIndex(0) < MAX_ALOWED_TEMP ) {
    static int counter;
    counter ++;
    if (counter == 10) {
      onceTempTimer = true;
      counter = 0;
    }
  }
}
void error(int errortype) {
  switch (errortype) {
    case NO_MILK:
      lcd.begin(16, 2);
      lcd.setCursor(11, 0);
      lcd.rightToLeft();
      printHeb("אין חלב");
      while (1) {};
      break;
    case HIGH_TEMP:
      lcd.begin(16, 2);
      lcd.setCursor(4, 0);
      lcd.print("ERROR HT");
      while (1) {
        lcd.setCursor(5, 1);
        lcd.print(sensors.getTempCByIndex(0));
      };
      break;
    case LOW_TEMP:
      lcd.begin(16, 2);
      lcd.setCursor(4, 0);
      lcd.print("ERROR LT");
      while (1) {
        lcd.setCursor(5, 1);
        lcd.print(sensors.getTempCByIndex(0));
      };
      break;
  }
}

and serial monitor

Found chip PN532
Firmware ver. 1.6
Waiting for an ISO14443A or ISO14443B Card ...
initialization SD done.
getting price from eeprom
price is: 39 agurot
getting  amount open time from eeprom
amount of open time in msec is: 50
getting group price from sd
group price is: 5 agurot
getting subscriber price from sd
subscriber price is: 50 agurot
getting subscriber amount for sale from sd
subscriber amount is: 100
members.txt
8B83B979,00001,1;!groups.txt
,160162000000000000000000000000000000000000000000:00000!thermostat()
<up>
<up>
<up>
<up>
<up>
<up>
<up>
<up>
initialization SD done.
members.txt
8B83B979,00001,1;!groups.txt
,160162000000000000000000000000000000000000000000:00000!initialization SD done.
members.txt
8B83B979,00001,1;!groups.txt
,160162000000000000000000000000000000000000000000:00000!thermostat()
<up>
<up>
<up>
<up>
<up>
<up>
<up>
<up>
members.txt
groups.txt
⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮```

Your topic was MOVED to its current forum category as it is more suitable than the original

Normally, when something really strange is going on, I suspect a memory problem.
But I compiled the code:

Sketch uses 19638 bytes (7%) of program storage space. Maximum is 253952 bytes.
Global variables use 1492 bytes (18%) of dynamic memory, leaving 6700 bytes for local variables. Maximum is 8192 bytes.

So you have SRAM... but, maybe some of the libs have dynamic buffering which would be a concern. So maybe since you are using an AVT Mega, insert the free-memory code below and call it before loop() and inside loop() ...

Arduino Playground - AvailableMemory

tryed and indeed when entering menu the freeMemory()=25.
So how can i fix this up?

I think you mean, Arduino Mega2560R3, which has 8KB of SRAM. You "could" move to another Arduino board with more SRAM

  • or -
    You can code to move constants and strings into flash.
    Example:

const byte PROGMEM upSign[8]   = {  0b00000,  0b00000,  0b00100,  0b00100,  0b01110,  0b01110,  0b11111,  0b00000};
const byte PROGMEM downSign[8] = {  0b00000,  0b11111,  0b01110,  0b01110,  0b00100,  0b00100,  0b00000,  0b00000};
const byte PROGMEM enterSign[8] = { 0b00001,  0b00001,  0b00001,  0b00101,  0b01101,  0b11111,  0b01100,  0b00100};
const byte PROGMEM celciusSign[8] = {0b00111,  0b00101,  0b00111,  0b00000,  0b00000,  0b00000,  0b00000,  0b00000};

And move print strings into flash, too:

  Serial.println(F("initialization SD done."));

just the above made a weebit more breathing room:

Sketch uses 19658 bytes (7%) of program storage space. Maximum is 253952 bytes.
Global variables use 1436 bytes (17%) of dynamic memory, leaving 6756 bytes for local variables. Maximum is 8192 bytes.

1492 - 1436 = 56 bytes gained.

If optimizations do not give you stability, move up to a more capable system board and port your code over (few changes are expected.)

THANKS

I have managed to optimise the code alot and indded the code doesnt crash anymore.
But i have a part in the program that still doesnt work propely.
I have made a function so that a person could create a group by first typing in the group name in hebrew.
The fonts are 160 to 186 so if you write 160 to lcd ("lcd.write(160)") it will display the first letter of hebrew alfabet this is all saved in a int array max 15 letters it suposed to save the name to a file called groups.txt so that when a member of the group places its nfc tag to the reader the groups name will show up on the lcd but it doesnt save the name yust some weird numbers see Serial monitor out put?

This is the code

case CREATEGROUPMENU:
          int groupName[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
          int currentposition = 12;
          static int enterPressed = 0;
          int letter = 221;
          bool clearOnce = false;
          static long lastTimeOff;
          do {
            if (!clearOnce) {
              clearOnce = true;
              lcd.setCursor(15, 0);
              lcd.rightToLeft();
              //printHeb("שם:             ");
              for (byte k = 0; k < 2; k++) {
                lcd.write(pgm_read_word(&nameString[k]));
              }
              lcd.print(":             ");
            }
            lcd.setCursor(currentposition, 0);
            unsigned long currentMillis = millis();
            static long previousMillis;
            static bool letterOn;
            if (currentMillis - previousMillis >= 500) {
              previousMillis = currentMillis;// save the last time you blinked the letter
              if (!letterOn) {// if the letter is off turn it on and vice-versa:
                lcd.write(letter);
                groupName[currentposition] = letter;
                letterOn = true;
              } else {
                lcd.write(159);
                letterOn = false;
              }
            }
            switch (key()) {
              case KEYUP:
                enterPressed = 0;
                if (letter == 221) {
                  letter = 159;
                }
                if (letter == 186) {
                  letter = 159;
                }
                if (letter < 186) {//taf 186
                  letter++;
                }
                //Serial.println(letter);
                break;
              case KEYDOWN:
                enterPressed = 0;
                if (letter == 221) {
                  letter = 187;
                }
                if (letter == 160) {
                  letter = 187;
                }
                if (letter > 160) {//alef 160
                  letter--;
                }
                //Serial.println(letter);
                break;
              case KEYENTER:
                if (!letterOn) {
                  lcd.write(letter);
                }
                if (currentposition > 0) {
                  currentposition--;
                }
                letter = 221;
                enterPressed++;
                if (enterPressed == 2 ) {
                  hitEnter = true;
                }
                break;
            }
          } while (!hitEnter);
          long timer = millis() + 5000;
          lcd.clear();
          //Serial.print("timer");
          Serial.println(timer);
          do {
            Serial.println(millis());
            lcd.setCursor(15, 0);
            lcd.rightToLeft();
            //printHeb("הצג כרתיס לשמור");
            for (byte k = 0; k < 16; k++) {
              lcd.write(pgm_read_word(&presentCardToSaveString[k]));
            } Serial.print("freeMemory()=");
            Serial.println(freeMemory());
            if (IsthereATagToRead()) {
              Serial.print("freeMemory()=");
              Serial.println(freeMemory());
              createNewGroup(groupName);
              //addMemberToGroup(globalUid, createNewGroup(groupName) , 1);
              lcd.setCursor(15, 0);
              //printHeb("נוסף קבוצה חדש");
              for (byte k = 0; k < 16; k++) {
                lcd.write(pgm_read_word(&newGroupAddedString[k]));
              }
              delay(1500);
              menuPosition = MAINMENU;
              break;
              break;
            }
          } while (timer > millis());
          menuPosition = MAINMENU;
          break;
      }

and this is the library:

long createNewGroup(int groupName[15]) {// each group in the group file looks as follow: name in int 160 for alef * 16 places on lcd followed by ":" followed by log of portions used  followed by ","
  File myFile;
  myFile = SD.open("groups.txt", O_RDWR);
  long filePosition = 0;
  bool endOfFile = false;
  do {
    uint8_t reading = myFile.read();
    if (reading == '*' ) { //found empty spot
      break;
    }
    if (reading == '!') {

      endOfFile = true;
      break;
    }
  } while (1);
  myFile.seek(myFile.position() - 1);
  if (endOfFile) {
    myFile.print(",");
  }
  for (int i = 0; i <= 15; i++) {
    if (groupName[i] > 0) {
      myFile.print(groupName[i]);

    }
    else {
      myFile.print(F("000"));

    }
  }
  myFile.print(F(":"));
  //Serial.println("printing:");
  for (int i = 0; i <= 4; i++) {
    myFile.print(F("0"));

  }

  if (endOfFile) {
    myFile.print(F("!"));
  } else {
    myFile.print(F(","));
  }
  long  myfilePosition = myFile.position() - 55;;
  myFile.close();
  return myfilePosition;

} 

and here the Serial monitor:

<enter>
<down>
<up>
<enter>
<up>
<enter>
<enter>
21523
16526
freeMemory()=6523
16778
freeMemory()=6523
17030
freeMemory()=6523
17282
freeMemory()=6523
0x8B 0x83 0xB9 0x79
freeMemory()=6523
members.txt
!groups.txt
,000000000000000000000000000000221160160000000580:00000!thermostat()
freeMemory()=6523
freeMemory()=6523

this should look like 160160000000000000000000000000000000000

wich shows on the lcd as twice the first hebrew letter if the following part of code is used:

void displayGroupName(long groupId) {
  File myFile;
  myFile = SD.open("groups.txt", O_RDWR);
  myFile.seek(groupId);

  lcd.setCursor(15, 0);
  lcd.rightToLeft();
  for (int x = 0; x <= 15; x++) {
    int letter = 0;
    for (int y = 0; y <= 3; y++) {
      if (y == 0) {
        letter += (myFile.read() - '0') * 100;
        ////Serial.print("position 1:");
        ////Serial.println(letter);
      }
      if (y == 1) {
        letter += (myFile.read() - '0') * 10;
      }
      if (y == 2) {
        letter += myFile.read() - '0';
      }
    }
    ////Serial.print(" ");
    ////Serial.print(letter);
    if (letter == 0) {
      lcd.print(F(" "));
    }
    else lcd.write(letter);

  }
}

My suggestion is to create a short sketch to write to the SD the file in the character format you desire then see what you got. SD issues are difficult to think through since there are so many dependencies.

You may also find this article enlightening.
Arduino Memories | Memories of an Arduino | Adafruit Learning System

Good luck,

Ray

1 Like

Thanks alot my code is now running smoothly!
the second part was a small bug wich i managed to fix!

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