Geofencing Alarmanlage - [Teil 3 der GPS Modul Reihe] - AZ-Delivery

Willkommen zu einem neuen Teil unserer GPS-Monitor Reihe. Heute zeige ich eine weitere spannende Verwendungsmöglichkeit unseres GPS Moduls. Wir bauen mithilfe des GPS Modules eine "Alarmanlage" für Mobile Dinge, wie z.B. ein Motorrad, ein Auto, einen Campingwagen oder das eigene Fahrrad. Das besondere an unserer "Alarmanlage" ist, dass sie auf Grundlage des Geofencings (s.u.) arbeitet.

Der Aufbau

So sieht der Schaltplan dazu aus:

Benötigte Hardware

Als Hardware-Einzelteile benötigen wir aus dem Shop:

Anzahl Beschreibung Zusatz
1 Ardunio Nano
1 NEO-6M GPS Modul
1 Relais Modul Low aktiv, 1 bis 2 Relais
1 Taster
3 Widerstände 120 Ohm
1 RGB LED gemeinsame Kathode

Erklärung zu Geofencing

Bevor wir beginnen, schauen wir uns auf Wikipedia die Definition des Begriffs Geofencing an:

Aus Wikipedia:

Mit Geofencing (Kunstwort aus englisch geographic „geografisch“ und fence „Zaun“) wird das automatisierte Auslösen einer Aktion durch das Überschreiten einer gedachten Begrenzung auf der Erdoberfläche oder in der Luft[1] bezeichnet. In den meisten Fällen definiert die Begrenzung eine geschlossene Fläche, sodass zwischen innen und außen unterschieden werden kann. Beispielsweise kann beim Eintritt in die Fläche oder beim Verlassen der Fläche eine Benachrichtigung ausgelöst werden.

Das beobachtete Objekt muss dazu in regelmäßigen Abständen seine Position senden oder die Abfrage seiner Position von außen ermöglichen. Diese Ortsbestimmung kann über das Mobilfunksystem auf Funkzellenebene oder koordinatenbezogen über ein Navigationssatellitensystem erfolgen.

Als Geofencing-Bereiche können Kreise oder Rechtecke definiert werden; durch Verwendung von Polygonzügen können aber auch komplexe Geometrien, beispielsweise administrative Grenzen, verarbeitet werden. Die Entscheidung, ob sich das beobachtete Objekt innerhalb oder außerhalb des vordefinierten Gebietes befindet, wird mit Hilfe eines Geoinformationssystems getroffen.

Die ausgelöste Aktion kann sich auf eine Benachrichtigung per E-Mail oder SMS beschränken, sie kann bei Fahrzeugen aber auch die Aktivierung einer Wegfahrsperre sein oder auch ein Warnsignal des Gerätes, das dem Anwender die Überschreitung des Bereichs signalisiert. Durch Verwendung von Daten weiterer Sensoren kann die Entscheidung über eine Alarmauslösung differenziert werden.

Je nach Komplexität der Aufgabe werden die Daten von Dritten erhoben und ausgewertet, was, insbesondere bei der Personenüberwachung, mit zusätzlichen datenschutzrechtlichen Fragestellungen verbunden ist.

Quelle: Wikipedia

Was bedeutet dies für die Arbeitsweise unserer „Alarmanlage“? Nun, dies bedeutet, dass unser System nicht, wie vielen anderen Systemen bei Erschütterung des zu sichernden Objektes oder bei Aktivierung eines elektrischen Verbrauchers auslöst, sondern erst! bei Hinausbewegen des gesicherten Objektes aus einem selbst definierten, runden "virtuellen Zaun" heraus. (Daher stammt auch der Begriff des Geofencings)

Dieser virtuelle Zaun wird beim Aktivieren der Alarmanlage von dem Arduino um den aktuellen Standort des Objektes gelegt. D.h wird bei aktivierter „Alarmanlage“ erst beim Verlassen der AKTUELLEN Standortes aus einem selbst definierbaren Radius hinaus Alarm ausgelöst. Dieser Radius kann im Programm mithilfe der Variable

double GeofenceinMeters = 30;

