#include <SoftwareSerial.h>
#include <TinyGPS++.h>
#include<TMRpcm.h>
#include <SPI.h>
#include <SD.h>
#define RXPin 2
#define TXPin 3
#define GPSBaud 9600
#define ConsoleBaud 9600
char location;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
char * wavFiles[] = {"a.wav","b.wav","c.wav" };
const int CS_PIN = 4;
TMRpcm tmrpcm;
void setup()
{
Serial.begin(ConsoleBaud);
...................
tmrpcm.speakerPin = 9;
pinMode(CS_PIN, OUTPUT);
Serial.println("A simple tracker using TinyGPS++.");
Serial.println();
}
void loop()
{
// If any characters have arrived from the GPS,
// send them to the TinyGPS++ object
....................
// Let's display the new location and altitude
// whenever either of them have been updated.
if (gps.location.isUpdated() || gps.altitude.isUpdated())
{
Serial.print("Location: ");
Serial.print(gps.location.lat(), 6);
Serial.print(",");
.............................
}
}
There was a similar question recently. Here's the main point:
/dev:
From the TMRpcm author:This library can be very processor intensive... May interfere with other libraries that rely on interrupts.
In your case, using a software serial library is probably not feasible. It might work with AltSoftSerial (requires pins 8 & 9, no PWM on 10). I doubt it would work with my NeoSWSerial. It definitely won't work with SoftwareSerial.
You will probably have to connect the GPS to
Serial
. Connect the GPS TX to Arduino pin 0 (RX) and GPS RX to Arduino pin 1 (TX). You will have to disconnect the GPS TX wire every time you want to upload a new sketch. You can still print debug statements.
That post also mentions switching from the default SD library (old) to the latest SdFat library. Here's a NeoGPS/SdFat version of your sketch:
#include <NMEAGPS.h>
#include <TMRpcm.h>
#include <SPI.h>
#include <SdFat.h> // <-- install new library and edit pcmConfig.h
//------------------------------
// PICK ONE of these for your GPS connection:
// 1) probably have to do this one
#define gpsPort Serial
// 2) This /might/ work
//#include <AltSoftSerial.h>
//AltSoftSerial gpsPort; // must be on pins 8 & 9
// 3) Doubtful
//#include <NeoSWSerial.h>
//NeoSWSerial gpsPort( 2, 3 );
// 4) NO WAY!
//#include <SoftwareSerial.h>
//SoftwareSerial gpsPort( 2, 3 );
//------------------------------
#define GPSBaud 9600
#define ConsoleBaud 9600
NMEAGPS gps;
NeoGPS::Location_t home( 24.012268, 89.278297 );
char * wavFiles[] = {"a.wav","b.wav","c.wav" };
const int CS_PIN = 4;
TMRpcm tmrpcm;
void setup()
{
Serial.begin(ConsoleBaud);
//gpsPort.begin(GPSBaud); // don't have to do this if gpsPort == Serial
tmrpcm.speakerPin = 9;
pinMode(CS_PIN, OUTPUT);
Serial.println( F("A simple tracker using NeoGPS.\n") ); // F macro saves RAM!
}
void loop()
{
// If any characters have arrived from the GPS,
// send them to the NeoGPS object
if (gps.available( gpsPort )) {
gps_fix fix = gps.read();
// Let's display the new location and altitude
if (fix.valid.location || fix.valid.altitude)
{
Serial.print( F("Location: ") );
Serial.print(fix.latitude(), 6);
Serial.print( ',' );
Serial.print( fix.longitude(), 6);
Serial.print( F(" Altitude: ") );
Serial.println( fix.altitude() );
if (fix.location.DistanceKm( home ) < 0.100) { // 100 meters = 0.1km
//give the voice output for my home
tmrpcm.play(wavFiles[1]);
}
}
}
}
You weren't correctly comparing the current location with your home location. The above sketch shows how to test if you're within 100m of the "home" location.
If you want to try it, NeoGPS is available from the Arduino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries.
Cheers,
/dev
Its working, Sir. Thank you so much for your help. I really so much appreciate it. You are a lifesaver.
#define RXPin 0
#define TXPin 1
#define gpsPort Serial
#define GPSBaud 9600
#define ConsoleBaud 9600
....................................
char * wavFiles[] = {"a.wav","b.wav","c.wav" };
const int CS_PIN = 4;
TMRpcm tmrpcm;
void setup()
{
Serial.begin(ConsoleBaud);
//gpsPort.begin(GPSBaud); // don't have to do this if gpsPort == Serial
......................
{
Serial.println( F("Card Failure") ); // F macro saves RAM
return;
}
tmrpcm.play("hello.wav");
delay(5000);
Serial.println( F("A simple tracker using NeoGPS.\n") ); // F macro saves RAM!
}
void loop()
{
{
;
pinMode(echoPin, INPUT);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2)/29.1;
Serial.print(distance);
delay(3000);
..................
// If any characters have arrived from the GPS,
// send them to the NeoGPS object
{
// Let's display the new location and altitude
.............
Serial.print( fix.longitude(), 6);
Serial.print( F(" Altitude: ") );
Serial.println( fix.altitude() );
................
}
}
}
}
I could not install the SdFat.h library file.
The SdFat library is a little different, because you have to unzip SdFat-master into a temporary directory, then copy the nested SdFat-master/SdFat directory to Arduino/Libraries. Do not unzip SdFat-master into Arduino/Libraries.
The project has to give output in voice for both sensors.
It looks like you have to use Multi Mode.
BTW, using delay will cause you to lose GPS data:
delay(3000);
Do not use delay.
You should take an ultrasonic reading after a gps fix is available. Then you can decide what track(s) to play based on the 2 distances:
#include <NMEAGPS.h>
#include <TMRpcm.h>
#include <SPI.h>
#include <SdFat.h>
SdFat SD;
#define gpsPort Serial
#define GPSBaud 9600
#define ConsoleBaud 9600
const int trigPin = 8;
const int echoPin = 7;
NMEAGPS gps;
NeoGPS::Location_t home( 24.012268, 89.278297 );
char * wavFiles[] = { "a.wav", "b.wav", "c.wav" };
const int CS_PIN = 4;
TMRpcm tmrpcm;
void setup()
{
Serial.begin(ConsoleBaud);
//gpsPort.begin(GPSBaud); // don't have to do this if gpsPort == Serial
tmrpcm.speakerPin = 9;
pinMode(CS_PIN, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
if(!SD.begin(CS_PIN)) {
Serial.println( F("Card Failure") ); // F macro saves RAM
return;
}
tmrpcm.play("hello.wav");
delay(5000);
Serial.println( F("A simple tracker using NeoGPS.\n") ); // F macro saves RAM!
}
void loop()
{
// If any characters have arrived from the GPS,
// send them to the NeoGPS object
if (gps.available( gpsPort )) {
gps_fix fix = gps.read();
// A new GPS fix was received, take an ultrasonic reading now
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
pinMode(echoPin, INPUT);
long duration = pulseIn(echoPin, HIGH);
long ultrasonicDistance = (duration/2)/29.1;
float gpsDistanceKm = 1000.0; // far away until we calculate it
// Let's display the new location and altitude
if (fix.valid.location || fix.valid.altitude)
{
Serial.print( F("Location: ") );
Serial.print(fix.latitude(), 6);
Serial.print( ',' );
Serial.print( fix.longitude(), 6);
Serial.print( F(" Altitude: ") );
Serial.println( fix.altitude() );
gpsDistanceKm = fix.location.DistanceKm( home );
}
// Display the distances
Serial.print( F("Distance: ultrasonic = ") );
Serial.print(ultrasonicDistance);
if (gpsDistanceKm < 1000.0) {
Serial.print( F(", GPS = ") );
Serial.print(gpsDistanceKm);
}
Serial.println();
// If no audio is busy playing, check to see if we should play something
if (!tmrpcm.isPlaying()) {
// Use the 2 distances to decide what audio to play
if (gpsDistanceKm < 0.100) // 100 meters = 0.1km
{
//give the voice output for my home
tmrpcm.play(wavFiles[2]);
}
if ((90 <= ultrasonicDistance) && (ultrasonicDistance < 102))
{
tmrpcm.play(wavFiles[0]);
} else if ((80 <= ultrasonicDistance) && (ultrasonicDistance <= 89))
{
tmrpcm.play(wavFiles[1]);
}
}
}
}
I do not know if this is how you use "Multi mode".
BTW, indentation is important. Use control-T in the IDE editor to auto-format your sketch.
Can you tell me pleas which Venus GPS module you buy from SparkFun?
Thank you, Sir. Its working perfectly.
the time delay is mandatory for the GPS.
Nonsense.
it will just keep repeating the location in voice output.
You need to think about what you want to happen.
Does it play the audio just once, when you first get "close" to home?
Do you have to get "far" from home before it plays the audio again, when you come back? How far away do you have to get?
The GPS coordinates varies a lot
Your GPS device is only accurate to 3m at its best. 10m to 30m is not unusual, depending on whether you have good or bad satellite reception.
Is there any way to get more accurate coordinate?
While stationary, you can average locations for 30 minutes to an hour to get an accurate stationary location.
Otherwise, you have to spend more money to have a "base" device that is stationary (at home?). It will have to send information to the "roaming" device. That information is used to increase the accuracy of the roaming device's GPS locations. This is not cheap.
I think the cheapest, easiest way to do what you want is to use hysteresis in your distance tests. For example
bool atHome = true;
void loop()
{
... GPS and distance code ...
if (distance > 250m) {
atHome = false;
}
if (!atHome and (distance < 100m)) {
atHome = true;
play the recording
}
}
It only plays the record once, when you get within 100m of home. It will not play the recording again until you go 250m away from home and then get with 100m of home. The whole sketch:
#include <NMEAGPS.h>
#include <TMRpcm.h>
#include <SPI.h>
#include <SdFat.h>
SdFat SD;
#define gpsPort Serial
#define GPSBaud 9600
#define ConsoleBaud 9600
const int trigPin = 8;
const int echoPin = 7;
NMEAGPS gps;
NeoGPS::Location_t home( 24.012268, 89.278297 );
bool atHome = true;
char * wavFiles[] = { "a.wav", "b.wav", "c.wav" };
const int CS_PIN = 4;
TMRpcm tmrpcm;
void setup()
{
Serial.begin(ConsoleBaud);
gpsPort.begin(GPSBaud); // don't have to do this if gpsPort == Serial
tmrpcm.speakerPin = 9;
pinMode(CS_PIN, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
if(!SD.begin(CS_PIN)) {
Serial.println( F("Card Failure") ); // F macro saves RAM
return;
}
tmrpcm.play("hello.wav");
delay(5000);
Serial.println( F("A simple tracker using NeoGPS.\n") ); // F macro saves RAM!
}
void loop()
{
// If any characters have arrived from the GPS,
// send them to the NeoGPS object
if (gps.available( gpsPort )) {
gps_fix fix = gps.read();
// A new GPS fix was received, take an ultrasonic reading now
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
pinMode(echoPin, INPUT);
long duration = pulseIn(echoPin, HIGH);
long ultrasonicDistance = (duration/2)/29.1;
float gpsDistanceKm = 10000.0; // far away until we calculate it
// Let's display the new location and altitude
Serial.print( F("Location: ") );
if (fix.valid.location) {
Serial.print(fix.latitude(), 6);
Serial.print( ',' );
Serial.print( fix.longitude(), 6);
gpsDistanceKm = fix.location.DistanceKm( home );
}
Serial.print( F(" Altitude: ") );
if (fix.valid.altitude)
Serial.print( fix.altitude() );
Serial.println();
// Display the distances
Serial.print( F("Distance: ultrasonic = ") );
Serial.print(ultrasonicDistance);
if (fix.valid.location) {
Serial.print( F(", GPS = ") );
Serial.print(gpsDistanceKm);
}
Serial.println();
if (gpsDistanceKm > 0.250) { // 250m
atHome = false;
}
// If no audio is busy playing, check to see if we should play something
if (!tmrpcm.isPlaying()) {
// Use the 2 distances to decide what audio to play
if (!atHome && (gpsDistanceKm < 0.100)) // 100 meters = 0.1km
{
atHome = true;
//give the voice output for my home
tmrpcm.play(wavFiles[2]);
}
if ((90 <= ultrasonicDistance) && (ultrasonicDistance < 102))
{
tmrpcm.play(wavFiles[0]);
} else if ((80 <= ultrasonicDistance) && (ultrasonicDistance <= 89))
{
tmrpcm.play(wavFiles[1]);
}
}
}
}
Cheers,
/dev
#include <SPI.h>
#include <SD.h>
#define RXPin 0
#define TXPin 1
#define GPSBaud 9600
#define ConsoleBaud 9600
#define gpsPort Serial
const int trigPin = 8;
const int echoPin = 7;
char mychar ;
void setup()
{
//gpsPort.begin(GPSBaud); // don't have to do this if gpsPort == Serial
tmrpcm.speakerPin = 9;
.............
Serial.println( F("Card Failure") ); // F macro saves RAM
return;
}
delay(5000);
Serial.println( F("A simple tracker using NeoGPS.\n") ); // F macro saves RAM!
}
void loop()
{
// If any characters have arrived from the GPS,
// send them to the NeoGPS object
// A new GPS fix was received, take an ultrasonic reading now
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
{
Serial.print( F("Location: ") );
Serial.print(fix.latitude(), 6);
Serial.print( ',' );
Serial.print( fix.longitude(), 6);
Serial.print( F(" Altitude: ") );
Serial.println( fix.altitude() );
}
Serial.print( F("Distance: ultrasonic = ") );
Serial.print(ultrasonicDistance);
Serial.println();
..........
...........
}
}
How about deleting one of your usernames: raineee35 or atik666. Maybe you're using two computers, but you should only login with one username.
As for the progressing through waypoints "home", "cafe", and "market", I would suggest putting them in an array. Then calculate the distance to each of them when you get a new fix. Incorporate the hysteresis I suggested in my previous reply to limit how often a the audio is played.
A separate problem is giving directions. You have to know which way the vehicle is facing to suggest "turn right". GPS does not give you a direction when the speed is < 5kph. You could suggest "go west" at any time.
Here is a similar thread. I posted a sketch with an array of Locations.
Cheers,
/dev
Sir,
We are different persons but working on the same team. That is why our questions are similar.
Please sir help us.It's our final year project.Sir we are a team not same person.
Thanks
if (!atHome && (fix.location.DistanceKm( home ) < 0.050))
{
atHome = true;
tmrpcm.play("50.wav");
}
if (!atHome && (fix.location.DistanceKm( cafe ) < 0.020))
{
atHome = true;
tmrpcm.play("hw.wav");
}
else if (!atHome && (fix.location.DistanceKm( market ) < 0.010))
{
atHome = true;
tmrpcm.play("cg.wav");
}
I think you are missing an "else". Only one of those should happen. Beyond that...
It's not working sir. The audio output repeats with respect to co-ordinate outputs.
... you'll have to be more specific.
You may need to have another flag for which of the two things are playing: location or distance audio tracks. Your current code will only start one of them at a time, unless they both start at the same time. Maybe something like this:
bool locationPlaying, distancePlaying;
...
if (!tmrpcm.isPlaying()) {
locationPlaying = false;
distancePlaying = false;
}
if (!locationPlaying && !atHome) {
if (fix.location.DistanceKm( home ) < 0.050)
{
atHome = true;
tmrpcm.play("50.wav");
locationPlaying = true;
}
else if (fix.location.DistanceKm( cafe ) < 0.020)
{
atHome = true;
tmrpcm.play("hw.wav");
locationPlaying = true;
}
else if (fix.location.DistanceKm( market ) < 0.010)
{
atHome = true;
tmrpcm.play("cg.wav");
locationPlaying = true;
}
}
if (!distancePlaying) {
if ((20 <= ultrasonicDistance) && (ultrasonicDistance < 49))
{
tmrpcm.play("first.wav");
distancePlaying = true;
}
else if ((50<= ultrasonicDistance) && (ultrasonicDistance <= 79))
{
tmrpcm.play("second.wav");
distancePlaying = true;
}
else if ((80<= ultrasonicDistance) && (ultrasonicDistance <= 120))
{
tmrpcm.play("third.wav");
distancePlaying = true;
}
}
Try adding some debug print statements to show the distances and the flags.
Dear dev sir,
We have completed our project temporarily. Without your help we may not be successful. If all the people will be helpful like you then all the new amateur programmer will inspire to go ahead.We are really grateful to you that could not express in words.Thank you so much sir.