Arduino -> Processing hacking SerialCallResponse

Hi,

I've been working on this for the last few hours and I can't for the life of me see what's wrong with it.

I've a PARALLAX RFID sensor attached to my UNO? board, running on Windows 7, Arduino 1.0.5.

I'm trying to send two streams of data to Processing - both are numbers. One set of numbers (int) is associated with the RFID, the other set of chars associated with a rotary encoder.

I'm after hacking the SerialCallResponse example. Below is the loop function from Arduino and the code from Processing that prints the data.

The second stream of data is coming into Processing just fine, but the first stream just shows a '0'. Any ideas as to what the issue is? Does it have something to do with the data types? I thought I checked that...I'l lost.

Any help appreciated

int secondSensor = 0;
int trackNum = 0;

void loop()
{
  // if we get a valid byte, read analog ins:
  if (Serial.available() > 0) {
    
    ReadSerial(RFIDTAG);
    if (RFIDTAG == "3600095756"){//if its card A
      trackNum = 10;
    } 
    if (RFIDTAG == "190035D511"){//if its card B
      trackNum = 20;
    }
    // get incoming byte:
    inByte = Serial.read();
    
    firstSensor = trackNum;
    secondSensor = 111;
    //thirdSensor = 533;  
    // send sensor values:
    Serial.write(firstSensor);
    Serial.write(secondSensor);
    //Serial.write(thirdSensor);
    
        
  }//CLOSE Serial.available
}//CLOSE loop function

Processing

if (serialCount > 1 ) {
      rfid = serialInArray[0];
      rotary = serialInArray[1];
      //fgcolor = serialInArray[2];

      // print the values (for debugging purposes only):
      println(rfid + "\t" + rotary + "\t");

      // Send a capital A to request new sensor readings:
      myPort.write('A');
      // Reset serialCount:
      serialCount = 0;
    }

I've a PARALLAX RFID sensor attached to my UNO? board, running on Windows 7, Arduino 1.0.5.

Attached how?

    ReadSerial(RFIDTAG);

What is this function doing? The name implies that it is reading serial data, but Processing is on the other end of the serial port, so that doesn't make sense.

    Serial.write(firstSensor);
    Serial.write(secondSensor);

You are sending binary data.

You have not provided near enough code to actually help you.

Ok, sorry for not providing much detail.

Before I paste the code out fully, I think the issue might be exactly what you said: I’m reading the rfid through serial and trying to communicate with Processing through Serial. However, I am able to read the secondSensor in Processing fine. I don’t understand why I can read one of the data streams, but not the other?

This is my Arduino code, which shows how its connected:

/*
  Serial Call and Response
 Language: Wiring/Arduino
 
 This program sends an ASCII A (byte of value 65) on startup
 and repeats that until it gets some data in.
 Then it waits for a byte in the serial port, and 
 sends three sensor values whenever it gets a byte in.
 
 Thanks to Greg Shakar and Scott Fitzgerald for the improvements
 
   The circuit:
 * potentiometers attached to analog inputs 0 and 1 
 * pushbutton attached to digital I/O 2
 
 Created 26 Sept. 2005
 by Tom Igoe
 modified 24 April 2012
 by Tom Igoe and Scott Fitzgerald

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/SerialCallResponse

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

String RFIDTAG="";
String DisplayTAG="";

int firstSensor = 4;    // first analog sensor
int secondSensor = 0;   // second analog sensor
int trackNum = 0;
int inByte = 0;         // incoming serial byte

void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(2400);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  pinMode(2, OUTPUT);   // digital sensor is on digital pin 2
  digitalWrite(2, LOW);
 
  establishContact();  // send a byte to establish contact until receiver responds 
}

void loop()
{
  // if we get a valid byte, read analog ins:
  if (Serial.available() > 0) {
    // get incoming byte:
    inByte = Serial.read();
    
    ReadSerial(RFIDTAG);
    if (RFIDTAG == "190035D511"){
          trackNum = 1;
        } 
    if (RFIDTAG == "3600095756"){
          trackNum = 2;
        }
    if (RFIDTAG == "190035E473"){
          trackNum = 3;
        }
    if (RFIDTAG == "17007EFC59"){
          trackNum = 4;
        }
    //firstSensor = 115;
    //secondSensor = 111;
    //thirdSensor = 533;  
    // send sensor values:
    //Serial.write(firstSensor);
    firstSensor = trackNum;
    Serial.write(firstSensor);
    Serial.write(secondSensor);
    secondSensor ++;
    //Serial.write(thirdSensor);
  }
  
  if(DisplayTAG!=RFIDTAG)
  {
    DisplayTAG=RFIDTAG;
    Serial.println(RFIDTAG);
  }
  
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.print('A');   // send a capital A
    delay(300);
  }
}

void ReadSerial(String &ReadTagString)
{
  
  int bytesread = 0;
  int  val = 0; 
  char code[10];
  String TagCode="";

  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 

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

And this is my Processing code:

// This example code is in the public domain.

import processing.serial.*;

int bgcolor;           // Background color
int fgcolor;           // Fill color
Serial myPort;                       // The serial port
int[] serialInArray = new int[2];    // Where we'll put what we receive
int serialCount = 0;                 // A count of how many bytes we receive
int rfid, rotary;                 // Starting position of the ball
boolean firstContact = false;        // Whether we've heard from the microcontroller

void setup() {
  size(256, 256);  // Stage size
  noStroke();      // No border on the next thing drawn

  // Set the starting position of the ball (middle of the stage)
  

  // Print a list of the serial ports, for debugging purposes:
  println(Serial.list());

  // I know that the first port in the serial list on my mac
  // is always my  FTDI adaptor, so I open Serial.list()[0].
  // On Windows machines, this generally opens COM1.
  // Open whatever port is the one you're using.
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 2400);
}

void draw() {
  background(bgcolor);
  fill(fgcolor);
  
}

void serialEvent(Serial myPort) {
  // read a byte from the serial port:
  int inByte = myPort.read();
  // if this is the first byte received, and it's an A,
  // clear the serial buffer and note that you've
  // had first contact from the microcontroller. 
  // Otherwise, add the incoming byte to the array:
  if (firstContact == false) {
    if (inByte == 'A') { 
      myPort.clear();          // clear the serial port buffer
      firstContact = true;     // you've had first contact from the microcontroller
      myPort.write('A');       // ask for more
    } 
  } 
  else {
    // Add the latest byte from the serial port to array:
    serialInArray[serialCount] = inByte;
    serialCount++;

    // If we have 2 bytes:
    if (serialCount > 1 ) {
      rfid = serialInArray[0];
      rotary = serialInArray[1];
      //fgcolor = serialInArray[2];

      // print the values (for debugging purposes only):
      println(rfid + "\t" + rotary + "\t");

      // Send a capital A to request new sensor readings:
      myPort.write('A');
      // Reset serialCount:
      serialCount = 0;
    }
  }
}

Right, the issue was a serial port issue, as you alluded too. I don’t understand it exactly, but I had to use SoftwareSerial.

Thanks for the pointer PaulS!

See below:

Arduino code:

/*

RFID SOUT <---> Arduino Digital Pin 5
RFID ENABLE <---> Arduino Digital Pin 2

*/

