-
Notifications
You must be signed in to change notification settings - Fork 0
/
gps-tracker.ino
189 lines (156 loc) · 5.92 KB
/
gps-tracker.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/* -----------------------------------------------------------
This checks for a good GPS fix every few minutes, and publishes
data/state information if necessary. If not, it will save data
by staying quiet.
---------------------------------------------------------------*/
// Getting the library
#include "AssetTracker.h"
// Keep track of the last time we published data
long lastPublish = 0;
// Keep track of the last time we checked our environment
long lastPublishCheck = 0;
// How many minutes between checks?
int delayMinutes = 2;
// How many minutes between heartbeats? The backend expects every 10 minutes.
int delayHeartbeatMinutes = 7;
// Acceptable drift, in degrees. If change doesn't exceed this, the truck is stationary.
float acceptableDrift = 0.0005;
// GPS coordinates from the last publish. Don't send anything new if we haven't moved much
bool previousCoordinatesSet = false;
float previousLon = 0;
float previousLat = 0;
// What did we last send?
String lastPublishType = "F"; // Press F to pay respects
// Creating an AssetTracker named 't' for us to reference
AssetTracker t = AssetTracker();
// A FuelGauge named 'fuel' for checking on the battery state
FuelGauge fuel;
// setup() and loop() are both required. setup() runs once when the device starts
// and is used for registering functions and variables and initializing things
void setup() {
// Sets up all the necessary AssetTracker bits
t.begin();
// Enable the GPS module. Defaults to off to save power.
// Takes 1.5s or so because of delays.
t.gpsOn();
// Opens up a Serial port so you can listen over USB
Serial.begin(9600);
Particle.function("batt", batteryStatus);
Particle.function("gps", gpsPublish);
Particle.function("gpsIfMoved", gpsPublishIfMoved);
// For debugging
Particle.variable("lastPubType", lastPublishType);
}
// loop() runs continuously
void loop() {
// Must be run to capture the GPS output.
t.updateGPS();
// if the current time - the last time we published is greater than your set delay...
if (millis()-lastPublishCheck > delayMinutes*60*1000) {
// Remember when we published
lastPublishCheck = millis();
gpsPublishIfMoved("");
}
}
// Actively ask for a GPS reading if you're impatient. Only publishes if there's
// a GPS fix, otherwise returns '0'
int gpsPublish(String command) {
if (t.gpsFix()) {
previousLon = t.readLon();
previousLat = t.readLat();
previousCoordinatesSet = true;
Particle.publish("G", t.readLatLon(), 60, PRIVATE);
return 1;
} else {
return 0;
}
}
// Publishes different states if different consitions are met.
// Return codes:
// 0 = We were online, and continue to be.
// Sent a heartbeat.
// 1 = We were online, and continue to be, but recently published.
// Nothing was done.
// 2 = We were online, then we moved.
// Sent an offline.
// 3 = We were offline, but stationary.
// Sent coordinates.
// 4 = We were offline, and moved.
// Nothing was done.
// 5 = No GPS Fix.
// Nothing was done.
int gpsPublishIfMoved(String command) {
// No GPS fix, no good data.
if (!t.gpsFix()) {
return 5;
}
if (!previousCoordinatesSet) {
// Our first update! Hopefully the first of many.
previousLon = t.readLonDeg();
previousLat = t.readLatDeg();
Serial.println(String::format("previousLon %f",previousLon));
Serial.println(String::format("previousLat %f",previousLat));
previousCoordinatesSet = true;
}
// How far have we moved since we last checked?
// Make the reasonable assumption that the earth is flat.
float thisLon = t.readLonDeg();
float thisLat = t.readLatDeg();
float changeLon = f_abs(previousLon - thisLon);
float changeLat = f_abs(previousLat - thisLat);
Serial.println(String::format("previousLon %f",previousLon));
Serial.println(String::format("previousLat %f",previousLat));
Serial.println(String::format("thisLon %f",thisLon));
Serial.println(String::format("thisLat %f",thisLat));
Serial.println(String::format("changeLon %f",changeLon));
Serial.println(String::format("changeLat %f",changeLat));
if (changeLon > acceptableDrift || changeLat > acceptableDrift) {
// Update our records.
previousLon = thisLon;
previousLat = thisLat;
if (lastPublishType != "F") {
Particle.publish("F", "", 60, PRIVATE);
lastPublishType = "F";
lastPublish = millis();
return 2;
}
return 4;
}
if (lastPublishType == "F") {
Particle.publish("G", t.readLatLon(), 60, PRIVATE);
lastPublishType = "G";
lastPublish = millis();
return 3;
}
if (millis()-lastPublish > delayHeartbeatMinutes*60*1000) {
Particle.publish("H", "", 60, PRIVATE);
lastPublishType = "H";
lastPublish = millis();
return 0;
}
return 1;
}
// Lets you remotely check the battery status by calling the function "batt"
// Triggers a publish with the info (so subscribe or watch the dashboard)
// and also returns a '1' if there's >10% battery left and a '0' if below
int batteryStatus(String command){
// Publish the battery voltage and percentage of battery remaining
// if you want to be really efficient, just report one of these
// the String::format("%f.2") part gives us a string to publish,
// but with only 2 decimal points to save space
Particle.publish("B",
"v:" + String::format("%.2f",fuel.getVCell()) +
",c:" + String::format("%.2f",fuel.getSoC()),
60, PRIVATE
);
// if there's more than 10% of the battery left, then return 1
if (fuel.getSoC()>10){ return 1;}
// if you're running out of battery, return 0
else { return 0;}
}
float f_abs(float f) {
if (f < 0) {
return -1 * f;
}
return f;
}