GEO location that can trace the chain of the spread to lock down infected areas. DIY using Arduino

Programming, Tutorial, Coding, New Design, and/or any project for your Arduino and Raspberry Pi can post your topic /suggestion here.
User avatar
dondon pramis
Inventor
Contact:
Location: Philippines
Posts: 64
Joined: Sun Feb 12, 2017 8:28 am

GEO location that can trace the chain of the spread to lock down infected areas. DIY using Arduino

Mon Mar 30, 2020 10:57 am

COVID-19 is a highly infectious and easily contractable virus that can become extremely hard to control once it begins to spread. Social isolation/distancing is one of the most important and effective steps one can take to break the chain and to keep healthy people from getting infected. If an infected person comes into contact with a healthy person then that person gets infected too and when both people come in contact with a third or fourth person, they also get infected, and in this way, the chain continues and this dangerous disease starts to spread throughout the whole country, resulting in the death of a large number of people. Because of these reasons, it becomes important for people to distance themselves from others as much as possible so that they do not contract the virus, or spread it if they’re already infected. To help with this, today we’re making a device that will alert healthy people when they go near areas that have been infected by the virus. For this, we use the GPS module to create a GEOFence between the infected area and the healthy area. We will also use a GSM Module that informs the person and the authorities if anybody violates the law and tries to enter an infected area or if any infected person tries to enter a healthy area. Later, we will also create a traceability system using GEO location that can trace the chain of the spread to lock down infected areas.

So let’s start our project with shopping for the following components.
parts-requirements.png
parts-requirements.png (25.56 KiB) Viewed 1073 times
Now, Let's proceed with the coding:

First, we need to open Arduino IDE and install the Required library (FONA, SSD1306, and NEOGPS) and then we can begin with the coding.

Since we have initialised the library in code, we can now set the pin definitions for serial communication with SIM800l Module. Next, we have the setup function which consists of the code that starts the communication with SIM800l module, NEO GPS Module and with SSD10306 as well. After this, we need to create the code where we set the locations for home and for infected areas where the effect of the virus is very high. Next, we have created a ‘while’ loop that checks the location of the person in real-time and, using the ‘if’ condition, we will check if the user has entered within a 100-metre radius of an infected area or person. If so, the device will alert the user of the same. Next, we have a piece of code that live updates information on OLED display. The next piece of code will let us know if the user has left their home at a time when there was a government-imposed lockdown, and if that is the case, a text message will be sent to the authorities.

We have also created another, non-test, code which helps to alert the user whenever there is a government-imposed lockdown so that in case the user is outside they can quickly change their position.

Code:

Code: Select all

#include <NMEAGPS.h>
#include "Adafruit_FONA.h"
#include <SoftwareSerial.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

#define FONA_RX 5
#define FONA_TX 4
#define FONA_RST 11
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire oled;
int buzzerpin=13;
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

#define gpsPort Serial
#define GPS_PORT_NAME "Serial"
#define DEBUG_PORT Serial

#if !defined( NMEAGPS_PARSE_RMC ) &  \
    !defined( NMEAGPS_PARSE_GGA ) &  \
    !defined( NMEAGPS_PARSE_GLL )
  #error You must uncomment at least one of NMEAGPS_PARSE_RMC, NMEAGPS_PARSE_GGA or NMEAGPS_PARSE_GLL in NMEAGPS_cfg.h!
#endif

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

#if !defined( GPS_FIX_LOCATION )
  #error You must uncomment GPS_FIX_LOCATION in GPSfix_cfg.h!
#endif

char replybuffer[255];
String commands="";
char fonaNotificationBuffer[64];          //for notifications from the FONA
char smsBuffer[250];

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
NMEAGPS gps;

