I have built a speedometer, based on this youtube video: https://www.youtube.com/watch?v=gKuJxjxNP-k&t=34s
The speedometer is for a car, so it needs to be in real-time and accurate, with the actual speed that the car reads. The speedometer is built with a NEO-6m GPS module with an antenna. It is hooked up to an Arduino Nano and an OLED 0.96".
This is the code and wiring diagram. The code is the same as the video and uses TinyGps library. But simplified to just show me the current speed(kmh). I have removed every other line of code, to reduce latency. Wiring diagram of speedometer. Uisng NEO-6M GPS, Nano, and OLED 0.96"
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);
#include <SoftwareSerial.h>
#define rxPin 2
#define txPin 3 //unused
SoftwareSerial neogps(rxPin,txPin);
#include <TinyGPS++.h> //1.0.3
TinyGPSPlus gps;
//---------------------------------------------------------------------------
int x_max = 128; //OLED display width, in pixels
int y_max = 62; //OLED display width, in pixels
int x_center = x_max/2;
int y_center = y_max/2+10;
int speed;
int adjspeed;// Adjusted speed for oversetimation by car
int num_sat;
//satellite logo
#define sat_logo_width 20
#define sat_logo_height 20
const unsigned char sat_logo[] = {
0x00, 0x01, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x06, 0x00, 0x60, 0x30, 0x00,
0x60, 0x78, 0x00, 0xc0, 0xfc, 0x00, 0x00, 0xfe, 0x01, 0x00, 0xff, 0x01,
0x80, 0xff, 0x00, 0xc0, 0x7f, 0x06, 0xc0, 0x3f, 0x06, 0x80, 0x1f, 0x0c,
0x80, 0x4f, 0x06, 0x19, 0xc6, 0x03, 0x1b, 0x80, 0x01, 0x73, 0x00, 0x00,
0x66, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x70, 0x00, 0x00
};
//---------------------------------------------------------------------------
//Program variables
double lat;
double lng;
void gauge() {
//TOP LEFT: draw satellite logo and number of satellites
u8g.drawXBM(0, 0, sat_logo_width, sat_logo_height, sat_logo);
u8g.setPrintPos(18, 5);
u8g.print(num_sat, 5);
//---------------------------------------------------------------------------
// Show Speed and align its position
u8g.setFont(u8g_font_profont22);
u8g.setPrintPos(54,60);
if (adjspeed>99) {
u8g.setPrintPos(47,60);
}
u8g.print(adjspeed);
//---------------------------------------------------------------------------
}
void setup(void) {
Serial.begin(9600);
neogps.begin(9600);
u8g.setFont(u8g_font_chikita);
u8g.setColorIndex(1);
}
void loop(void){
Read_GPS();
//Display Data on Oled
{
u8g.firstPage();
do {
gauge();
}
while( u8g.nextPage() );
}
}
void Read_GPS(){
boolean newData = false;
for (unsigned long start = millis(); millis() - start < 100;)
{
while (neogps.available())
{
if (gps.encode(neogps.read()))
{
newData = true;
break;
}
}
}
//If newData is true
if(newData == true){
newData = false;
Get_GPS();
}
else {
//no data
}
}
void Get_GPS(){
num_sat = gps.satellites.value();
if (gps.location.isValid() == 1) {
speed = gps.speed.kmph();
adjspeed = 1.03*speed; // the speed is adjusted(increaed) to match the speed that the actuall car outputs. (Because there is a law stating that cars need to overestimate the actual speed by a little bit
Serial.print("Speed: ");
Serial.println(adjspeed);
}
}
The speedometer is accurate and shows the right speed, but there is a latency of around 1-2 seconds. For example, if the car starts accelerating from 0, the OLED shows the speed 1-2 seconds later, the same with when the car brakes. I need the latency to be, at least, less than a second.
I'm a bit of a beginner and not sure how to reduce this latency. I was hoping for someone here to explain to me how I can reduce this latency
for
statement inRead_GPS()
?