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.
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;
}
}
}