I'm using a GPS with a transmitter for a high altitude balloon project. I want the code to work as follows:
- The GPS has a lock - the transmitter sends the relevant GPS data
- The GPS doesn't have a lock - the transmitter sends "Acquiring signal..." or similar message until GPS gets a lock
Case 1 works fine, when the GPS has a lock it transmits GPS data.
In trying to implement case 2, the transmitter repeatedly sends "Acquiring signal..." regardless of whether the GPS has a lock or not. I thought, maybe it's sending the message so often, the rest of the program doesn't have time to check if the GPS has a lock, so I implemented the following snippet of code to have the program only send "Acquiring signal..." every minute:
TinyGPS gps;
unsigned long check_GPS_fix = 0;
gps.f_get_position(¤t_lat, ¤t_lon, &fix_age);
if (fix_age == TinyGPS::GPS_INVALID_AGE && ((check_GPS_fix - millis()) > 60000)) {
rtty_txstring("Acquiring signal\n"); //rtty_txstring is just a function that operates the transmitter. You can think of it as Serial.print
check_GPS_fix = millis();
}
However, if you look closely, I implemented it wrong, as the second condition should be millis()-check_GPS_fix. Hence, the way it is written, the program should never enter this if statement. But it does! And it keeps sending "Acquiring signal" repeatedly, with no break between messages.
Earlier I tried setting up this functionality as follows:
TinyGPS gps;
if (gps.encode(<insert byte of serial data here>)) {
//Get your GPS data here, send it along
}
else {
rtty_txstring("Acquiring signal\n");
}
But, as before, all I got was "Acquiring signal" on the radio.
I know the GPS has a lock because I can upload a sketch to just read GPS data through the serial monitor and I can see that it has a lock. We were outside so it had a clear view of the sky. Once I switched back to the radio sketch though, just back to "Acquiring signal"
So this leads ultimately to my question: How can I use TinyGPS to find out if the GPS unit has a signal lock or not and send that information in such a way that once it does get a lock, I can switch to transmitting GPS coordinates? Also, why the hell is it entering an if statement whose conditions have not been met? And don't tell me Murphy's law, because Murphy says anything that CAN go wrong will, but this is something that theoretically can't go wrong!!!!! ![]()
Below is the rest of my code, I wouldn't worry too much about rtty_txstring and rtty_txbyte since they just operate the radio and they work regardless of what data gets sent to them.
/*
Radio Data Transmission
Transmits data via Radiometrix NTX2
Created 2011
by Upu http://ava.upuaut.net
RTTY code from Rob Harrison Icarus Project.
Modified 2011
by Nickolai http://www.nickolai.me for Project HAL
*/
//#include <NewSoftSerial.h>
//NewSoftSerial nss(3,4);
#include <SoftwareSerial.h>
SoftwareSerial nss = SoftwareSerial(3,4);
#include <TinyGPS.h>
TinyGPS gps;
#include <SD.h>
int RADIO_SPACE_PIN=6;
int RADIO_MARK_PIN=7;
char DATASTRING[500];
char SDcardbuffer[6000];
char GPSbyte;
float current_altitude = 0;
float current_lat = 0;
float current_lon = 0;
float current_speed = 0;
unsigned long fix_age = 0;
unsigned long time = 0;
unsigned long comp_time = 0;
unsigned long date = 0;
int writestart = 0;
int writetime = 0;
char writemessage[50];
unsigned long check_GPS_fix = 0;
int i = 0;
int j = 0;
void setup()
{
pinMode(RADIO_SPACE_PIN,OUTPUT);
pinMode(RADIO_MARK_PIN,OUTPUT);
nss.begin(4800);
if (!SD.begin(10))
{
rtty_txstring("Card failed or not present");
}
rtty_txstring("Card initialized");
}
void loop()
{
comp_time = millis() / 1000;
GPSbyte = nss.read();
SDcardbuffer[j] = GPSbyte;
j++;
if (gps.encode(GPSbyte)) {
current_altitude = gps.f_altitude();
gps.get_datetime(&date,&time,&fix_age);
gps.f_get_position(¤t_lat, ¤t_lon, &fix_age);
// if (fix_age == TinyGPS::GPS_INVALID_AGE) {
// rtty_txstring("Acquiring signal");
// }
sprintf(DATASTRING, "Time running: %d sec, Lat: %f, Lon: %f, Alt: %f m, Fix age: %d\n",comp_time,current_lat, current_lon, current_altitude, fix_age);
rtty_txstring(DATASTRING);
if (GPSbyte == 10 && j > 900) {
writestart = millis();
writetoSD("RESULTS.TXT", SDcardbuffer);
j = 0;
writetime = millis() - writestart;
sprintf(writemessage, "Write time was: %d milliseconds",writetime);
rtty_txstring(writemessage);
}
}
if (GPSbyte == 10 && j > 900) {
writestart = millis();
writetoSD("RESULTS.TXT", SDcardbuffer);
j = 0;
writetime = millis() - writestart;
sprintf(writemessage, "Write time was: %d milliseconds",writetime);
rtty_txstring(writemessage);
}
//gps.f_get_position(¤t_lat, ¤t_lon, &fix_age);
//if (((check_GPS_fix - millis()) > 60000)) {
// rtty_txstring("Acquiring signal\n");
// check_GPS_fix = millis();
//}
}
void rtty_txstring (char * string)
{
/* Simple function to sent a char at a time to
** rtty_txbyte function.
** NB Each char is one byte (8 Bits)
*/
char c;
c = *string++;
while ( c != '\0')
{
rtty_txbyte (c);
c = *string++;
}
}
void rtty_txbyte (char c)
{
/* Simple function to sent each bit of a char to
** rtty_txbit function.
** NB The bits are sent Least Significant Bit first
**
** All chars should be preceded with a 0 and
** proceded with a 1. 0 = Start bit; 1 = Stop bit
**
*/
int i;
rtty_txbit (0); // Start bit
// Send bits for for char LSB first
for (i=0;i<7;i++) // Change this here 7 or 8 for ASCII-7 / ASCII-8
{ if (c & 1) rtty_txbit(1); else rtty_txbit(0); c = c >> 1;
}
rtty_txbit (1); // Stop bit
}
void rtty_txbit (int bit)
{
if (bit)
{
// high
digitalWrite(RADIO_MARK_PIN, HIGH);
digitalWrite(RADIO_SPACE_PIN, LOW);
}
else
{
// low
digitalWrite(RADIO_SPACE_PIN, HIGH);
digitalWrite(RADIO_MARK_PIN, LOW);
}
// delayMicroseconds(1680); // 600 baud unlikely to work.
//delayMicroseconds(3375); // 300 baud
delayMicroseconds(10000); // For 50 Baud uncomment this and the line below.
delayMicroseconds(10150); // For some reason you can't do 20150 it just doesn't work.
}
void callback()
{
digitalWrite(RADIO_SPACE_PIN, digitalRead(RADIO_SPACE_PIN) ^ 1);
}
void writetoSD(char* filename, char* buffer)
{
File datafile = SD.open(filename, FILE_WRITE);
if (datafile)
{
datafile.println(buffer);
}
datafile.close();
}
//uint16_t gps_CRC16_checksum (char *string)
//{
// size_t i;
// uint16_t crc;
// uint8_t c;
//
// crc = 0xFFFF;
//
// // Calculate checksum ignoring the first two $s
// for (i = 2; i < strlen(string); i++)
// {
// c = string[i];
// crc = _crc_xmodem_update (crc, c);
// }
//
// return crc;
//}