Hardware Part
Hardware connection
Accuracy of the Device
Full Arduino Code
#include "TinyGPS++.h"
#include <SoftwareSerial.h>
static const int RXPin = 5, TXPin = 4;
static const uint32_t GPSBaud = 9600;
static const uint32_t GSMBaud = 9600;
//Pin connection
SoftwareSerial GPSserial(RXPin, TXPin);// The serial connection to the GPS device
SoftwareSerial GSMserial(3, 2); //SIM800L Tx & Rx is connected to Arduino #3 & #2
TinyGPSPlus gps;// The TinyGPS++ object
String GPSdata = "";//store GPS information
unsigned long lastTime;//store last operation time
bool flag=0;//0 not valid; 1 valid
void setup(){
Serial.begin(9600);
GPSserial.begin(GPSBaud);
GSMserial.begin(GSMBaud);
}
void loop(){
GPSserial.listen();
changeGPSdata();
//GSMserial.listen();
if(flag==1 && (millis()-lastTime>=20000)){
Serial.println(GPSdata);
sendMessage();
updateTime();
}
else{
//do nothing;
}
}
//change GPS data
void changeGPSdata(){
String newGPSdata = "";
while (GPSserial.available() > 0){
gps.encode(GPSserial.read());
if (gps.location.isValid()){
//GPSdata = "Time: " + String(gps.time.value()) + " Latitude= " + String(gps.location.lat(), 6) + " Longitude= " + String(gps.location.lng(), 6) +" speed(km/h)= " + String(gps.speed.kmph(),6);
GPSdata = String(gps.time.value()) + "," + String(gps.location.lat(), 6) + "," + String(gps.location.lng(), 6) +"," + String(gps.speed.kmph(),6);
flag = 1;//set valid falg
}
else{
flag = 0;// not valid
}
}
}
//send GPS information
void sendMessage () {
GSMserial.println("AT"); //Once the handshake test is successful, it will back to OK
updateSerial();
GSMserial.println("AT+CMGF=1"); // Configuring TEXT mode
updateSerial();
GSMserial.println("AT+CMGS=\"+ZZXXXXXXXXXX\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
updateSerial();
GSMserial.print(GPSdata); //text content
updateSerial();
GSMserial.write(26);
}
void updateSerial()
{
delay(500);
while (Serial.available())
{
GSMserial.write(Serial.read());//Forward what Serial received to Software Serial Port
}
while(GSMserial.available())
{
Serial.write(GSMserial.read());//Forward what Software Serial received to Serial Port
}
}
void updateTime() {
lastTime = millis();
}
Arduino Board Project Download
Final Edition:
https://drive.google.com/drive/folders/1tA6Y1dUj1VSD1pBhyMKE4b2FFEr29m0W?usp=share_link
GPS Test Edition:
https://drive.google.com/drive/folders/1BhY-DcoaU0tMH_h0ja8K3JuroICfWofN?usp=sharing
GSM Test Edition:
https://drive.google.com/drive/folders/1ryGhIXvut-3yhWArx0XJnVpWdFu0KeUp?usp=sharing
Explination of the code
You will need to use the "SoftwareSerial" to control the information transmition between Arduino board and other modules. Cause we got 2 modules here, we declear two SoftwareSerial objects for each of them.
static const int RXPin = 5, TXPin = 4;
//Pin connection
SoftwareSerial GPSserial(RXPin, TXPin);// The serial connection to the GPS device
SoftwareSerial GSMserial(3, 2); //SIM800L Tx & Rx is connected to Arduino #3 & #2
Then in the setup() part, you need to initialize and let them start to work.
static const uint32_t GPSBaud = 9600;
static const uint32_t GSMBaud = 9600;
void setup(){
Serial.begin(9600);
GPSserial.begin(GPSBaud);
GSMserial.begin(GSMBaud);
}
In this project, we need to get GPS data from GPS module and communicate with the GSM module. Thus, it is more clear if we have 2 functions to dealing with each module seperatly. The first function focus on getting GPS data:
TinyGPSPlus gps;// The TinyGPS++ object
String GPSdata = "";//store GPS information
unsigned long lastTime;//store last operation time
bool flag=0;//0 not valid; 1 valid
//change GPS data
void changeGPSdata(){
String newGPSdata = "";
while (GPSserial.available() > 0){
gps.encode(GPSserial.read());
if (gps.location.isValid()){
//GPSdata = "Time: " + String(gps.time.value()) + " Latitude= " + String(gps.location.lat(), 6) + " Longitude= " + String(gps.location.lng(), 6) +" speed(km/h)= " + String(gps.speed.kmph(),6);
GPSdata = String(gps.date.value())+String(gps.time.value()) + "," + String(gps.location.lat(), 6) + "," + String(gps.location.lng(), 6) +"," + String(gps.speed.kmph(),6);
flag = 1;//set valid falg
}
else{
flag = 0;// not valid
}
}
}
Another function focus on sending the receiving GPS data.
//send GPS information
void sendMessage () {
GSMserial.println("AT"); //Once the handshake test is successful, it will back to OK
updateSerial();
GSMserial.println("AT+CMGF=1"); // Configuring TEXT mode
updateSerial();
GSMserial.println("AT+CMGS=\"+ZZxxxxxxxxxx\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
updateSerial();
GSMserial.print(GPSdata); //text content
updateSerial();
GSMserial.write(26);
}
The updateSerial() is a function which aims to send arduino board loacl serial into the GSM module SoftwareSerial.
void updateSerial()
{
delay(500);
while (Serial.available())
{
GSMserial.write(Serial.read());//Forward what Serial received to Software Serial Port
}
while(GSMserial.available())
{
Serial.write(GSMserial.read());//Forward what Software Serial received to Serial Port
}
}
Finally, we dealing with the Arduino loop() part. It first set GPS module in listening and call function to change local stored GPS data. Then check whetehr there is new GPS data received and the interval of time has already reached to 20 seconds.
void loop(){
GPSserial.listen();
changeGPSdata();
//GSMserial.listen();
if(flag==1 && (millis()-lastTime>=20000)){
Serial.println(GPSdata);
sendMessage();
updateTime();
}
else{
//do nothing;
}
}
The function updateTime() is used to recored the time of last sending message.
void updateTime() {
lastTime = millis();
}
Problems that may happend
Only get information from one module and can only control that one.
This happend because that you have two SoftwareSerial objects in you Arduino Code. The Arduino UNO R3 board can only listen to one SoftwareSerial object at one time by default.
In my code,
void setup(){
Serial.begin(9600);
GPSserial.begin(GPSBaud);
GSMserial.begin(GSMBaud);
}
Only the GSMserial will be listened by the board by default. Thus we need to set the GPSserial to be listened at the beginning of the loop().
Using the code GPSserial.listen(); to set its listener.
SIM800l module didn't work
There are several reasons.
The most important one is the input voltage and current. You need to make sure there is voltage with the value of 3.4V~4.4V applied on the chip. And the supplying current should be more than 2A. USB power supply cannot give you such big current, thus, we need to use the AC socket or an additional power supply for this module. AC socket power supplly can give you 12V and more than 2A.
Another reason is that the SIM card is not in the correct position.
Finally, the signal may be disturbed by a nearby metal.
More information about SIM800l can be found here (https://lastminuteengineers.com/sim800l-gsm-module-arduino-tutorial/)
Specifications of components
AC Socket Battery
NEO-6M GPS Module
SIM800L GSM Module