I'm currently playing around with a GPRS shield on an Arduino Uno, for which I have to write raw AT commands over the SoftwareSerial
. At the moment, I just want to be able to talk to the GPRS from my PC, so I've written a really basic program to send serial in two directions:
#include <SoftwareSerial.h>
SoftwareSerial GPRS(7, 8);
void setup()
{
GPRS.begin(19200);
Serial.begin(19200);
}
void loop()
{
if (GPRS.available())
{
Serial.write(GPRS.read());
}
if (Serial.available())
{
GPRS.write(Serial.read());
}
}
So the communication looks something like this:
HW SW
+----+ Serial +-------+ Serial +------+
| | | | | |
| +--------> +--------> |
| PC | |Arduino| | GPRS |
| <--------+ <--------+ |
| | | | | |
+----+ +-------+ +------+
This seems to work fine for shorter commands:
AT+CPIN?
+CPIN: READY
OK
But I'm really interested in doing a NETSCAN
to see what networks are available. When I try it, I get this:
AT+CNETSCAN
------MOST SUITABLE CELL------
Operator:"YES OPTUS",MCC:505,75
And that's all. I pulled out a logic analyser to spy on the serial pins themselves, and it appears that the complete message is being sent back to the Arduino from the GPRS module perfectly okay - but for some reason, it gets cut off before it reaches my PC.
This is what the logic analyser sees over the SW (top two tracks) and HW (bottom tracks) serial lines:
So it appears that the entire GPRS response is being read by the Arduino before it starts to send anything back to the PC, and I assume that some sort of buffer has been overrun and I only get the start of the message.
So - how should I go about passing through long strings between serial ports like this? I assumed that using if (X.available())
instead of while
would alleviate any issues with long strings (because it appears that this way the two serial ports should take turns with one byte at a time), but is that assumption incorrect?