Hi!
Thanks to all of You supporting me in the previous topic, Speedometer using UNO and GPS.
Now I have tested the project in my car and in a railroad car.
The 2 different environments, car or railroad shows a little different strange things.
Common is:
Data is not uptated for some time. Speed, Altitude and Compass (direction) are on holiday for quite some time, say from 10 to 30 seconds.
In the railcar speed unexpectedly drops to 2/3 and stays there for some seconds before updating to proper values.
Being at home in the shop I added some debugging code using the ".age()" function printed out to Serial Monitor. The Project is at rest, no moves. Logging maximum age of Speed and Altitude I reach quite large time laps like 30 seconds or more.
I probably don't understand what is told in TinyGPS++ | Arduiniana.
The code is large…
boolean debug = false;
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>
#define BACKLIGHT_PIN 13
hd44780_I2Cexp mylcd; // declare lcd object: auto locate & config exapander chip
// LCD geometry
const int LCD_COLS = 20;
const int LCD_ROWS = 4;
// The TinyGPS++ object
TinyGPSPlus gps;
//Create GPS channel
#define RX 2
#define TX 3
SoftwareSerial mySerial(RX, TX); // pick any 2 unused digital pins (not pins 0 or 1)
long Start_Up_Time;
#define time_adj 2// adjust: +1 for winter time, +2 for summer time
int act_cnt = 0;
char activity[] = "<><>";
//int last_tmp_a, last_tmp_A, last_tmp_SP = 0;
int last_tmp_SP, last_tmp_A, last_tmp_D = 0;
unsigned long last_tmp_SP_time, last_tmp_A_time, last_tmp_D_time = millis();
bool clear_debug_print = true;
unsigned int speed_age_min, altitude_age_min = 65535;
unsigned int speed_age_max, altitude_age_max = 0;
void setup()
{
int status;
status = mylcd.begin(LCD_COLS, LCD_ROWS);
if (status) // non zero status means it was unsuccesful
{
status = -status; // convert negative status value to positive number
// begin() failed so blink error code using the onboard LED if possible
hd44780::fatalError(status); // does not return
}
mylcd.clear();
// initalization was successful, the backlight should be on now
mySerial.begin(9600); // 9600 is the default baud rate for my Neo6m units
Serial.begin(9600);// For PC, serial monitor
// Print start message to the LCD
mylcd.print("Starting");
// Print start message to the PC
Serial.println("Starting");//sent to PC
Start_Up_Time = millis();
clear_debug_print = true;
}
void loop()
{
int tmp;
while (mySerial.available() > 0)
gps.encode(mySerial.read());
//Then query it for the desired information:
// Altitude
//if (gps.altitude.isUpdated())
if (gps.altitude.isValid())
{
if (debug)
{
Serial.print("ALT = ");
Serial.println(gps.altitude.meters());
}
tmp = int(gps.altitude.meters() + 0.5);
if (tmp > 9999) tmp = 9999;
if (tmp < -999) tmp = -999;
mylcd.setCursor(0, 1);
mylcd.print("Alt: ");
if (tmp < 1000) mylcd.print(" ");
if (tmp < 100) mylcd.print(" ");
if (tmp < 10) mylcd.print(" ");
mylcd.print(tmp);
// mylcd.print(" "); //tested 180709 22.17
if (last_tmp_A == tmp)
{
mylcd.setCursor (9, 2); mylcd.print("A "); mylcd.setCursor(11, 2); mylcd.print( min( ( millis() - last_tmp_A_time) / 1000, 999));
clear_debug_print = false;
}
else
{
last_tmp_A = tmp;
last_tmp_A_time = millis();
clear_debug_print = true;
}
tmp = gps.altitude.age();
altitude_age_max = max(altitude_age_max, tmp);
altitude_age_min = min(altitude_age_min, tmp);
if(altitude_age_min == 0) altitude_age_min = 999;
Serial.print("Altitude age: "); Serial.print(tmp); Serial.print(" ");
Serial.print(altitude_age_min); Serial.print(" "); Serial.print(altitude_age_max); Serial.print(" ");
}
// Hdop
if (gps.hdop.isValid())
{
tmp = gps.hdop.value();
mylcd.setCursor(16, 3);
if (tmp > 100) mylcd.print("H>1");
else mylcd.print("H<1");
}
// speed
if (gps.speed.isValid())
{
tmp = int(gps.speed.kmph() + 0.5);
mylcd.setCursor(0, 0);
mylcd.print("Speed: ");
if (tmp < 100)mylcd.print(" ");
if (tmp < 10)mylcd.print(" ");
mylcd.print(tmp);
// mylcd.print(" "); remarking 180709 21.08
if (last_tmp_SP == tmp)
{
mylcd.setCursor(15, 2); mylcd.print("S "); mylcd.setCursor(17, 2); mylcd.print( min( ( millis() - last_tmp_SP_time) / 1000, 999));
clear_debug_print = false;
}
else
{
last_tmp_SP = tmp;
last_tmp_SP_time = millis();
clear_debug_print = true;
}
tmp = gps.speed.age();
speed_age_max = max(speed_age_max, tmp);
speed_age_min = min(speed_age_min, tmp);
if(speed_age_min == 0) speed_age_min = 999;
Serial.print("Speed age: "); Serial.print(tmp); Serial.print(" ");
Serial.print(speed_age_min); Serial.print(" "); Serial.println(speed_age_max);
}
// date
if (gps.date.isUpdated())
{
mylcd.setCursor(0, 3);
mylcd.print(gps.date.year());
mylcd.print("-");
if (gps.date.month() < 10) mylcd.print("0");
mylcd.print(gps.date.month());
mylcd.print("-");
if (gps.date.day() < 10) mylcd.print("0");
mylcd.print(gps.date.day());
}
// time
if (gps.time.isUpdated())
{
if (debug)
{
Serial.print("Time = "); Serial.print(gps.time.hour()); // Hour (0-23) (u8)
Serial.print("."); Serial.print(gps.time.minute()); // Minute (0-59) (u8)
Serial.print("."); Serial.println(gps.time.second()); // Second (0-59) (u8)
}
mylcd.setCursor(0, 2);
tmp = gps.time.hour() + time_adj; // adjust: +1 for winter time, +2 for summer time
if (tmp >= 24) tmp = tmp - 24;
if (tmp < 10) mylcd.print("0");
mylcd.print(tmp);
mylcd.print("-");
if (gps.time.minute() < 10) mylcd.print("0");
mylcd.print(gps.time.minute());
mylcd.print("-");
if (gps.time.second() < 10) mylcd.print("0");
mylcd.print(gps.time.second());
mylcd.print(" ");
}
// Cource, Direction
if (gps.course.isValid())
{
tmp = int(gps.course.deg());
while (tmp >= 360) tmp = tmp - 360;
mylcd.setCursor(11, 0);
mylcd.print("Dir: ");
if (tmp < 100 ) mylcd.print(" ");
if (tmp < 10 ) mylcd.print(" ");
mylcd.print(tmp);
if (last_tmp_D == tmp)
{
mylcd.setCursor(11, 1); mylcd.print("D "); mylcd.setCursor(13, 1); mylcd.print( min( ( millis() - last_tmp_D_time) / 1000, 999));
clear_debug_print = false;
}
else
{
last_tmp_D = tmp;
last_tmp_D_time = millis();
clear_debug_print = true;
}
}
// satelites
if (gps.satellites.isValid())
{
mylcd.setCursor(11, 3);
mylcd.print("S: ");
mylcd.setCursor(13, 3);
mylcd.print(gps.satellites.value());
}
mylcd.setCursor(19, 3);
mylcd.print(activity[act_cnt++ % 4]);
if (((millis() - Start_Up_Time) / 1000) > 60)
{
if (clear_debug_print)
{
clear_debug_print = false;
mylcd.setCursor(8, 2); mylcd.print(" "); // clear pos 8 - 19 from startup msg
mylcd.setCursor(11, 1); mylcd.print(" "); // clear pos 11 - 19 from startup msg
}
}
}
My main interest is to have a higher update frequency and, of course, knowing the freschness of data shown.
Anybody that will try to read the code and point out things that can be coded in a better way? I'm prepared to assist with more of my thinking to ease the Reading of the code.