GeoFence Treasure Hunt With Artemis Global Tracker
Contributors:
[redacted]
The Code
Here, we have the main loop function which combines the logic above with functions that interact with the AGT hardware.
// MAIN LOOP FUNCTION
void loop() {
if (WIN) {
Serial.println(F("YOU FOUND THE TREASURE!!"));
signalVictory();
while (true) {
delay(2000);
Serial.println(F("YOU FOUND THE TREASURE!!"));
}
} else {
geofenceState currentGeofenceState; // Create storage for the geofence state
boolean result = myGNSS.getGeofenceState(currentGeofenceState);
Serial.print(F("getGeofenceState returned: ")); // Print the combined state
Serial.print(result); // Get the geofence state
if (!result) // If getGeofenceState did not return true
{
Serial.println(F(".")); // Tidy up
return; // and go round the loop again
}
// Print the Geofencing status
// 0 - Geofencing not available or not reliable; 1 - Geofencing active
Serial.print(F(". status is: "));
Serial.print(currentGeofenceState.status);
// Print the numFences
Serial.print(F(". numFences is: "));
Serial.print(currentGeofenceState.numFences);
// Print the state of the geofence
// 0 - Unknown; 1 - Inside; 2 - Outside
Serial.print(F(". The geofence stats is: "));
Serial.print(currentGeofenceState.states[0]);
byte fenceStatus = digitalRead(geofencePin); // Read the geofence pin
digitalWrite(LED, !fenceStatus); // Set the LED (inverted)
Serial.print(F(". Geofence pin (PIO14) is: ")); // Print the pin state
Serial.print(fenceStatus);
Serial.println(F("."));
// GET CURRENT POSITION
curr_lat = myGNSS.getLatitude(); // Get the latitude in degrees * 10^-7
curr_long = myGNSS.getLongitude(); // Get the longitude in degrees * 10^-7
curr_angle = (getCoordinateBearing(latitude, longitude, curr_lat, curr_long) + 180) % 360;
curr_distance = getCoordinateDistance(latitude, longitude, curr_lat, curr_long);
Serial.print(F("Current Latitude: "));
Serial.print(curr_lat);
Serial.print(F(". Current Longitude: "));
Serial.println(curr_long);
Serial.print(F("Goal Angle: "));
Serial.print(goal_angle);
Serial.print(F(". Goal Distance: "));
Serial.println(goal_distance);
Serial.print(F("Current Angle: "));
Serial.print(curr_angle);
Serial.print(F(". Current Distance: "));
Serial.println(curr_distance);
score = sqrt(curr_distance * curr_distance + goal_distance * goal_distance - 2 * goal_distance * curr_distance * cos((curr_angle * (2*PI/360)) - (goal_angle * (2*PI/360))));
Serial.print(F("Current Score: "));
Serial.print(score);
if (score < 2) {
WIN = true;
} if (score < 5) {
Serial.println(F(": HOT!!"));
} else if (score < 12) {
Serial.println(F(": Warmerrr..."));
} else if (score < 20) {
Serial.println(F(": Room Temp"));
} else {
Serial.println(F(": Ice Cold..."));
}
Serial.println();
}
digitalWrite(LED, LOW);
delay(score*5);
digitalWrite(LED, HIGH);
delay(score*5);
}
Once the player finds the treasure, the victory function runs, which connects the AGT to the Iridium network and sends a victory message.
void signalVictory() {
int signalQuality = -1;
int err;
pinMode(LED, OUTPUT); // Make the LED pin an output
gnssOFF(); // Disable power for the GNSS
pinMode(gnssBckpBatChgEN, INPUT); // GNSS backup batttery charge control
pinMode(geofencePin, INPUT); // Configure the geofence pin as an input
pinMode(iridiumPwrEN, OUTPUT); // Configure the Iridium Power Pin
digitalWrite(iridiumPwrEN, LOW); // Disable Iridium Power
pinMode(superCapChgEN, OUTPUT); // Configure the super capacitor charger enable pin
digitalWrite(superCapChgEN, LOW); // Disable the super capacitor charger
pinMode(iridiumSleep, OUTPUT); // Iridium 9603N On/Off (Sleep) pin
digitalWrite(iridiumSleep, LOW); // Put the Iridium 9603N to sleep
pinMode(iridiumRI, INPUT); // Configure the Iridium Ring Indicator as an input
pinMode(iridiumNA, INPUT); // Configure the Iridium Network Available as an input
pinMode(superCapPGOOD, INPUT); // Configure the super capacitor charger PGOOD input
modem.endSerialPort();
// Enable the supercapacitor
Serial.println(F("Enabling the supercapacitor charger..."));
digitalWrite(superCapChgEN, HIGH);
delay(1000);
// wait for the capacitor to charge
while (digitalRead(superCapPGOOD) == false)
{
Serial.println(F("Waiting for supercapacitors to charge..."));
delay(1000);
}
Serial.println(F("Supercapacitors charged!"));
// Enable power for the 9603N (Iridium Connection)
Serial.println(F("Enabling 9603N power..."));
digitalWrite(iridiumPwrEN, HIGH); // Enable Iridium Power
delay(1000);
modem.setPowerProfile(IridiumSBD::USB_POWER_PROFILE);
// Startup the modem
Serial.println(F("Starting modem..."));
err = modem.begin();
if (err != ISBD_SUCCESS)
{
Serial.print(F("Begin failed: error "));
Serial.println(err);
if (err == ISBD_NO_MODEM_DETECTED)
Serial.println(F("No modem detected: check wiring."));
return;
}
// Test the signal quality.
err = modem.getSignalQuality(signalQuality);
if (err != ISBD_SUCCESS)
{
Serial.print(F("SignalQuality failed: error "));
Serial.println(err);
return;
}
modem.useMSSTMWorkaround(false);
Serial.print(F("On a scale of 0 to 5, signal quality is currently "));
Serial.print(signalQuality);
Serial.println(F("."));
// Send the message
Serial.println(F("Trying to send the message. This might take several minutes."));
err = modem.sendSBDText("YOU FOUND THE TREASURE!!");
if (err != ISBD_SUCCESS)
{
Serial.print(F("sendSBDText failed: error "));
Serial.println(err);
if (err == ISBD_SENDRECEIVE_TIMEOUT)
Serial.println(F("Try again with a better view of the sky."));
}
// POWER DOWN IRIDIUM CONNECTION
// Clear the Mobile Originated message buffer
Serial.println(F("Clearing the MO buffer."));
err = modem.clearBuffers(ISBD_CLEAR_MO); // Clear MO buffer
if (err != ISBD_SUCCESS)
{
Serial.print(F("clearBuffers failed: error "));
Serial.println(err);
}
// Power down the modem
Serial.println(F("Putting the 9603N to sleep."));
err = modem.sleep();
if (err != ISBD_SUCCESS)
{
Serial.print(F("sleep failed: error "));
Serial.println(err);
}
Serial.println(F("Disabling 9603N power..."));
digitalWrite(iridiumPwrEN, LOW); // Disable Iridium Power
Serial.println(F("Disabling the supercapacitor charger..."));
digitalWrite(superCapChgEN, LOW); // Disable the super capacitor charger
Serial.println(F("Game Complete!"));
}