Go Down

Topic: Reading 9 Hex-Digits with RFID (Read 1 time) previous topic - next topic


Hi all,

I'm working on a project that's very similar to http://makeprojects.com/Project/Charlie's+RFID+Teddy+Bear/1411/1#.UL22GaHVof8. I'm using the following hardware:

  • Arduino Uno

  • Waveshield

  • ID-12 RFID reader (125 kHz)

  • 60 Parallax RFID tags embedded in blocks

When you take a block and hold it up to the the reader, you will hear (via the waveshield) a specific sound. I've managed to get this working. The problem is, i've discovered (now that the tags are glued inside wood blocks) 4 pairs of blocks that share the same first 8 hexidecimals. Rather than cut open the blocks and switch out the tags, I want to modify the code so that it reads the first 9 or 10 digits of the RFID tag as opposed to the first 8.

I've made a few modifications (read: guesses) to the code so that it will pull the first 9 digits, but I can't get it to play the associated sounds. It keeps displaying the 9 digits in the serial reader but saying it can't open the 9 digit sound file. (Yes, I did rename the sound files on the SD card so they are also 9 digits). Any ideas?

Code: [Select]
// An interactive bear for Charlie -- RFID triggered sound responses

#include <FatReader.h>
#include <SdReader.h>
#include "WaveHC.h"
#include "WaveUtil.h"

SdReader memcard;
FatVolume vol;
FatReader root;
FatReader file;
WaveHC wave;

#define ENABLE 8      // Set the pin number for enabling the RFID reader. The Audio Shield uses pins 2-5.
#define NUMTAGS 22

int  val = 0;
char code[10];
int bytesread = 0;

char knowntags[NUMTAGS][11] = {"2100DFB002", "2100E0B6ED", "2100DFF660", "2100DFD586", "2100DFB1E5", "2100E0CBAA", "2100E07B21", "2100E0B9D6", "2100D82331", "2100DFA060", "2100DFBC77", "2100DFA69A", "2100D7EFF7", "2100DFE251", "2100E02F09", "2100DFBF83", "2100DFD9EA", "2100E0ABA6", "2100DFDFC4", "2100DFF0DF", "36005B7B50", "36005B7C05"};
char soundfiles[NUMTAGS][9] = {"1000.WAV", "1001.WAV", "1002.WAV", "1003.WAV", "1004.WAV", "1005.WAV", "1006.WAV", "1007.WAV", "1008.WAV", "1009.WAV", "1010.WAV", "1011.WAV", "1012.WAV", "1013.WAV", "1014.WAV", "1015.WAV", "1016.WAV", "1017.WAV", "1018.WAV", "1019.WAV", "1020.WAV", "1021.WAV"};
char filename[1][13];

void setup() {
  //////// Set up RFID reader to collect tag information /////////////////////
  Serial.begin(9600);         // RFID reader SOUT pin connected to Serial RX pin at 2400bps
  pinMode(ENABLE,OUTPUT);     // Set digital pin 7 as OUTPUT to connect it to the RFID /ENABLE pin
  digitalWrite(ENABLE, LOW);  // Activate the RFID reader
  //////// Set the pins to output for driving the Audio Shield
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  ////////// Set up the Audio Shield by initializing the memory card for reading ////////
  if (!memcard.init()) {
    // If something went wrong sdErrorCheck prints out the error check
    putstring_nl("Card init. failed!");
  //This will optimize the reading of the memory card -- remove it if it times out
  // Find a FAT formatted partition by looking in teh first five slots. Remember your memory card should be FAT16 or FAT32 formatted
  uint8_t partition;
  for (partition = 0; partition < 5; partition++) {
    if (vol.init(memcard, partition))
  if (partition == 5)
    putstring_nl("No valid FAT partition");
    while(1); // This is a point of no return. Format your memory card properly and try again.

  // Open the root directory for reading the files
  if (!root.openRoot(vol))
    putstring_nl("Can't open root directory");
    while(1); // Something went wrong here so investigate the file system on your memory card.
  // If you got this far then the card is ready to read
  putstring_nl("Ready to go");

// If we find an error, check what the error is and show it on the serial terminal
void cardErrorCheck(void)
  if(!memcard.errorCode()) return;
  putstring("\n\rSD I/O error:");
  putstring(", ");
  while(1); // Stick here if there is an error

void loop() {

  if(Serial.available() > 0) {          // if data available from reader 
    if((val = Serial.read()) == 10) {   // check for header
      bytesread = 0;
      while(bytesread<10) {              // read 10 digit code
        if( Serial.available() > 0) {
          val = Serial.read();
          if((val == 10)||(val == 13)) { // if header or stop bytes before the 10 digit reading
            break;                       // stop reading
          code[bytesread] = val;         // add the digit           
          bytesread++;                   // ready to read next digit 
      if(bytesread == 10) {              // if 10 digit read is complete
        Serial.print("TAG code is: ");   // possibly a good TAG
        Serial.println(code);            // print the TAG code
        Serial.flush();                  // Flush the serial buffer before trying to read a new code
      bytesread = 0;


void playsound(char codetoplay[]) {
  for(int i = 0; i<8; i++) {    // Make a filename from the first 8 characters of the RFID tag number
  silence(); //shut down anything that is currently playing and close that file

void playfile(char *name) {
  if (!file.open(root, name)) {
      putstring_nl("Couldn't open file");
   if (!wave.create(file)) {
     putstring_nl("Not a valid WAV");

void silence() {
  if(wave.isplaying) {


Can an SD file have a file name longer than 8 characters?


Any ideas?

Yes. I suggest that you to learn to use the carriage return now and then. This is ridiculous.

Code: [Select]
char knowntags[NUMTAGS][11] = {"2100DFB002", "2100E0B6ED", "2100DFF660", "2100DFD586", "2100DFB1E5", "2100E0CBAA", "2100E07B21", "2100E0B9D6", "2100D82331", "2100DFA060", "2100DFBC77", "2100DFA69A", "2100D7EFF7", "2100DFE251", "2100E02F09", "2100DFBF83", "2100DFD9EA", "2100E0ABA6", "2100DFDFC4", "2100DFF0DF", "36005B7B50", "36005B7C05"};

Code: [Select]
      if(bytesread == 10) {              // if 10 digit read is complete
How do you know/why do you assume that the tag is 10 characters? There is an end-of-tag marker sent. Read and store data until that marker arrives.

You can name the files 0.wav, 1.wav, 2.wav, etc. Then, after properly NULL terminating (you are not currently) code, loop through the array of knowntags, looking for a match. Play the file with the name that matches the index where the scanned tag is found.

Code: [Select]
        Serial.flush();                  // Flush the serial buffer before trying to read a new code
This just screams CLUELESS. I'm not even going to ask why its here. I'm simply going to say that it is not what you should be doing, so get rid of it.
The art of getting good answers lies in asking good questions.

Go Up