0

My project involves and RFID reader connected to an Arduino Pro Mini (5V, 16MHz) and an Adafruit CC3000 breakout WiFi chip. The device reads RFID tags and sends them to my web service. I am using Software Serial to read the RFID device data.

After I scan something, the Arduino tries to send the value that was read to the web service. This obviously causes a delay and the program only continues execution (i.e. next iteration of the loop() function) after the data has been sent.

My problem is simple. While the value is being sent, the serial buffer is can still accept scans from the RFID reader and on subsequent iterations, because there is data in the buffer the device attempts to send data again.

My question is how can I stop the software serial port from receiving data while I am trying to send data to the web service? Then when the data is sent successfully, how can I re-enable the software serial port from accepting data?

  • 1
    Beware the when you re-enable receiving from an asynchronously transmitter source, you will have a high chance of seeing the tail end of a message which began while you were disabled, so you will probably need logic to discard incoming characters until you see the start of a new, valid message. – Chris Stratton Oct 9 '14 at 18:56
8

Call serial.end() to stop receiving.

Then call serial.begin(...) again when you want to start listening again.

| improve this answer | |
3

According to the docs, SoftwareSerial doesn't support .end(), so Gerben's answer won't work here, I think.

It's hacky, but you could exploit the fact that only one SoftwareSerial can receive data at a time, and create a second one, activating it with SoftwareSerial.listen(). Then .listen() again on your original SoftwareSerial, when you want to resume listening.

Or, you could do as Marty Grogan says, and flush the read buffer before starting a new read. Again, I don't think SoftwareSerial supports a flush method as such, so you'd need to just .read() until there's nothing .available().

| improve this answer | |
  • 2
    SoftwareSerial doesn't support .end() - it does now, maybe it did not before. @Gerben linked to the source which shows the exact lines of code. They turn off the pin-change interrupts for that pin, thus (that instance of) SoftwareSerial will no longer react to incoming data. – Nick Gammon Sep 4 '15 at 5:51
  • Again, I don't think SoftwareSerial supports a flush method as such - again, it does now, as the source code shows. You may wish to edit your answer, to keep it up to date... :-) – Greenonline Mar 4 '16 at 13:32
2

Whether or not the serial data becomes available really does not matter. If you flush the port before every read rather than consuming the data, let 'er rip. If you are using interrupts, toggle interrupts on the serial pin.

| improve this answer | |
0

The important parts are the GPS.end() which removes the interrupt routine and effectively stops listening to input although the data continues and the GPS.begin(baud) which reinstates the interrupt routine. The other statements are program specific and could be anything that you want to do while the input data processing is off.

I am using it on a project where I smooth scroll time/date on an LED matrix but the SoftwareSerial interrupt routine makes the scrolling jerky. I have reduced the NMEA sentences to just one but it still takes a noticeable amount of time to process it. So the GPS is always on and sending but I only listen 4 times per hour by doing an ss.begin() for 5 second (or until valid data), save it then do the ss.end(). Problem solved. I get mildly jerky scrolling for 5 seconds but it is rarely noticed and my time is always right.

I will post the routine on my web site, ILikeTheInternet.com, in a few days.

| improve this answer | |
  • If you could post the routine in your answer that would be useful, as links tends to die after a period of time. Also Iliketheinternet.com doesn't appear to respond to http requests currently. – Greenonline Mar 4 '16 at 13:28
0

I have successfully used two Software Serial interfaces by using the .listen() method.

SoftwareSerial swSerial1(4,5);
SoftwareSerial swSerial2(6,8);

swSerial1.begin(9600);
swSerial2.begin(9600);

At this point the Arduino is listening to swSerial2 because it was defined last. If I wanted to use swSerial1 in the loop I would call

swSerial1.listen();

And switch back with

swSerial2.listen();

This avoids the significant overhead of ending and re-beginning software serial connections.

| improve this answer | |
0

Just a guess but I believe the current version of SoftSerial actually uses PCINT to detect the individual bits. I believe if that were disabled you would stop reception. It will take some work to get it to work without problems. This is just a guess.

| improve this answer | |
-1

I had the same problem with reading GPS-Data on Port 11 while sending APRS-Data out. This code worked for me:

GPS.end();

aprs_send(); 
while (afsk_busy());

GPS.begin(GPS_BAUDRATE);
| improve this answer | |
  • 1
    Should the two lines in the middle be ran right after GPS.end() or right before GPS.begin()? What do they do? – Anonymous Penguin Jul 21 '15 at 19:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.