Admin Mode Not Fully Working

Hello, I posted earlier about a memory problem and it was fixed. I hope you can all help me with this one.

I have an RFID tag read, compared to a database, then returned true or false. After it checks the database it compares it to the hard-coded "Master Tag". If it is this tag it enters "Admin Mode" and waits for another tag and stores it. Right now I'm just trying to get it to read it and print it in Admin Mode and it's not working. I'll post the Serial output after the code.

#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 readByte, addByte[13], tagString[13], mastertag[13] = {
    '4', 'E', '0', '0', '0', '4', '3', 'D', '3', '8', '4', 'F'    };
  int index = 0, filesize;
  boolean reading = false, cardready = false;

  while (mySerial.available() > 0) {

    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");
    }

  }

  if (compare(mastertag, tagString)) {
    Serial.println("Master Tag Found, Entering Admin Mode");
    resetreader();
    index = 0;

    while (cardready == false) {
      if (mySerial.available() > 0) {
        while (mySerial.available() > 0) {
          for (int f = 0; f < 12; f++) {
            addByte[index] = mySerial.read();
            index++;
          }
        }
        Serial.println("Done Reading");

        Serial.print(addByte[0]);
        Serial.print(addByte[1]);
        Serial.print(addByte[2]);
        Serial.print(addByte[3]);
        Serial.print(addByte[4]);
        Serial.print(addByte[5]);
        Serial.print(addByte[6]);
        Serial.print(addByte[7]);
        Serial.print(addByte[8]);
        Serial.print(addByte[9]);
        Serial.print(addByte[10]);
        Serial.print(addByte[11]);
        Serial.println();
        cardready = true;
      }
    }

  }

  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);

  logread.seek(0);

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

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

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

here is the Serial Output.

4E00043D384F
No Match Found
Master Tag Found, Entering Admin Mode
Done Reading
ÿÿÿÿÿÿÿÿÿÿÿ
4E000456D8C4
No Match Found

       while (mySerial.available() > 0) {
          for (int f = 0; f < 12; f++) {
            addByte[index] = mySerial.read();
            index++;
          }
        }

You are checking if one byte is available, and when it is, you are reading 12.

It shouldn't matter. The Innovations ID-12 RFID reader I am using outputs all 12 once a tag is scanned, so once I get the start byte I can read the tag. It works perfectly earlier in the code and I tries to just copy and paste but it gave the same output as it does with the for loop.

Here is the new code I wrote.

#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 readByte, tempByte, addByte[13], tagString[13], mastertag[13] = {
    '4', 'E', '0', '0', '0', '4', '3', 'D', '3', '8', '4', 'F'        };
  int index = 0, filesize;
  boolean reading = false, cardreading = false, cardready = false;

  while (mySerial.available() > 0) {

    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");
    }

  }

  if (compare(mastertag, tagString)) {
    Serial.println("Master Tag Found, Entering Admin Mode");
    resetreader();
    index = 0;

    while (cardready == false) {
        while (mySerial.available() > 0) {
          tempByte = mySerial.read();

          if (tempByte == 2) cardreading = true;
          if (tempByte == 3) cardreading = false;

          if (cardreading && tempByte != 2 && tempByte != 10 && tempByte != 13) {
            tagString[index] = tempByte;
            index ++;
          }
        }
        if (index == 12) {
          Serial.println("Done Reading");
          Serial.print(addByte[0]);
          Serial.print(addByte[1]);
          Serial.print(addByte[2]);
          Serial.print(addByte[3]);
          Serial.print(addByte[4]);
          Serial.print(addByte[5]);
          Serial.print(addByte[6]);
          Serial.print(addByte[7]);
          Serial.print(addByte[8]);
          Serial.print(addByte[9]);
          Serial.print(addByte[10]);
          Serial.print(addByte[11]);
          Serial.print(addByte[12]);
          Serial.print(addByte[13]);
          Serial.println();
          cardready = true;
        }
    }
  }
  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);

  logread.seek(0);

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

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

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

This is the output I get:

4E00043D384F
No Match Found
Master Tag Found, Entering Admin Mode
Done Reading
×

  char readByte, tempByte, addByte[13], ...

So, addByte is 13 bytes long.

        Serial.println("Done Reading");
        Serial.print(addByte[0]);
        Serial.print(addByte[1]);
        Serial.print(addByte[2]);
        Serial.print(addByte[3]);
        Serial.print(addByte[4]);
        Serial.print(addByte[5]);
        Serial.print(addByte[6]);
        Serial.print(addByte[7]);
        Serial.print(addByte[8]);
        Serial.print(addByte[9]);
        Serial.print(addByte[10]);
        Serial.print(addByte[11]);
        Serial.print(addByte[12]);
        Serial.print(addByte[13]);

