Serial.read from two sources

Hi All!

I am having a bit of a problem with my Arduino NG. I have plugged it in to a Parallax RFID and the Arduino reads it brilliantly, sending out codes to Processing. Now I'd like my Processing program to work on the output from the Arduino and then send an integer back in. Is it possible to have two different Serial.read in the Arduino program (one from the RFID, one from Processing)? It doesn't work as it is, do I have to change to different baud rates or do a Serial.flush between the two reads?

Thanks for all help!

//Jenny

The arduino only has one hardware serial port.

But som clever people have found a way to make a seofware serial port using other pins than the Hw port.

Check the playground for softserial. Be aware though that the softserial is limited to max 9600 Baud.

... and there is no "serial.available" function in software serial, which is a problem if the board is doing more than just waiting for serial data to arrive on one of the digital pins.

Oh my, that was interesting news, thanks for the help!

I tried the SoftwareSerial example on Arduino - Home (see below) but nothing happens when I type in a character in the serial monitor (with baud rate of 9600 chosen). The only stuff I use is the arduino and an LED between GND and pin 13 (and of course the cable to the computer). Do I actually need to plug in something (like a wire?) inbetween (the new) rx and tx?

Sorry that this question is very basic, I am a beginner at all this ...

Example code without modifications:

/*
SoftwareSerial example

Sample of the SoftwareSerial library. Listens for serial in on pin 2
and sends it out again on pin 3.

by Tom Igoe
based on examples by David Mellis and Heather Dewey-Hagborg
written: 6 Jan 2007

*/

// include the SoftwareSerial library so you can use its functions:
#include <SoftwareSerial.h>

#define rxPin 2
#define txPin 3
#define ledPin 13

// set up a new serial port
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
byte pinState = 0;

void setup() {
// define pin modes for tx, rx, led pins:
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
pinMode(ledPin, OUTPUT);
// set the data rate for the SoftwareSerial port
mySerial.begin(9600);
}

void loop() {
// listen for new serial coming in:
char someChar = mySerial.read();
// print out the character:
mySerial.print(someChar);
// toggle an LED just so you see the thing's alive.
// this LED will go on with every OTHER character received:
toggle(13);

}

void toggle(int pinNum) {
// set the LED pin using the pinState variable:
digitalWrite(pinNum, pinState);
delay(2000);
// if pinState = 0, set it to 1, and vice versa:
pinState = !pinState;
}

That example code listens for data on pin 2 and sends it on pin 3, the cable to the computer is by default connected on pins 0 and 1 for the hardware serial port.

