Dropped Characters With Hardware/SoftwareSerial Bridge?

Hi all,

I am interfacing an RN-XV to an older PC at 2400 baud. It works perfectly, no data is dropped when connected directly. Not using flow control.

However, I’d like to introduce an Arduino Uno (actually, a MicroView) into the middle of the setup to eventually do some real-time data translation. This mostly works, but when there is a large burst of incoming data, a few characters get dropped and the data gets a slightly garbled, but it does recover.

Helpful diagram:

Code:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(8, 9); // RX, TX

void setup()  
{
  Serial.begin(2400);
  mySerial.begin(2400);
}

void loop() // run over and over
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}

Nothing to it, right? I’m having a hard time believing that the Uno can’t keep up, especially at such a low baud rate, but I’m sure there are background issues with interrupts and so on introduced by SoftwareSerial. Initial guess is that a buffer is filling up somewhere, but I’m not an expert on the innards.

Any suggestions?

What protocol are you using to ensure the RN-XV and the PC do not transmit at the same time?

Paul

None. Why would that be a potential problem?

Because your Arduino program only reads from one port at a time.

Paul

available() is a non-blocking call though, isn't it?

So it checks one port for available characters then the other as fast as possible, only calling read() on either port when a character is actually available, or so I would assume. If there's a better approach I'd love to hear it.

My code is directly adapted from the SoftwareSerial example: https://www.arduino.cc/en/Tutorial/SoftwareSerialExample

The newer version of this library is a little more efficient. It's part of the latest IDE version, or directly from here. Some folks have better success with AltSoftSerial, although it is restricted to certain pins.

your Arduino program only reads from one port at a time.

Hmmm, I think that's the best he can do with a single processor.

Cheers,
/dev

The problem is with interrupts.
The hardware serial port has an internal buffer which uses interrupts to read the port and fill the buffer which is an efficient way to do this.
The Software Serial port cannot tolerate interrupts as the CPU has to calculate the bit times and any interrupt will cause this calculation to be incorrect.
So if at any time both ports are sending or receiving at the same time , then its possible to get data corruption / loss.
To do this properly, you need a board that has 2 hardware serial ports.

SoftwareSerial disables interrupts for the entire time it takes to send a character. Interrupts are briefly enabled while it reloads and then, back to darkness. It works okay in some circumstances, but you can see how it might also fail.

If you have the pins available, try AltSoftSerial.
If not, there are other alternatives to SoftwareSerial.

Do you have to use an Uno?

Hm. Weird that I’m still seeing this corruption even when only one side is transmitting.

@jboyton - The intent was to use a MicroView which is basically an Uno with an built-in OLED screen.

What other alternatives are you referring to? I don’t have the pins for AltSoftSerial unfortunately.

I suspect every time your program does anything with the software serial function, the interrupts are turned off, not only when transmitting.

Try debugging by only reading from one serial port.

Paul

Thanks Paul for the help - I think I solved it by doing what you suggested. I also swapped the Hardware/Software serial pins around, and the problem remained on the PC side.

It looks like the “PC” wasn’t running precisely at 2400 baud, I upgraded the serial port driver and it works much better. I also upgraded to the latest Arduino IDE (with the newest SoftwareSerial) for good measure on the MicroView side.

So my theory is that the RN-XV was more tolerant of the slightly off baud rate than the MicroView.

It’s working quite well now. I can even update the MicroView’s OLED while simultaneously sending and receiving on both Serial ports.

Thanks everyone for their input!