You are displaying 14 bytes there (0 to 13).

Nowhere in your code to you move anything to addByte. So naturally it displays rubbish.

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

You are reading into tagString not addByte.

I am now running out of memory for (seemingly) no reason. I feel is has something to do with my database function. Please let me know if you see anything! 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 readByte, tempByte, addByte[13], tagString[13], mastertag[13] = {
    '4', 'E', '0', '0', '0', '4', '3', 'D', '3', '8', '4', 'F'        };
  int index = 0, filesize;
  boolean reading = false, cardreading = false, cardready = false;
  File logread = SD.open("log.txt", FILE_WRITE);

  while (mySerial.available() > 0) {

    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");
    }

  }

  if (compare(mastertag, tagString)) {
    Serial.println("Master Tag Found, Entering Admin Mode");
    resetreader();
    index = 0;
    delay(3000);

    while (cardready == false) {
        while (mySerial.available() > 0) {
          tempByte = mySerial.read();

          if (tempByte == 2) cardreading = true;
          if (tempByte == 3) cardreading = false;

          if (cardreading && tempByte != 2 && tempByte != 10 && tempByte != 13) {
            addByte[index] = tempByte;
            index ++;
          }
        }
        if (index == 12) {
          Serial.println("Done Reading");
          filesize = logread.size();
          logread.seek(filesize);
          logread.print(addByte[0]);
          logread.print(addByte[1]);
          logread.print(addByte[2]);
          logread.print(addByte[3]);
          logread.print(addByte[4]);
          logread.print(addByte[5]);
          logread.print(addByte[6]);
          logread.print(addByte[7]);
          logread.print(addByte[8]);
          logread.print(addByte[9]);
          logread.print(addByte[10]);
          logread.print(addByte[11]);
          logread.close();
          cardready = true;
        }
    }
  }
  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()) {
      logread.close();
      return false;
    }
  }
}

Could someone please look my code over? I have looked over and over and I can't find anything wrong :frowning:

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

There's a memcmp function built-in you know.


void cleartag(char one[]) {

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

This is pretty dodgy. The string is not null-terminated. Why not just work your way up to 13, since that's how long the strings are?

Anyway, this would be easier:

  memset(tagString, 0, sizeof tagString);

Hmmm, I don't see how that would solve the memory problem. I did change it to 13 and it performed exactly the same. I am running out of SRAM and the arduino is resetting itself. I had this problem before and when I put logread.close(); in both true and false of the boolean database function it worked but after putting in some more code it started to do it again. I checked over it again and it closes the file every time but the arduino is still resetting itself. Here is the Serial output when I hold a tag to the reader continuously if it is unknown:

4E00047A81B1
No Match Found
4E00047A81B1
No Match Found
4E00047A81B1
No Match Found
4E00047A81B1
No Match Found
4E00047A81B1
No Match Found
4E00047A81B1
No Match Found
4E00047A81B1
No Match Found
4E00047A81B1
No Match Found
4E00047A81B1
No Match Found
4E00047A81B1
No Match Found
Initializing SD Card
SD Card Ready
Waiting for Tag
4E00047A81B1
No Match Found
4E00047A81B1
No Match Found

Here:

void loop() {

...

  File logread = SD.open("log.txt", FILE_WRITE);

Where does this file get closed? It's opened every time through loop. And why open for writing anyway? Surely only open for writing when you are updating the cards.

I just looked over the code and found that the file only close after "Admin Mode". I made it so the file opened in "Admin Mode" and it works perfectly. No more restarting. Thanks again for all your help.

Hmmm, I don't see how that would solve the memory problem.

Well, then you should really do some research (or even just some thinking). How does strlen() know how long the string is? It expects that what will be passed to it will be a NULL terminated array of chars. You are not passing it a NULL terminated array of chars, but it doesn't know that. So, it goes looking for the NULL. It is not in the bounds of your array, but strlen() doesn't know that. Wherever it finds a NULL, in some other variable or array defines the length of your array. So, your code then initializes much more than just your array. That is a memory problem.

#include <SD.h>

The SD library needs a 512 byte buffer. On other than a Mega, that's 1/4 of the memory available.

  char readByte, tempByte, addByte[13], tagString[13], mastertag[13] = {
    '4', 'E', '0', '0', '0', '4', '3', 'D', '3', '8', '4', 'F'        };

The mastertag array is not NULL terminated, either.

You could easily use strcmp(), instead of writing your own functions, if you simply used strings rather than char arrays.

I suggested memcmp earlier, which will handle fixed-length data.