Using a minimally modified code from tinyGPSPlus, I can draw my visible sats to tft. I want to label them as well w/SVN (ex: GPS18, GPS09, etc..) anyone know how to parse this out of the sat data?
Thx!
// XRAD'S SATELLITE TFT DISPLAY TRACKER
// Original code from Mikal Hart, found in GPS+ examples
// Modified by XRAD 4/30/22 because he wanted to see
// the overhead satellites. Hardware: NEOM8N010 GPS,
// Adafruit 3.5 tft, Teensy 4.1. The azimuth and elevation
// are used to calculate x/y position and radius on the TFT, and
// SNR is used to calculate the radious of each visable satellite.
// Higher SNR means better signal, and those satellites nearer
// to 90 degree elevation are generally higher SNR, and display
// as larger radii on the TFT...cool! Of course, you can
// do much more with the available satellite network strings.
#include <TinyGPSPlus.h>
#include <FastLED.h>//used for awesome built in timer!
#include <Adafruit_GFX.h>
#include "Adafruit_HX8357.h"//3.5" tft
//my tft control pins below. hardware MOSI,MISO,CLK as numSatrmal
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST -1 // RST can be set to -1
#define TFT_LITE 23// for control tft led brightness/on/off
#define width 480
#define height 320
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_RST);
static const int RXPin = 0, TXPin = 1;
TinyGPSPlus gps;
static const int MAX_SATELLITES = 40;
TinyGPSCustom totalGPGSVMessages(gps, "GPGSV", 1); // $GPGSV sentence, first element
TinyGPSCustom messageNumber(gps, "GPGSV", 2); // $GPGSV sentence, second element
TinyGPSCustom satsInView(gps, "GPGSV", 3); // $GPGSV sentence, third element
TinyGPSCustom satNumber[4]; // to be initialized later
TinyGPSCustom elevation[4];
TinyGPSCustom azimuth[4];
TinyGPSCustom snr[4];
struct
{
bool active;
int elevation;
int azimuth;
int snr;
} sats[MAX_SATELLITES];
void clearSatMap() {
tft.fillCircle(250, 140, 138, HX8357_BLACK);//just clear inside the GPS circle
//draw the dotted cross
for (int x = 55; x < 195; x++) {
tft.drawPixel((2 * x), 140, HX8357_GREEN);
}
for (int y = 0; y < 140; y++) {
tft.drawPixel(250, (2 * y), HX8357_GREEN);
}
}
void drawSatMap() { //draw a map w/dotted cross. numSatTE: map is numSatt centered on tft!
tft.drawRoundRect(110, 0, 280, 280, 10, HX8357_GREEN);
for (int x =28; x < 98; x++) {
tft.drawPixel((4 * x), 140, HX8357_GREEN);
}
for (int y = 0; y < 70; y++) {
tft.drawPixel(250, (4 * y), HX8357_GREEN);
}
tft.drawCircle(250, 140, 140, HX8357_GREEN);
tft.setCursor(245, 2);
tft.fillRect(245, 2, 10, 14, HX8357_BLACK);
tft.setTextColor(HX8357_GREEN); tft.setTextSize(2);
tft.println("N");
}
void setup() {
Serial.begin(115200);
Serial.flush();
tft.begin();
tft.setRotation(3);//horizontal
pinMode(TFT_LITE, OUTPUT);
digitalWrite(TFT_LITE, HIGH);//HIGH is ON, LOW is OFF
tft.fillScreen(HX8357_BLACK);
tft.setCursor(0, 80);
tft.setTextSize(2);
tft.setTextColor(HX8357_WHITE);
tft.println(" XRAD'S SATELLITE TFT TRACKER");
delay(2000);
tft.fillScreen(HX8357_BLACK);
drawSatMap();
Serial1.begin(9600);//my GPS device uses 9600 baud, using teensy Serial1
delay(100);
Serial.print("XRAD'S SATELLITE TRACKER");
Serial.println();
// Initialize all the uninitialized TinyGPSCustom objects
for (int i = 0; i < 4; ++i) {
satNumber[i].begin(gps, "GPGSV", 4 + 4 * i); // offsets 4, 8, 12, 16
elevation[i].begin(gps, "GPGSV", 5 + 4 * i); // offsets 5, 9, 13, 17
azimuth[i].begin( gps, "GPGSV", 6 + 4 * i); // offsets 6, 10, 14, 18
snr[i].begin( gps, "GPGSV", 7 + 4 * i); // offsets 7, 11, 15, 19
}
}
void loop() {
if (Serial1.available() > 0)// This is teensy hardware serial 1
{
gps.encode(Serial1.read());
if (totalGPGSVMessages.isUpdated())//just GPS sats
{
for (int i = 0; i < 4; ++i)
{
int numSat = atoi(satNumber[i].value());
if (numSat >= 1 && numSat <= MAX_SATELLITES)
{
sats[numSat - 1].elevation = atoi(elevation[i].value());
sats[numSat - 1].azimuth = atoi(azimuth[i].value());
sats[numSat - 1].snr = atoi(snr[i].value());
sats[numSat - 1].active = true;
}
}
int totalMessages = atoi(totalGPGSVMessages.value());
int currentMessage = atoi(messageNumber.value());
int A = 0;//angle 0-360
int r = 0;//0 to 120
if (totalMessages == currentMessage) {
for (int i = 0; i < MAX_SATELLITES; ++i)
if (sats[i].active) {
//Serial.print(F(" Elevation="));
//Serial.print(F(" "));
//Serial.print(sats[i].elevation);
r = (sats[i].elevation); //convert to radius for satellite location
//Serial.print(F(" "));
int plotR = map(r, 0, 90, 130, 0);//map elevation to tft radius
//Serial.print(F(" Azimuth="));
//Serial.print(sats[i].azimuth);
A = (sats[i].azimuth);//A is the angle which is converted to x,y
A = A-90;//this is correction factor to rotate around plot axis to align w/numSatrth
//Serial.print(F(" "));
//Serial.print(F(" SNR="));
//Serial.print(sats[i].snr);
//Serial.print(F(" NEXT SATELLITE: "));
int val = (sats[i].snr);
int miniR = map(val, 0, 120, 1, 30);//map SNR to mini radius of each satellite
if (r <= 130) {//don't draw outside the satellite map!
//numSatw let's take the three elements from above and draw them on tft
//with adafruit draw circle gfx routine!!
tft.fillCircle( 250 + (plotR) * cos((A) * PI / 180 ), 140 + plotR * sin((A) * PI / 180 ), miniR, HX8357_WHITE);
}
}
Serial.println();
for (int i = 0; i < MAX_SATELLITES; ++i)
sats[i].active = false;
}
}
}
EVERY_N_SECONDS(10) {//clear the old data off the tft every 'x' seconds
//clearSatMap();
drawSatMap();
}
}