Skip to content

Instantly share code, notes, and snippets.

@lepsa
Created October 29, 2016 12:54
Show Gist options
  • Save lepsa/b655532dda9c7992330e9c900099e48c to your computer and use it in GitHub Desktop.
Save lepsa/b655532dda9c7992330e9c900099e48c to your computer and use it in GitHub Desktop.
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Servo.h>
#include <TinyGPS++.h>
#include <math.h>
// Components
Servo servo;
TinyGPSPlus gps;
LiquidCrystal lcd(5,6,7,8,9,10);
volatile bool buttonPressed = false;
// Target information
const double targetLat = -27.476039; // Brisbane botanical gardens
const double targetLong = 152.976406;
const double targetRadius = 20; // metres
// Servo positions
const int servoUnlock = 0;
const int servoLock = 90;
// EEPROM
const int eepromAddr = 0;
const int unlockAttempts = 10;
const int eepromSecret = 1;
const int secretUnlockCount = 30;
const int baudRate = 9600;
const int screenTimeout = 10000;
void setup()
{
servo.attach(3);
servo.write(servoLock); // Lock the box before anything else happens.
// Pin setup.
pinMode(2, INPUT); // Button
// Setup objects
attachInterrupt(0, buttonInterupt, RISING); // Button setup
// Component setup
lcd.begin(16, 2);
gps = TinyGPSPlus();
// EEPROM setup.
if(EEPROM.read(eepromAddr) > unlockAttempts)
{
EEPROM.write(eepromAddr, unlockAttempts);
}
// Secret unlock
if(EEPROM.read(eepromSecret) >= secretUnlockCount)
{
servo.write(servoUnlock);
EEPROM.write(eepromSecret, 0);
EEPROM.write(eepromAddr, unlockAttempts);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Secret unlock");
delay(screenTimeout);
}
else
{
EEPROM.write(eepromSecret, EEPROM.read(eepromSecret) + 1);
}
Serial.begin(baudRate);
}
void loop()
{
// Feed gps object NMEA data;
while(Serial.available() > 0)
{
gps.encode(Serial.read());
}
// If data is valid, continue.
if(gps.location.isValid())
{
// Show GPS accuracy
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("GPS Locked");
lcd.setCursor(0, 1);
String accuracy = (gps.hdop.value() / 100) > 5 ? "poor" : "good";
lcd.print("Accuracy: " + accuracy); // Need to rework
delay(100);
// On button press
if(buttonPressed == true)
{
buttonPressed = false;
// Check attempts left
if(EEPROM.read(eepromAddr) > 0)
{
// Check distance to target, unlock if close enough
EEPROM.write(eepromAddr, EEPROM.read(eepromAddr) - 1);
if(gps.distanceBetween(gps.location.lat(), gps.location.lng(), targetLat, targetLong) <= targetRadius)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Box Unlocked");
lcd.setCursor(0, 1);
lcd.print("Well Done!");
servo.write(servoUnlock);
delay(screenTimeout);
}
else
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tries Left: " + String(EEPROM.read(eepromAddr)));
lcd.setCursor(0, 1);
lcd.print(String(round(gps.distanceBetween(gps.location.lat(), gps.location.lng(), targetLat, targetLong))) + "m"); // Round shown distance to nearest metre.
delay(screenTimeout);
}
}
// No attempts left.
else
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Not Tries Left");
lcd.setCursor(0, 1);
lcd.print("Permantly Locked");
delay(screenTimeout);
}
}
}
// Searching for GPS
else
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Searching for");
lcd.setCursor(0, 1);
lcd.print("GPS");
delay(100);
}
}
void buttonInterupt()
{
buttonPressed = true;
delayMicroseconds(500000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment