Skip to content

Instantly share code, notes, and snippets.

@sharanyadas
Created April 15, 2018 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sharanyadas/28214c8c5369f97553dffd317f19d799 to your computer and use it in GitHub Desktop.
Save sharanyadas/28214c8c5369f97553dffd317f19d799 to your computer and use it in GitHub Desktop.
ParkingFinder
//*****************************
// Project name: PARKING FINDER
// A device that has a GPS to detect current location and a GSM to send the location info via SMS or via HTTP POST.
// This device is fed a signal from OCCUPIED SPOT when an occupied spot is detected. After getting the signal, this device
// will send the curent location (detected by GPS) as a URL via GSM so that the user does not enter an occupied spot.
//
//*****************************
#include <SoftwareSerial.h>
// **************************************
// Power supply and pin Connectivity INFO
// **************************************
// Power:
// Arduino VCC and GND to Breadboard and then Bradboard to GPS and GSM +ve and -ve
// Arduino to GPS Serial connection:
// Arduino pin 3(Rx) to GPS TX
// Arduino pin 2(Tx) to GPS RX
// Arduino to GSM SIM900 Serial connection:
// Arduino pin 5(Rx) to GSM TX
// Arduino pin 6(Tx) to GSM RX
// Action pin to simulate switch:
// Pin 12 of PARKING FINDER Arduino is connected to Pin 8 of EMPTY SPOT and GND of EMPTY SPOT to GND of PARKING FINDER
//Install the adafruit GPS library from https://github.com/adafruit/Adafruit-GPS-Library and copied to Arduino Library folder
//Load the GPS Library form the adafruit site above
#include <Adafruit_GPS.h>
//Initialize SoftwareSerial, and tell it that I will be connecting to GPS through pins 2 (TX) and 3 (RX)
SoftwareSerial mySerial(3, 2);
//Create GPS object
Adafruit_GPS GPS(&mySerial);
//*****Data structure to keep GPS data*****
//The National Marine Electronics Association (NMEA)
//has developed a specification that defines the interface
//between various pieces of marine electronic equipment.
//GPS receiver communication is defined within this specification.
//Most computer programs that provide real time position information understand
//and expect data to be in NMEA format. This data includes the complete PVT (position, velocity, time)
//solution computed by the GPS receiver. The idea of NMEA is to send a line of data called a sentence
//that is totally self contained and independent from other sentences.
//More info: http://www.gpsinformation.org/dale/nmea.htm
// I checked NMEA data using https://rl.se/gprmc
String NMEA1; // hold our first NMEA sentence
String NMEA2; // hold our second NMEA sentence
char c; //Used to read the characters spewing from the GPS module
//**********************
//GSM/GPRS related datastructure and info
//**********************
// REFERENCE FOR GSM GPRS chip:
// http://simcom.ee/modules/gsm-gprs/sim900/
// https://www.youtube.com/watch?v=9UEcT5GxdBk
//AT COMMANDS for GSM GPRS:
// AT : health check
// AT+CMGF=1 : Supports SMS?
// AT+CMGS="+14085945068" : Establish connection to send SMS. WIll get ">" prompt
// AT+CMGL="ALL" : Read all messaages from SIM card
// AT+CMGR=2 : Read the 2nd message from SIM
// AT+CMGD=2 : Delete the 2nd message from SIM
//Initialize SoftwareSerial, and tell it that I will be connecting through pins 5 and 6 to GPRS/GSM module
int rxPin = 5;
int txPin = 6;
int actionPin = 12;
boolean state, lastState;
SoftwareSerial GPRS(rxPin, txPin); // Note: ArduinoTx goes to GPRS Rx
unsigned char buffer[64]; // buffer array for data received on serial port from GSM/GPRS
int count = 0; // counter for buffer array
// Data structure needed to make google map URL
String MapString = "http://maps.google.com/maps?q=";
String GoogleMapURL;
char longitude_buff[8];
char lattitude_buff[8];
int stateChangeCounter = 0;
//************************
// Function: setup()
// Purpose : Initial setup of pins, serial chalens and establishing connectivity to GPS and GSM from Arduino
//************************
void setup()
{
Serial.begin(9600); //Turn on the Serial channel of Arduino which is connected to laptop Arduino IDE console
//************************************
//ActionPin setup to simulate a switch
//************************************
Serial.println("Setup: GSM");
//This is the Arduino pin to simulate the state change. State change is used as a command by code to send SMS/Web data.
pinMode(actionPin, INPUT);
state = digitalRead(actionPin);
lastState = state;
//*********************
//GSM/GPRS related setup
//*********************
GPRS.begin(9600);
GPRS.println("AT"); // Send this command to check the health of GSM/SPRS chip. We don't read and interpret the result though
delay(1000); // give sec to respond
//******************
//GPS related setup
//******************
Serial.println("Setup: GPS");
GPS.begin(9600); //Turn GPS on at baud rate of 9600
GPS.sendCommand("$PGCMD,33,0*6D"); // Turn Off GPS Antenna Update. We are not intersted about this
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate, other settings are 5HZ or 10HZ. 1HZ seems more stable
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //Tell GPS we want only $GPRMC and $GPGGA NMEA sentences
delay(2000); //Pause for 2 sec
Serial.println("Setup: END");
}
//************************
// Function: loop()
// Purpose : The main forver loop. Here in every pass we read GPS data, action pin and if action is
// toggled we send a SMS / Web data
//************************
void loop()
{
//Read the GPS to get the location Data
readGPS(); //This is a function I defined below which reads two NMEA sentences from GPS
delay(500); //delay so that we can get opportunity to work on other sensor reading etc in Arduino
//GSM/GPRS Read
while (GPRS.available())
{
Serial.write(GPRS.read()); // Write stuff from GSM module to serial monitor
Serial.println("Inside GPRS.available() == TRUE ");
}
//Read current state of actionPin. If not same as last state then send SMS / Web data
state = digitalRead(actionPin);
Serial.print("Last state= ");
Serial.print(lastState);
Serial.print(" Current state= ");
Serial.println(state);
if (state != lastState)
{
stateChangeCounter++;
if ( stateChangeCounter == 2)
{
// May be false signal... Not sure why getting 2 consecutive state change! No need to send Data
stateChangeCounter = 0;
} else {
Serial.println("******** State change happened ********");
sendData();
}
lastState = state;
}
delay(500);
}
//************************
// Function: sendData()
// Purpose : This function is sending the a SMS message and / or HTTP POST with the current GPS location via an URL
//************************
void sendData()
{
Serial.println("Empty parking signal came! ");
Serial.println("Message from PARKING FINDER. Empty parking is available! Location is:");
//Print GPS Location INFO in Serial Port
Serial.println(NMEA1);
Serial.println(NMEA2);
Serial.print("\nTime: ");
Serial.print(GPS.hour, DEC); Serial.print(':');
Serial.print(GPS.minute, DEC); Serial.print(':');
Serial.print(GPS.seconds, DEC); Serial.print('.');
Serial.println(GPS.milliseconds);
Serial.print("Date: ");
Serial.print(GPS.day, DEC); Serial.print('/');
Serial.print(GPS.month, DEC); Serial.print("/20");
Serial.println(GPS.year, DEC);
Serial.print("Fix: "); Serial.print((int)GPS.fix);
Serial.print(" quality: "); Serial.println((int)GPS.fixquality);
Serial.print("Location: ");
Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
Serial.print(", ");
Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
Serial.print("Location (in degrees, works with Google Maps (-ve means S or W)): ");
Serial.print(GPS.latitudeDegrees, 4);
Serial.print(", ");
Serial.println(GPS.longitudeDegrees, 4);
Serial.println(GoogleMapURL);
Serial.print("Speed (knots): "); Serial.println(GPS.speed);
Serial.print("Angle: "); Serial.println(GPS.angle);
Serial.print("Altitude: "); Serial.println(GPS.altitude);
Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
Serial.println("");
//Prepare and send the SMS/TEXT via GSM/GPRS if signal is good otherwise just print in console
if (GPS.fix) {
// NEED TO OPEN FOR SENDING TEXT
GPRS.println("AT+CMGF=1");
delay(500);
GPRS.println("AT+CMGS=\"+14085945068\"");
delay(500);
GPRS.println("Message from PARKING FINDER. This parking spot is occupied! Location is:");
//Send the Location info via text
GPRS.println(GoogleMapURL);
delay(500);
GPRS.write(0x1a); // End the text message with Ctl-Z character
delay(500);
}
}
//**********************
// Function: readGPS()
// PURPOSE:
// This function will read and remember two NMEA sentences from GPS.
// Read the 2 NEMA sentences one after after each other (no operation
// in between) so that in between buffer does not get jammed by more GPS data in between.
//*********************
void readGPS() {
clearGPS(); //Serial port probably has old or corrupt data, so begin by clearing it all out
while(!GPS.newNMEAreceived()) { //Keep reading characters in this loop until a good NMEA sentence is received
c=GPS.read(); //read a character from the GPS
}
GPS.parse(GPS.lastNMEA()); //Once you get a good NMEA, parse it
NMEA1=GPS.lastNMEA(); //Once parsed, save NMEA sentence into NMEA1
while(!GPS.newNMEAreceived()) { //Go out and get the second NMEA sentence, should be different type than the first one read above.
c=GPS.read();
}
GPS.parse(GPS.lastNMEA());
NMEA2=GPS.lastNMEA();
Serial.println(NMEA1);
Serial.println(NMEA2);
Serial.print("\nTime: ");
Serial.print(GPS.hour, DEC); Serial.print(':');
Serial.print(GPS.minute, DEC); Serial.print(':');
Serial.print(GPS.seconds, DEC); Serial.print('.');
Serial.println(GPS.milliseconds);
Serial.print("Date: ");
Serial.print(GPS.day, DEC); Serial.print('/');
Serial.print(GPS.month, DEC); Serial.print("/20");
Serial.println(GPS.year, DEC);
Serial.print("Fix: "); Serial.print((int)GPS.fix);
Serial.print(" quality: "); Serial.println((int)GPS.fixquality);
Serial.print("Location: ");
Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
Serial.print(", ");
Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
if (GPS.fix) {
Serial.print("Location (in degrees, works with Google Maps (-ve means S or W)): ");
Serial.print(GPS.latitudeDegrees, 4);
Serial.print(", ");
Serial.println(GPS.longitudeDegrees, 4);
Serial.print("Speed (knots): "); Serial.println(GPS.speed);
Serial.print("Angle: "); Serial.println(GPS.angle);
Serial.print("Altitude: "); Serial.println(GPS.altitude);
Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
}
//Lattitude - float to String
if (GPS.latitudeDegrees < 0) { // It's South
dtostrf((GPS.latitudeDegrees * -1), 7, 4, lattitude_buff); // In other part of world we may have to use 8 instead of 7
GoogleMapURL = MapString + String(lattitude_buff) + "S,";
} else { // It's North
dtostrf(GPS.latitudeDegrees, 7, 4, lattitude_buff); // In other part of world we may have to use 8 instead of 7
GoogleMapURL = MapString + String(lattitude_buff) + "N,";
}
//Longitude - float to String
if (GPS.longitudeDegrees < 0) { // It's West
dtostrf((GPS.longitudeDegrees * -1), 8, 4, longitude_buff);
GoogleMapURL += String(longitude_buff);
GoogleMapURL += "W";
} else { // It's East
dtostrf(GPS.longitudeDegrees, 8, 4, longitude_buff);
GoogleMapURL += String(longitude_buff);
GoogleMapURL += "E";
}
Serial.println(GoogleMapURL);
Serial.println("");
}
//*********
// Function: clearGPS()
//Since between GPS reads, we still have data streaming in,
//we need to clear the old data by reading a few sentences, and discarding these
//**********
void clearGPS() {
while(!GPS.newNMEAreceived()) {
c=GPS.read();
}
GPS.parse(GPS.lastNMEA());
while(!GPS.newNMEAreceived()) {
c=GPS.read();
}
GPS.parse(GPS.lastNMEA());
}
//*****************************
// Project name: EMPTY SPOT
// This device will instantly detect any empty parking sport using ultrasonic wave. Once it detects the spot it will
// send a signal to PARKING FINDER and trigger a vibration for visual effect.
// NOTE:
// I have a reverse logic in code now. i.e. it will send a signal and trigger vibration when parking is
// occupied (distance <= threshold)
//*****************************
//REFERENCE
// https://howtomechatronics.com/tutorials/arduino/ultrasonic-sensor-hc-sr04/
// https://howtomechatronics.com/tutorials/arduino/lcd-tutorial
// Temp Sensor+Vibe+LED : https://learn.sparkfun.com/tutorials/lilypad-development-board-activity-guide/11-thermal-alert-project
// http://www.toptechboy.com/arduino/lesson-20-arduino-lcd-project-for-measuring-distance-with-ultrasonic-sensor/
//
//Lily Pad Pin
const int vibe = 8; // LilyPad vibe - through this we send 5V power to vibe. Other vibe goes to GND
// HC-SR04 Pin
const int trigPin = 9; // HC-SR04 ultrasonic sensor
const int echoPin = 10; // HC-SR04 ultrasonic sensor
long duration;
int distance;
void setup() {
//HC-SR04 ultrasound device setup
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// Vive setup
pinMode(vibe, OUTPUT);
// serial console to display in computer
Serial.begin(9600);
}
void loop() {
//clear trigPin of ultrasonic sensor
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
//triggering trigPin of ultrasonic sensor
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
//clear trigPin of ultrasonic sensor
digitalWrite(trigPin, LOW);
//setting up echoPin to read the roundtrip time
duration = pulseIn(echoPin, HIGH);
//calculating distance based on roundtrip time
distance = duration * 0.034/2;
//print Distance in serial console
Serial.print("Distance: ");
Serial.println(distance);
if (distance <= 5) //if distance is under threshold value (in cm)
{
digitalWrite(vibe, HIGH); //vibrate the device
Serial.println("Threshold passed!"); // print in serial console as well
delay(500); // vibrate for for 500ms
digitalWrite(vibe, LOW); //turn off vibration
}
} // End of Loop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment