2

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:

enter image description here

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?

1

The output of the logic analyser is pretty clear. The problem will be a buffer overflow. One question is whether it is the receive buffer or the send buffer.

My best guess is the receive buffer: What could go wrong with your code is that the interrupts used by SoftwareSerial take precedence over the ones used by HardwareSerial. So maybe that's the reason why nothing is sent before the full message is received.

The SoftwareSerial library has a debug flag (_DEBUG) which you can enable to pulse a pin as an overflow indictator.

What I would try is to swap Software- and HardwareSerial (i.e. use SoftwareSerial for the communication with the PC). If the problem is as described above it should then vanish because the HardwareSerial does not block interrupts (nor the program flow) while receiving a byte.

  • Using software serial to PC appears difficult as far as I can tell! Is there a good guide somewhere? My other possibility is trying to get my hands on a Leo, or any other board with more hardware serials. – Daniel Buckmaster Mar 28 '15 at 11:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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