From d0b38011d214ca46a9ecd1757ef11774c63ad999 Mon Sep 17 00:00:00 2001 From: id101010 Date: Thu, 3 Dec 2015 02:28:22 +0100 Subject: [PATCH] Code cleanup --- .gitignore | 27 +++++ src/sketch.ino | 268 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 206 insertions(+), 89 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..edc5e79 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/src/sketch.ino b/src/sketch.ino index 29eacb3..5b030d9 100644 --- a/src/sketch.ino +++ b/src/sketch.ino @@ -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 #include #include #include // Defines -#define GPSECHO false // make true to debug GPS -#define ANTIFLICKER 500 // timeout for lcd +#define GPSECHO false // True -> debug GPS raw +#define ANTIFLICKER 1000 // Timeout for lcd // Declarations const float deg2rad = 0.01745329251994; -const float rEarth = 6371000.0; // can replace with 3958.75 mi, 6370.0 km, or 3440.06 NM -float range = 3000; // distance from HERE to THERE -String here; // read from GPS -String tmp; -int gpsWasFixed = HIGH; // did the GPS have a fix? -boolean usingInterrupt = false; -void useInterrupt(boolean); -SoftwareSerial mySerial(3,2); -Adafruit_GPS GPS(&mySerial); -LiquidCrystal lcd(8, 9, 4, 5, 6, 7); +const float rEarth = 6371000.0; // Earths radius in meters +float range = 9999; // Distance between src and pos +String destination = "N46 59.776, E007 27.771"; +String position = ""; // read from GPS +String tmp = ""; -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() { lcd.begin(16, 2); - + lcd.clear(); + //Serial.begin(9600); //Serial.println("[DEBUGGING INFORMATIONS]:"); 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 - useInterrupt(true); // reads the steaming data in a background + useInterrupt(true); // Reads in bbackground delay(1000); } void loop() { - // Parse GPS if new NMEA is available - if (GPS.newNMEAreceived()) { - if (!GPS.parse(GPS.lastNMEA())) { + if (GPS.newNMEAreceived()) { // Read nmea string if available + if (!GPS.parse(GPS.lastNMEA())) { // Parse string if possible return; } } - if (GPS.fix) { - gpsWasFixed = HIGH; + if (GPS.fix) { // If there was a fix + position = gps2string(); // get position string + + lat1 = string2lat(position); + lat2 = string2lat(destination); + lon1 = string2lon(position); + lon2 = string2lon(destination); - here = gps2string ((String) GPS.lat, GPS.latitude, (String) GPS.lon, GPS.longitude); - range = haversine(string2lat(here), string2lon(here), string2lat(there), string2lon(there)); + range = haversine(lat1, lon1, lat2, lon2); // calculate dist to target tmp = String(range); tmp += " [m]"; - - /*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); + print_message("I wand up.", tmp); } else { - lcd.clear(); - lcd.setCursor(0,0); - lcd.print("Hello Mischa!"); - lcd.setCursor(0,1); - lcd.print("Take me outside!"); - delay(200); + print_message("Hello Mischa!", "Take me outside!"); // No fix available } if (range < 20.0) { - delay(1000); - lcd.clear(); - lcd.setCursor(0,0); - lcd.print("Unlocked!"); - lcd.setCursor(0,1); - lcd.print("[@1AK!!^~443]"); - delay(5000); + print_message("Unlocked!", "Password"); // Destination reached } } +/************************************************** + * 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) { - // Interrupt is called once a millisecond, looks for any new GPS data, and stores it - char c = GPS.read(); - if (GPSECHO){ + char c = GPS.read(); // Read from serial input + + if (GPSECHO){ // If GPSECHO is enabled 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) { - if (v) { - OCR0A = 0xAF; - TIMSK0 |= _BV(OCIE0A); - usingInterrupt = true; + if (v) { + OCR0A = 0xAF; // Set up timer0 + TIMSK0 |= _BV(OCIE0A); // Enable timer0 } else { - TIMSK0 &= ~_BV(OCIE0A); - usingInterrupt = false; + TIMSK0 &= ~_BV(OCIE0A); // Disable timer0 } } -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) { s = "0" + 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"; - int dd = (int) latitude/100; - int mm = (int) latitude % 100; - int mmm = (int) round(1000 * (latitude - floor(latitude))); - String gps2lat = lat + int2fw(dd, 2) + " " + int2fw(mm, 2) + "." + int2fw(mmm, 3); + // fetch data + String lat = (String)GPS.lat; + String lon = (String)GPS.lon; + String gps2lat, gps2lon; + 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; mm = (int) longitude % 100; mmm = (int) round(1000 * (longitude - floor(longitude))); - String gps2lon = lon + int2fw(dd, 3) + " " + int2fw(mm, 2) + "." + int2fw(mmm, 3); - String myString = gps2lat + ", " + gps2lon; - return myString; + gps2lon = lon + int2fw(dd, 3) + " " + int2fw(mm, 2) + "." + int2fw(mmm, 3); + + // 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"; - 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); + // returns radians: e.g. String position = "N38 58.892, W076 29.177"; + 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; - if (myString.charAt(0) == 'S') { - lat *= -1; // Correct for hemisphere + + if (position.charAt(0) == 'S') { + lat *= -1; // Correct for hemispposition } + 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"; - 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); + // returns radians: e.g. String position = "N38 58.892, W076 29.177"; + 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; - if (myString.charAt(12) == 'W') { - lon *= -1; // Correct for hemisphere + + if (position.charAt(12) == 'W') { + lon *= -1; // Correct for hemispposition } + 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) { - // returns the great-circle distance between two points (radians) on a sphere - float h = sq((sin((lat1 - lat2) / 2.0))) + (cos(lat1) * cos(lat2) * sq((sin((lon1 - lon2) / 2.0)))); + // 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 d = 2.0 * rEarth * asin (sqrt(h)); + return d; }