// The base location, in degrees * 10,000,000
//NeoGPS::Location_t base( 0.000221,0.000117 ); 
NeoGPS::Location_t home( 0.002651,0.000241);
NeoGPS::Location_t restrict1( 0.001651,0.000241); 
NeoGPS::Location_t restrict2( 0.001651,0.000241); 
NeoGPS::Location_t restrict3( 0.001651,0.000241); 
void setup()
{
  DEBUG_PORT.begin(9600);
  DEBUG_PORT.println( F("NMEAdistance.ino started.") );
  DEBUG_PORT.println( F("Looking for GPS device on " GPS_PORT_NAME) );
  pinMode(13,INPUT);
  gpsPort.begin(9600);
   fonaSerial->begin(4800);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find Felix"));
    while(1);
  }
  Serial.println(F("Felix is OK"));

  // Print SIM card IMEI number.
  char imei[16] = {0}; // MUST use a 16 character buffer for IMEI!
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("SIM card IMEI: "); Serial.println(imei);
  }

  fonaSerial->print("AT+CNMI=2,1\r\n");  //set up the FONA to send a +CMTI notification when an SMS is received

  Serial.println("FONA Ready");
   oled.begin(&Adafruit128x64, I2C_ADDRESS);
  //oled.setFont(TimesNewRoman16_bold);
 oled.setFont(Callibri11_bold); 

} // setup

void loop()
{
  
  while (gps.available( gpsPort )) {
gps_fix fix = gps.read(); // save the latest
    // When we have a location, calculate how far away we are from the base location.
 /////////////////////
  char* bufPtr = fonaNotificationBuffer;  
  
  if (fona.available())     
  {
    int slot = 0;          
    int charCount = 0;
    //Read the notification into fonaInBuffer
    do  {
      *bufPtr = fona.read();
      Serial.write(*bufPtr);
      delay(1);
    } while ((*bufPtr++ != '\n') && (fona.available()) && (++charCount < (sizeof(fonaNotificationBuffer)-1)));
    
    *bufPtr = 0;

   
    if (1 == sscanf(fonaNotificationBuffer, "+CMTI: " FONA_PREF_SMS_STORAGE ",%d", &slot)) {
      Serial.print("slot: "); Serial.println(slot);
      
      char callerIDbuffer[32];  //we'll store the SMS sender number in here
      
   
      if (! fona.getSMSSender(slot, callerIDbuffer, 31)) {
        Serial.println("Didn't find SMS message in slot!");
      }
      Serial.print(F("FROM: ")); Serial.println(callerIDbuffer);

        // Retrieve SMS value.
        uint16_t smslen;
        if (fona.readSMS(slot, smsBuffer, 250, &smslen)) { // pass in buffer and max len!
          Serial.println(smsBuffer);
          commands=smsBuffer;
          Serial.println(commands);
          if(commands=="Lock down"){
            oled.println("roaming outside home");
            
          }
         
    }
  }
}


 /////////////////////////////
      float range1 = fix.location.DistanceMiles( home );
      float range2 = fix.location.DistanceMiles( restrict1 );
      float range3 = fix.location.DistanceMiles( restrict2 );
      float range4 = fix.location.DistanceMiles( restrict3 );

      DEBUG_PORT.print( F("Range:1 ") );
      DEBUG_PORT.print( range1 );
      DEBUG_PORT.print( F("Range:2 ") );
      DEBUG_PORT.print( range2 );
      DEBUG_PORT.print( F("Range:3") );
      DEBUG_PORT.print( range3 );
      DEBUG_PORT.println( "range in miles" );
      
      oled.clear();
      oled.println(" Distance from safe Zone");
      oled.print(range1);
      oled.print("miles\n");
      oled.print((range1*1.609));
      oled.print(" km\n");
 
   if (((range2*1.609)<0.19) or((range3*1.609)<0.1) or ((range4*1.609)<0.1)){
      oled.println("In infected area");
      if (!fona.sendSMS("7979952235", "Hey, person has entered to restricted area")) {
        Serial.println(F("Failed"));
      } else {
        Serial.println(F("Sent!"));
        delay(4000);
      }
  }
   
   if (((range2*1.609)>0.19)){
       digitalWrite(13,HIGH);
       oled.println("roaming outside safezone");
     if (!fona.sendSMS("7979952235", "Hey, This man going out of safezone ")) {
        Serial.println(F("Failed"));
      } else {
        Serial.println(F("Sent!"));
        delay(4000);
      }
  }else{
    
  digitalWrite(13,LOW);
  delay(300);
}
  }
  
} // loop

Code: Select all

#include <NMEAGPS.h>
#include "Adafruit_FONA.h"
#include <SoftwareSerial.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

#define FONA_RX 5
#define FONA_TX 4
#define FONA_RST 11
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire oled;
int buzzerpin=13;
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

#define gpsPort Serial
#define GPS_PORT_NAME "Serial"
#define DEBUG_PORT Serial

