Serial hierarchy

Hi there,

I was wondering if someone could tell me whether or not it would be possible to program 2 things:

  • set up a hierarchy or order list from serial inputs (i.e. 1 code has to be inputted before another works)
  • prevent a command from continuously repeating itself inside a loop

The image attached shows how I am connecting RFIDs to a small thermal printer.
I want to be able to stop the repetition (as seen on the paper constantly repeating itself) and also set up a hierarchy with the RFIDs I use. In other words, I dont want RFID 2 to work, unless RFID 1 has been activated, and simultaneously with the remaining 4 - 5 RFID’s

#include <SoftwareSerial.h>
#include <Thermal.h>

int printer_RX_Pin = 2;
int printer_TX_Pin = 3;

Thermal printer(printer_RX_Pin, printer_TX_Pin, 19200);
#define RFIDEnablePin 4 //Pin that enables reading. Set as OUTPUT and LOW to read an RFID tag
#define RFIDSerialRate 2400 //Parallax RFID Reader Serial Port Speed
#define RxPin 5 //Pin to read data from Reader 
#define TxPin 6 //Pin to write data to the Reader NOTE: The reader doesn't get written to, don't connect this line.
SoftwareSerial RFIDReader(RxPin,TxPin);

String RFIDTAG=""; //Holds the RFID Code read from a tag
String DisplayTAG = ""; //Holds the last displayed RFID Tag
int led = 10; //small LED on circuit

void setup() 
{
  printer.setHeatTime(120); // 80 is default from page 23 of datasheet. Controls speed of printing and darkness
  printer.setHeatInterval(12); // 2 is default from page 23 of datasheet. Controls speed of printing and darkness
  printer.setPrintDensity(15); // Not sure what the defaut is. Testing shows the max helps darken text. From page 23.
  printer.setPrintBreakTime(10); // Not sure what the defaut is. Testing shows the max helps darken text. From page 23.
  printer.justify('C'); //sets text justification (right, left, center) accepts 'L', 'C', 'R'

  RFIDReader.begin(RFIDSerialRate);   // RFID reader SOUT pin connected to Serial RX pin at 2400bps
  pinMode(RFIDEnablePin,OUTPUT);   // Set Enable pin as OUTPUT to connect it to the RFID /ENABLE pin
  pinMode(led, OUTPUT);
  digitalWrite(RFIDEnablePin, LOW);
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Please Scan RFID");  // prints hello with ending line break 
}

void loop() 
{
  if(RFIDReader.available() > 0) {  // If data available from reader
    ReadSerial(RFIDTAG);  //Read the tag number from the reader. Should return a 10 digit serial number
  }
  if(DisplayTAG!=RFIDTAG)  //This only displays a tag once, unless another tag is scanned
  {
    DisplayTAG=RFIDTAG;
    Serial.println(RFIDTAG);
  }
  if(RFIDTAG == "0700B94F5A") // *******COMMAND FOR PRINTING OUT OF ARDUINO 2 ********
  {
    printer.setSize('L'); // set type size, accepts 'S', 'M', 'L'
    printer.println("THIS IS HOW TO USE AN RFID"); //print line
    printer.feed(); //advance one line
    printer.feed(); //advance one line
    Serial.println("end");
    delay(5000); //added to create a break between readings.... maybe?
    RFIDTAG = 0; // trying to reset the tag
  }
  if(RFIDTAG == "840035182F") // *******COMMAND FOR PRINTING OUT OF ARDUINO 2 ********
  {
    printer.setSize('L'); // set type size, accepts 'S', 'M', 'L'
    printer.println("Also this"); //print line
    printer.feed(); //advance one line
    printer.feed(); //advance one line
    Serial.println("end");
    delay(5000);
    RFIDTAG = 0; // trying to reset the tag
  }
}




