1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| // if you use an Arduino with only one Serial port, uncomment this line
#define USE_SW_SERIAL
#ifdef USE_SW_SERIAL
#include <SoftwareSerial.h>
const uint8_t RXPin = 2; // the arduino pin on which to receive serial data from your GPS
const uint8_t TXPin = 3; // the arduino pin on which to transmit serial data to your GPS
SoftwareSerial gpsSerial(RXPin, TXPin);
#else
#define gpsSerial Serial1 // otherwise define here which Hardware Serial Port to use
#endif
// define your GPS baud rate (9600 is the default for GPS Neo 7M)
const uint32_t GPSBaud = 9600;
// The pins setting the distance threshold
const uint8_t pinDistance1 = 4;
const uint8_t pinDistance2 = 5;
// the pin triggering the alert. HIGH by default, turns LOW when distance is above threshold
const uint8_t alertPin = 9;
// the pin for the sound (a simple piezo) pin --- (piezo +) [piezo] (piezo -) ---- GND
const uint8_t piezoPin = 10;
// --------------------------------------------------------------
#include <TinyGPS++.h> // download from https://github.com/mikalhart/TinyGPSPlus
TinyGPSPlus gps;
double recordedLatitude;
double recordedLongitude;
double HaversineDistance(const double lat1, const double long1, const double lat2, const double long2)
{
double latRad1 = radians(lat1);
double latRad2 = radians(lat2);
double lonRad1 = radians(long1);
double lonRad2 = radians(long2);
double half_diffLa = (latRad2 - latRad1) / 2.0;
double s_half_diffLa = sin(half_diffLa);
double half_doffLo = (lonRad2 - lonRad1) / 2.0;
double s_half_doffLo = sin(half_doffLo);
double computation = asin(sqrt(s_half_diffLa * s_half_diffLa + cos(latRad1) * cos(latRad2) * s_half_doffLo * s_half_doffLo));
return 2.0 * 6372795.0 * computation;
}
bool feedGPS()
{
bool gotFix = false;
while (gpsSerial.available() > 0)
if (gps.encode(gpsSerial.read())) {
gotFix = true;
break;
}
return gotFix;
}
uint32_t maxDistance()
{
uint8_t dipSwitchByte = (digitalRead(pinDistance2) << 1) | digitalRead(pinDistance1);
switch (dipSwitchByte) {
case 0b10: return 50; // 50m
case 0b01: return 100; // 100m
}
return 20; // 20m
}
void checkPosition()
{
static bool firstFix = true;
static bool alert = false;
if (gps.location.isValid()) {
Serial.print(F("Position: ")); Serial.print(gps.location.lat());
Serial.write(','); Serial.println(gps.location.lng());
if (firstFix) {
recordedLatitude = gps.location.lat();
recordedLongitude = gps.location.lng();
tone(piezoPin, 1000, 200);
delay(210);
tone(piezoPin, 1000, 200);
firstFix = false;
Serial.print(F("Recorded Position = "));
Serial.print(recordedLatitude, 6); Serial.write(','); Serial.print(recordedLongitude, 6);
Serial.print(F("\t(Alerte @"));
Serial.print(maxDistance()); Serial.println(F(" m)"));
} else {
// we already recorded our start position
double distance = HaversineDistance(gps.location.lat(), gps.location.lng(), recordedLatitude, recordedLongitude);
Serial.print(F("Distance from origin: ")); Serial.print(distance); Serial.print(F(" m\t(Alerte @"));
Serial.print(maxDistance()); Serial.println(F(" m)"));
if (distance >= maxDistance()) {
if (!alert) {
digitalWrite(alertPin, LOW);
alert = true;
tone(piezoPin, 300, 100);
delay(120);
tone(piezoPin, 100, 100);
Serial.print(F("alert distance = ")); Serial.println(distance);
}
} else {
if (alert) {
digitalWrite(alertPin, HIGH);
tone(piezoPin, 300, 100);
delay(120);
tone(piezoPin, 600, 100);
Serial.print(F("Distance back in range : ")); Serial.println(distance);
}
alert = false;
}
}
}
}
void setup() {
pinMode(pinDistance1, INPUT_PULLUP);
pinMode(pinDistance2, INPUT_PULLUP);
pinMode(alertPin, OUTPUT);
pinMode(piezoPin, OUTPUT);
digitalWrite(alertPin, HIGH); // will go low in case of Alert
Serial.begin(115200);
gpsSerial.begin(GPSBaud);
tone(piezoPin, 2000, 100);
}
void loop() {
if (feedGPS()) checkPosition();
} |
Partager