RFID module software serial + serial read

Greetings all!

Im having a bit of an issue applying a conditional to a value printed in the serial monitor. I have an RFID module found here:

http://www.elechouse.com/elechouse/index.php?main_page=product_info&cPath=90_93&products_id=2156

It Arduino source code, and am not having problems with just getting the module to work. As I stated, I am trying to add a conditional that once a specific tag ID is printed in serial monitor (as it is doing), print a message.

code below with my addition commented:

#include <SoftwareSerial.h> 
SoftwareSerial mySerial(2, 3); //pin2 Rx, pin3 Tx 

int CMD[64];
int comlen =0;
int out_flag =0;
String result = String('77 08 92 73'  ,DEC);
int resulting = '4D085C49';
//byte C;



void setup() 
{ 
  Serial.begin(9600);
  mySerial.listen();
  Serial.println("Serial number will be displayed here if a card is detected by the module:\n"); 
  // set the data rate for the SoftwareSerial port 
  mySerial.begin(9600); 
  delay(10);
  mySerial.write(0x02); //Send the command to RFID, please refer to RFID manual 
} 
void loop() // run over and over 
{ 

  while (Serial.available()) 
  {
    int a = SerialReadHexDigit();
    //Serial.println(a);
    if(a>=0){
      CMD[comlen] = a;
      comlen++;
    }
    delay(10);
  }

  for(int i=0; i<comlen; i+=2){
    int c = mySerial.write( CMD[i]*16 + CMD[i+1]);



  }
  comlen =0;

  byte C;
  while (mySerial.available()) {
    C = mySerial.read();




    if (C<16) Serial.print("0");
    Serial.print(C ,HEX); //Display the Serial Number in HEX 
    //Serial.print(" ");



    out_flag =1;

/////////// MY ADDITION /////////////////////////////

    if(Serial.available())
    {
      C = Serial.read();
      if (C == resulting){

        Serial.println("IM IN");
      }
    }

//////////////////////////////////////////////////
  }

  if (out_flag >0) {
    Serial.println();
    out_flag = 0;
  }

}



int SerialReadHexDigit()
{
  byte c = (byte) Serial.read();
  if (c >= '0' && c <= '9') {
    return c - '0';
  } 
  else if (c >= 'a' && c <= 'f') {
    return c - 'a' + 10;
  } 
  else if (c >= 'A' && c <= 'F') {
    return c - 'A' + 10;
  } 
  else {
    return -1;   // getting here is bad: it means the character was invalid
  }
}

thanks ahead of time :slight_smile:

Start off by using the Auto Format tool and re-posting the code to make it readable.

done. sorry about that.

There is no way the character stored in the variable 'C' can equal the integer resulting which has the value '49'.

If you meant to compare against the hex value 4D085C49 you should say:

const unsigned long resulting = 0x4D085C49UL;

Note: The single character read from the serial port will never match the constant 0x4D085C49UL.

Thanks, John.

I have tried your suggestion without anything printing out in the serial monitor from my condition.

danieljay:
Thanks, John.

I have tried your suggestion without anything printing out in the serial monitor from my condition.

John wasn't making a "suggestion," he was pointing out a problem. If you've fixed the problem and you're still having issue, then post the updated code.

Also, why are there so many nested if/while Serial.available() statements? You have an if nested within a while nested within a while. That's extremely convoluted. Simply check if there is a character available, read it, and do something with it. Don't try and read more within the single if/while statement.

Thanks, Arrch.

I had..."reevaluated my problems" (yes?) and followed your...suggestions...

no luck.

danieljay:
Thanks, Arrch.

I had..."reevaluated my problems" (yes?) and followed your...suggestions...

no luck.

But you're not going to show us your new code? There isn't one single "switch" that you can flick that will make everything start working. You have multiple issues with your sketch that need to progressively get fixed.

#include <SoftwareSerial.h> 
SoftwareSerial mySerial(2, 3); //pin2 Rx, pin3 Tx 

int CMD[64];
int comlen =0;
int out_flag =0;

const unsigned long resulting = 0x4D085C49UL;

//byte C;



void setup() 
{ 
  Serial.begin(9600);
  mySerial.listen();
  Serial.println("Serial number will be displayed here if a card is detected by the module:\n"); 
  // set the data rate for the SoftwareSerial port 
  mySerial.begin(9600); 
  delay(10);
  mySerial.write(0x02); //Send the command to RFID, please refer to RFID manual 
} 
void loop() // run over and over 
{ 

  while (Serial.available()) 
  {
    int a = SerialReadHexDigit();
    //Serial.println(a);
    if(a>=0){
      CMD[comlen] = a;
      comlen++;
    }
    delay(10);
  }

  for(int i=0; i<comlen; i+=2){
    int c = mySerial.write( CMD[i]*16 + CMD[i+1]);



  }
  comlen =0;

  byte C;
  while (mySerial.available()) {
    C = mySerial.read();




    if (C<16) Serial.print("0");
    Serial.print(C ,HEX); //Display the Serial Number in HEX 
    //Serial.print(" ");



    out_flag =1;

 if (C == resulting){

        Serial.println("IM IN");
        
      }
  }

  if (out_flag >0) {
    Serial.println();
    out_flag = 0;
  }
 

}

