Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Hand tools and fabrication machines | ||||||
| ||||||
| ||||||
|
I practice aeromodelling and I like to know the speed and altitude of my planes. unfortunately, commercial GPS data loggers are very expensive.
So I decided to make a GPS data logger based on Arduino for a cost less than 50€.
My first prototype is based on Arduino Uno R3 with a Sainsmart ST7735 screen with integrated SD card and a NEO 6M V2 GPS module.
In the second project I would use an Arduino Nano with an SSD1306 OLED screen, the same GPS module, and a micro SD card. The weight with case should be around 40 grams and can easily be integrated into a medium-sized aircraft (size L 50 mm X l 30mm X H 22mm).
It will be my next project (I'm waiting for the materials.)
TESTIt's not easy to film a screen of Arduino in a car, but I did it and you can see the result on the video.
The next test will be with the new, smaller and lighter prototype on a radio-controlled aircraft. To be continued!
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#define cs 10
#define dc 9
#define rst 8
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
static const int RXPin = 4, TXPin = 3; //GPS communication
static const uint32_t GPSBaud = 9600;
#define OLED_RESET 5
TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);
int x=80;
int xh=80;
int maxhigh=0;
int maxspeed = 0, speed1 = 0;
int high1 = 0;;
void setup()
{
Serial.begin(9600);
ss.begin(GPSBaud);
tft.initR(INITR_GREENTAB);
tft.fillScreen(ST7735_BLACK);
tft.setCursor(5, 58);
tft.setTextSize(1);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("initilisation");
}
void loop()
{
tft.setTextSize(1);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
// affichage des informations a chaque bonne reception satellite
while (ss.available() > 0){
gps.encode(ss.read());
if (gps.location.isUpdated()){
cadre();
tft.setCursor(5, 44);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("Latitude :");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(gps.location.lat(), 6);
tft.setCursor(5, 58);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("Longitude :");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(gps.location.lng(), 6);
//affichage ecran date
tft.setCursor(5, 7);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("date : ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(gps.date.day());
tft.print(" ");
tft.print(gps.date.month());
tft.print(" ");
tft.print(gps.date.year());
//affichage ecran heure
tft.setCursor(5, 20);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("heure : ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(gps.time.hour()+1);
tft.print(" ");
tft.print(gps.time.minute());
tft.print(" ");
tft.print(gps.time.second());
tft.print(" ");
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.setCursor(3, 30);
//affichage ecran altitude
tft.setCursor(5, 80);
tft.print("H m :");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print (gps.altitude.meters(),0);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(" ");
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.setCursor(5, 95);
hmax();
tft.print("Hmax :");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxhigh);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(" ");
courbeh();
//affichage ecran vitesse
tft.setCursor(5, 115);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("V act: ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print (gps.speed.kmph(),0);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(" ");
tft.setCursor(5, 130);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
vmax();
tft.print("vmax: ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxspeed);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(" ");
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
courbe();
//affichage ecran nombre de satellites
tft.setCursor(5, 147);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("nombre de Sat : ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(gps.satellites.value());
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(" ");
// Horizontal Dim. of Precision (100ths-i32)
Serial.print("HDOP = ");
Serial.println(gps.hdop.value());
smartDelay(400);
}
}
}
// delai pour une bonne recption
static void smartDelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
void cadre() {
// affichage ecran
//cadre
tft.drawLine(0,0,130,0,ST7735_RED);
tft.drawLine(0,1,130,1,ST7735_RED);
tft.drawLine(0,158,130,158,ST7735_RED);
tft.drawLine(0,142,130,142,ST7735_RED);
tft.drawLine(0,141,130,141,ST7735_RED);
tft.drawLine(0,107,130,107,ST7735_RED);
tft.drawLine(0,108,130,108,ST7735_RED);
tft.drawLine(80,108,80,140,ST7735_RED);
tft.drawLine(81,109,81,140,ST7735_RED);
tft.drawLine(80,70,80,108,ST7735_RED);
tft.drawLine(81,70,81,108,ST7735_RED);
tft.drawLine(0,159,130,159,ST7735_RED);
tft.drawLine(0,0,0,156,ST7735_RED);
tft.drawLine(1,1,1,157,ST7735_RED);
tft.drawLine(127,0,127,156,ST7735_RED);
tft.drawLine(126,0,126,156,ST7735_RED);
tft.drawLine(0,35,130,35,ST7735_RED);
tft.drawLine(0,36,130,36,ST7735_RED);
tft.drawLine(0,70,130,70,ST7735_RED);
tft.drawLine(0,71,130,71,ST7735_RED);
}
void courbe() {
int nouvelleValeur;
// converison vitesse max (350 km/h) en pixel
nouvelleValeur = map((gps.speed.kmph()), 0, 150, 137, 110); // car l'cran a 64 pixels de haut
x++;
tft.drawPixel(x,nouvelleValeur,ST7735_CYAN);
if (x>123) {
x=80;
tft.fillRect(82,110,43,30,ST7735_BLACK);
}
}
void courbeh() {
int nouvelleValeurh;
// converison vitesse max (350 km/h) en pixel
nouvelleValeurh = map((gps.altitude.meters()), 0, 1000, 104, 72); // car l'cran a 64 pixels de haut
xh++;
tft.drawPixel(xh,nouvelleValeurh,ST7735_CYAN);
if (xh>123) {
xh=80;
tft.fillRect(82,72,43,35,ST7735_BLACK);
}
}
void vmax() {
// calcul vitese maximum
speed1 = (gps.speed.kmph());
if ( speed1 > maxspeed) {
maxspeed = speed1;
}
}
void hmax() {
// calcul altitude maximum
high1 = (gps.altitude.meters());
if ( high1 > maxhigh) {
maxhigh = high1;
}
}
#include <SPI.h>
#include<SD.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#define cs 10
#define dc 9
#define rst 8
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
static const int RXPin = 4, TXPin = 3; //GPS communication
static const uint32_t GPSBaud = 9600;
const int cs_sd=4;
#define OLED_RESET 5
TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);
int x=80;
int xh=80;
int maxhigh=0;
int maxspeed = 0, speed1 = 0;
int high1 = 0;;
void setup()
{
Serial.begin(9600);
ss.begin(GPSBaud);
tft.initR(INITR_GREENTAB);
tft.fillScreen(ST7735_BLACK);
tft.setCursor(5, 58);
tft.setTextSize(1);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("initilisation");
tft.setCursor(5, 70);
tft.print("init SD");
delay(1000);
if(!SD.begin(cs_sd)) //Condition vrifiant si la carte SD est prsente dans l'appareil
{
tft.setCursor(5, 82);
tft.print("Defaut SD");
return;
}
tft.setCursor(5, 82);
tft.print("Carte SD OK");
delay(1000);
tft.fillScreen(ST7735_BLACK);
File data = SD.open("donnees.txt",FILE_WRITE); // Ouvre le fichier "donnees.txt"
data.println(""); data.println("Dmarrage acquisition"); // Ecrit dans ce fichier
data.close();
}
void loop()
{
tft.setTextSize(1);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
// affichage des informations a chaque bonne reception satellite
while (ss.available() > 0){
gps.encode(ss.read());
if (gps.location.isUpdated()){
cadre();
tft.setCursor(5, 44);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("Latitude :");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(gps.location.lat(), 6);
tft.setCursor(5, 58);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("Longitude :");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(gps.location.lng(), 6);
//affichage ecran date
tft.setCursor(5, 7);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("date : ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(gps.date.day());
tft.print(" ");
tft.print(gps.date.month());
tft.print(" ");
tft.print(gps.date.year());
String Date=String(gps.date.day())+(" ")+(gps.date.month())+(" ")+(gps.date.year());
//affichage ecran heure
tft.setCursor(5, 20);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("heure : ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(gps.time.hour()+1);
tft.print(" ");
tft.print(gps.time.minute());
tft.print(" ");
tft.print(gps.time.second());
tft.print(" ");
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.setCursor(3, 30);
String Temps=String(gps.time.hour()+1)+(" ")+(gps.time.minute())+(" ")+(gps.time.second());
//affichage ecran altitude
tft.setCursor(5, 80);
tft.print("H m :");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print (gps.altitude.meters(),0);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(" ");
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.setCursor(5, 95);
hmax();
tft.print("Hmax :");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxhigh);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(" ");
courbeh();
//affichage ecran vitesse
tft.setCursor(5, 115);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("V act: ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print (gps.speed.kmph(),0);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(" ");
tft.setCursor(5, 130);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
vmax();
tft.print("vmax: ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxspeed);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(" ");
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
courbe();
//affichage ecran nombre de satellites
tft.setCursor(5, 147);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("nombre de Sat : ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(gps.satellites.value());
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(" ");
// Horizontal Dim. of Precision (100ths-i32)
Serial.print("HDOP = ");
Serial.println(gps.hdop.value());
smartDelay(400);
// Ecriture des donnes dans le fichier texte
File data=SD.open("donnees.txt",FILE_WRITE);
data.println(Date + " " + Temps + " " + String(gps.location.lat(), 6)+" "+String(gps.location.lng(), 6)+(" ")+String(gps.altitude.meters(),0)+(" ")+String(maxhigh)+(" ")+String(gps.speed.kmph(),0)+(" ")+String(maxspeed));
data.close();
}
}
}
// delai pour une bonne recption
static void smartDelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
void cadre() {
// affichage ecran
//cadre
tft.drawLine(0,0,130,0,ST7735_RED);
tft.drawLine(0,1,130,1,ST7735_RED);
tft.drawLine(0,158,130,158,ST7735_RED);
tft.drawLine(0,142,130,142,ST7735_RED);
tft.drawLine(0,141,130,141,ST7735_RED);
tft.drawLine(0,107,130,107,ST7735_RED);
tft.drawLine(0,108,130,108,ST7735_RED);
tft.drawLine(80,108,80,140,ST7735_RED);
tft.drawLine(81,109,81,140,ST7735_RED);
tft.drawLine(80,70,80,108,ST7735_RED);
tft.drawLine(81,70,81,108,ST7735_RED);
tft.drawLine(0,159,130,159,ST7735_RED);
tft.drawLine(0,0,0,156,ST7735_RED);
tft.drawLine(1,1,1,157,ST7735_RED);
tft.drawLine(127,0,127,156,ST7735_RED);
tft.drawLine(126,0,126,156,ST7735_RED);
tft.drawLine(0,35,130,35,ST7735_RED);
tft.drawLine(0,36,130,36,ST7735_RED);
tft.drawLine(0,70,130,70,ST7735_RED);
tft.drawLine(0,71,130,71,ST7735_RED);
}
void courbe() {
int nouvelleValeur;
// converison vitesse max (350 km/h) en pixel
nouvelleValeur = map((gps.speed.kmph()), 0, 150, 137, 110); // car l'cran a 64 pixels de haut
x++;
tft.drawPixel(x,nouvelleValeur,ST7735_CYAN);
if (x>123) {
x=80;
tft.fillRect(82,110,43,30,ST7735_BLACK);
}
}
void courbeh() {
int nouvelleValeurh;
// converison vitesse max (350 km/h) en pixel
nouvelleValeurh = map((gps.altitude.meters()), 0, 1000, 104, 72); // car l'cran a 64 pixels de haut
xh++;
tft.drawPixel(xh,nouvelleValeurh,ST7735_CYAN);
if (xh>123) {
xh=80;
tft.fillRect(82,72,43,35,ST7735_BLACK);
}
}
void vmax() {
// calcul vitese maximum
speed1 = (gps.speed.kmph());
if ( speed1 > maxspeed) {
maxspeed = speed1;
}
}
void hmax() {
// calcul altitude maximum
high1 = (gps.altitude.meters());
if ( high1 > maxhigh) {
maxhigh = high1;
}
}
Comments