Can't manage to sort a file and display time & date on a LCD screen.

Hello everyone,

I have to make an interface using an Arduino Uno and a LCD screen.
I use push buttons to select sub-menus, a SD card to display a list of products from a file and a RTC (DS 1302) to give time and date.

The push buttons are connected to pins 2 to 7; LCD screen is connected to pins 8, 9, A0 to A3.
The RTC has pins A4 and A5.Pins 10 to 13 are available.

The problem is in the setup part. I initialize the RTC then I read the original file on the SD card to sort it alphabetically in an array and write this array into another file. Finally the LCD screen is initialized.

When the push button was down, I could read both time and date on the screen but not anymore, since I added the SD file.

Here is the code (the sorting part isn't written yet).

#include <LiquidCrystal.h>
#include <SD.h>
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
#define TAILLE_MAX 24
#define LIGNES 12
#define TEST 11

boolean Vprdt=0, Vperime=0, VOK=0, Vselect=0, ind=0, ind2=0, Vannule=0, VHD=0, men=1;//men-> menu
int buttonCount=0, buttonCountAnterior=0, positionText; 
const int prdt=2, perime=3, OK=4, select=5, annule=6, HD=7;//bouttons poussoirs 1 à 6
int prdtList=0, perimeList=0;
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

int continuer = 1, i=0, n=0, x, y, z;
char tableau [TAILLE_MAX]="";
char tab[LIGNES][TAILLE_MAX]={{},{}};
char tabFin[LIGNES][TAILLE_MAX]={{},{}};
char character;

String heure, date;
File myFile;

const int RS=17; //LCD screen pins
const int E=16; 
const int D4=15; 
const int D5=14; 
const int D6=8; 
const int D7=9; 

LiquidCrystal lcd(RS, E, D4, D5, D6, D7);// initialisation LCD en mode 4 bits

//RTC code
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.write(0);
   Wire.write(decToBcd(second));    // 0 to bit 7 starts the clock
   Wire.write(decToBcd(minute));
   Wire.write(decToBcd(hour));      // If you want 12 hour am/pm you need to set
                                   // bit 6 (also need to change readDateDs1307)
   Wire.write(decToBcd(dayOfWeek));
   Wire.write(decToBcd(dayOfMonth));
   Wire.write(decToBcd(month));
   Wire.write(decToBcd(year));
   Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);  // Need to change this if 12 hour am/pm
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

/**xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx**/

void setup()
{
   Wire.begin();
   
  second = 0;
  minute =45;
  hour = 8;
  dayOfWeek = 7;
  dayOfMonth = 28;
  month = 4;
  year = 14;
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
      
  pinMode(annule, INPUT);//push button initialization
  pinMode(perime, INPUT);
  pinMode(prdt, INPUT);
  pinMode(select, INPUT);
  pinMode(OK, INPUT);
  pinMode(HD, INPUT);
  
  digitalWrite(annule, LOW);
  digitalWrite(perime, LOW);
  digitalWrite(prdt, LOW);
  digitalWrite(select, LOW);
  digitalWrite(OK, LOW);
  digitalWrite(HD, LOW);
  
    
   pinMode(10, OUTPUT);//for SD card
  
  //test : SD card ?
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
  //reading SD file
  
  myFile = SD.open("liste.txt", FILE_READ);
  if (myFile) {
    Serial.println("Start reading...");
    myFile.seek(0);

   while(myFile.available())
    {
        while(character != '\n')
               {
                 character = myFile.read();
                 tab[x][y]=character;
                 Serial.print(tab[x][y]);
                 y++;
                 delay(10);
               }
               if (character=='\n')
               {
                character='0'; 
                y=0;
               }
               x++;
    }
    
        myFile.close();
    Serial.println("Read.");
     } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
  //file read.
 
  //start sorting
   x=0;
   Serial.println("Start sorting...");
   
   for (x=0; x<LIGNES;x++)
         {
           for (y=0; y<TAILLE_MAX;y++)
         {
           tabFin[x][y]=tab[x][y];
         }
         }
    x=0; 
  
  lcd.begin(16,2); // initialization LCD screen 

delay(100);
}

/**xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx**/

void loop()
{
    lcd.setCursor(6,0);
   lcd.print("Menu") ; 
  
  Vannule = digitalRead(annule);//Push buttons down?
  Vprdt = digitalRead(prdt);
  VOK = digitalRead(OK);
  VHD = digitalRead(HD);
  Vselect = digitalRead(select);
  Vperime = digitalRead(perime);
  
  if (Vprdt==HIGH)
    {
      buttonCount=1;
    }
    
    if (Vperime==HIGH)
    {
      buttonCount=2;
    }
    
    if (VOK==HIGH)
    {
      buttonCount=3;
    }
    
    if (Vselect==HIGH)
    {
      buttonCount=4;
    }
    
    if (Vannule==HIGH)
    {
      buttonCount=5;
    }
    
    if (VHD==HIGH)
    {
      buttonCount=6;
    }
    
    if (buttonCount==6)//if push button n°6 down, display time and date.
    {
    getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
      
      lcd.clear();
      delay(10);

      date= String(dayOfMonth, DEC) + "/" + String(month, DEC) + "/" + String(year, DEC);
      heure = String(hour, DEC) + ":" + String(minute, DEC);
      lcd.setCursor(4,0);
      lcd.print(date);
      lcd.setCursor(5,1);
      lcd.print(heure);
      delay(2000);
      lcd.clear();
      delay(10);
      buttonCount=0;
    }
}

