I need help with Geofencing

Hello everyone,

despite searching the whole internet for days I wasn't able to get what I want.

simply my project is to create a home quarantine device. I am almost done with it , I have got the desired location outputs and I was able to store it in the database.

it is just this last part that it troubled me the most and I am not able to do it, which is Geofencing . Basically what I want is if the quarantined person leaves his area it would send an SMS messages that notifies me that the person left the designed boundaries.

if someone could help me please. I'd be forever grateful

the components I am using are
1 Arduino uno
2 SIM 800L
3 NEO-6M GPS

The code I am using

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <AltSoftSerial.h>

#define rxPin 2
#define txPin 3
SoftwareSerial sim800L(rxPin,txPin); 

SoftwareSerial GPRS(2, 3);
boolean state, lastState;

//GPS Module RX pin to Arduino 9
//GPS Module TX pin to Arduino 8
AltSoftSerial neogps;


TinyGPSPlus gps;

unsigned long previousMillis = 0;
long interval = 60000;


void setup()
{
  //Start of Alret sms message 
  pinMode(4, INPUT_PULLUP);
  state = digitalRead(4);
  lastState = state;
  
  GPRS.begin(9600);
  Serial.begin(9600);
  
  GPRS.println("AT+CMGF=1");
  
  delay(1000);
  // end of Alret sms message 
  
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(9600);
  
  //Begin serial communication with Arduino and SIM800L
  sim800L.begin(9600);

  //Begin serial communication with Arduino and SIM800L
  neogps.begin(9600);

  Serial.println("Initializing...");
  //delay(10000);

  //Once the handshake test is successful, it will back to OK
  sendATcommand("AT", "OK", 2000);
  sendATcommand("AT+CMGF=1", "OK", 2000);
  //sim800L.print("AT+CMGR=40\r");
  
}

void loop()
{
   state = lastState;
  lastState = digitalRead(4);
  
  if ( state != lastState ) {
    sendSMS();
  }
  
  delay(500);
  
  while(sim800L.available()){
    Serial.println(sim800L.readString());
  }
  while(Serial.available())  {
    sim800L.println(Serial.readString());
  }

    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis > interval) {
       previousMillis = currentMillis;
       sendGpsToServer();
    }
}
void sendSMS() {
  Serial.print("wire was cut ");
  Serial.println(state ? "on" : "off");
  
  GPRS.println("AT+CMGS=\"+05488345708\"");  
  
  delay(500);
  
  GPRS.print("wire was plugged ");
  GPRS.println(state ? "on" : "off");
  
  GPRS.write( 0x1a ); // ctrl+Z character
  
  delay(500);
}
int sendGpsToServer()
{
    //Can take up to 60 seconds
    boolean newData = false;
    for (unsigned long start = millis(); millis() - start < 2000;){
      while (neogps.available()){
        if (gps.encode(neogps.read())){
          newData = true;
          break;
        }
      }
    }
  
    //If newData is true
    if(true){
      newData = false;
      
      String latitude, longitude;
      float altitude;
      unsigned long date, time, speed, satellites;
  
      latitude = String(gps.location.lat(), 6); // Latitude in degrees (double)
      longitude = String(gps.location.lng(), 6); // Longitude in degrees (double)
      altitude = gps.altitude.meters(); // Altitude in meters (double)
      date = gps.date.value(); // Raw date in DDMMYY format (u32)
      time = gps.time.value(); // Raw time in HHMMSSCC format (u32)
      
      
      Serial.print("Latitude= "); 
      Serial.print(latitude);
      Serial.print(" Longitude= "); 
      Serial.println(longitude);
  
      //if (latitude == 0) {return 0;}
      
      String url, temp;
      url = "http://cmpe2finalproject.000webhostapp.com/gpsdata.php?lat=";
      url += latitude;
      url += "&lng=";
      url += longitude;

 

      Serial.println(url);    
      delay(300);
          
    sendATcommand("AT+CFUN=1", "OK", 2000);
    //AT+CGATT = 1 Connect modem is attached to GPRS to a network. AT+CGATT = 0, modem is not attached to GPRS to a network
    sendATcommand("AT+CGATT=1", "OK", 2000);
    //Connection type: GPRS - bearer profile 1
    sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", "OK", 2000);
    //sets the APN settings for your network provider.
    sendATcommand("AT+SAPBR=3,1,\"APN\",\"internet\"", "OK", 2000);
    //enable the GPRS - enable bearer 1
    sendATcommand("AT+SAPBR=1,1", "OK", 2000);
    //Init HTTP service
    sendATcommand("AT+HTTPINIT", "OK", 2000); 
    sendATcommand("AT+HTTPPARA=\"CID\",1", "OK", 1000);
    //Set the HTTP URL sim800.print("AT+HTTPPARA="URL","http://cmpe2finalproject.000webhostapp.com/gpsdata.php?lat=";
    sim800L.print("AT+HTTPPARA=\"URL\",\"");
    sim800L.print(url);
    sendATcommand("\"", "OK", 1000);
    //Set up the HTTP action
    sendATcommand("AT+HTTPACTION=0", "0,200", 1000);
    //Terminate the HTTP service
    sendATcommand("AT+HTTPTERM", "OK", 1000);
    //shuts down the GPRS connection. This returns "SHUT OK".
    sendATcommand("AT+CIPSHUT", "SHUT OK", 1000);

  }
  return 1;    
}

