Skip to content

Commit bce1b85

Browse files
authored
Merge pull request #679 from adafruit/TheKitty-patch-36
Create Track_Your_Treats.ino
2 parents 8ed784a + 53c4590 commit bce1b85

1 file changed

Lines changed: 166 additions & 0 deletions

File tree

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
// Track Your Treats - Ultimate GPS Shield Halloween Candy Route Tracker
2+
// Author: Tony DiCola
3+
//
4+
// See the guide at:
5+
// https://learn.adafruit.com/track-your-treats-halloween-candy-gps-tracker/overview
6+
//
7+
// Released under a MIT license:
8+
// https://opensource.org/licenses/MIT
9+
#include <SPI.h>
10+
#include <Adafruit_GPS.h>
11+
#include <SoftwareSerial.h>
12+
#include <SD.h>
13+
14+
15+
// Configuration (you don't normally need to change these values):
16+
17+
#define LED_PIN 6 // Pin connected to an LED that flashes the status of the project.
18+
19+
#define BUTTON_PIN 5 // Pin connected to the button.
20+
21+
#define LOGGING_PERIOD_SEC 15 // Seconds to wait between logging GPS locations.
22+
23+
#define GPS_RX_PIN 8 // GPS receiver RX (pin 8 on the shield).
24+
25+
#define GPS_TX_PIN 7 // GPS receiver TX (pin 7 on the shield)
26+
27+
#define SD_CS_PIN 10 // Chip select pin for SD card.
28+
29+
30+
// Global state (you don't need to change these values):
31+
SoftwareSerial gpsSerial(GPS_RX_PIN, GPS_TX_PIN); // Software serial connection to GPS receiver.
32+
Adafruit_GPS GPS(&gpsSerial); // GPS class to interact with receiver.
33+
File logfile; // SD card log file.
34+
uint32_t logCounter = 0; // Counter until next location log is recorded.
35+
36+
37+
// Halt function called when an error occurs. Will print an error and stop execution while
38+
// doing a fast blink of the LED. If the watchdog is enabled it will reset after 8 seconds.
39+
void halt(const __FlashStringHelper *error) {
40+
Serial.println(error);
41+
while (1) {
42+
digitalWrite(LED_PIN, LOW);
43+
delay(100);
44+
digitalWrite(LED_PIN, HIGH);
45+
delay(100);
46+
}
47+
}
48+
49+
// Timer interrupt called every millisecond to check for new data from the GPS.
50+
SIGNAL(TIMER0_COMPA_vect) {
51+
// Check for new GPS data.
52+
GPS.read();
53+
// Decrease the count since last location log.
54+
if (logCounter > 0) {
55+
logCounter--;
56+
}
57+
}
58+
59+
// Log the current GPS location with the specified note.
60+
void logLocation(const char* note) {
61+
logfile.print(GPS.latitudeDegrees, 6);
62+
logfile.print(',');
63+
logfile.print(GPS.longitudeDegrees, 6);
64+
logfile.print(',');
65+
logfile.print(note);
66+
logfile.println();
67+
logfile.flush();
68+
}
69+
70+
void setup() {
71+
// Initialize serial port.
72+
Serial.begin(115200);
73+
Serial.println(F("Track your Treats - Ultimate GPS Shield"));
74+
75+
// Initialize LED and button.
76+
pinMode(LED_PIN, OUTPUT);
77+
pinMode(BUTTON_PIN, INPUT_PULLUP);
78+
79+
// make sure that the default chip select pin is set to
80+
// output, even if you don't use it:
81+
pinMode(SD_CS_PIN, OUTPUT);
82+
83+
// Initialize SD card (assumes running on Uno, for Leonardo see below).
84+
if (!SD.begin(SD_CS_PIN)) {
85+
// Initialize SD card for Leonardo or other chips (using software SPI)
86+
//if (!SD.begin(SD_CS_PIN, 11, 12, 13)) {
87+
halt(F("Card init. failed!"));
88+
}
89+
90+
// Create the next log file on the SD card.
91+
char filename[15];
92+
strcpy(filename, "GPSLOG00.CSV");
93+
for (uint8_t i = 0; i < 100; i++) {
94+
filename[6] = '0' + i/10;
95+
filename[7] = '0' + i%10;
96+
// Create file if it does not exist.
97+
if (!SD.exists(filename)) {
98+
break;
99+
}
100+
}
101+
Serial.print("Using log file: ");
102+
Serial.println(filename);
103+
104+
// Open the log file.
105+
logfile = SD.open(filename, FILE_WRITE);
106+
if(!logfile) {
107+
halt(F("Failed to open log file!"));
108+
}
109+
110+
// Set the first line of the log file as the column headers.
111+
logfile.println("latitude,longitude,note");
112+
logfile.flush();
113+
114+
// Connect to the GPS receiver and configure it to receive location updates once a second.
115+
GPS.begin(9600);
116+
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY); // Recommended minimum output only (all we need for this project).
117+
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // Once a second update rate.
118+
GPS.sendCommand(PGCMD_NOANTENNA); // Turn off antenna status.
119+
120+
// Configure timer0 compare interrupt to run and parse GPS data every millisecond.
121+
// See the SIGNAL function further below for the code that is called during this interrupt.
122+
OCR0A = 0xAF;
123+
TIMSK0 |= _BV(OCIE0A);
124+
125+
Serial.println("Ready!");
126+
}
127+
128+
void loop() {
129+
// Parse GPS messages when they are received.
130+
if (GPS.newNMEAreceived()) {
131+
GPS.parse(GPS.lastNMEA());
132+
}
133+
134+
// Light the LED solid if there's a GPS fix, otherwise flash it on and off once a second.
135+
if (GPS.fix) {
136+
digitalWrite(LED_PIN, HIGH);
137+
}
138+
else {
139+
// No fix, blink the LED once a second and stop further processing.
140+
digitalWrite(LED_PIN, (millis()/1000) % 2);
141+
return;
142+
}
143+
144+
// Check if the button is pressed.
145+
if (digitalRead(BUTTON_PIN) == LOW) {
146+
// Pause a bit to debounce.
147+
delay(100);
148+
if (digitalRead(BUTTON_PIN) == LOW) {
149+
// Button pressed! Log the current location as having good candy.
150+
logLocation("Good Candy");
151+
// Then flash the light 5 times to signal the location was recorded.
152+
for (int i=0; i<5; ++i) {
153+
digitalWrite(LED_PIN, HIGH);
154+
delay(250);
155+
digitalWrite(LED_PIN, LOW);
156+
delay(250);
157+
}
158+
}
159+
}
160+
161+
// Periodically log the location.
162+
if (logCounter == 0) {
163+
logLocation("Location");
164+
logCounter = LOGGING_PERIOD_SEC*1000;
165+
}
166+
}

0 commit comments

Comments
 (0)