VERY weird glitch, PLEASE help! (RFID Project)

Hello all, I am working on a project that uses the ID-12 RFID reader and an SD card. I have the ID-12 working as well as the SD card. I am scanning any card presented, checking it against a text file with a list of codes on the SD card and doing a certain action if it's in the database or not. This code I wrote is all working fine, except for the matched card. Let me explain, if I scan an unknown card it will print the code, check it against the database, and return false, which I then use to print "Match Not Found". If a known card is scanned, it prints it, checks it, then returns true. I then use this to print, "Match Found". This code I have works PERFECTLY. Until a known card is scanned 23 times. On the 23rd time it starts to return false after it checks to the database no matter what. PLEASE look this over and tell me if you catch anything!

Thanks!

RFID_With_Database.ino (2.56 KB)

To save other people downloading it, I'll post the sketch here:

#include <SoftwareSerial.h>

#include <SD.h>

SoftwareSerial mySerial(2, 4);

int resetpin = 3;  //Reader reset pin.
int ledpin = 7;  //Status LED pin.
int CS_pin = 10;

void setup() {

  Serial.begin(9600);  //Initialize main serial connection.
  mySerial.begin(9600);  //Initialize reader serial connection.
  pinMode(resetpin, OUTPUT);  //Define reset pin as an output.
  pinMode(ledpin, OUTPUT);  //Define the LED pin as output.
  pinMode(CS_pin, OUTPUT);
  digitalWrite(resetpin, HIGH);  //Pull the reset pin high.
  Serial.println("Initializing SD Card");

  if (!SD.begin(CS_pin)) {
    Serial.println("Card Failed. Quitting");
    return;
  }

  Serial.println("SD Card Ready");
  Serial.println("Waiting for Tag");
}

void loop() {

  char tagString[13], mastertag[13] = {
    '4', 'E', '0', '0', '0', '4', '5', '6', 'D', '8', 'C', '4'      };
  int index = 0, filesize;
  boolean reading = false;

  while (mySerial.available()) {

    char readByte = mySerial.read();

    if(readByte == 2) reading = true;
    if(readByte == 3) reading = false;

    if(reading && readByte != 2 && readByte != 10 && readByte != 13){
      tagString[index] = readByte;
      index ++;
    }
  }

  printtag(tagString);

  if (strlen(tagString) != 0) {
    if (database(tagString) == true) {
      Serial.println("Match Found");
      digitalWrite(ledpin, HIGH);
      delay(1000);
      digitalWrite(ledpin, LOW);
    }
    else {
      Serial.println("No Match Found");
    }
  }

  cleartag(tagString);
  resetreader();
  delay(200);
}

void resetreader() {
  digitalWrite(resetpin, LOW);
  digitalWrite(resetpin, HIGH);
  delay(150);
}

boolean compare(char one[], char two[]) {

  for (int i = 0; i < 12; i++) {
    if (one[i] != two[i]) {
      return false;
    }
  }
  return true;
}
void cleartag(char one[]) {

  for (int i = 0; i < strlen(one); i++) {
    one[i] = 0;
  }
}

void printtag(char one[]) {

  int printer = 0;

  if (!strlen(one) == 0) {

    for (int i = 0; i < 12; i++) {
      Serial.print(one[i]);
      printer++;
    }
    if (printer == 12) {
      Serial.println();
    }
  }
}

boolean database(char one[]) {

  char sdarray[13];
  boolean match = false;
  File logread = SD.open("log.txt", FILE_WRITE);

  if (logread) {
    logread.seek(0);
    while (logread.available() && match == false) {
      for (int i = 0; i < 12; i++) {
        sdarray[i] = logread.read();
      }

      if (compare(one, sdarray) && match == false) {
        match = true;
        return true;
      }
    }

    if (match == false && !logread.available()) {
      return false;
      logread.close();
    }
  }
}

You don't seem to be closing the database on a good match. Won't you run out of memory?

Thanks for posting the code. I haven't really thought of it running out of memory, but that does solve another problem I've been having. The weird thing is, it works for 22 times, then on the 23rd good match, it's stops working.

Does closing the file fix it? That's not weird. You had enough memory for 22 file opens but not 23.

Does the behavior change if you change the dimension of tagString[] to 50 ?

Good catch Nick - it took me until now to notice that logread.close() never gets called. I'd have expected gcc to complain about dead code after the return false;

A warning maybe. But we don't see warnings.

