-
Notifications
You must be signed in to change notification settings - Fork 21
/
main.ino
151 lines (101 loc) · 3.72 KB
/
main.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// This #include statement was automatically added by the Spark IDE.
#include "Adafruit_GPS.h"
#include <math.h>
#define mySerial Serial1
Adafruit_GPS GPS(&mySerial);
int lastSecond = 0;
bool ledState = false;
// lets keep the radio off until we get a fix, or 2 minutes go by.
SYSTEM_MODE(SEMI_AUTOMATIC);
#define STARTING_LATITUDE_LONGITUDE_ALTITUDE "41.8369,-87.6847,200"
void setup() {
// electron asset tracker shield needs this to enable the power to the gps module.
pinMode(D6, OUTPUT);
digitalWrite(D6, LOW);
// for blinking.
pinMode(D7, OUTPUT);
digitalWrite(D7, LOW);
GPS.begin(9600);
mySerial.begin(9600);
Serial.begin(9600);
//
// The fun part!
//
suggest_time_and_location();
//# request a HOT RESTART, in case we were in standby mode before.
GPS.sendCommand("$PMTK101*32");
delay(250);
// request everything!
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_ALLDATA);
delay(250);
// turn off antenna updates
GPS.sendCommand(PGCMD_NOANTENNA);
delay(250);
}
void loop() {
bool hasGPSTime = ((GPS.year != 80) && (GPS.year != 0));
// process and dump everything from the module through the library.
while (mySerial.available()) {
char c = GPS.read();
// lets echo the GPS output until we get a good clock reading, then lets calm things down.
if (!hasGPSTime) {
Serial.print(c);
}
if (GPS.newNMEAreceived()) {
GPS.parse(GPS.lastNMEA());
}
}
// wait 60 seconds, or until we have a fix before we get online to help get a quicker fix.
if (Particle.connected() == false) {
if ((GPS.latitude != 0) || (millis() > 120000)) {
Particle.connect();
}
}
if (GPS.seconds != lastSecond) {
lastSecond = GPS.seconds;
// every second, toggle the LED.
digitalWrite(D7, (ledState) ? HIGH : LOW);
ledState = !ledState;
if (hasGPSTime) {
String currentTime = String::format("GPS TIME is %d/%d/%d at %d:%d:%d, location is %f, %f",
GPS.month, GPS.day, GPS.year,
GPS.hour, GPS.minute, GPS.seconds,
GPS.latitude, GPS.longitude
);
Serial.println(currentTime);
}
else {
Serial.println("GPS TIME: searching the skies...");
}
}
}
void suggest_time_and_location() {
String locationString = STARTING_LATITUDE_LONGITUDE_ALTITUDE;
//TODO: guarantee that the clock has actually been set by the cloud, and we're not early.
//Particle.syncTime();
time_t timeValue = Time.now();
String timeString = Time.format(timeValue, "%Y,%m,%d,%H,%M,%S");
Particle.publish("GPS", "Time was " + String(timeString));
// PMTK740,YYYY,MM,DD,hh,mm,ss*CS<CR><LF>
// PMTK741,Lat,Long,Alt,YYYY,MM,DD,hh,mm,ss *CS<CR><LF>
//The packet contains reference location for the GPS receiver. To have faster TTFF, the accuracy of the location shall be better than 30km.
String gpsTimeCmd = "PMTK740," + timeString;
String locationTimeCmd = "PMTK741,"+locationString + "," + timeString;
String cmd = String::format("$%s*%02x", gpsTimeCmd.c_str(), crc8(gpsTimeCmd));
mySerial.println(cmd);
//GPS.sendCommand(cmd.c_str()); // why doesn't this support const char *...
delay(250);
cmd = String::format("$%s*%02x", locationTimeCmd.c_str(), crc8(locationTimeCmd));
mySerial.println(cmd);
//GPS.sendCommand(cmd.c_str()); // why doesn't this support const char *...
delay(250);
}
int crc8(String str) {
int len = str.length();
const char * buffer = str.c_str();
int crc = 0;
for(int i=0;i<len;i++) {
crc ^= (buffer[i] & 0xff);
}
return crc;
}