int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout){

    uint8_t x=0,  answer=0;
    char response[100];
    unsigned long previous;

    //Initialice the string
    memset(response, '\0', 100);
    delay(100);
    
    //Clean the input buffer
    while( sim800L.available() > 0) sim800L.read();
    
    if (ATcommand[0] != '\0'){
      //Send the AT command 
      sim800L.println(ATcommand);
    }

    x = 0;
    previous = millis();

    //this loop waits for the answer with time out
    do{
        //if there are data in the UART input buffer, reads it and checks for the asnwer
        if(sim800L.available() != 0){
            response[x] = sim800L.read();
            //Serial.print(response[x]);
            x++;
            // check if the desired answer (OK) is in the response of the module
            if(strstr(response, expected_answer) != NULL){
                answer = 1;
            }
        }
    }while((answer == 0) && ((millis() - previous) < timeout));

  Serial.println(response);
  return answer;
}

What works, what doesn’t?

I don’t see any geofencing calculations in your posted code, I may misunderstand.

Can you get a GPS reading on the Serial monitor?

Oops, OK I see you claim you do.

Can you send a message to SMS, any message?

So… geofencing is a matter of establish the fence, some solutions combine rectangles of lat/long and circles of a given radius at a lat/long to cover the area of interest.

Then calculate if your are inside any of the rectangles forming your fenced area, or closer than the radius to any circles that are also part of your fenced area.

If so send the message.

I googled

   geofence 

and

   distance between two points latitude longitude 

You will find some formulas, maybe even some code.

HTH

a7

Hello alto,

everything about the code i posted works perfectly, and I still haven't written any code about geofencing calculations, matter of fact , this is the part that I am struggling with as I stated in the post.

yes I am able to send messages.

Thank you!!

Are you looking for someone to write the code for you? Provide you with help in debugging the code you write?

Hello Idahowalker

Yes you could say so.

You might want to contact the moderators and have this posting moved to the gigs and collaboration forum.

Honestly this is my first post here so I am still trying to figure out how this whole website works

OK, have you googled?

Try

arduino geofence circle rectangle

I see this and many other ways to spend some time:

It is as I said.

Form rectangles bounded by north, south east and west points of a certain latitude and longitude.

Form circles at a given point latitude and longitude and a radius.

Your entire fenced area is all the rectangles and circles so formed.

See if your point is close to a circle center or within a rectangle.

Easiest: rectangles whose borders run north-south and east-west.

A bit harder: arbitrary polygon of points.

a7

yes I am googling rn , well I do understand the logic and thank you for making it more clear ,
it is just how to translate this logic to a code.
could you provide me with sample code if you came across one so far ?

I am looking for something I saw years ago. Haven't (yet) found it, but is was plain and simple: cirlces and nicely orientated rectangles. It was so simple I didn't think to stash the code, figuring it would be easy if the time came.

Take a look here

for some general hand-waving.

a7

1 Like

Thank you for your time Sir , please do let me know if you find the code , thank you very much for sticking with me

NP. I have no life.

But certainly you should be able to muddle your way through to code at least a simply fenced rectangular area:

Am I North of the Southern border and South of the Northern border?
   (my latitude < Northern border latitude) && (my latitude > Southern border latitude)

AND

Am I East of the Western border and West of the Eastern border?
   (my longitude < Western border longitude) &c...

THEN

I must be in this rectangle.

if your area is made up of multiple such rectangles, test them all; if you are inside any of them, you are IN.

You might have to think about it a bit more if you are planning that this works everywhere in the world. :expressionless:

a7

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.