void ReadSerial(String &ReadTagString) //Code for programming the RFID Reader
{
  int bytesread = 0;
  int  val = 0; 
  char code[10];
  String TagCode="";

  if(RFIDReader.available() > 0) {          // If data available from reader 
    if((val = RFIDReader.read()) == 10) {   // Check for header 
      bytesread = 0; 
      while(bytesread<10) {                 // Read 10 digit code 
        if( RFIDReader.available() > 0) { 
          val = RFIDReader.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 

        for(int x=0;x<10;x++)              //Copy the Chars to a String
        {
          TagCode += code[x];
        }
        ReadTagString = TagCode;          //Update the caller
        while(RFIDReader.available() > 0) //Burn off any characters still in the buffer
        {
          RFIDReader.read();
        } 
      } 
      bytesread = 0;
      TagCode="";
    } 
  } 
}

This is the code I am currently working on. The Serial Monitor displays the RFID’s codes when they are in range of the reader. I think this is where most of the magic should happen, but im not entirely sure on it.

Thankyou :slight_smile:
Alex

set up a hierarchy or order list from serial inputs (i.e. 1 code has to be inputted before another works)

Possible, and relatively easy. Keeping track of whether or not the nth tag has been read requires an array of booleans. Set/check the nth element of the array to see if the nth tag has been presented or deal with the nth tag being presented.

prevent a command from continuously repeating itself inside a loop

Yes, but what “command” is “repeating itself inside a loop” isn’t at all clear.

Your indenting is horrid, and inexcusable, given the Tools + Auto Format menu item. Use it before posting code again.

Hello again Paul,

I've auto formatted the code (inside the arduino code ...program...IDE?)
Its still a bit of a mess.

the "repetition" element is the command for printing

 printer.println("THIS IS HOW TO USE AN RFID"); //print line

Hence why I keep getting the printed repetitions as seen in the image.

Please let me know if there are any better ways to format my code so it is more accessible :slight_smile:

    RFIDTAG = 0; // trying to reset the tag

By assigning a String a 0? That isn't going to work.

RFIDTAG = "";

If you don't want something to repeat within loop() then you need to have a variable that can record the fact that it has been printed already.

...R

Well, the problem is that the serial monitor displays the last ********* digit RFID code, meaning that my system rereads and reprocesses that RFID code.

Robin that variable sounds bang on. Can you possibly tell me if there is a term for that sort of variable? Showing my true inexperience here but Im not sure how one would set up a recording variable.

Im not sure if this is what you meant Robin,

But this is a section of code from the void loop

 void loop() 
{
  if(RFIDReader.available() > 0) {  // If data available from reader
    ReadSerial(RFIDTAG);  //Read the tag number from the reader. Should return a 10 digit serial number
  }
  if(DisplayTAG!=RFIDTAG)  //This only displays a tag once, unless another tag is scanned
  {
    DisplayTAG=RFIDTAG;
    Serial.println(RFIDTAG);
  }

Which I thought would solve the issue of reprinting, but it doesn't. Perhaps I need to set up a separate function..
The problem isn't the reading to the serial.monitor, but the subsequent printing that is caused by it, that keeps repeating, perhaps a similar bit of code like the one above for the printer as well?

http://snippets-r-us.com is down the road a ways. Here, we want to see ALL of your code. Have you made the changes I suggested?

js1000boy:
Im not sure if this is what you meant Robin,

If you think about it, the variable that holds the "state" of whether something has happened must be unchanged within the loop unless you want it to. This sort of thing goes by the grand name of a State Variable - but it is just an ordinary variable used for this purpose.

The simplest way to have a variable that is unchanged within a loop is to use a global variable - one that is defined before setup(). So for example

boolean isPrinted = false;

setup() {

}

loop() {
   if (isPrinted == false) {
       Serial.print("stuff");
       isPrinted = true;
   }
}

...R

Hi Paul,

the

 RFIDTAG = "";

Snippet comes as standard in the original code and when given a delay, does cause the printer to reset its function, but doesn’t appear prevent the program from continuously re-reading the RFID and displaying the code over and over.

Robin, the global variable works to an extent. (THANKYOU FOR IT). But if you can see from the code, I have had to alternative true and false values in the loop. I was wondering if a reset of the isPrinted boolean could be caused by a change of DisplayTAG? Meaning that when I do all 10 of these, then they don’t need to work after a specific RFID. I hope that makes sense.

////////////////////////////////////////////////////////////////////
//Following are in setup, but do not need to be. Use them anywhere. 
//Just here so they do not just keep printing over and over
//Printer will ignore commands during printing, so use delay(3000)
//after prints to ensure it see everything you want to print.
//SOME FUNCTIONS WILL FEED A LINE WHEN CALLED TO SOLIDIFY SETTING
////////////////////////////////////////////////////////////////////

#include <SoftwareSerial.h>
#include <Thermal.h>

int printer_RX_Pin = 3;
int printer_TX_Pin = 2;
boolean isPrinted = false;


Thermal printer(printer_RX_Pin, printer_TX_Pin, 19200);

#define RFIDEnablePin 4 //Pin that enables reading. Set as OUTPUT and LOW to read an RFID tag
#define RFIDSerialRate 2400 //Parallax RFID Reader Serial Port Speed
#define RxPin 5 //Pin to read data from Reader 
#define TxPin 6 //Pin to write data to the Reader NOTE: The reader doesn't get written to, don't connect this line.
SoftwareSerial RFIDReader(RxPin,TxPin);
String RFIDTAG=""; //Holds the RFID Code read from a tag
String DisplayTAG = ""; //Holds the last displayed RFID Tag
int led = 10; //small LED on circuit

void setup(){

  RFIDReader.begin(RFIDSerialRate);   // RFID reader SOUT pin connected to Serial RX pin at 2400bps
  pinMode(RFIDEnablePin,OUTPUT);   // Set Enable pin as OUTPUT to connect it to the RFID /ENABLE pin
  pinMode(led, OUTPUT);
  digitalWrite(RFIDEnablePin, LOW);
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Please Scan RFID");  // prints hello with ending line break

  printer.setHeatTime(120); // 80 is default from page 23 of datasheet. Controls speed of printing and darkness
  printer.setHeatInterval(12); // 2 is default from page 23 of datasheet. Controls speed of printing and darkness
  printer.setPrintDensity(15); // Not sure what the defaut is. Testing shows the max helps darken text. From page 23.
  printer.setPrintBreakTime(10); // Not sure what the defaut is. Testing shows the max helps darken text. From page 23.

  printer.justify('C'); //sets text justification (right, left, center) accepts 'L', 'C', 'R'
  printer.setSize('S'); // set type size, accepts 'S', 'M', 'L'
  printer.println("Simon"); //print line
  printer.setSize('S'); // set type size, accepts 'S', 'M', 'L'
  printer.println("test");
  printer.setSize('L'); // set type size, accepts 'S', 'M', 'L'
  printer.println("Pub next Friday?"); //print line
  printer.feed(); //advance one line
  printer.feed(); //advance one line
  printer.setSize('S'); // set type size, accepts 'S', 'M', 'L
  printer.println("Message from Alex"); //print line//printer.println(1234);

  printer.printBarcode("123456789123"); //print simple bar code - up to 12 characters long//printer.printFancyBarCode("WWW.BILDR.ORG"); // print fancy barcode. Cap latters and some symbols
  printer.setBarcodeHeight(50); // set barcode px height: 0-255

  printer.boldOn(); // Turn bold on//printer.boldOff(); //Rurn bold off
  printer.doubleHeightOn(); // sets type to print double hight//printer.doubleHeightOff(); //Turn off double hight printing
  printer.inverseOn(); //set to print white on black//printer.inverseOff(); //set to print black on white (default)

  printer.sleep(); //Tell printer to sleep. MUST call wake before printing again, even if reset//printer.wake(); //Wake //printer.
  printer.wake();

  printer.setSize('L'); // set type size, accepts 'S', 'M', 'L'
  printer.feed(); //advance one line
  printer.tab(); //Tabs text over 8 spaces

  printer.justify('R'); //sets text justification (left, center, right) accepts 'L', 'C', 'R'

  printer.setDefault(); //set printer to defaults. ****WILL FEED SEVERAL LINES WHEN CALLED***

}

void loop(){
  if(RFIDReader.available() > 0) {  // If data available from reader
    ReadSerial(RFIDTAG);  //Read the tag number from the reader. Should return a 10 digit serial number
  }
  if(DisplayTAG!=RFIDTAG)  //This only displays a tag once, unless another tag is scanned
  {
    DisplayTAG=RFIDTAG;
    Serial.println(RFIDTAG);
  }

  if(RFIDTAG == "4D004A8087") // *******COMMAND FOR PRINTING OUT OF ARDUINO 2 ********
  {
    if (isPrinted == false) {
      printer.setSize('L'); // set type size, accepts 'S', 'M', 'L'
      printer.println("Test 1"); //print line
      printer.feed(); //advance one line
      printer.feed(); //advance one line
      RFIDTAG = ""; // trying to reset the tag
      isPrinted = true;
    }


  }
  if(RFIDTAG == "4D004A797A") // *******COMMAND FOR PRINTING OUT OF ARDUINO 2 ********
  {
    if (isPrinted == true) {
    printer.setSize('L'); // set type size, accepts 'S', 'M', 'L'
    printer.println("Test2"); //print line
    printer.feed(); //advance one line
    printer.feed(); //advance one line
    RFIDTAG = ""; // trying to reset the tag
    isPrinted = false;
  }
}
}




void ReadSerial(String &ReadTagString) //Code for programming the RFID Reader
{
  int bytesread = 0;
  int  val = 0; 
  char code[10];
  String TagCode="";

  if(RFIDReader.available() > 0) {          // If data available from reader 
    if((val = RFIDReader.read()) == 10) {   // Check for header 
      bytesread = 0; 
      while(bytesread<10) {                 // Read 10 digit code 
        if( RFIDReader.available() > 0) { 
          val = RFIDReader.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 

        for(int x=0;x<10;x++)              //Copy the Chars to a String
        {
          TagCode += code[x];
        }
        ReadTagString = TagCode;          //Update the caller
        while(RFIDReader.available() > 0) //Burn off any characters still in the buffer
        {
          RFIDReader.read();
        } 
      } 
      bytesread = 0;
      TagCode="";
    } 
  } 
}

Simplest thing may be to have two variables isPrintedA and isPrintedB (but with sensible names). Or maybe one for every RFID code. If there are several of them I would use an array to shorten things.

...R