Created
October 29, 2016 12:54
-
-
Save lepsa/b655532dda9c7992330e9c900099e48c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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