definiert werden. Im folgend vorgestellten Quelltext ist diese Variable mit einem Radius von 30 Metern vordefiniert. Diese sollte aber nach den eigenen Bedürfnissen angepasst werden.

Wer die Bibliothek TinyGPS++ noch nicht bei GitHub heruntergeladen hat (siehe Teil 1 unseres GPS-Blogs), hier noch einmal der Link:  https://github.com/mikalhart/TinyGPSPlus/releases

Die Software

// GPS Alarmanlage 2020 Tobias Kuch GPL 3.0
#define SwitchPIN 9
#define RGBLED_Red 8
#define RGBLED_Green 7
#define RGBLED_Blue 6
#define Relais_Alarm 2
#include <SoftwareSerial.h>
#include <TinyGPS++.h>

TinyGPSPlus gps;
SoftwareSerial ss(4, 3);


float ActualGpsLAT = 0; 
float ActualGpsLON = 0;
bool DistanceInKM = false;
bool Button1Pressed = false;
double Distance = 0;
bool systemarmed = false;
bool initsystemarmed = false;
double GeofenceinMeters = 30;

bool Engage_Alarm = false;
byte SmartdelayLoop = 0;

void setup()
{
  systemarmed = false;
  Serial.begin(9600);
  pinMode(SwitchPIN, INPUT_PULLUP); // Setzt den Digitalpin 9 als Inputpin mit internem Pullup
  pinMode(RGBLED_Red,OUTPUT);
  pinMode(RGBLED_Green,OUTPUT);
  pinMode(RGBLED_Blue,OUTPUT);
  pinMode(Relais_Alarm,OUTPUT);
  digitalWrite(Relais_Alarm, HIGH);
  digitalWrite(RGBLED_Red, LOW);
  digitalWrite(RGBLED_Green, LOW);
  digitalWrite(RGBLED_Blue, HIGH);
  delay(100);
  digitalWrite(RGBLED_Red, HIGH);
  digitalWrite(RGBLED_Green, LOW);
  digitalWrite(RGBLED_Blue, LOW);
  delay(100);
  digitalWrite(RGBLED_Red, LOW);
  digitalWrite(RGBLED_Green, HIGH);
  digitalWrite(RGBLED_Blue, LOW);

  ss.begin(9600);
  smartdelay(1000);
}

void loop()
{

if (gps.location.isValid()& ActualGpsLAT < 90 & ActualGpsLON < 180 )
    {   
    if (gps.location.isUpdated())
      {  
      if ((systemarmed) && (initsystemarmed) )
        {
        initsystemarmed = false;
        digitalWrite(RGBLED_Red, HIGH);
        digitalWrite(RGBLED_Green, LOW);
        digitalWrite(RGBLED_Blue, LOW);
        Serial.println (gps.location.lat());
        Serial.println (gps.location.lng());
        Serial.println("ValidGPS Coordinates transferred to Memory");
        ActualGpsLAT = gps.location.lat();  // Location is stored in Memory
        ActualGpsLON = gps.location.lng();  // Location is stored in Memory
        Serial.println (ActualGpsLAT);
        Serial.println (ActualGpsLON);
        }        
      double Getlat = gps.location.lat();
      double Getlng = gps.location.lng();
      
      Distance = gps.distanceBetween(Getlat,Getlng,ActualGpsLAT,ActualGpsLON);
      Serial.print("Distance Calculated: "); 
      Serial.print(Distance); 
      Serial.println(" m"); 
      if ((systemarmed) && (!(initsystemarmed)) )
        {
        if ((Distance > GeofenceinMeters) && ((ActualGpsLAT != gps.location.lat()) || (ActualGpsLON != gps.location.lng()) ) ) 

          {
            // engage time Limited Alarm !
             Engage_Alarm = true;
             SmartdelayLoop = 0;
             Serial.println("Alarm Engaged, transferring new GPS Coordinates to Memory.");
             ActualGpsLAT = gps.location.lat();  // Location is stored in Memory
             ActualGpsLON = gps.location.lng();  // Location is stored in Memory 
             Serial.println (ActualGpsLAT);
             Serial.println (ActualGpsLON);
          }            
        }
      }    
    } 

Alarm_Control();
smartdelay(5000);
}


