Buffer? - Problems when reading from SoftwareSerial

Hi!

I have a project, where I’ve to read about 500bytes of data which is returned from my GPRS device. That’s only possible for me, if I set the _SS_MAX_RX_BUFF to 256 in the softwareserial.h

If I let it at the default value of 64, I always receive garbage after a while and I am not able to read all data that comes back. Since I am only interessted in some of the data I jump over the first 220 data and than read what comes back. What am I doing wrong? What’s the best way to read, for example 500bytes of data.

That’s my function, which makes problems:

int GetHTMLResponse () {
  char c;
  char * p_config_anfang;  // Pointer zum Configstring  
  char * p_config_ende;    
  int GPRS_RespIndexer = 0;                    // Zum Positionieren der Chars in den GPRS_Response String
  unsigned long endtime = millis()+15000;      // 15 Sekunden maximal auf Antwort warten (TIMEOUT)
  int jump = 0;                                // 180 Zeichen überspringen (Header, etc...)
  int ascii;  
  boolean exit = 0;
  boolean config_found = 0;
  
  Serial.print("Empfangen:");
  while(((millis() < endtime) && GPRS_RespIndexer < 150) && !exit ) {   // 151 Zeichen haben im GPRS_Response[] Platz (150+'\0')
    if (GPRS_Serial.available()) {
      c = (unsigned char)GPRS_Serial.read(); 

      jump++;
      if (jump >= 220) {                // 220 Zeichen am Anfang des HTML Transfers überspringen, danach 150 Zeichen in String schreiben    
      
          //Serial.print(c);
          ascii = c;
          if (ascii != 10 && ascii != 13) {
            GPRS_Response[GPRS_RespIndexer] = c;            // Character in den String speichern
            GPRS_RespIndexer++;
            GPRS_Response[GPRS_RespIndexer] = '\0';         // String abschliessen, damit wir jederzeit beenden können
            if (strstr( GPRS_Response, "CLOSED" )) exit = 1;  // CLOSED im Text gefunden -> Beenden
         }
      }
    }
  }
  // Serial.print("Anzahl Zeichen:"); Serial.println(GPRS_RespIndexer);
    
  Serial.println(GPRS_Response);
  Serial.println();
}

Thank you,
Wolfi

IMO the best way is not to use SoftwareSerial for reading large amounts of data. I assume you are running on a Uno or similar and do not have a second hardware port. If you don't need to use the hardware serial receive port for sending commands from the PC to the Arduino, then you could use it to receive data from the GPRS device, provided the GPRS device can drive a 1K load to ground or +5v (because Arduino pin 1 is connected to the output of the USB to serial converter via 1k).

Hi dc42,

thank you for your answer. I’ll try to rewrite my code so, that it’ll use the hardware port for the GPRS communication and the Softserial for the status outputs (debugging).
I wonder, how people use this softwareserial? I am using 19200bps only and get problems. Are all of them transmitting very little data?

Best regards
Wolfgang

I wonder, how people use this softwareserial?

SoftwareSerial (NewSoftSerial from 0023 and earlier) works quite well for reading large amounts of data, as long as you are reading it faster than it is being generated. That is typically possible with a GPS and many other things that generate only a small amount of data, like pH probes, for instance.

With a GPRS, maybe not.

and the Softserial for the status outputs (debugging).

Not to the Serial Monitor, you won't. You really need to upgrade to a device with multiple hardware serial ports, such as the Mega which has 4.

You could try using the hardware serial port for transmitting debug data to the serial monitor, and for receiving GPRS data. Then use software serial for transmitting GPRS data. What you won't be able to do it type things into the serial monitor and read them on the Arduino.