I have two Arduino devices, and am using NewSoftSerial to communicate between them. The problem is that whenever I read data with NewSoftSerial's read, the data is corrupted. I found a pattern by repeatedly sending byte '240'. What I receive:
NewSoftSerial seems to be losing its place in the stream of bits. At each byte the offset between where it thinks the start of a byte is, and where the start actually is, gets worse and worse. In my example, it's off by 4 bits at the end. Here's how I'm reading the data:
while (!finished)
{
if (softLink.available() > 0)
{
touchBuffer[touchIndex] = softLink.read();//data corrupted here
touchIndex++;
if (touchIndex >= TOUCH_BUFFER_SIZE)
finished = true;
}//if available()
else if (digitalRead(LS_TOUCH_PIN) == LOW)
finished = true;
}//while !finished
What is the baud rate you are using? The soft side of the new soft serial library might be affecting the max baud rate. Also what arduino board are you using? Either one of them using internal oscillator?
Are you using parity and/or stop bits? The purpose of these is to maintain sync with the bitstream and detect bit errors. You can get serial comms to work without them under ideal conditions, but when conditions aren't ideal you'll find them very useful.
I'm using 38400 baud. The receiving board is an Arduino Nano, and the sending board is a TouchSlide Shield. It describes itself as an "Atmel Butterfly Development Board".
I should mention that the sender (Touchshield) is using the built-in UART, only the receiver (Nano) is using NewSoftSerial. However, the Nano can send data to the Touchshield continually for the better part of an hour with not even one bit out of place. It's the reverse that's causing me headaches.
The sender code looks like this:
//Stores touch data received from the touchscreen
char touchBuffer[TOUCH_BUFFER_SIZE];
//The index of the current element in touchBuffer to write to
int touchIndex = 0;
I was unable to use that baud rate on my duemilanove boards so consider dropping the rate. If you are not constantly using that bandwidth, you face two things: data corruption (software delay and possible line noise) and receiving buffer overflow (cause you transferred too many bytes before the receiver finds time to process). Try 19200 instead.
I'm afraid I'm stuck using 38400 - I need to send images to the touchscreen as fast as I can. Even at 38400 baud, I'm still only sending 1 image every 4 seconds. I also found that 38400 was too high, but I only send at 19200 over the link. Since I'm using software serial, this results in a speedup for me, since the Nano is only hung up doing blocking sends for half as long.
I'd rather monitor the offset in software, and compensate for it, than reduce the baud rate any lower. The Touchshield only has a small amount of data to send, and I could always use a series of four zero bits to indicate a single 0, and four 1 bits to indicate a single 1.
Let me try just once more because "The sender code looks like this" doesn't help at all, in fact the little bit of code you posted suggests that there is very likely to be a bug somewhere there.
The way that you describe the problem with the bit shifting of the input character doesn't look "possible" under normal conditions. However, with a software UART you can always have a problem that it can't keep up at higher transmission rates. If it is having trouble keeping up, then the sequence that you post is precisely the kind of thing that will occur.
Can you configure the sending end to transmit two stop bits? - i.e. 8-n-2 ? The extra stop bit would give the receiver software time to catch up.
The char datatype is a signed type, meaning that it encodes numbers from -128 to 127. For an unsigned, one-byte (8 bit) data type, use the byte data type.
It isn't clear which version you are using exactly, but the SoftwareSerial I have turns interrupts off during a write (because it has to get the timing right). I'm not particularly surprised that, with a fast baud rate, and doing other serial comms at the same time, that data is being corrupted.
You could try swapping them (make the hardware one the software one and vice versa).
Why do a flush? Do you want to throw the data away?
Ehhh... good point. The manual says: "Waits for the transmission of outgoing serial data to complete. (Prior to Arduino 1.0, this instead removed any buffered incoming serial data.) " I'm using Arduino version 0018, which I assume means 1.8 though... so I would expect to see the newer behaviour.
Which version is that? I've used all the versions from 15 on up and they all have Serial.write().
Well, here's what I get when I try it:
[apply] /tmp/build2430831250169278482.tmp/tmp/touchslide/touchslide.pde: In function 'void sendTouches()':
[apply] /tmp/build2430831250169278482.tmp/tmp/touchslide/touchslide.pde:165: error: 'class HardwareSerial' has no member named 'write'
It's version 0018, but is a custom version for the TouchSlide Shield called 'Antipasto'.
Can you configure the sending end to transmit two stop bits? - i.e. 8-n-2 ?
I'm not sure how to approach this using Arduino's Serial library... however, after sleeping on it I now feel that the baud rate is the issue here.
I'm going to try a design like so:
Main Link (38400 baud) Nano (NewSoftSerial) <-----> TouchSlide (Hardware UART)
-Nano endlessly streams drawing commands to the TouchSlide.
-TouchSlide sends a few bytes to the nano when it's ready to transmit (these will be garbled as in my first post)
Secondary Link (9600 baud) Nano (NewSoftSerial) <-----> TouchSlide (SoftSerial)
-TouchSlide sends touch data to the Nano
-The Nano stops sending on the Main Link whenever it receives any data there, and switches the NewSoftSerial to the Secondary Link
-The Nano resumes sending on the Main Link when the transmission ends.
My only concern is that I'm not sure the Main Link is full-duplex, in which case it could take a while for the Nano to get the notification to switch to the secondary link.