program going bezerk after 5 cycles

Hi Everyone,

I wrote a little program that does the following:

  • An RFID reader detect a Tag, and extract the serial number
  • That serial number is compared with a list of authorized numbers, from an SD card file
  • If number is valid, user is allowed to do an action
  • if same user try the same tag again, the serial number will be recognized, but a second action won’t be allowed
  • If a serial number is NOT found, a “Unrecognized” message will show up

Format on the file is :

  • 9 bytes for serial number
  • 1 byte for tag’s team (future)
  • 2 “footer” bytes (\n)

The messages are sent to an LCD, over I2C

Everything (almost) works fine: the first 5 tags that are scanned, will behave properly (it can be 5 time the same tag). on the 6th one, the serial number is recognized, but it looks like it does not get compared …

anyone has an idea ???

code is as follow:

(note that anything directed to the serial port WAS for troubleshooting)

/*
  SD card read/write

 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4
 
 */
#include <Wire.h> 
#include <SD.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR    0x20
#define BACKLIGHT_PIN  7
#define En_pin  4
#define Rw_pin  5
#define Rs_pin  6
#define D4_pin  0
#define D5_pin  1
#define D6_pin  2
#define D7_pin  3
int PB1 = 2;
int PB2 = 3;
int MaxTags = 0;
boolean Used[20];  // set for 20 users, for now
String MyString;
int NewData = 0;
boolean NotDone = 1;
int Position = 0;
String ComparedString = "";
String Line1 = "";
String Line2 = "";
int Temp = 0;

LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
File myFile;

void setup(){
  lcd.begin (16,2);
  lcd.setBacklightPin(BACKLIGHT_PIN,NEGATIVE);
  lcd.setBacklight(1);    
  Serial.begin(9600);
  pinMode(PB1,INPUT);
  pinMode(PB2,INPUT);
  pinMode(10, OUTPUT);       // don't ask, must be there for the SD library to work
  pinMode(9,OUTPUT);         // buzzer
    Line1 ="Initialising ";
    Line2 = "SD card...";
    Display();
  //Serial.println("Initializing SD card...");
  if (!SD.begin(4)) {
    Line1 ="Inititialisation";
    Line2 = "Failed !";
    Display();
    //Serial.println("Initializing Failed...");
    return;
  }
    Line1 ="Initialisation";
    Line2 = "completed";
    Display();
  //Serial.println("initialization done.");
  
  myFile = SD.open("TAGS.txt", FILE_READ);
    if (myFile) { 
      MaxTags = (myFile.available()/12);
      Line1 = "There are: ";
      Line1 = Line1 + MaxTags;
      Line2 = "Tags Registered";
      Display();
      delay (1000);
    } 
} 
void Display(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(Line1);
  lcd.setCursor(0,1);
  lcd.print(Line2);
  delay(500);         // delay to allow user enough time to read the latest message
}
void loop(){
  // the thing about the Temp, is to wait a bit before re-initialising the "Ready" message
  if (Temp < 250){
    Serial.println(Temp);
    Temp = Temp+1;
  }
  if (Temp == 250){
   Line1 = "     Ready !"; 
   Line2 = "   Swap a Tag ";
   Display();
   Temp = 251;
  }
  if (Serial.available() != 0) {// data present from RFID
    Temp= 0;
    RFID();
  }
  if (digitalRead(PB1)==1){
    // nothing for now
  }
  if (digitalRead(PB2)==1){
    // nothing for now
  }
}