int SerialReadHexDigit()
{
  byte c = (byte) Serial.read();
  if (c >= '0' && c <= '9') {
    return c - '0';
  } 
  else if (c >= 'a' && c <= 'f') {
    return c - 'a' + 10;
  } 
  else if (c >= 'A' && c <= 'F') {
    return c - 'A' + 10;
  } 
  else {
    return -1;   // getting here is bad: it means the character was invalid
  }
}
while (mySerial.available()) 
{
    C = mySerial.read();
    if (C<16) Serial.print("0");
    Serial.print(C ,HEX); //Display the Serial Number in HEX 
    out_flag =1;

    if (C == resulting){

      Serial.println("IM IN");

    }
}

A single byte will never be equal to

const unsigned long resulting = 0x4D085C49UL;

You need to read the data in, one byte at a time, and combine to create an unsigned long.

You need to read the data in, one byte at a time, and combine to create an unsigned long.

So to clarify, I will take the bytes of data, i.e. 4D085C49
which converted to HEX = 0x340x440x300x380x350x430x340x39

am I on the right path?

which converted to HEX = 0x340x440x300x380x350x430x340x39

??
No
Take each byte, shift the long int by 8 then OR the byte into the long int

This might help you:-

long int tokenInVar(){
  long number = 0;
       for(int i=0; i<8; i++) number = (number << 4) | convertFromHex(int(token[i]));
   return(number);
}

long int convertFromHex(int ascii){ 
  if(ascii > 0x39) ascii -= 7; // adjust for hex letters upper or lower case
  return(ascii & 0xf);
}

Thanks Grumpy Mike,

I had inserted your bit of code but it seems to not find the variable "token" in scope. is token suppose to be my incoming byte variable?

code below:

#include <SoftwareSerial.h> 
SoftwareSerial mySerial(2, 3); //pin2 Rx, pin3 Tx 

int CMD[64];
int comlen =0;
int out_flag =0;
long number = 0;
const unsigned long resulting = 0x4D085C49UL;

const int led = 13;
byte C;

void setup() 
{ 
  pinMode(led,OUTPUT);
  Serial.begin(9600);
  mySerial.listen();
  Serial.println("Serial number will be displayed here if a card is detected by the module:\n"); 
  // set the data rate for the SoftwareSerial port 
  mySerial.begin(9600); 
  delay(10);
  mySerial.write(0x02); //Send the command to RFID, please refer to RFID manual 
} 
void loop() // run over and over 
{ 

  while (Serial.available()) 
  {
    int a = SerialReadHexDigit();
    //Serial.println(a);
    if(a>=0){
      CMD[comlen] = a;
      comlen++;
    }
    delay(10);
  }

  for(int i=0; i<comlen; i+=2){
    int c = mySerial.write( CMD[i]*16 + CMD[i+1]);



  }
  comlen =0;

  byte C;
  while (mySerial.available()) {
    C = mySerial.read();




    if (C<16) Serial.print("0");
    Serial.print(C ,HEX); //Display the Serial Number in HEX 
    //Serial.print(" ");



    out_flag =1;

    if (C == number){

      Serial.println("IM IN");
      digitalWrite(led,HIGH);

    }
  }

  if (out_flag >0) {
    Serial.println();
    out_flag = 0;
  }


}

int SerialReadHexDigit()
{
  byte c = (byte) Serial.read();
  if (c >= '0' && c <= '9') {
    return c - '0';
  } 
  else if (c >= 'a' && c <= 'f') {
    return c - 'a' + 10;
  } 
  else if (c >= 'A' && c <= 'F') {
    return c - 'A' + 10;
  } 
  else {
    return -1;   // getting here is bad: it means the character was invalid
  }
}


long int tokenInVar(){
  //long number = 0; declared in scope
  // int token[8];
  for(int i=0; i<8; i++) number = (number << 4) | convertFromHex(int(token[i]));
  return(number);

}

long int convertFromHex(int ascii){ 
  if(ascii > 0x39) ascii -= 7; // adjust for hex letters upper or lower case
  return(ascii & 0xf);
}

danieljay:
is token suppose to be my incoming byte variable?

Not in the example. Token appears to be an array that contains the values that need to be converted. He didn't give you exactly what you needed, he gave you an example which you actually have to study to see how it works and how you can incorporate it into your code.

  mySerial.listen();
  Serial.println("Serial number will be displayed here if a card is detected by the module:\n"); 
  // set the data rate for the SoftwareSerial port 
  mySerial.begin(9600);

You
You can't listen() to an instance of SoftwareSerial until AFTER you call begin()!

    int c = mySerial.write( CMD[i]*16 + CMD[i+1]);

Have you looked at the documentation for the write() method? Does it really matter how many characters you are writing? Why are you ADDING two characters? That makes NO sense.