// GPS TRACKER PROGRAM EXAMPLE - VERSION 2.65 // FOR GPS EXPERIMENTATION // CODE DISPLAYS UTC TIME, NUMBER OF SATs, LATITUDE, LONGTITUDE & MAIDENHEAD LOCATOR // GOOD FOR PORTABLE HAM RADIO CLOCK or OTHER APPLICATIONS // Simply added a timer function to count the time till the GPS module gets its first // info from the Satellites AND used different OLED Library and Screen layout. // Simply to match more tastes! // PORTIONS OF CODE TAKEN FROM MANY PLACES and LIBRARY EXAMPLES. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation,version 3 of the License. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Based on ATMEGA328P AVR WITH 8 MHz EXTERNAL CRYSTAL // Using SV1AFN's GPS from APRS1 board // Programming through ISP port ON BOARD // Bootloader has been installed using Arduino as ISP Programmer // OLED connected to I2C port #include #include //https://github.com/olikraus/u8x82lib #include //https://github.com/mikalhart/TinyGPSPlus U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); // Good for 128 x 64 0.94 inch I2C WHITE or YELLOW-BLUE OLED // OLED CONNECTS TO I2C PINS SDA & SCL TOP LEFTMOST PINS ON BOARD, +V3.3 & GND PINS 2 & 6 ON ISP CONNECTOR TinyGPSPlus gps; // GPS uses UART's D0, D1 Rx - Tx pins, Baud rate is set @9600 at setup section unsigned long lastTx = 0; char nw, wl; float lastTxLat = 0.00; float lastTxLng = 0.00; float lastTxdistance = 0.0; int previousHeading = 400; int lastbearing = 0; int headingDelta, lastheadingDelta = 0; byte hour = 0, minute = 0, second = 0; int sats = 0; unsigned long secondtimer = 0; unsigned long timer = 0; //int buttonState = 0; //const int buttonPin = 8; // BUTTON GOOD FOR EXTRA PROGRAMMABLE FEATURES - CONNECTS TO S1 and +V3.3 ON BOARD //====================================================================================================== void setup() { Serial.begin(9600); // BEGIN UART @9600 BPS u8x8.begin(); } //====================================================================================================== void loop() { { if (millis() - secondtimer >= 1000) { second++; secondtimer = millis(); if (second == 60) { second = 0; minute++; if (minute == 60) { minute = 0; hour++; if (hour == 24) { hour = 0; } } } } } while (Serial.available() > 0) { gps.encode(Serial.read()); } if ( gps.time.isUpdated() ) { hour = gps.time.hour(); minute = gps.time.minute(); second = gps.time.second(); } { sats = gps.satellites.value(); } //================================== Triggered by gps location updates ================================ if ( gps.location.isUpdated() ) { lastTxdistance = TinyGPSPlus::distanceBetween( gps.location.lat(), gps.location.lng(), lastTxLat, lastTxLng); lastbearing = (int)TinyGPSPlus::courseTo( lastTxLat, lastTxLng, gps.location.lat(), gps.location.lng()); nw = gps.location.rawLat().negative ? 'S' : 'N'; wl = gps.location.rawLng().negative ? 'W' : 'E'; // Get headings and heading delta headingDelta = abs(lastbearing - (int)gps.course.deg()); if (headingDelta > 180) { headingDelta = 360 - headingDelta; } lastheadingDelta = abs(lastbearing - previousHeading); if (lastheadingDelta > 180) { lastheadingDelta = 360 - lastheadingDelta; } } // endof gps.location.isUpdated() //======================= CONVERSION OF GPS CO-ORDINATES TO MAIDENHEAD LOCATOR ======================== long latt, lonn; lonn = (gps.location.lng() * 100000) + 18000000; // Step 1 latt = (gps.location.lat() * 100000) + 9000000; // Adjust so Locn AA is at the pole char MH[6] = {'A', 'A', '0', '0', 'a', 'a'}; // Initialise our print string MH[0] += lonn / 2000000; // Field MH[1] += latt / 1000000; MH[2] += (lonn % 2000000) / 200000; // Square MH[3] += (latt % 1000000) / 100000; MH[4] += (lonn % 200000) / 8333; // Subsquare .08333 is 5/60 MH[5] += (latt % 100000) / 4166; // .04166 is 2.5/60 String MH_txt = ""; // Build up Maidenhead into a string that's easy to print int i = 0; while (i < 6) { MH_txt += MH[i]; i++; } // endof Maidenhead calculation //======================================== OLED DISPLAY =============================================== u8x8.setFont(u8x8_font_8x13_1x2_r); u8x8.inverse(); u8x8.setCursor(1,0); u8x8.print(F("UTC: ")); if (hour < 10) u8x8.print(F("0")); u8x8.print(hour); u8x8.print(F(":")); if (minute < 10) u8x8.print(F("0")); u8x8.print(minute); u8x8.print(F(":")); if (second < 10) u8x8.print(F("0")); u8x8.print(second); u8x8.noInverse(); u8x8.setFont(u8x8_font_chroma48medium8_r); u8x8.setCursor(0, 3); u8x8.print(F("LOCATOR: ")); u8x8.print(MH_txt); u8x8.setCursor(0, 4); u8x8.print(F("LAT : ")); u8x8.print(gps.location.lat(), 6); u8x8.setCursor(0, 5); u8x8.print(F("LONG: ")); u8x8.print(gps.location.lng(), 6); u8x8.setCursor(3, 7); u8x8.print(F("# SATs: ")); if (sats <10) u8x8.print(F("0")); u8x8.print(sats); }