Oh man, you guys are good! I hadn't really been worrying about memory until now! I did have logread.close(); for when the database cannot find a match but I didn't when it did find a match. Fixed it and it works beautifully. The memory limit also explains a lot of erratic behavior when more code was added. Thanks so much. If I have anymore questions, I know where to go.

P.S. This was my first project. I barely knew any C or C++ before this and the community has really helped.

Alright, new question. As previously stated, I changed the code and it worked. I now have the chore of adding a new tag to the database if a tag is scanned after the master tag is scanned. Putting it in a sort of "Admin Mode". I have been able to make it wait for a tag to become ready to be read before it does anything in admin mode. I now need it to read it into an array like it does earlier in the code. I have tried a couple things but they haven't worked. I can take care of writing them to the database, I just can't get another tag to be read once in admin mode. Any suggestions or code would be awesome! Thanks!

#include <SoftwareSerial.h>

#include <SD.h>

SoftwareSerial mySerial(2, 4);

int resetpin = 3;  //Reader reset pin.
int ledpin = 7;  //Status LED pin.
int CS_pin = 10;

void setup() {

  Serial.begin(9600);  //Initialize main serial connection.
  mySerial.begin(9600);  //Initialize reader serial connection.
  pinMode(resetpin, OUTPUT);  //Define reset pin as an output.
  pinMode(ledpin, OUTPUT);  //Define the LED pin as output.
  pinMode(CS_pin, OUTPUT);
  digitalWrite(resetpin, HIGH);  //Pull the reset pin high.
  Serial.println("Initializing SD Card");

  if (!SD.begin(CS_pin)) {
    Serial.println("Card Failed. Quitting");
    return;
  }

  Serial.println("SD Card Ready");
  Serial.println("Waiting for Tag");
}

void loop() {

  char tagString[13];
  int index = 0, filesize;
  boolean reading = false;

  while (mySerial.available()) {

    char readByte = mySerial.read();

    if(readByte == 2) reading = true;
    if(readByte == 3) reading = false;

    if(reading && readByte != 2 && readByte != 10 && readByte != 13){
      tagString[index] = readByte;
      index ++;
    }
  }

  printtag(tagString);

  if (strlen(tagString) != 0) {
    if (database(tagString) == true) {
      Serial.println("Match Found");
      digitalWrite(ledpin, HIGH);
      delay(1000);
      digitalWrite(ledpin, LOW);
    }
    else {
      Serial.println("No Match Found");
    }
  }
  adminmode(tagString);
  cleartag(tagString);
  resetreader();
  delay(200);
}

void resetreader() {
  digitalWrite(resetpin, LOW);
  digitalWrite(resetpin, HIGH);
  delay(150);
}

boolean compare(char one[], char two[]) {

  for (int i = 0; i < 12; i++) {
    if (one[i] != two[i]) {
      return false;
    }
  }
  return true;
}
void cleartag(char one[]) {

  for (int i = 0; i < strlen(one); i++) {
    one[i] = 0;
  }
}

void printtag(char one[]) {

  int printer = 0;

  if (!strlen(one) == 0) {

    for (int i = 0; i < 12; i++) {
      Serial.print(one[i]);
      printer++;
    }
    if (printer == 12) {
      Serial.println();
    }
  }
}

boolean database(char one[]) {

  char sdarray[13];
  boolean match = false;
  File logread = SD.open("log.txt", FILE_WRITE);

  if (logread) {
    logread.seek(0);
    while (logread.available() && match == false) {
      for (int i = 0; i < 12; i++) {
        sdarray[i] = logread.read();
      }

      if (compare(one, sdarray) && match == false) {
        match = true;
        logread.close();
        return true;
      }
    }

    if (match == false && !logread.available()) {
      return false;
      logread.close();
    }
  }
}

void adminmode(char one[]) {

  char mastertag[13] = {
    '4', 'E', '0', '0', '0', '4', '5', '6', 'D', '8', 'C', '4'          };
  boolean cardready = false, tagreading = false;
  int addex = 0;

  if (compare(one, mastertag)) {
    Serial.println("Master Tag Found, Entering Admin Mode");

    while (cardready == false) {
      if (mySerial.available()) {
        cardready = true;
      }
    }

    Serial.println("Tag Ready");

  }
  resetreader();
}

You'll probably want to change

    if (match == false && !logread.available()) {
      return false;
      logread.close();
    }

To

    if (match == false && !logread.available()) {
      logread.close();
      return false;
    }

before you get very far into the admin stuff.

Good catch, don't know how I missed that. Thanks.