void Alarm_Control()
{
if (Engage_Alarm)
  {
  if (SmartdelayLoop < 7)
    {
    digitalWrite(Relais_Alarm, LOW);  

    } else
    {
    Engage_Alarm = false;
    digitalWrite(Relais_Alarm, HIGH);  
    } 
  } else
  {
  Engage_Alarm = false;
  digitalWrite(Relais_Alarm, HIGH);  
  }
}
static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    if (!(digitalRead(SwitchPIN)))   // read the input pin
      {
      delay(100);   //debouncing  
      if (!Button1Pressed)
        {
        Button1Pressed = true;
        systemarmed = !systemarmed;
        if (systemarmed)
           {
           digitalWrite(RGBLED_Red, HIGH);
           digitalWrite(RGBLED_Green, LOW);
           digitalWrite(RGBLED_Blue, HIGH);
           initsystemarmed = true;
           Serial.println("Alarm System Activated with Init Coordinates:"); 
           Serial.println (gps.location.lat());
           Serial.println (gps.location.lng());
           
           } else
           {
           Serial.println("Alarm System DeActivated");  
           digitalWrite(RGBLED_Red, LOW);
           digitalWrite(RGBLED_Green, HIGH);
           digitalWrite(RGBLED_Blue, LOW);
           initsystemarmed = false;
           Engage_Alarm = false;
           SmartdelayLoop = 0;
           digitalWrite(Relais_Alarm, HIGH); 
           }         
        } 
      }  else
      {
      Button1Pressed = false;  
      }
      
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
  SmartdelayLoop = SmartdelayLoop + 1;
}


Bedienung

Zur Bedienung und Kontrolle unserer „Geofence Alarmanlage“ stehen uns nachfolgende Bedienelemente zur Verfügung:

  • Status-Anzeige: RGB LED

Magenta leuchtend: Die Alarmanlage ist scharf, Alarmanlagenfunktion ist jedoch noch nicht gegeben, da der GPS-Empfänger keine gültigen GPS-Informationen empfangen konnte. Eine Scharfschaltung erfolgt automatisch bei Empfang eines gültigen GPS-Signals.
Grün leuchtend: Die Alarmanlage ist unscharf, die Alarmanlage kann bei Bedarf scharfgeschaltet werden.
Rot leuchtend: Die Alarmanlage ist scharf.

  • Status-Änderung: Taster

Zur Scharfstellung bzw. Abschaltung der Alarmanlage dient der Taster, der an Port D9 angeschlossen ist. Dieser Port ist als Eingang definiert mit internem Pullup-Widerstand. Beim Drücken des Tasters wird D9 kurzzeitig auf Ground gelegt. (Zu beachten: Signal muss MINDESTENS 500 ms anliegen). Dabei dient der Taster als Ein- bzw. Ausschalter.

Bei Auslösung der Alarmanlage wird der MOS-Transistor Ausgang (Port: 2) für 30 Sekunden auf Low geschaltet. Dieser Ausgang eignet sich für eine Sirene, die bei Bedarf daran angeschlossen und für 30 Sekunden aktiviert wird.

Auf einen weiteren Schaltausgang, der bei Auslösung der Alarmanlage einen weiteren MOS-Transistor bis zur Deaktivierung der Alarmanlage aktiviert, wird aus guten Gründen! verzichtet.
Beispielsweise ist u.a ein zeitlich unbegrenzter und damit dauerhafter Alarm Ton in Deutschland nicht erlaubt!

Bitte beachten Sie, dass das vorgestellte Projekt lediglich eine prinzipielle Durchführbarkeit belegt. Sollte diese Schaltung in der Praxis eingesetzt werden, schließe ich die Haftung für etwaige daraus entstehende Schäden aus. Dies schließt auch genervte Nachbarn durch Fehlalarme mit ein :)

Es soll hier lediglich das Prinzip des Geofencings anhand eines konkreten Anwendungsbeispiels verdeutlicht werden. Ich wünsche viel Spaß beim Nachbau und Experimentieren. 

