Arduino with Parallax RFID reader storing variables in char

arduinoparallaxrfidserial

I am quite new to electronics and have been tinkering around with this Arduino UNO w/ WiFi Shield and the Parallax RFID R/W Module.

Link to the RFID Module: http://www.parallax.com/Store/Accessories/CommunicationRF/tabid/161/ProductID/688/List/0/Default.aspx?SortField=ProductName,ProductName

Link to it's Data Sheet:
http://www.parallax.com/Portals/0/Downloads/docs/prod/rf/28440-RFIDReadWrite-v1.0.pdf

So currently I have been using code I have found on the Arduino Playground, which I have adapted.

Namely: http://playground.arduino.cc/Learning/ParallaxRFIDreadwritemodule

Also: http://playground.arduino.cc/Learning/PRFID

(The latter is the older Read-Only module but proved helpful because of the error checking involved).

Objective:
To be able to read a tag, successfully store in a char array, or whatever is most appropriate, byte format would be preferable as so not to loose any smaller numbers when converted to DEC. I also need the value from the array to be assigned to another value so that the array can then be flushed for the presence of another card.

I have a semi-working program, However the serial monitor displays garbage

Initialised Serial Port at 9600bps
Initialising SD card...
SD card initialisation done.
Nothing to clear on SD card.
Code is: üÖ©ÿÿÿÿÿÿ
Code is: üºÿÿÿÿÿÿ

I have a feeling it is to do with a stop bit after the array has been filled but cannot be sure. I am 100% sure my Serial monitor is set to the correct baud 9600.

Code:

#include <SoftwareSerial.h> // SoftwareSerial to power the serial communications;
/** End inclusion of libraries
    */

#define RFID_READ 0x01 // Enable READ
#define RFID_WRITE 0x02 // Enable WRITE
#define ERR_OK 0x01 // Error checking
#define STOP_BYTE 0x0D // last byte recieved from a tag
#define CODE_LEN 11 // length of code
#define TERMINATOR 0x00
#define txPin 6 // Enable digital pin 6
#define rxPin 8 // Enable digital pin 8

#define readMemorySector 32 // Define variable for accessing various memory sectors on a card

// Initialise SoftwareSerial to input and output pins for mySerial
SoftwareSerial mySerial(rxPin, txPin);

//int val; // Buffer to store value when reading from a card, before printing to the serial monitor
int runs = 0; // Run counter
char code[CODE_LEN];
int bytes_read = 0;

void setupRFIDREAD()
{
   /** Set up RFID READ
   */
  mySerial.begin(9600); // initialises the rxPin and txPin using mySerial
  pinMode(txPin, OUTPUT); // defines txPin as OUTPUT   
  pinMode(rxPin, INPUT);  // defines rxPIN as INPUT

  //digitalWrite(6, LOW); // Enable reader

      /** Set up SD Card
  */
  Serial.println(F("Initialising SD card...")); // Initialising SD Card 

  pinMode(10, OUTPUT); //Initialises the sdPin as an output, even if it's not used
  digitalWrite(10, HIGH); // Disable WiFi SPI link before starting the SD cards as both use the same SPI Bus

  if (!SD.begin(4)) { // see if the card is present and can be initialized:
    Serial.println(F("initialisation failed, card faulty or not present!"));
    return; // don't do anything more
  }

  Serial.println(F("SD card initialisation done."));

  //clear the SD card
  if (SD.exists("test.txt")) {
    SD.remove("test.txt");
    Serial.println(F("SD card cleared."));
  } else {
    Serial.println(F("Nothing to clear on SD card."));
    return;
  }

}

void loopRFIDREAD()
{
  int val;    

  mySerial.print("!RW"); //To communicate with the RFID Read/Write Module, the user must first send a three-byte header string of !RW (in ASCII), followed by the desired single-byte command (in hexadecimal).
  mySerial.write(byte(RFID_READ)); //Initiates the read function.
  mySerial.write(byte(readMemorySector));  // Indicates which memorySector is to be read. In this case 32 which is the unique identifier.

  if(mySerial.available() > 0) {
    if((val = mySerial.read()) == ERR_OK){
      bytes_read = 0;
      while(bytes_read < CODE_LEN) {
        if(mySerial.available() > 0) {
          val = mySerial.read();
            if(( val == ERR_OK) || (val == STOP_BYTE))
              break;
    code[bytes_read] = val;
    bytes_read++;
  }
  }

 if(bytes_read == CODE_LEN) {
    Serial.print("Code is: ");
    Serial.println(code);
  }
  bytes_read = 0;

    digitalWrite(6, HIGH); // Disable reader as not to flood it
// Delay 750 milliseconds before next read and print cycle
delay(750);
    digitalWrite(6, LOW); // Enable reader
}
}
}

Please ignore the SD card functionality as that is used for another part of the program.

As you can see I have changed the code drastically from the code provided on the playground for this R/W module as the code looped without any checks and made it very difficult to control the output. Therefore I combined the code from the earlier version of the reader.

So then end goal for this is to be able to read and store a fob's ID into this char array, which will then be queried to a web server for additional data.

Hope you can help, if in need of any more detail please ask.

Best Answer

What is being stored into the code[] array is a series of binary values:

code[bytes_read] = val;

The actual values retrieved by val = mySerial.read(); are most likely values from 0x00 through 0xff (0 to 255 in decimal).

  1. You need to decide how you want those byte values displayed: As hexadecimal digit pairs(00 .. ff), as decimal numbers (0 .. 255) or as the ASCII representations of those values (which is what is happening now).

    • Note that byte values up to 31 have no standard visual representation (hence the junk characters), 32 is a space, 33 onward are symbols, numbers, letters and so on up to value 127.
    • 128 through 255 again have different representations on different systems, "Extended ASCII"
  2. Apart from this, a C string consists of a series of ASCII characters terminated by a null, or 0 value. Without appropriately terminating a string, print() and println() will not meaningfully terminate the displayed string.

In short, you will have to adopt one of the several ways of displaying byte values in readable form. A bit of searching on the web or on StackOverflow should show you several algorithms to achieve this in C.

Only then would you see what you are expecting to see in the serial monitor.