What I think you want to do is wait for a character on the hardware port, so you need to add Serial.begin(9600); to setup and in your loop, wait on: if ( Serial.available()) { ?.
When a character is available, I think you then want to communicate with the Parallax device connected on pins 2 and 3.

Thanks for your reply!

The example that I wrote was only to see if I could get the SoftwareSerial to work. The actual problem we have is the following:

We want the RFID reader to listen to tags. When a tag is put in front of it, the result is sent to a Processing program via a USB cable. The program compares this to a list of products and replies an integer concerning the related products. The arduino is then supposed to light a couple of lamps in a pattern.

Is this possible, and does it require SoftwareSerial?

Thanks for all the help for a poor newbie!

//J

Did you try to listen to the RFID device on pin 2? In your posted sketch, you could replace mySerial.print(someChar); with a Serial.print(someChar) that would send any received characters to the serial monitor on the PC using the USB cable. (don't forget the Serial.begin in setup)

Once you have confirmed that you are receiving the RFID data, you can add code that gets a response from your processing app and lights the lamps as required.

The functionality you want should be achievable with the arduino, but bear in mind that as pointed out above, SoftwareSerial blocks waiting for a character and drops characters that come in when your code is not listening (unless your RFID reader has some handshaking). This could be a problem if a new tag comes in and out of proximity to the reader before you have had a response from Processing on the previous tag.

You can't run any kind of loop if your using software serial, that means you can't do anything except listen for the RFID tag and then print it to processing. You won't be able to do anything with a response from processing, because that requires a loop, eg, listen for tag, send to processing, wait for processing to reply, do something, then listen for tag.

So, here's one solution

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1201476854/5#5

It's cheaper than buying a wiring board, because that's what you'll be needing for 2 hardware serial ports.

Put a lilypad via I2C to the Arduino, and the RFID reader to the hardware serial of the lilypad. That way the Arduino is free to run loops send and receive responses on its hardware serial port.

I just tested it with an RFID module, works like a charm.

You won't be able to do anything with a response from processing, because that requires a loop, eg, listen for tag, send to processing, wait for processing to reply, do something, then listen for tag.

Hi John, I think what Jenny wants to do is:

  • listen for tag, (this will block but there is nothing else to do)
  • send to processing
  • wait for processing to reply
  • light some LEDs
  • loop back to listen for a tag

Adding hardware to receive the RFID input would be more robust, but more complicated and expensive then perhaps it needs to be. I would think this app should work with SoftwareSerial as long as a second RFID tag did not come in and out of proximity while waiting for and handling the response to the previous one.

Am I missing something?

You won't be able to do anything with a response from processing, because that requires a loop, eg, listen for tag, send to processing, wait for processing to reply, do something, then listen for tag.

Hi John, I think what Jenny wants to do is:

  • listen for tag, (this will block but there is nothing else to do)
  • send to processing
  • wait for processing to reply
  • light some LEDs
  • loop back to listen for a tag

Adding hardware to receive the RFID input would be more robust, but more complicated and expensive then perhaps it needs to be. I would think this app should work with SoftwareSerial as long as a second RFID tag did not come in and out of proximity while waiting for and handling the response to the previous one.

Am I missing something?

Software serial hangs until there's serial data, so if the program isn't needed for anything else, then yes it can sit there and wait for a tag, and then run through a sequence, and then return and wait for another tag.

The problem with that, is if there is no tag, then the program hangs. So, if you wanted LEDs turned off after a certain amount of time, then it won't / can't process that request, until serial data becomes available.

The simplest explanation, is the blinking LED example code won't work when software serial is hung up waiting for serial data, time virtually stands still, or "gets put on hold" for choice of better words. Any miscellaneous functions based on time, or counters, or external events like processing deciding its time to tell the board to turn all the LEDs off, simply will not work.

There is no serial.available function for ss and that's the core of the problem. Serial available lets you check for serial data, and if there is none, then the controller can go away and do something else, as you'd expect, otherwise... it's almost not worth using one.

Personally I've spent about 3+ months trying to solve the software serial problem, actually not solve it, but work through various hacks and improvisations .. and spent a small fortune in the process. Eventually, I ended up with a wiring board, but then decided to have a peek at the Lilypads because they're so incredibly inexpensive. Coincidentally, I'm working with RFID modules, and processing, software serial was a serious sticky point until the Lilypad I2C, they cost less than 20 bucks, and give you about as much power as wiring board, minus the copious numbers of A/D's and the "very" generous 128k :slight_smile:

I haven't really looked at this properly, but could SoftwareSerial not be modified fairly easily to respond to an interrupt on the rx pin to read characters?

Something like:

In Init: Set softwareserial.read() to an interrupt on the rx pin

In interrupt (softwareserial.read()):

  1. disable interrupts
  2. read exactly 1 byte of serial data fom the pin using existing library code into buffer
  3. re-enable interrupt

Wouldn't this get round the current read limitation in softwareserial?

Dave

Dave, Its a little tricky using an interrupt for this but it can be done. In fact, it has been done. There is an interrupt driven software serial routine in this library . See the uartsw routines.

I wonder if anyone has tried to get this going on the arduino?

A possible solution might be a UART 16550 or variant on it. This would provide 16 bytes of buffering while you were doing other things. Price about $6.

Thanks all for you suggestions!

Since I haven't done much programming, it seems like the Lilypad might offer the easiest and most reliable solution. John - do you know if there is any good example that I can follow to get the master/slave connection to work? This is all very new to me... :slight_smile:

Thanks all for you suggestions!

Since I haven't done much programming, it seems like the Lilypad might offer the easiest and most reliable solution. John - do you know if there is any good example that I can follow to get the master/slave connection to work? This is all very new to me... :slight_smile:

The wiring you can follow this picture:-

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1201476854/5#5

The code you use, is in the examples library of Arduino 10

Sketchbook --> Examples -- > Library Wire --- > ( slave_receiver.pde ) + ( master_writer.pde )

I've got mine wired to a blueSmirf, and the second Lilypad wired to an RFID module. Even using these off-the-shelf components, it's the world's most inexpensive BT-RFID reader.

You can make these cheaper by buying 168's from Adafruit, here:-

http://www.adafruit.com/index.php?main_page=product_info&cPath=19&products_id=56

Then follow the instructions for building an Arduino on a bread board, and trim back the components you don't need. You should be able to make something for about 20 bucks, plus the cost of whatever else you add on.

Brilliant, thanks for the help!