At the very beginning, there was only a problem while displaying time and date ("28:4914" displayed). Now, when I check the Serial monitor, I read "initialization failed!" whereas the SD card is in its slot.
On the first line of the LCD screen, there are some grey rectangles as if the connections weren't the right ones.

I guess that if that problem is solved, the rest will be easier.

Thanks a lot,

Beth

   while(myFile.available())
    {
        while(character != '\n')
               {
                 character = myFile.read();

What happens if there isn't a \n in the file?

                 tab[x][y]=character;

What happens if the record is more than 23 characters long?
What happens if there are more than 24 records in the file?

Error handling IS important.

  if (Vprdt==HIGH)
    {
      buttonCount=1;
    }

Nonsense. You aren't counting anything.

Add some Serial.print() statements to see where the code is not doing what you want.

How is the SD card connected to the Arduino? Typically, SD cards are accessed using SPI, which means pins 11, 12, and 13. You are using pin 4 as the chip select pin AND as a switch pin. Hardly a good idea.

What happens if there isn't a \n in the file?

My file is written in that way. There are 12 lines for 12 products.
Each line is composed of the name of the product and its quantity.

What happens if the record is more than 23 characters long?
What happens if there are more than 24 records in the file?

Can't happen. There are less than 23 characters, every line has the same number of characters. I wrote the sorting programme apart and tested it without any problem.

I use an Ethernet shield for the SD card and I picked up the code on the arduino website.

Can't happen.

Bullshit.

I use an Ethernet shield for the SD card

Which means that you MUST set pin 10 as OUTPUT and you can not use it for anything else.

You need to get the switch off of pin 4, too.

Which means that you MUST set pin 10 as OUTPUT and you can not use it for anything else.

I already set pin 10 as an OUTPUT and there is nothing else on it.

I've figured out why I couldn't read it : the SD card was damaged. The card has been formated but I could only read it once. The card is damaged again.

Everything works perfectly if I ahve the following code :

void setup()
{
   Wire.begin();
   /*
  second = 0;
  minute =45;
  hour = 8;
  dayOfWeek = 7;
  dayOfMonth = 28;
  month = 4;
  year = 14;
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);*/
  
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
      
  pinMode(annule, INPUT);//push button initialization
  pinMode(perime, INPUT);
  pinMode(prdt, INPUT);
  pinMode(select, INPUT);
  pinMode(OK, INPUT);
  pinMode(HD, INPUT);
  
  digitalWrite(annule, LOW);
  digitalWrite(perime, LOW);
  digitalWrite(prdt, LOW);
  digitalWrite(select, LOW);
  digitalWrite(OK, LOW);
  digitalWrite(HD, LOW);
  
    
   pinMode(10, OUTPUT);//for SD card
  
  //test : SD card ?
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
  //reading SD file
  
  myFile = SD.open("liste.txt", FILE_READ);
  if (myFile) {
    Serial.println("Start reading...");
    myFile.seek(0);

   while(myFile.available())
    {
        while(character != '\n')
               {
                 character = myFile.read();
                 tab[x][y]=character;
                 Serial.print(tab[x][y]);
                 y++;
                 delay(10);
               }
               if (character=='\n')
               {
                character='0'; 
                y=0;
               }
               x++;
    }
    
        myFile.close();
    Serial.println("Read.");
     } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");}
  
  //file read.
  //with this as comment
  //start sorting
 /*  x=0;
   Serial.println("Start sorting...");
   
   for (x=0; x<LIGNES;x++)
         {
           for (y=0; y<TAILLE_MAX;y++)
         {
           tabFin[x][y]=tab[x][y];
         }
         }*/
   // x=0; 
  
  lcd.begin(16,2); // initialization LCD screen 

delay(100);
}

Capture.JPG

I removed the RTC and the programme works! My list is sorted! How do you explain that?

My list is sorted! How do you explain that?

The SD class must be sorting the file names before it returns the data to you.

It works half of the time. So, could you tell me how exactly I should connect the SD card? You told me to set pin 10 as an OUTPUT, I did it, but what about pin 4?

but what about pin 4?

What about it? You told the SD class that pin 4 was it's pin to own. Don't touch it.

It works half of the time.

Which half?

What about it? You told the SD class that pin 4 was it's pin to own. Don't touch it.

Ok. I set pin 10 as you told me, don't touch anymore to pin 4, so what do I write in SD.begin()? I tried with nothing written in it but still doesn't work.

Which half?

It depends on what I write. It can work for 10 min without any problem but, if I add two lines, the card becomes a ghost, impossible to detect it. (I perfectly know what you'll say). The thing is I tested the sorting programme before and when I mix the two, it fails.

You might be close to running out of memory.

You might be close to running out of memory.

Would it be possible? The programme only takes 16 454 bytes whereas the uno can store twice more.
I should maybe replace it by a mega.

so what do I write in SD.begin()?

4, just like you had.

Would it be possible?

Of course it would.

The programme only takes 16 454 bytes whereas the uno can store twice more.

That's flash memory. You are likely running out of SRAM.

You could recover some by using the F() macro:
Serial.println(F("initialization failed!"));

You could recover some by using the F() macro:
Serial.println(F("initialization failed!"));

That won't be enough, the programme is not completely written. I should switch for a mega, shouldn't I?

4, just like you had.

So what were you trying me to do? If it is not that, what's the matter with pin 4? I am bad at Arduino programming.