// Tiny GPS by Mike Hart //Modified by Brendan Fellows & Kin Bou #include #include #include /* This code Controls //an Adafruit Ultimate GPS Breakout Board //an Adafruit BMP085 Barometric Pressure/Temp & Altitude sensor // A Piesto Buzzer //A Radiometrix TX2H-434-65-5V Transmitter //A Radiometrix NRX2-434-65 Receiver //And sends this data out via RTTY to be decoded */ TinyGPS gps; Adafruit_BMP085 bmp; int RADIO_SPACE_PIN=2; int RADIO_MARK_PIN=3; char DATASTRING[500]; char temp_flat[20]; char temp_flon[20]; char temp_falt[20]; unsigned long comp_time = 0; struct position_record // Total 25 bytes { unsigned int sequence_no; // 2 bytes uint8_t hour; // 1 byte uint8_t minute; // 1 byte uint8_t second; // 1 byte float latitude; // 4 bytes float longitude; // 4 bytes unsigned int altitude; // 2 bytes unsigned int velocity; // 2 bytes uint8_t sats; // 1 byte int8_t temp1; // Internal // 1 byte int8_t temp2; // External // 1 byte int8_t custom[5]; // 5 bytes }; position_record record1 = {0,0,0,0, 0.0,0.0, 0,0,0,0,0, {0,0,0,0,0}};//{0,1,2,3, -33.1234, 138.2345, 40575,200,10,4,-5, {0,0,0,0,0}}; static void gpsdump(TinyGPS &gps); static bool feedgps(); static void print_float(float val, float invalid, int len, int prec); static void print_int(unsigned long val, unsigned long invalid, int len); static void print_date(TinyGPS &gps); static void print_str(const char *str, int len); char txBuffer[128]; char debugBuffer[128]; char latString[12]; char longString[12]; void setup() { if (!bmp.begin()) { Serial.println("Could not find a valid BMP085 sensor, check wiring!"); while (1) {} } pinMode(RADIO_SPACE_PIN,OUTPUT); pinMode(RADIO_MARK_PIN,OUTPUT); pinMode(11, OUTPUT); // speaker on pin 11 Serial.begin(9600); Serial1.begin(9600); rtty_txstring("GPS initialized, "); rtty_txstring("by Brendan Fellows.\n"); Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version()); Serial.println("Stratos Afterlife Version"); Serial.println("Modified by Brendan Fellows"); Serial.println("Original Program by Mikal Hart"); Serial.println(); Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS)); Serial.println(); Serial.println("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum"); Serial.println(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to Peak Hill ---- RX RX Fail"); Serial.println("-----------------------------------------------------------------------------------------------------------------------------------------"); } int del = 200; // for tone length int lowrange = 4000; // the lowest frequency value to use int highrange = 9000; // the highest... void loop() { // increasing tone for (int a = lowrange; a<=highrange; a++) { tone (11, a, del); } // decreasing tone for (int a = highrange; a>=lowrange; a--) { tone (11, a, del); } bool newdata = false; unsigned long start = millis(); // Every second we print an update while (millis() - start < 1000) { if (feedgps()) newdata = true; } comp_time = millis() / 1000; Serial.print("Temperature = "); Serial.print(bmp.readTemperature()); Serial.println(" *C"); Serial.print("Pressure = "); Serial.print(bmp.readPressure()); Serial.println(" Pa"); // Calculate altitude assuming 'standard' barometric // pressure of 1013.25 millibar = 101325 Pascal Serial.print("Altitude = "); Serial.print(bmp.readAltitude()); Serial.println(" meters"); // you can get a more precise measurement of altitude // if you know the current sea level pressure which will // vary with weather and such. If it is 1015 millibars // that is equal to 101500 Pascals. Serial.print("Real altitude = "); Serial.print(bmp.readAltitude(100690)); Serial.println(" meters"); Serial.println(); delay(500); gpsdump(gps); delay(1000); getGPS(); //polls the GPS and parses the data into the GPS data variables genSentence(); //takes the data and generates a sentence for transmission (eg; $$HUTTON,1,03:47:22,35.40024,-40.12334,6,10,0,0,0) } static void gpsdump(TinyGPS &gps) { float flat, flon, falt; unsigned long age, date, time, chars = 0; unsigned short sentences = 0, failed = 0; static const float PEAK_HILL_LAT = -32.7409, PEAK_HILL_LON = 148.2204; print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5); print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5); gps.get_datetime(&date,&time); gps.f_get_position(&flat, &flon, &age); print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 11, 5); print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 5); print_int(age, TinyGPS::GPS_INVALID_AGE, 5); print_date(gps); falt = gps.f_altitude(); print_float(falt, TinyGPS::GPS_INVALID_F_ALTITUDE, 8, 2); print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2); print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2); print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6); print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0UL : (unsigned long)TinyGPS::distance_between(flat, flon, PEAK_HILL_LAT, PEAK_HILL_LON) / 1000, 0xFFFFFFFF, 9); print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : TinyGPS::course_to(flat, flon, -32.7409, 148.2204), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2); print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, PEAK_HILL_LAT, PEAK_HILL_LON)), 6); gps.stats(&chars, &sentences, &failed); print_int(chars, 0xFFFFFFFF, 6); print_int(sentences, 0xFFFFFFFF, 10); print_int(failed, 0xFFFFFFFF, 9); Serial.println(); record1.sequence_no++; sprintf(DATASTRING, "Time running: %d sec", comp_time); rtty_txstring(DATASTRING); dtostrf(flat, 3, 4, temp_flat); dtostrf(flon, 3, 4, temp_flon); dtostrf(falt, 7, 4, temp_falt); sprintf(DATASTRING, " Alt: %s m \n", temp_falt); rtty_txstring(DATASTRING); sprintf(DATASTRING, "$$SAT1,%u,%02u:%02u:%02d,%s,%s,%u,%u,%u,\n" , record1.sequence_no, record1.hour, record1.minute, record1.second, temp_flat, temp_flon, record1.altitude, record1.velocity, record1.sats); rtty_txstring(DATASTRING); } static void print_int(unsigned long val, unsigned long invalid, int len) { char sz[32]; if (val == invalid) strcpy(sz, "*******"); else sprintf(sz, "%ld", val); sz[len] = 0; for (int i=strlen(sz); i 0) sz[len-1] = ' '; Serial.print(sz); feedgps(); } static void print_float(float val, float invalid, int len, int prec) { char sz[32]; if (val == invalid) { strcpy(sz, "*******"); sz[len] = 0; if (len > 0) sz[len-1] = ' '; for (int i=7; i= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1; for (int i=flen; i23) digitalWrite(4,HIGH); //Uncomment this line during Daylight Savings if (digitalRead(4)==HIGH) // if the user has set the switch for daylight-savings time { --hour; } { hour=hour+1; } if (hour>23) day=day+1; if (hour=24) hour=0; if (age == TinyGPS::GPS_INVALID_AGE) Serial.print("******* ******* "); else { char sz[32]; sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ", day, month, year, hour, minute, second); Serial.print(sz); } print_int(age, TinyGPS::GPS_INVALID_AGE, 5); feedgps(); } static void print_str(const char *str, int len) { int slen = strlen(str); for (int i=0; i> 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); } 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]; } return crc; } void getGPS() { // get the GPS data gps.f_get_position(&record1.latitude, &record1.longitude); record1.sats = (uint8_t)gps.satellites(); record1.altitude = (unsigned int)gps.f_altitude(); record1.velocity = (unsigned int)gps.f_speed_kmph(); gps.crack_datetime(0, 0, 0, &record1.hour, &record1.minute, &record1.second); } void genSentence() { if(record1.sats != 0){ dtostrf(record1.latitude, 11, 5, latString); dtostrf(record1.longitude, 11, 5, longString); } }