Bis zum nächsten Mal.

      Für arduinoProjekte für anfänger

      7 Kommentare

      MannixPB

      MannixPB

      Hallo. Ich habe das Projekt mal nachgebaut und die “Distance Calculated” beobachtet Ohne den Standort gewechselt zu haben, wird irgendwann ein Wert über 30 Meter angezeigt und somit der Alarm ausgelöst.
      Hat jemand eine Idee warum ?

      Gruß
      Manfred

      Sonnhard Stubbe

      Sonnhard Stubbe

      Ich bin eher ein Anfänger und nicht sehr versiert bei der Arduino-Programmierung. Bei der Kompilierung des Sketches erhalte ich beim Kommando “smartdelay(….)” stets die Fehlermeldung “smartdelay was not declared in this scope”. Was mache ich falsch?

      Jörg

      Jörg

      Hallo an alle, hallo Killian,

      leider nicht viel Neues. Ich habe jetzt 5 Platinen mit Antenne ausprobiert.
      Nur bei einer Platine bekomme ich beim Anlegen von 3,3 Volt sofort eine Reaktion der blauen LED auf dem GPS Board. Laut Beschreibung blinkt die blaue LED sekündlich, wenn genügend Satelliten erreichbar sind. (laut Beschreibung leuchtet die LED gar nicht, wenn die Suche nach Satelliten erfolgt) Nach einer Weile leuchtet dann die blaue LED des GPS Boards sekündlich , allerdings bekomme ich weiterhin im Seriellen Monitor 0.00 angezeigt. RX von GPS hängt an D3 Nano, TX von GPS hängt an D4 Nano.
      TX des Nanos blinkt auch sekündlich, aber anscheinend kommt kein gültiges Signal vom GPS Board an.
      Die anderen 4 GPS Boards machen gar nichts?!
      Ich bin auch ratlos, hat noch jemand eine Idee?
      Viele Grüße
      Jörg

      kilian stern

      kilian stern

      Hallo Jörg, mir gehts wie dir, nur dass bei mir die Antenne nicht einmal blinkt. Hast du schon mehr Info?
      Gruß
      kilian

      Jörg S.

      Jörg S.

      Hallo an alle,
      ich habe es nachgebaut, allerdings bekomme ich keine GPS Koordinaten!!!!
      RX der GPS Platine ist an D3 des Nanos und TX an D4,
      GPS Platine mit Antenne hängt an 5V Versorgung und blinkt im Sekundentakt blau.
      Allerdings bekomme ich beim Druck des Tasters nur 0.00 angezeigt.
      Hat jemand eine Idee?

      Vielen Dank und Grüße
      Jörg

      Dieter Pahl

      Dieter Pahl

      Ich habe mit großem Interesse die drei Beiträge von Tobias Kuch zum Geocaching/GPS gelesen. Den im Teil 1 und 2 beschriebenen Aufbau habe ich nachgebaut und alles läuft ausgezeichnet. Da mich für Fotozwecke das Tracking mit GPS interessiert, habe ich versucht, den im Teil 2 beschriebenen Aufbau um ein SPI- Modul (Mini SD Card Reader) zu erweitern. Schaltungstechnisch war das kein Problem, aber meine “Erweiterungen” am Originalsketch von Tobias sind unzureichend. Konkret: immer wenn ich den Taster betätige um die Zielköördinaten zu überschreiben sollen Datum, Uhrzeit und die aktuellen Koordinatenpaare auf die SD Karte geschrieben werden. hat da jemand, vieleicht sogar Tobias, eine Idee für mich? Ich würde mich sehr freuen!
      Mit vielen Grüßen
      Dieter Pahl

      Hübner

      Hübner

      Das ist genau das,was ich schon seit Jahren suche! Jetzt benötige ich noch eine erweiterung,welche mir die aktuelle Position übermittelt. Z.B. per sms.
      Für mich geht es darum Weidegeräte zu sichern! Beim wieder einschalten an einem anderem Standort muss es die Aktuelle Position senden. Mit freundlichen Grüßen Uwe Hübner

      Kommentar hinterlassen

      Alle Kommentare werden von einem Moderator vor der Veröffentlichung überprüft

      Empfohlene Blogbeiträge

      1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
      2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
      3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
      4. ESP32 - das Multitalent - AZ-Delivery