diff --git a/GPS_Dog_Collar/GPS_Dog_Collar/GPS_Dog_Collar.ino b/GPS_Dog_Collar/GPS_Dog_Collar/GPS_Dog_Collar.ino new file mode 100644 index 000000000..afb5bc914 --- /dev/null +++ b/GPS_Dog_Collar/GPS_Dog_Collar/GPS_Dog_Collar.ino @@ -0,0 +1,319 @@ +#define OLED_DC 6 //Atmega32u4 Breakout Pin D7 +#define OLED_CS 9 //Atmega32u4 Breakout Pin B5 +#define OLED_CLK 5 //Atmega32u4 Breakout Pin C6 +#define OLED_MOSI 4 //Atmega32u4 Breakout Pin D4 (Pin on OLED labeled DATA) +#define OLED_RESET 8 //Atmega32u4 Breakout Pin B4 + +//Connect GPS TX to Atmega32u4 Breakout Pin B7 (Leonardo Pin D10) +//Connect GPS RX to Atmega32u4 Breakout Pin B6 (Leonardo Pin D11) + +#include + +#include +#include +#include +#include + +Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); + +#define NUMFLAKES 10 +#define XPOS 0 +#define YPOS 1 +#define DELTAY 2 + +/* This sample code demonstrates the normal use of a TinyGPS object. + It requires the use of SoftwareSerial, and assumes that you have a + 4800-baud serial GPS device hooked up on pins 3(rx) and 4(tx). +*/ + +TinyGPS gps; +SoftwareSerial nss(11, 10); + +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); + +//ENTER YOUR DESIRED DISTANCE GOAL (IN MILES) +//------------------------------------------------------------------------------- +float GOAL = 3; //Distances can include decimal points +//------------------------------------------------------------------------------- + +// Maximum speed and last known position +float maxSpeed = 0; +float lastFlat = 0; +float lastFlon = 0; +long totalDistance = 0; + +boolean start = 1; +int i = 0; + +void setup() +{ + Serial.begin(9600); + nss.begin(9600); + + // by default, we'll generate the high voltage from the 3.3v line internally! (neat!) + display.begin(SSD1306_SWITCHCAPVCC); + // init done + + display.clearDisplay(); + display.display(); +} + +void loop() +{ + bool newdata = false; + unsigned long start = millis(); + + // Every second we print an update + while (millis() - start < 1000) + { + if (feedgps()) + newdata = true; + } + + gpsdump(gps); +} + +static void gpsdump(TinyGPS &gps) +{ + float flat, flon; + unsigned long age, date, time, chars = 0; + unsigned short sentences = 0, failed = 0; + + gps.f_get_position(&flat, &flon, &age); + + //print_date(gps); + + //gps.stats(&chars, &sentences, &failed); + //print_int(chars, 0xFFFFFFFF, 6); + //print_int(sentences, 0xFFFFFFFF, 10); + //print_int(failed, 0xFFFFFFFF, 9); + //Serial.println(); + + if (gps.f_speed_kmph() > 3.9) + { + if (start == 1) + { + start = 0; + lastFlat = flat; + lastFlon = flon; + } + else + { + //totalDistance = gps.distance_between(flat, flon, LONDON_LAT, LONDON_LON); + totalDistance = totalDistance + calc_dist(flat, flon, lastFlat, lastFlon); + lastFlat = flat; + lastFlon = flon; + } + } + + display.clearDisplay(); + + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(0,0); + + float fDist = totalDistance; + //convert meters to miles + fDist *= 0.000621371192; + //float fSpeed = gps.f_speed_kmph(); + printLCDFloat(fDist, 2); + display.print(" Miles ("); + + float targetDist = fDist / GOAL; + + printLCDFloat(targetDist*100, 0); + display.print("%)"); + + display.drawLine(0, 12, 0, 31, WHITE); + + display.drawLine(63, 28, 63, 31, WHITE); + display.drawLine(127, 12, 127, 31, WHITE); + display.drawLine(31, 28, 31, 31, WHITE); + + display.drawLine(95, 28, 95, 31, WHITE); + display.drawLine(0, 28, 127, 28, WHITE); + display.drawLine(0, 12, 127, 12, WHITE); + + display.fillRect(2, 14, (124 * targetDist), 13, 1); + + if (gps.hdop() > 2000) { + //display.fillRect(2, 14, (124), 13, BLACK); + display.fillRect(0, 0, 128, 32, BLACK); + display.fillCircle(6, 6, 2, WHITE); + display.fillCircle(64, 6, 2, WHITE); + display.fillCircle(122, 6, 2, WHITE); + display.fillCircle(35, 6, 2, WHITE); + display.fillCircle(93, 6, 2, WHITE); + + if (i==0){ + display.drawCircle(6, 6, 4, WHITE); + } + if (i==1){ + display.drawCircle(35, 6, 4, WHITE); + } + if (i==2){ + display.drawCircle(64, 6, 4, WHITE); + } + if (i==3){ + display.drawCircle(93, 6, 4, WHITE); + } + if (i==4){ + display.drawCircle(122, 6, 4, WHITE); + i = 0; + } else { + i++; + } + + display.setTextColor(WHITE); + display.setCursor(5,20); + display.print("Acquiring Satellites"); + } + + display.display(); +} + +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; i 0) + display.print("."); + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + int toPrint = int(remainder); + ltoa(toPrint, sTemp, 10); + display.print(sTemp); + remainder -= toPrint; + } +} + +static void print_date(TinyGPS &gps) +{ + int year; + byte month, day, hour, minute, second, hundredths; + unsigned long age; + gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age); + if (age == TinyGPS::GPS_INVALID_AGE) + Serial.print("******* ******* "); + else + { + char sz[32]; + sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ", + month, day, 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