void RFID(){
    Line1 ="Data Received...";
    Line2 = "";
    Display();
  //Serial.println("Data received....");
  digitalWrite(9,HIGH);
  delay(80);
  digitalWrite(9,LOW);
  Serial.read();      // flush Header
  Serial.read();      // flush 1 st digit
  Serial.read();      // flush 2 nd digit
  Serial.read();      // flush 3 rd digit
  //Serial.println("Extracting.... ");
  MyString = "";
  while (Serial.available() > 0){
    NewData = Serial.read();
    BuildString();
  }
  //Serial.println("going to compare routine");
   Compare();
}
void BuildString()
{
  if(NewData == 3){       // 3 = Footer
    Line1 ="Fob number :";
    Line2 = MyString;
    Display();  
    //Serial.print("Serial Number Read: ");
    //Serial.println(MyString);
    while(Serial.available()){
      Serial.read();
    }
    return;
  }
  MyString = MyString + char(NewData);
}

void Compare(){
    Position = 0;
    //Serial.println("Opening file");
    myFile = SD.open("TAGS.txt", FILE_READ);
    if (myFile) { 
      //Serial.println("Searching ...."); 
      while(NotDone == 1) {
            ComparedString = "";
        for(int i=0;i<9;i++){
        ComparedString = ComparedString + (char(myFile.read()));
        }
        myFile.read() ;     // Flush the Team character        
        myFile.read() ;     // Flush the '\' character
        myFile.read();      // Flush the 'n' character
        //if (ComparedString ==""){
          //NotDone = 0;
        //}
        if (MyString == ComparedString){
          Line1 = " Found tag...";
          //Serial.println("Found tag");
          if (Used[Position] == 0){
           Line2 = "Tag never used !";
           Display();
            //Serial.println("Tag never used");
            Used[Position] = 1;
            return;            
          }
          if (Used[Position] == 1){
           Line2 = "Tag used before";
           Display();
            //Serial.println("Tag used before !");
            return;
          }
          NotDone = 0;
        }
        Position = Position + 1;
        if(Position == (MaxTags)){
        Line1 = "Unrecognized tag";
        Line2 = " Contact Staff !";
        Display();
        //Serial.println("Unrecognized tag !");
          return;
        }
      }
     }
}

You need to close the file.

So if at least one byte is in the serial buffer go ahead and read four bytes.

Plus read the how to use the forum sticky and learn all about code tags.

Thanks Wildbill…that solved it !

Any idea why it worked for 5 cycles everytime ?!?

jouellet: Any idea why it worked for 5 cycles everytime ?!?

Any idea why you didn't go back to your first post and edit it to show your very long code properly in code tags (the # button).

...R

wow !

some people are more interested into me fixing the way I displayed my code than trying to provide an answer.....

I did not know at first how to display code in my post. Once it was posted, I did not know that it was SOOOO important to fix it....

Fixed now...

Got an answer ?

If I had to guess, I note that there was an update made to the SD library (according to the documentation) to allow multiple files to be opened. I suspect that there is a specific finite number that can be opened though and it's somewhere in the region of five. It's also possible that there's no specific limit but file buffers are dynamically allocated & you ran out of memory. If you really care though, you've got the library source to find out!

Thanks WildBill.

I was just curious if there was an easy/known answer.

your advise on closing the file was THE solution.

wildbill: If I had to guess, I note that there was an update made to the SD library (according to the documentation) to allow multiple files to be opened. I suspect that there is a specific finite number that can be opened though and it's somewhere in the region of five. It's also possible that there's no specific limit but file buffers are dynamically allocated & you ran out of memory. If you really care though, you've got the library source to find out!

Running out of memory is the problem. There is no limit on the number of files that can be opened, but there needs to be 512 bytes of memory per open file. Opening the 5th file manifested the problem when the file was written to, because data was written the the buffer, which overwrote something on the stack, causing the Arduino to crash when trying to return.

some people are more interested into me fixing the way I displayed my code than trying to provide an answer.....

I did not know at first how to display code in my post. Once it was posted, I did not know that it was SOOOO important to fix it..

Some people want to make they're not wasting their time by commenting on code that has been mangled when improperly posted. Putting code inside code tags ensures that mangling does not occur, and also shows that you have read the prominently posted sticky threads, telling you the best way to get help on the forum.