#if !defined( NMEAGPS_PARSE_RMC ) &  \
    !defined( NMEAGPS_PARSE_GGA ) &  \
    !defined( NMEAGPS_PARSE_GLL )
  #error You must uncomment at least one of NMEAGPS_PARSE_RMC, NMEAGPS_PARSE_GGA or NMEAGPS_PARSE_GLL in NMEAGPS_cfg.h!
#endif

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

#if !defined( GPS_FIX_LOCATION )
  #error You must uncomment GPS_FIX_LOCATION in GPSfix_cfg.h!
#endif

char replybuffer[255];
String commands="";
char fonaNotificationBuffer[64];          //for notifications from the FONA
char smsBuffer[250];

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
NMEAGPS gps;

// The base location, in degrees * 10,000,000
//NeoGPS::Location_t base( 0.000221,0.000117 ); 
NeoGPS::Location_t home( 0.002651,0.000241);
NeoGPS::Location_t restrict1( 0.001651,0.000241); 
NeoGPS::Location_t restrict2( 0.001651,0.000241); 
NeoGPS::Location_t restrict3( 0.001651,0.000241); 
void setup()
{
  DEBUG_PORT.begin(9600);
  DEBUG_PORT.println( F("NMEAdistance.ino started.") );
  DEBUG_PORT.println( F("Looking for GPS device on " GPS_PORT_NAME) );
  pinMode(13,INPUT);
  gpsPort.begin(9600);
   fonaSerial->begin(4800);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find Felix"));
    while(1);
  }
  Serial.println(F("Felix is OK"));

  // Print SIM card IMEI number.
  char imei[16] = {0}; // MUST use a 16 character buffer for IMEI!
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("SIM card IMEI: "); Serial.println(imei);
  }

  fonaSerial->print("AT+CNMI=2,1\r\n");  //set up the FONA to send a +CMTI notification when an SMS is received

  Serial.println("FONA Ready");
   oled.begin(&Adafruit128x64, I2C_ADDRESS);
  //oled.setFont(TimesNewRoman16_bold);
 oled.setFont(Callibri11_bold); 

} // setup

void loop()
{
  
  while (gps.available( gpsPort )) {
gps_fix fix = gps.read(); // save the latest
    // When we have a location, calculate how far away we are from the base location.
 
      float range1 = fix.location.DistanceMiles( home );
      float range2 = fix.location.DistanceMiles( restrict1 );
      float range3 = fix.location.DistanceMiles( restrict2 );
      float range4 = fix.location.DistanceMiles( restrict3 );

      DEBUG_PORT.print( F("Range:1 ") );
      DEBUG_PORT.print( range1 );
      DEBUG_PORT.print( F("Range:2 ") );
      DEBUG_PORT.print( range2 );
      DEBUG_PORT.print( F("Range:3") );
      DEBUG_PORT.print( range3 );
      DEBUG_PORT.println( "range in miles" );
      
      oled.clear();
      oled.println(" Distance from safe Zone");
      oled.print(range1);
      oled.print("miles\n");
      oled.print((range1*1.609));
      oled.print(" km\n");
 
   if (((range2*1.609)<0.19) or((range3*1.609)<0.1) or ((range4*1.609)<0.1)){
      oled.println("In infected area");
      if (!fona.sendSMS("7979952235", "Hey, person entered to infected area")) {
        Serial.println(F("Failed"));
      } else {
        Serial.println(F("Sent!"));
        delay(4000);
      }
  }
   
   if (((range2*1.609)>0.19)){
       digitalWrite(13,HIGH);
       oled.println("roaming outside safezone");
     if (!fona.sendSMS("0919123456", "Hey, This person going out of safezone ")) {
        Serial.println(F("Failed"));
      } else {
        Serial.println(F("Sent!"));
        delay(4000);
      }
  }else{
    
  digitalWrite(13,LOW);
  delay(300);
}
  }
  
} // loop

Circuit Diagram for this Project:
connection-diagram.jpg
connection-diagram.jpg (28.16 KiB) Viewed 1073 times
Testing
Insert a 2G SIM Card in SIM800l Module and wait for a few minutes. When the SIM800l searches the network, the LED will blink faster and when it connects to the sim network the LED blink will slow down. Now, when you try to enter an infected area, the GPS module will alert you and will send a message to the set number regarding your contact with the infected area.

Please Share this project #stayathome #staysafe


Return to “ARDUINO AND RASPBERRY PI”

Links