#include <SoftwareSerial.h>

//Parallax RFID Reader 
#define RFIDEnablePin 2 //Pin that enables reading. Set as OUTPUT and LOW to read an RFID tag
#define RFIDSerialRate 2400 //Parallax RFID Reader Serial Port Speed

//Using SoftwareSerial Library to locate the serial pins off the default set
//This allows the Arduino to be updated via USB with no conflict
#define RxPin 5 //Pin to read data from Reader 
#define TxPin 4 //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 firstSensor = 0;
int secondSensor = 0;
int trackNum = 0;
int inByte = 0;

void setup() 
{
  // RFID reader SOUT pin connected to Serial RX pin at 2400bps
  RFIDReader.begin(RFIDSerialRate);

  // Set Enable pin as OUTPUT to connect it to the RFID /ENABLE pin
  pinMode(RFIDEnablePin,OUTPUT); 

  // Activate the RFID reader
  // Setting the RFIDEnablePin HIGH will deactivate the reader
  // which could be usefull if you wanted to save battery life for
  // example.
  digitalWrite(RFIDEnablePin, LOW);

  Serial.begin(9600);           // set up Serial library at 9600 bps

  Serial.println("Hello world --!");  // prints hello with ending line break 
  
  establishContact();
}

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
  }

  //This only displays a tag once, unless another tag is scanned
  if(DisplayTAG!=RFIDTAG)
  {
    DisplayTAG=RFIDTAG;
    //Serial.println(RFIDTAG);
  }
  
  if(RFIDTAG == "3600095756"){
    trackNum = 1;
  }
  if(RFIDTAG == "190035D511"){
    trackNum = 2;
  }
  if(RFIDTAG == "190035E473"){
    trackNum = 3;
  }
  if(RFIDTAG == "17007EFC59"){
    trackNum = 4;
  }
  if(RFIDTAG == "190035E3D2"){
    trackNum = 5;
  }
  firstSensor = trackNum;
  Serial.write(firstSensor);
  Serial.write(secondSensor);
  secondSensor ++;
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.print('A');   // send a capital A
    delay(300);
  }
}

void ReadSerial(String &ReadTagString)
{
  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="";
    } 
  } 
}

Processing:

// This example code is in the public domain.

import processing.serial.*;

int bgcolor;           // Background color
int fgcolor;           // Fill color
Serial myPort;                       // The serial port
int[] serialInArray = new int[2];    // Where we'll put what we receive
int serialCount = 0;                 // A count of how many bytes we receive
int rfid, rotary;                 // Starting position of the ball
boolean firstContact = false;        // Whether we've heard from the microcontroller

void setup() {
  size(256, 256);  // Stage size
  noStroke();      // No border on the next thing drawn

  // Set the starting position of the ball (middle of the stage)
  

  // Print a list of the serial ports, for debugging purposes:
  println(Serial.list());

  // I know that the first port in the serial list on my mac
  // is always my  FTDI adaptor, so I open Serial.list()[0].
  // On Windows machines, this generally opens COM1.
  // Open whatever port is the one you're using.
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
}

void draw() {
  background(bgcolor);
  fill(fgcolor);
  
}

void serialEvent(Serial myPort) {
  // read a byte from the serial port:
  int inByte = myPort.read();
  // if this is the first byte received, and it's an A,
  // clear the serial buffer and note that you've
  // had first contact from the microcontroller. 
  // Otherwise, add the incoming byte to the array:
  if (firstContact == false) {
    if (inByte == 'A') { 
      myPort.clear();          // clear the serial port buffer
      firstContact = true;     // you've had first contact from the microcontroller
      myPort.write('A');       // ask for more
    } 
  } 
  else {
    // Add the latest byte from the serial port to array:
    serialInArray[serialCount] = inByte;
    serialCount++;

    // If we have 2 bytes:
    if (serialCount > 1 ) {
      rfid = serialInArray[0];
      rotary = serialInArray[1];
      //fgcolor = serialInArray[2];

      // print the values (for debugging purposes only):
      println(rfid + "\t" + rotary + "\t");

      // Send a capital A to request new sensor readings:
      myPort.write('A');
      // Reset serialCount:
      serialCount = 0;
    }
  }
}