Hardware components | ||||||
| × | 1 | ||||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
Software apps and online services | ||||||
![]() |
| |||||
Hand tools and fabrication machines | ||||||
![]() |
| |||||
![]() |
|
I made this project to check distance travel and max speed for my truck model. GPS gets coordinates and checks position writing on SD card data log.csv. You can setup a speed limit with a led alarm or a buzzer. SD card log.csv can be read with open office. Anyway you can easily modify it in log.txt. I have add a reset button and a red BEC plug for external battery. Normally I power it from USB socket. Altitude needs 3D fix for better result. You can config NEO6M GPS (or better GPS) from "u-blox center" for this operation is much better use a GPS module with usb socket as to connect it direct to com port.
1 / 10
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <NMEAGPS.h>
#include <NeoSWSerial.h>
const int cs_sd=2;
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire oled;
NMEAGPS gps;
gps_fix fix;
File myFile;
float odo;
float Speed;
float alt;
NeoGPS::Location_t lastLoc;
bool lastLocOK = false;
static const int RXPin = 5, TXPin = 4; //-- gps pin
static const uint32_t GPSBaud = 9600;
NeoSWSerial gpsPort(RXPin, TXPin);
const int SHOW_INTERVAL = 1;
const int INITIAL_SHOW = (2 * SHOW_INTERVAL) - 1;
int show = INITIAL_SHOW;
const int LED_PIN = 3; //-- led on at speed limit
const float SPEED_LIMIT = 0.0; // --setup speed limit value es: 55.0; kmh default 0.0
int maxs = 0;
void setup(){
pinMode (LED_PIN, OUTPUT);
Serial.begin(9600);
gpsPort.begin(GPSBaud);
Wire.begin();
oled.begin(& Adafruit128x64, I2C_ADDRESS);
oled.setFont(TimesNewRoman16);
oled.clear();
oled.println(" ");
oled.println(" GPS LOGGER"); //you can custom this text
oled.println(" ");
oled.println(" WELCOME"); //you can custom this text
delay(3000);
oled.clear();
if(!SD.begin(cs_sd)){
oled.clear();
oled.println(" ");
oled.print("NO SD");
delay(3000);
return;}
oled.println(" ");
oled.print(" SD Card OK");
delay(2000);
oled.clear();
File data = SD.open("log.csv",FILE_WRITE);
data.println("");
data.println("Dat Hr+ Lat Lon Alt Vel Dis" );
data.close();}
void loop(){
if (gps.available( gpsPort )) {
gps_fix fix = gps.read();
show = (show + 1) % SHOW_INTERVAL;
if (fix.valid.speed && (fix.speed_kph() > SPEED_LIMIT)) {
digitalWrite( LED_PIN, HIGH );
} else {
digitalWrite( LED_PIN, LOW ); }
if (fix.valid.location) {
if (lastLocOK) {
odo += fix.location.DistanceKm( lastLoc );
Speed = (fix.speed_kph());}
lastLoc = fix.location;
lastLocOK = true;}
if ( Speed > maxs)
maxs = Speed;
if (fix.valid.altitude)
alt = ( fix.altitude () );
if (show == 0) {
#define MAX_CHARS 24
char displayBufffer[MAX_CHARS];
oled.setCursor(0,0);
snprintf(displayBufffer, MAX_CHARS, " DIST : % 3d.%02d", (int)odo, (int)(odo * 100)%100);//distance
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, " KMH: % 3d.%02d", (int)Speed, (int)(Speed * 100)%100);//speed
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, " MxSP: % 3d.%02d", (int)maxs, (int)(maxs * 100)%100);//max top speed
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, " ALT : % 3d.%02d", (int)alt, (int)(alt * 100)%100);//altitude
oled.println(displayBufffer);}
if (fix.dateTime);
String Temps=String(fix.dateTime.hours )+(":")+(fix.dateTime.minutes)+(":")+(fix.dateTime.seconds);
String Date=String(fix.dateTime.date )+("/")+(fix.dateTime.month)+("/")+(fix.dateTime.year);
File data=SD.open("log.csv",FILE_WRITE);
data.println(Date +(" ")+ Temps +(" ")+ String(fix.latitude(), 6)+(" ")+String(fix.longitude(), 6)+(" ")+(alt)+(" ") +(Speed)+(" ")+(odo));
data.close();}}
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <NMEAGPS.h>
//#include <SoftwareSerial.h> //check library or change neoSWSerial.h
#include <NeoSWSerial.h>
const int cs_sd=2;
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire oled;
NMEAGPS gps;
gps_fix fix;
File myFile;
float odo;
float Speed;
float alt;
NeoGPS::Location_t lastLoc;
bool lastLocOK = false;
static const int RXPin = 5, TXPin = 4; //-- gps pin
static const uint32_t GPSBaud = 9600;
NeoSWSerial gpsPort(RXPin, TXPin);
const int SHOW_INTERVAL = 1;
const int INITIAL_SHOW = (2 * SHOW_INTERVAL) - 1;
int show = INITIAL_SHOW;
const int LED_PIN = 3;
const float SPEED_LIMIT = 0.0; // --setup speed limit value es: 55.0; kmh default 0.0
int maxs = 0;
void setup(){
pinMode (LED_PIN, OUTPUT);
Serial.begin(9600);
gpsPort.begin(GPSBaud);
Wire.begin();
oled.begin(&SH1106_128x64, I2C_ADDRESS);
oled.setFont(ZevvPeep8x16);
oled.clear();
oled.println(" ");
oled.println(" GPS LOGGER");
oled.println(" ");
oled.println(" WELCOME");
delay(3000);
oled.clear();
if(!SD.begin(cs_sd)){
oled.clear();
oled.println(" ");
oled.print("NO SD");
delay(3000);
return;}
oled.println(" ");
oled.print(" SD Card OK");
delay(2000);
oled.clear();
File data = SD.open("log.csv",FILE_WRITE);
data.println("");
data.println("Dat Hr+ Lat Lon Alt Vel Dis" );
data.close();}
void loop(){
if (gps.available( gpsPort )) {
gps_fix fix = gps.read();
show = (show + 1) % SHOW_INTERVAL;
if (fix.valid.speed && (fix.speed_kph() > SPEED_LIMIT)) {
digitalWrite( LED_PIN, HIGH );
} else {
digitalWrite( LED_PIN, LOW ); }
if (fix.valid.location) {
if (lastLocOK) {
odo += fix.location.DistanceKm( lastLoc );
Speed = (fix.speed_kph());}
lastLoc = fix.location;
lastLocOK = true;}
if ( Speed > maxs)
maxs = Speed;
if (fix.valid.altitude)
alt = ( fix.altitude () );
if (show == 0) {
#define MAX_CHARS 24
char displayBufffer[MAX_CHARS];
oled.setCursor(0,0);
snprintf(displayBufffer, MAX_CHARS, " K m :% 3d.%02d", (int)odo, (int)(odo * 100)%100);
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, " Kmh :% 3d.%02d", (int)Speed, (int)(Speed * 100)%100);
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, " Mspd:% 3d.%02d", (int)maxs, (int)(maxs * 100)%100);
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, " Alt :% 3d.%02d", (int)alt, (int)(alt * 100)%100);
oled.println(displayBufffer);}
if (fix.dateTime);
String Temps=String(fix.dateTime.hours )+(":")+(fix.dateTime.minutes)+(":")+(fix.dateTime.seconds);
String Date=String(fix.dateTime.date )+("/")+(fix.dateTime.month)+("/")+(fix.dateTime.year);
File data=SD.open("log.csv",FILE_WRITE);
data.println(Date +(" ")+ Temps +(" ")+ String(fix.latitude(), 6)+(" ")+String(fix.longitude(), 6)+(" ")+(alt)+(" ") +(Speed)+(" ")+(odo));
data.close();}}
more data on display sh1106 1.3 version 2021''
Arduinoadd "Di" aerial distance (km) from fix point base. add "S"satellites count. add "Am"max altitude. add "He"heading degrees (360° N 180° S) previous data: "Km" odometer travel distance, "Sp" live speed, "Sm" max speed, "Al" altitude slm.
display now is full with 8 informations data most of it collect to SD card (just heading and satellite count are not)
display now is full with 8 informations data most of it collect to SD card (just heading and satellite count are not)
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <NMEAGPS.h>
#include <NeoSWSerial.h>
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
#define MAX_CHARS 24
#define RX_pin 5
#define TX_pin 4
#define SHOW_INTERVAL 1
#define GPS_baud 9600
SSD1306AsciiWire oled;
NMEAGPS gps;
gps_fix fix;
float odo, Speed, alt, Dist, head, maxs = 0, Am = 0;
unsigned int Sat = 0;
NeoGPS::Location_t lastLoc, base;
bool stScan = true, lastLocOK = false;
static NeoSWSerial gpsPort(RX_pin, TX_pin);
static constexpr int INITIAL_SHOW = (2 * SHOW_INTERVAL) - 1;
int show = INITIAL_SHOW;
const int LED_PIN = 3;
const float SPEED_LIMIT = 0.1; // speed limit value
void disp(int c, int r)
{
oled.clear();
oled.setCursor(c, r);
}
void setup() {
pinMode (LED_PIN, OUTPUT);
Serial.begin(9600);
gpsPort.begin(GPS_baud);
Wire.begin();
oled.begin(&SH1106_128x64, I2C_ADDRESS);
oled.setFont(ZevvPeep8x16);
oled.clear();
disp(30, 2);// as to center your name change 30
oled.println("YourName");//10 characters available here
delay(2000);
disp(55, 2);
oled.print("GPS");//5 characters available here
delay(2000);
oled.clear();
const int cs_sd = 2;
if (!SD.begin (cs_sd)) {
oled.clear();
disp(60, 2);
oled.print("SD");//if you read this on display mean SD is not present
delay(10000);
oled.clear();
return;
}
disp(60, 2);
oled.print("OK");
delay(2000);
oled.clear();
File data = SD.open("L.csv", FILE_WRITE);
data.println("");
data.println("Da Hr La Lo At Am Km Di Sp He Sa" );
data.close();
}
void loop() {
if (gps.available( gpsPort )) {
gps_fix fix = gps.read();
show = (show + 1) % SHOW_INTERVAL;
if (fix.valid.speed && (fix.speed_kph() > SPEED_LIMIT)) {
digitalWrite( LED_PIN, HIGH );
} else {
digitalWrite( LED_PIN, LOW );
}
if (fix.valid.location) {
if (lastLocOK) {
odo += fix.location.DistanceKm( lastLoc );
Speed = fix.speed_kph();
}
lastLoc = fix.location;
lastLocOK = true;
if (stScan) {
stScan = false;
base = fix.location;
} else {
Dist = ( fix.location.DistanceKm( base ) );
}
}
if ( Speed > maxs) maxs = Speed;
if (fix.valid.heading ) head = fix.heading() ;
if (fix.valid.satellites ) Sat = fix.satellites ;
if (fix.valid.altitude) alt = fix.altitude();
if ( alt > Am) Am = alt;
if (show == 0) {
char displayBufffer[MAX_CHARS];
oled.setCursor(0, 0);
snprintf(displayBufffer, MAX_CHARS, "Km:%2d.%1d", (int)odo, (int)(odo * 100) % 100);
oled.println(displayBufffer);
oled.setCursor(65, 0);
snprintf(displayBufffer, MAX_CHARS, "Di:%2d.%1d", (int)Dist, (int)(Dist * 100) % 100);
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, "Sp:%2d.%1d", (int)Speed, (int)(Speed * 10) % 10);
oled.println(displayBufffer);
oled.setCursor(65, 2);
snprintf(displayBufffer, MAX_CHARS, "Sm:%2d.%1d", (int)maxs, (int)(maxs * 10) % 10);
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, "Al:%2d.%1d", (int)alt, (int)(alt * 100) % 100);
oled.println(displayBufffer);
oled.setCursor(65, 4);
snprintf(displayBufffer, MAX_CHARS, "Am:%2d.%1d", (int)Am, (int)(Am * 100) % 100);
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, "Sa: %d", (int)Sat);
oled.println(displayBufffer);
oled.setCursor(65, 6);
snprintf(displayBufffer, MAX_CHARS, "He:%2d.%1d", (int)head, (int)(head * 100) % 100);
oled.println(displayBufffer);
}
File data = SD.open("L.csv", FILE_WRITE);
data.print(fix.dateTime.hours + 2);
data.print(":");
data.print(fix.dateTime.minutes);
data.print(" ");
data.print(fix.dateTime.date);
data.print("/");
data.print(fix.dateTime.month);
data.print(" ");
data.print(fix.latitude(), 6);
data.print(" ");
data.print(fix.longitude(), 6);
data.print(" ");
data.print(alt);
data.print(" ");
data.print(Am);
data.print(" ");
data.print(odo);
data.print(" ");
data.print(Dist);
data.print(" ");
data.print(Speed);
data.print(" ");
data.print(head);
data.print(" ");
data.print(Sat);
data.println();
data.close();
}
}
10/2021 update compass 16 sectors
Arduinoa new code version for oled 1.3'' sh1106 with travel time and compass 16 sectors
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <NMEAGPS.h>
#include <NeoSWSerial.h>
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
#define MAX_CHARS 24
#define RX_pin 5
#define TX_pin 4
#define SHOW_INTERVAL 1
#define GPS_baud 9600
SSD1306AsciiWire oled;
NMEAGPS gps;
gps_fix fix;
float odo, Dist;
unsigned int head, Speed, alt, Sat = 0, maxs = 0;
NeoGPS::Location_t lastLoc, base;
bool stScan = true, lastLocOK = false;
bool altOK = false;
bool Satok = false;
static NeoSWSerial gpsPort(RX_pin, TX_pin);
static constexpr int INITIAL_SHOW = (2 * SHOW_INTERVAL) - 1;
int show = INITIAL_SHOW;
const int LED_PIN = 3;
const float SPEED_LIMIT = 0.1; // speed limit value
void disp(int c, int r) {
oled.clear();
oled.setCursor(c, r);
}
const char* strBussola[16] = {"N ", "NNe", "NE ", "EnE", "E ", "EsE",
"SE ", "SSe", "S ", "SSw", "SW ", "WsW", "W ", "WnW", "NW ", "NNw"
};
int index;
int trovaIndice(float angolo) {
int _index;
for (_index = 0; _index < 16; _index++) {
float angoloDirezione = _index * 22.25 + 11.25;
float angoloMin = angoloDirezione - 11.25;
float angoloMax = angoloDirezione + 11.25;
if (angolo >= angoloMin && angolo <= angoloMax)
return _index;
}
return _index;
}
void setup() {
pinMode (LED_PIN, OUTPUT);
Serial.begin(9600);
gpsPort.begin(GPS_baud);
Wire.begin();
oled.begin(&SH1106_128x64, I2C_ADDRESS);
oled.setFont(ZevvPeep8x16);
//oled.displayRemap(true); // inversione dello schermo display
disp(0, 2);
oled.println(F(" YOUR NAME "));// put your name here
delay(1500);
oled.setCursor(24, 5);
oled.println(F("GPS LOGGER"));
delay(2500);
oled.clear();
const int cs_sd = 2;
if (!SD.begin (cs_sd)) {
oled.clear();
disp(50, 2);
oled.print(F("SD"));
delay(10000);
oled.clear();
}
File data = SD.open("L.csv", FILE_WRITE);
data.println("");
data.println(F("D H T La Lo At Km Di Ve He Co Sa" ));
data.close();
}
void loop() {
unsigned long tmp = millis() / 1000;
byte secondi = tmp % 60;
byte minuti = (tmp / 60) % 60;
byte ore = (tmp / 3600) % 24;
if (gps.available( gpsPort )) {
gps_fix fix = gps.read();
show = (show + 1) % SHOW_INTERVAL;
if (fix.valid.speed && (fix.speed_kph() > SPEED_LIMIT)) {
digitalWrite( LED_PIN, HIGH );
} else {
digitalWrite( LED_PIN, LOW );
}
if (fix.valid.location) {
if (lastLocOK) {
odo += fix.location.DistanceKm( lastLoc );
Speed = fix.speed_kph();
}
lastLoc = fix.location;
lastLocOK = true;
if (stScan) {
stScan = false;
base = fix.location;
} else {
Dist = ( fix.location.DistanceKm( base ) );
}
}
if ( Speed > maxs) maxs = Speed;
if (fix.valid.satellites ) {
Sat = fix.satellites ;
Satok = true;
}
if (fix.valid.heading ) {
head = fix.heading() ;
index = trovaIndice(head);
}
if (fix.valid.altitude){
alt = fix.altitude();
altOK = true;
}
if (show == 0) {
char displayBufffer[MAX_CHARS];
oled.setCursor(0, 0);
snprintf(displayBufffer, MAX_CHARS, "Km: %d.%d", (int)odo, (int)(odo * 100) % 100);
oled.println(displayBufffer);
oled.setCursor(65, 0);
snprintf(displayBufffer, MAX_CHARS, "Ve: %d", (int)Speed, (int)(Speed * 100) % 100);
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, "Di: %d.%d", (int)Dist, (int)(Dist * 100) % 100);
oled.println(displayBufffer);
oled.setCursor(65, 2);
snprintf(displayBufffer, MAX_CHARS, "Vm: %d", (int)maxs, (int)(maxs * 100) % 100);
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, "Al: %d", (int)alt, (int)(alt * 100) % 100);
oled.println(displayBufffer);
oled.setCursor(65, 4);
snprintf(displayBufffer, MAX_CHARS, "He: %d", (int)head, (int)(head * 100) % 100);
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, "%d:%d:%d ", (int)ore, (int)minuti, (int)secondi);
oled.println(displayBufffer);
oled.setCursor(65, 6);
snprintf(displayBufffer, MAX_CHARS, "Co: %s\n", (strBussola[index]));
oled.println(displayBufffer);
}
File data = SD.open("L.csv", FILE_WRITE);
data.print(fix.dateTime.hours + 2);
data.print(":");
data.print(fix.dateTime.minutes);
data.print(" ");
data.print(fix.dateTime.date);
data.print("/");
data.print(fix.dateTime.month);
data.print(" ");
data.print(ore);
data.print(":");
data.print(minuti);
data.print(":");
data.print(secondi);
data.print(" ");
data.print(fix.latitude(), 6);
data.print(" ");
data.print(fix.longitude(), 6);
data.print(" ");
data.print(alt);
data.print(" ");
data.print(odo);
data.print(" ");
data.print(Dist);
data.print(" ");
data.print(Speed);
data.print(" ");
data.print(head);
data.print(" ");
data.print(strBussola[index]);
data.print(" ");
data.print(Sat);
data.println();
data.close();
}
}
Comments
Please log in or sign up to comment.