Code cleanup

This commit is contained in:
id101010
2015-12-03 02:28:22 +01:00
parent 95685224b5
commit d0b38011d2
2 changed files with 206 additions and 89 deletions

27
.gitignore vendored Normal file
View File

@@ -0,0 +1,27 @@
# Object files
*.o
*.ko
*.obj
*.elf
.build/
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Temporary files
*.swp

View File

@@ -1,179 +1,269 @@
/* /*
* Reverse Geocache * Reverse Geocache
*
* A geocache device which unlocks in a specific area.
*
* Parts used:
* -----------
* - Arduino UNO R3
* - Ultimate GPS logger shield
* - 9V Battery
*/ */
#include <math.h> #include <math.h>
#include <LiquidCrystal.h> #include <LiquidCrystal.h>
#include <Adafruit_GPS.h> #include <Adafruit_GPS.h>
#include <SoftwareSerial.h> #include <SoftwareSerial.h>
// Defines // Defines
#define GPSECHO false // make true to debug GPS #define GPSECHO false // True -> debug GPS raw
#define ANTIFLICKER 500 // timeout for lcd #define ANTIFLICKER 1000 // Timeout for lcd
// Declarations // Declarations
const float deg2rad = 0.01745329251994; const float deg2rad = 0.01745329251994;
const float rEarth = 6371000.0; // can replace with 3958.75 mi, 6370.0 km, or 3440.06 NM const float rEarth = 6371000.0; // Earths radius in meters
float range = 3000; // distance from HERE to THERE float range = 9999; // Distance between src and pos
String here; // read from GPS String destination = "N46 59.776, E007 27.771";
String tmp; String position = ""; // read from GPS
int gpsWasFixed = HIGH; // did the GPS have a fix? String tmp = "";
boolean usingInterrupt = false;
void useInterrupt(boolean);
SoftwareSerial mySerial(3,2);
Adafruit_GPS GPS(&mySerial);
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
String there = "N46 59.776, E007 27.771"; SoftwareSerial mySerial(3,2); // Software Serial on 3 (rx) and 2 (tx)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // Init 16x2 LCD
Adafruit_GPS GPS(&mySerial); // Use software serial for gps com
float lat1 = 0;
float lat2 = 0;
float lon1 = 0;
float lon2 = 0;
// Prototypes
void useInterrupt(boolean);
void print_message(String Line1, String Line2);
/*******************************************/ /*******************************************/
//String there = "N46 55.090, W7 26.442"; // Gurten: N 46 55.090 E 7 26.442 //String destination = "N46 55.090, W7 26.442"; // Gurten: N 46 55.090 E 7 26.442
/*******************************************/ /*******************************************/
void setup() void setup()
{ {
lcd.begin(16, 2); lcd.begin(16, 2);
lcd.clear();
//Serial.begin(9600); //Serial.begin(9600);
//Serial.println("[DEBUGGING INFORMATIONS]:"); //Serial.println("[DEBUGGING INFORMATIONS]:");
GPS.begin(9600); GPS.begin(9600);
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); // RMC (recommended minimum) and GGA (fix data) including altitude GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); // Request RMC and GGA
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
useInterrupt(true); // reads the steaming data in a background useInterrupt(true); // Reads in bbackground
delay(1000); delay(1000);
} }
void loop() void loop()
{ {
// Parse GPS if new NMEA is available if (GPS.newNMEAreceived()) { // Read nmea string if available
if (GPS.newNMEAreceived()) { if (!GPS.parse(GPS.lastNMEA())) { // Parse string if possible
if (!GPS.parse(GPS.lastNMEA())) {
return; return;
} }
} }
if (GPS.fix) { if (GPS.fix) { // If there was a fix
gpsWasFixed = HIGH; position = gps2string(); // get position string
here = gps2string ((String) GPS.lat, GPS.latitude, (String) GPS.lon, GPS.longitude); lat1 = string2lat(position);
range = haversine(string2lat(here), string2lon(here), string2lat(there), string2lon(there)); lat2 = string2lat(destination);
lon1 = string2lon(position);
lon2 = string2lon(destination);
range = haversine(lat1, lon1, lat2, lon2); // calculate dist to target
tmp = String(range); tmp = String(range);
tmp += " [m]"; tmp += " [m]";
print_message("I wand up.", tmp);
/*Serial.print("Here: ");
Serial.print(here);
Serial.print("There: ");
Serial.println(there);
Serial.print("Range: ");
Serial.print(range);
Serial.println("m");*/
lcd.clear();
lcd.setCursor(0,0);
lcd.print("I want up.");
lcd.setCursor(0,1);
lcd.print(tmp);
delay(500);
} else { } else {
lcd.clear(); print_message("Hello Mischa!", "Take me outside!"); // No fix available
lcd.setCursor(0,0);
lcd.print("Hello Mischa!");
lcd.setCursor(0,1);
lcd.print("Take me outside!");
delay(200);
} }
if (range < 20.0) { if (range < 20.0) {
delay(1000); print_message("Unlocked!", "Password"); // Destination reached
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Unlocked!");
lcd.setCursor(0,1);
lcd.print("[@1AK!!^~443]");
delay(5000);
} }
} }
/**************************************************
* Name: print_message()
* Returns: nothing
* Params: Line1, Line2
* Descr: Print two strings on a 16x2 lcd
**************************************************/
void print_message(String Line1, String Line2)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(Line1);
lcd.setCursor(0,1);
lcd.print(Line2);
delay(ANTIFLICKER);
}
/**************************************************
* Name: SIGNAL()
* Returns: nothing
* Params: nothing
* Descr: Timer 0 interrupt service routine
* Gets called on timer0 overflow [1ms]
**************************************************/
SIGNAL(TIMER0_COMPA_vect) SIGNAL(TIMER0_COMPA_vect)
{ {
// Interrupt is called once a millisecond, looks for any new GPS data, and stores it char c = GPS.read(); // Read from serial input
char c = GPS.read();
if (GPSECHO){ if (GPSECHO){ // If GPSECHO is enabled
if (c) { if (c) {
UDR0 = c; UDR0 = c; // Send nmea char by char
} }
} }
} }
/**************************************************
* Name: useInterrupt()
* Returns: nothing
* Params: true/false
* Descr: Sets up timer0 and Interrupt
**************************************************/
void useInterrupt(boolean v) void useInterrupt(boolean v)
{ {
if (v) { if (v) {
OCR0A = 0xAF; OCR0A = 0xAF; // Set up timer0
TIMSK0 |= _BV(OCIE0A); TIMSK0 |= _BV(OCIE0A); // Enable timer0
usingInterrupt = true;
} else { } else {
TIMSK0 &= ~_BV(OCIE0A); TIMSK0 &= ~_BV(OCIE0A); // Disable timer0
usingInterrupt = false;
} }
} }
String int2fw (int x, int n)
/**************************************************
* Name: int2fw()
* Returns: string s
* Params: int x, int n
* Descr: returns a fixed-width string s
**************************************************/
String int2fw(int x, int n)
{ {
// returns a string of length n (fixed-width) String s = (String)x;
String s = (String) x;
while (s.length() < n) { while (s.length() < n) {
s = "0" + s; s = "0" + s;
} }
return s; return s;
} }
String gps2string (String lat, float latitude, String lon, float longitude) /***************************************************************
* Name: gps2string()
* Returns: string s
* Params: nothing
* Descr: returns a string "Ndd mm.mmm, Wddd mm.mmm";
***************************************************************/
String gps2string(void)
{ {
// returns "Ndd mm.mmm, Wddd mm.mmm"; // fetch data
int dd = (int) latitude/100; String lat = (String)GPS.lat;
int mm = (int) latitude % 100; String lon = (String)GPS.lon;
int mmm = (int) round(1000 * (latitude - floor(latitude))); String gps2lat, gps2lon;
String gps2lat = lat + int2fw(dd, 2) + " " + int2fw(mm, 2) + "." + int2fw(mmm, 3); float latitude = GPS.latitude;
float longitude = GPS.longitude;
int dd = 0;
int mm = 0;
int mmm = 0;
// lat string
dd = (int) latitude/100;
mm = (int) latitude % 100;
mmm = (int) round(1000 * (latitude - floor(latitude)));
gps2lat = lat + int2fw(dd, 2) + " " + int2fw(mm, 2) + "." + int2fw(mmm, 3);
// lon string
dd = (int) longitude/100; dd = (int) longitude/100;
mm = (int) longitude % 100; mm = (int) longitude % 100;
mmm = (int) round(1000 * (longitude - floor(longitude))); mmm = (int) round(1000 * (longitude - floor(longitude)));
String gps2lon = lon + int2fw(dd, 3) + " " + int2fw(mm, 2) + "." + int2fw(mmm, 3); gps2lon = lon + int2fw(dd, 3) + " " + int2fw(mm, 2) + "." + int2fw(mmm, 3);
String myString = gps2lat + ", " + gps2lon;
return myString; // Assemble
return (gps2lat + ", " + gps2lon);
} }
float string2lat (String myString) /**************************************************
* Name: string2lat()
* Returns: float latitude
* Params: String position
* Descr: returns the float representation of
* the current latitude.
**************************************************/
float string2lat(String position)
{ {
// returns radians: e.g. String myString = "N38 58.892, W076 29.177"; // returns radians: e.g. String position = "N38 58.892, W076 29.177";
float lat = ((myString.charAt(1) - '0') * 10.0) + (myString.charAt(2) - '0') * 1.0 + ((myString.charAt(4) - '0') / 6.0) + ((myString.charAt(5) - '0') / 60.0) + ((myString.charAt(7) - '0') / 600.0) + ((myString.charAt(8) - '0') / 6000.0) + ((myString.charAt(9) - '0') / 60000.0); float lat = ((position.charAt(1) - '0') * 10.0) + \
((position.charAt(2) - '0') * 1.0) + \
((position.charAt(4) - '0') / 6.0) + \
((position.charAt(5) - '0') / 60.0) + \
((position.charAt(7) - '0') / 600.0) + \
((position.charAt(8) - '0') / 6000.0) + \
((position.charAt(9) - '0') / 60000.0);
lat *= deg2rad; lat *= deg2rad;
if (myString.charAt(0) == 'S') {
lat *= -1; // Correct for hemisphere if (position.charAt(0) == 'S') {
lat *= -1; // Correct for hemispposition
} }
return lat; return lat;
} }
float string2lon (String myString) /**************************************************
* Name: string2lon()
* Returns: float longitude
* Params: String position
* Descr: returns the float representation of
* the current longitude.
**************************************************/
float string2lon (String position)
{ {
// returns radians: e.g. String myString = "N38 58.892, W076 29.177"; // returns radians: e.g. String position = "N38 58.892, W076 29.177";
float lon = ((myString.charAt(13) - '0') * 100.0) + ((myString.charAt(14) - '0') * 10.0) + (myString.charAt(15) - '0') * 1.0 + ((myString.charAt(17) - '0') / 6.0) + ((myString.charAt(18) - '0') / 60.0) + ((myString.charAt(20) - '0') / 600.0) + ((myString.charAt(21) - '0') / 6000.0) + ((myString.charAt(22) - '0') / 60000.0); float lon = ((position.charAt(13) - '0') * 100.0) + \
((position.charAt(14) - '0') * 10.0) + \
((position.charAt(15) - '0') * 1.0) + \
((position.charAt(17) - '0') / 6.0) + \
((position.charAt(18) - '0') / 60.0) + \
((position.charAt(20) - '0') / 600.0) + \
((position.charAt(21) - '0') / 6000.0) + \
((position.charAt(22) - '0') / 60000.0);
lon *= deg2rad; lon *= deg2rad;
if (myString.charAt(12) == 'W') {
lon *= -1; // Correct for hemisphere if (position.charAt(12) == 'W') {
lon *= -1; // Correct for hemispposition
} }
return lon; return lon;
} }
/**************************************************
* Name: haversine()
* Returns: float distance
* Params: float lat1, lon1, lat2, lon2
* Descr: Calculates the distance between
* two points given by (lat1/2 lon1/2)
**************************************************/
float haversine (float lat1, float lon1, float lat2, float lon2) float haversine (float lat1, float lon1, float lat2, float lon2)
{ {
// returns the great-circle distance between two points (radians) on a sphere // returns the great-circle distance between two points
float h = sq((sin((lat1 - lat2) / 2.0))) + (cos(lat1) * cos(lat2) * sq((sin((lon1 - lon2) / 2.0)))); float h = sq((sin((lat1 - lat2) / 2.0))) + \
(cos(lat1) * cos(lat2) * \
sq((sin((lon1 - lon2) / 2.0))));
float d = 2.0 * rEarth * asin (sqrt(h)); float d = 2.0 * rEarth * asin (sqrt(h));
return d; return d;
} }