I am making a reverse geocache box like the one made by Mikal Hart of Arduiniana.com. After getting my GPS to work I was super excited to see that he released his code through the make website MAKE 25: Arduino Revolution - Make: DIY Projects and Ideas for Makers Upon compiling the code however this line of code in the loop function...
float distance_meters = TinyGPS::distance_between(lat, lon, DEST_LATITUDE, DEST_LONGITUDE);
prompted this error message...
distance_between is not a member of TinyGPS
I have all of Mikal's libraries installed from arduiniana.com and am at a loss right now. can someone please point me in the right direction? Thank you!
Here is the whole program with the line in question highlighted for reference:
/*
puzzle_box_sample.pde - Sample Arduino Puzzle Box sketch for MAKE.
COPYRIGHT (c) 2008-2011 MIKAL HART. All Rights Reserved.
This software is licensed under the terms of the Creative
Commons "Attribution Non-Commercial Share Alike" license, version
3.0, which grants the limited right to use or modify it NON-
COMMERCIALLY, so long as appropriate credit is given and
derivative works are licensed under the IDENTICAL TERMS. For
license details see
http://creativecommons.org/licenses/by-nc-sa/3.0/
This source code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This code is written to accompany the January, 2011 MAKE article
entitled "Reverse Geocache Puzzle Box".
This sketch illustrates how one might implement a basic puzzle box
that incorporates rudimentary aspects of the technology in Mikal
Hart's Reverse Geocache(tm) puzzle.
"Reverse Geocache" is a trademark of Mikal Hart.
For supporting libraries and more information see
http://arduiniana.org.
*/
#include <PWMServo.h>
#include <NewSoftSerial.h>
#include <TinyGPS.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
/* Pin assignments for the version 1.0 shield */
static const int GPSrx = 2, GPStx = 3;
static const int LCD_Enable = 11, LCD_RS = 10, LCD_RW = 7;
static const int LCD_DB4 = 19, LCD_DB5 = 17, LCD_DB6 = 18, LCD_DB7 = 16;
static const int pololu_switch_off = 15; // Pololu switch control
static const int servo_control = 9;
static const int LED_pin = 12;
/* These values should be adjusted according to your needs */
static const int CLOSED_ANGLE = 90; // degrees
static const int OPEN_ANGLE = 165; // degrees
static const float DEST_LATITUDE = 48.8469;
static const float DEST_LONGITUDE = -2.9986;
static const int RADIUS = 2000; // meters
/* Fixed values should not need changing */
static const int DEF_ATTEMPT_MAX = 50;
static const int EEPROM_OFFSET = 100;
/* The basic objects needed */
NewSoftSerial nss(GPSrx, GPStx);
LiquidCrystal lcd(LCD_RS, LCD_RW, LCD_Enable, LCD_DB4, LCD_DB5, LCD_DB6, LCD_DB7);
TinyGPS tinygps;
int attempt_counter;
PWMServo servo;
/* A helper function to display messages of a specified duration */
void Msg(LiquidCrystal &lcd, const char *top, const char *bottom, unsigned long del)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(top);
lcd.setCursor(0, 1);
lcd.print(bottom);
delay(del);
}
/* The Arduino setup() function */
void setup()
{
/* attach servo motor */
servo.attach(servo_control);
/* establish a debug session with a host computer */
Serial.begin(115200);
/* establish communications with the GPS module */
nss.begin(4800);
/* establish communication with 8x2 LCD */
lcd.begin(16,2); // this for an 8x2 LCD -- adjust as needed
/* Make sure Pololu switch pin is OUTPUT and LOW */
pinMode(pololu_switch_off, OUTPUT);
digitalWrite(pololu_switch_off, LOW);
/* make sure motorized latch is closed */
servo.write(CLOSED_ANGLE);
/* read the attempt counter from the EEPROM */
attempt_counter = EEPROM.read(EEPROM_OFFSET);
if (attempt_counter == 0xFF) // brand new EEPROM?
attempt_counter = 0;
/* increment it with each run */
++attempt_counter;
/* Copyright notice */
Msg(lcd, "(C) 2010", "M. Hart", 1500);
/* Greeting */
Msg(lcd, "Welcome", "to your", 2000);
Msg(lcd, "puzzle", "box!", 2000);
/* Game over? */
if (attempt_counter >= DEF_ATTEMPT_MAX)
{
Msg(lcd, "Sorry!", "No more", 2000);
Msg(lcd, "attempts", "allowed!", 2000);
PowerOff();
}
/* Print out the attempt counter */
Msg(lcd, "This is", "attempt", 2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(attempt_counter);
lcd.print(" of ");
lcd.print(DEF_ATTEMPT_MAX);
delay(2000);
/* Save the new attempt counter */
EEPROM.write(EEPROM_OFFSET, attempt_counter);
Msg(lcd, "Seeking", "Signal..", 0);
}
/* The Arduino loop() function */
void loop()
{
/* Has a valid NMEA sentence been parsed? */
if (nss.available() && tinygps.encode(nss.read()))
{
float lat, lon;
unsigned long fix_age;
/* Have we established our location? */
tinygps.f_get_position(&lat, &lon, &fix_age);
if (fix_age != TinyGPS::GPS_INVALID_AGE)
{
/* Calculate the distance to the destination */
[glow] float distance_meters = TinyGPS::distance_between(lat, lon, DEST_LATITUDE, DEST_LONGITUDE);[/glow]
/* Are we close?? */
if (distance_meters <= RADIUS)
{
Msg(lcd, "Access", "granted!", 2000);
servo.write(OPEN_ANGLE);
}
/* Nope. Print the distance. */
else
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Distance");
lcd.setCursor(0, 1);
if (distance_meters < 1000)
{
lcd.print((int)distance_meters);
lcd.print(" m.");
}
else
{
lcd.print((int)(distance_meters / 1000));
lcd.print(" km.");
}
delay(4000);
Msg(lcd, "Access", "Denied!", 2000);
}
PowerOff();
}
}
/* Turn off after 5 minutes */
if (millis() >= 300000)
PowerOff();
}
/* Called to shut off the system using the Pololu switch */
void PowerOff()
{
Msg(lcd, "Powering", "Off!", 2000);
lcd.clear();
/* Bring Pololu switch control pin HIGH to turn off */
digitalWrite(pololu_switch_off, HIGH);
/* This is the back door. If we get here, then the battery power */
/* is being bypassed by the USB port. We'll wait a couple of */
/* minutes and then grant access. */
delay(120000);
servo.write(OPEN_ANGLE); // and open the box
/* Reset the attempt counter */
EEPROM.write(EEPROM_OFFSET, 0);
/* Leave the latch open for 10 seconds */
delay(10000);
/* And then seal it back up */
servo.write(CLOSED_ANGLE);
/* Exit the program for real */
exit(1);
}
Will