Tiny GPS++ Satellite Numbers

Hi everyone
I want to derive connected GPS satellite's PRNs using Arduino. So I tried this sketch in my knowledge with the help of TinyGPS++ library and its examples.

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);
TinyGPSCustom totalGPGSVMessages(gps, "GPGSV", 1);
TinyGPSCustom messageNumber(gps, "GPGSV", 2);
TinyGPSCustom prn[12];
struct {
  int prn;
} sats[12];

void setup() {
  Serial.begin(115200);
  ss.begin(9600);
  for (int i = 3; i < 15; i++) {
    prn[i].begin(gps, "GNGSA", i);
  }
}

void loop() {
  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while (true);
  }
  while (ss.available() > 0)
    if (gps.encode(ss.read()))
      if (totalGPGSVMessages.isUpdated())
      {
        int no = gps.satellites.value();
        if (no >= 1 && no <= 12)
        {
          sats[no].prn = atoi(prn[no].value());
        }
        int totalMessages = atoi(totalGPGSVMessages.value());
        int currentMessage = atoi(messageNumber.value());
        if (totalMessages == currentMessage)
        {
          Serial.print(F(" Nums="));
          for (int i = 0; i < 12; ++i) {
            Serial.print(sats[i].prn);
            Serial.print(F(" "));
          }
        }
  }
}

basically $GNGSA NMEA sentence has connected satellite PRNs as follows,

$GNGSA,A,3,29,23,24,18,15,22,,,,,,,1.53,0.71,1.35*1F

here from 3 to 12 are (29,23,...) PRNs and I tried to store them in array but its not works. I haven't advance knowledge about this type of programming. So how can I do this. I want to get PRN numbers from this NMEA sentence. I am hoping your help.

Thank You.

I don't know anything about TinyGPS, but I do know prn only has 12 elements.

The number of satellites above the horizon (from $GNGSV) can be higher than 12. The number of 'active' satellites (from $GNGSA) is limited to 12. Which PRN numbers did you want?

Have you looked at the TinyGPS++ example called "SatelliteTracker"?

@johnwasser
Yes. I want to all PRN Numbers which are available. I tried using Satellite Tracker example. But couldn't get solution. can you give me solution?

What did you get from the SatelliteTracker example and how was that different from what you want?

@johnwasser
my sketch was developed using Satellite tracker example. Satellite tacker using GPGSV and I want to derive from GNGSA. Those have different structure in NMEA format. simply I want to derive 3rd to 14th elements from GNGSA sentence and store them into array.

Explain what you expected to happen, and what happened instead.

It will work much better to parse the GNGSA sentence yourself, rather than try to make TinyGPS do it. And that way, you understand how everything works. The code should be simpler, too.

Does this do what you want?

// Based on the TinyGPS++ "SatelliteTracker" example but listing the PRN's of the 'Active' 
// satellites reported by the $GNGSA messages rather than the 'Visible' satellites reported 
// by the $GNGSV messages 

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);

TinyGPSCustom gngsa[12] =
{
  {gps, "GNGSA", 3},
  {gps, "GNGSA", 4},
  {gps, "GNGSA", 5},
  {gps, "GNGSA", 6},
  {gps, "GNGSA", 7},
  {gps, "GNGSA", 8},
  {gps, "GNGSA", 9},
  {gps, "GNGSA", 10},
  {gps, "GNGSA", 11},
  {gps, "GNGSA", 12},
  {gps, "GNGSA", 13},
  {gps, "GNGSA", 14}
};

static const int MAX_SATELLITES = 12;
int prns[MAX_SATELLITES];

void setup()
{
  Serial.begin(115200);
  ss.begin(GPSBaud);

  Serial.println(F("ActiveSatellites.ino"));
  Serial.println();
}

void loop()
{
  // Dispatch incoming characters
  if (ss.available() > 0)
  {
    char c = ss.read();
    Serial.write(c);  // Echo all GPS traffic
    if (gps.encode(c))
    {
      // Something was encoded
      if (gngsa[0].isUpdated())
      {
        // A $GNGSA message (ctive Satellites)
        
        // Gather the PRN numbers of the active satellites
        for (int i = 0; i < MAX_SATELLITES; ++i)
        {
          prns[i] = -1;
          if (gngsa[i].isValid())
          {
            prns[i] = atoi(gngsa[i].value());
          }
        }

        // Display all the active PRN nunbers
        for (int i = 0; i < MAX_SATELLITES; ++i)
        {
          if (prns[i] != -1)
          {
            Serial.print(prns[i]);
            Serial.print(F(" "));
          }
        }
        Serial.println();
      }  // End of $GNGSA processing

    } // End of gps.encode()
  }  // End of ss.available()
}

@johnwasser
Yes. I was tried several times not get solution. You are the man. Thank you very much. :slightly_smiling_face: