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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
| // Library Required on top of the Arduino environment. Those Library are the property of their respective owners
// SimpleBouton Library : http://forum.arduino.cc/index.php?topic=375232.0
// TinyGPS++ library : https://github.com/mikalhart/TinyGPSPlus
/*
--------------------------------------------------------------
KEEP THIS INFORMATION IF YOU USE THIS CODE
Copyright (c) 2021 Jay For the Developpez.com forum
https://www.developpez.net/forums/d2100922/general-developpement/programmation-systeme/embarque/arduino/projet-arduino-gps-neo-7m/
Licenses for libraires included in this program apply
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This program 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. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------
*/
// ======== CONFIGURATION DU HARDWARE ============
// 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 = 4; // 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 to set the alert distance 20 + 6 x bitMask (bitMask from LSB to MSB).
// eg if dip config is 1001 that's 9 in decimal, distance will be 20 + 9x6 = 74m.
// min distance = 20m, max distance with bitMaks @1111 = 100m
const uint8_t dipSwitchPins[] = {4, 5, 6, 7};
const uint8_t nbDipSwitches = sizeof dipSwitchPins / sizeof dipSwitchPins[0];
// button to record position, wired as : pin---But---GND
const uint8_t recordPositionPin = 8;
// the pin triggering the alert. HIGH by default, turns LOW when distance is above threshold
const uint8_t alertPin = 9;
// --------------------------------------------------------------
#include <simpleBouton.h>
simpleBouton boutonPosition(recordPositionPin);
#include <TinyGPS++.h>
TinyGPSPlus gps;
double recordedLatitude;
double recordedLongitude;
bool recordedPosition = false;
// The haversine formula determines the great-circle distance between two points on a sphere given their longitudes and latitudes
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; // in m, approximates earth to a sphere with radius is 6372795m
}
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 = 0;
for (uint8_t i = 0; i < nbDipSwitches; i++)
if (digitalRead(dipSwitchPins[i]) == LOW) bitSet(dipSwitchByte, i);
return 20ul + 6 * dipSwitchByte; // dipSwitchByte between 0 and 15 => distance between 20+0=20 and 20+6*15=100
}
void checkUserAction()
{
static bool recordingAttempt = false;
uint32_t duree = boutonPosition.dureeEnfonce();
boutonPosition.actualiser();
if (boutonPosition.vientDEtreEnfonce()) recordingAttempt = true;
if (recordingAttempt && (boutonPosition.vientDEtreRelache() || (duree > 2000))) {
if (gps.location.isValid()) {
recordedLatitude = gps.location.lat();
recordedLongitude = gps.location.lng();
recordedPosition = true;
recordingAttempt = false;
Serial.print(F("Recorded Position = "));
Serial.print(recordedLatitude, 6); Serial.write(','); Serial.println(recordedLongitude, 6);
} else {
Serial.println(F("Can't record position, no valid fix"));
}
}
}
void checkPosition()
{
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 (recordedPosition) {
double distance = HaversineDistance(gps.location.lat(), gps.location.lng(), recordedLatitude, recordedLongitude);
Serial.print(F("Distance from position: ")); Serial.print(distance); Serial.println(F(" m"));
if (distance >= maxDistance()) {
if (!alert) {
digitalWrite(alertPin, LOW);
alert = true;
Serial.print(F("alert distance = ")); Serial.println(distance);
}
} else {
if (alert) {
Serial.print(F("Distance back in range : "));
Serial.println(distance);
digitalWrite(alertPin, HIGH);
}
alert = false;
}
}
}
}
void setup() {
for (auto& p : dipSwitchPins) pinMode(p, INPUT_PULLUP);
pinMode(alertPin, OUTPUT);
digitalWrite(alertPin, HIGH); // will go low in case of Alert
Serial.begin(115200);
gpsSerial.begin(GPSBaud);
}
void loop() {
checkUserAction();
if (feedGPS()) checkPosition();
} |
Partager