Waveshare SIM 808 GSM GPS shied with UNO

Hey there!

I'm trying hard to get the shield working with anything else than the SoftwareSerial.h library. So fare my best approach was using the NeoSWSerial.h with the following code taken from https://forum.arduino.cc/index.php?topic=468114.0

//#define SIMCOM Serial1  /* direct connection is best  */

//#include <AltSoftSerial.h>
//AltSoftSerial SIMCOM; // 8 & 9 is second best

#include <NeoSWSerial.h>
NeoSWSerial SIMCOM( 2, 3 ); // 3rd best..

//SoftwareSerial NOT recommended

#include <NMEAGPS.h>
NMEAGPS gps;
gps_fix fix; // the parsed pieces from the GPRMC

#define DEBUG(x)      Serial.println(x)
//#define DEBUG(x)     /* to build without any debug prints */


enum state_t
  {
    WAITING,
    GPS_PWR_ON, GPS_PWR_ON_DELAY,
    GPS_PWR_OFF, GPS_PWR_OFF_DELAY,
    GPS_PKT_ON, GPS_PKT_ON_DELAY,
    GPS_PKT_OFF, GPS_PKT_OFF_DELAY,
    GET_GPS, GET_GPS_DELAY
  };

state_t  state = WAITING;
uint32_t stateTime;

void setup() {
  Serial.begin(9600);
  SIMCOM.begin(9600);
}

void loop() {

  switch (state) {

    case WAITING:
      serialClear();
      if (millis() - stateTime >= 10000) // once every 10 seconds
        state = GPS_PWR_ON;
      break;

    case GPS_PWR_ON:
      DEBUG("GPS PWR ON");
      SIMCOM.println( F("AT+CGPSPWR=1") );
      state     = GPS_PWR_ON_DELAY;
      stateTime = millis();
      break;

    case GPS_PWR_ON_DELAY:
      serialClear();
      if (millis() - stateTime >= 5000)
        state = GPS_PKT_ON;
      break;

    case GPS_PKT_ON:
      DEBUG("GPS PKT ON");
      SIMCOM.println( F("AT+CGPSOUT=1") );
      state     = GPS_PKT_ON_DELAY;
      stateTime = millis();
      break;

    case GPS_PKT_ON_DELAY:
      serialClear();
      if (millis() - stateTime >= 200)
        state = GET_GPS;
      break;

    case GET_GPS:
      if (gps.available( SIMCOM )) {
        fix = gps.read(); // received a new fix structure!

        // You might want to make sure there is valid data from the GPS.
        //     It may have bad reception, so you need to decide what to do when
        //     there is no valid data.
        // You could stay in this state until the fix becomes valid,
        //    and then send the message.  Your program could get stuck here
        //    if the GPS reception is bad.  Maybe that's what it should do.
        // Or you could go ahead and send a message without a lat/lon.
        // With the if test commented out, it will send a message now,
        //   perhaps *without* a valid lat/lon value.

        //if (fix.valid.date && fix.valid.time && fix.valid.location) {

          // What to do with the GPS data?
          Serial.print( fix.dateTime.seconds );
          Serial.print( ' ' );
          Serial.println( fix.latitude(), 6 );

          state     = GET_GPS_DELAY;
          stateTime = millis();
        //} else {
        //   ???
        //}
      }
      break;

    case GET_GPS_DELAY:
      serialClear();
      if (millis() - stateTime >= 200)
        state = GPS_PKT_OFF;
      break;

    case GPS_PKT_OFF:
      DEBUG("GPS PKT OFF");
      SIMCOM.println( F("AT+CGPSOUT=0") );
      state     = GPS_PKT_OFF_DELAY;
      stateTime = millis();
      break;

    case GPS_PKT_OFF_DELAY:
      serialClear();
      if (millis() - stateTime >= 200)
        state = GPS_PWR_OFF;
      break;

    case GPS_PWR_OFF:
      DEBUG("GPS PWR OFF");
      SIMCOM.println( F("AT+CGPSPWR=0") );
      state     = GPS_PWR_OFF_DELAY;
      stateTime = millis();
      break;

    case GPS_PWR_OFF_DELAY:
      serialClear();
      if (millis() - stateTime >= 500) {
        stateTime = millis();
        state = WAITING;
      }
      break;

  }
} // loop


void serialClear() {
  // Empty the input buffer.
  while (SIMCOM.available()) {
    char c = SIMCOM.read();
    Serial.write( c ); // to see the response, if you want
  }

//  while (Serial.available())
//    Serial.read();
}

thanks to -dev https://forum.arduino.cc/index.php?action=profile;u=165590 for the code.

My Output is:

GPS PWR ON
AT+CGPSPWR=1

OK
GPS PKT ON
AT+CGPSOUT=1

OK

Thanks in advance !
Siggi

It is not getting NMEA GPS data from the SIMCOM port. You can display what it does send by changing this:

   case GET_GPS:
      if (gps.available( SIMCOM )) {

... to this:

   case GET_GPS:
      if (SIMCOM.available()) {
        char c = SIMCOM.read();
        gps.handle  ( c ); // parse NMEA characters
        Serial.write( c ); // echo what it sent
      }
      if (gps.available()) {

This will parse the NMEA GPS data it sent AND display it on the Serial Monitor window.

If you see NMEA data like $GPRMC and $GPGGA, you may need to set the LAST_SENTENCE to something besides the default GPRMC, or make sure you have configured NeoGPS to parse the sentences it does send. Post some sample data (if any).

I have seen many questions about why this unit does NOT start sending GPS data...

SIMCOM.available() returns 0 ...
If i replace "SIMCOM.available()" by 1 it prints cryptic stuff .

Then it isn't sending any data. You'll have to research why it doesn't obey the command. I have no suggestions, except...

Be sure to read the spec for your exact model very carefully. I seem to remember that different models require additional commands.

Good point! I seems that I assumed that NMEAGPS.h can do some magic stuff.

As I interpret the description of the SIM808 it only sends data when this is triggered by "AT+CGNSINF".
I will try sending this command before each read.
Hope I will have time for that soon!

Thanks for your help!

Solved the problem. The description of the hardware in the Waveshare Wiki is a bit incomplete. At least for me. The provided files 'SIM800_Series_AT_Command_Manual_V1.09.pdf ' didn't have the needed information as well .
SIM808_GPS_Application_Note_V1.00.pdf did help.

The command: AT+CGPSOUT = has several options to control the output format.

Thank