OLED very slow update speed, GPS

OLED will display speed, but at a very slow update speed, perhaps every 5-7 seconds.

I'm very new to this so be gentle, i'm well aware that other GPS scripts i have seen are much larger and more complicated than mine, i'm just not at a stage yet where i under stand anything but the most basic programming.

GPS- UBlox 6m is TX is connected to D4, RX to D3.
OLED- is to SDA-A4 and CLK-A5

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

static const int RXPin = 4, TXPin = 3;

static const uint32_t GPSBaud = 9600; //was 4800

// The TinyGPS++ object

TinyGPSPlus gps;

// The serial connection to the GPS device

SoftwareSerial ss(RXPin, TXPin);

#define OLED_RESET 7

Adafruit_SSD1306 display(OLED_RESET);

String speedinkm;
int f=0;

void setup()

{

display.begin(SSD1306_SWITCHCAPVCC, 0x3c);

display.clearDisplay();

Serial.begin(9600);

ss.begin(GPSBaud);

}

void loop()

{

f = round( gps.speed.kmph());
speedinkm = String(f);
Serial.print(speedinkm);

// This sketch displays information every time a new sentence is correctly encoded.

while (ss.available() > 0)

if (gps.encode(ss.read()))

// displayInfo();

if (millis() > 5000 && gps.charsProcessed() < 10)

Serial.println(F("Speed"));
Serial.println(gps.speed.kmph(), 6);
Serial.print(F(","));
Serial.println(F("Number of sats"));
Serial.println(gps.satellites.value(), 6);
Serial.println(F("GPS Lat"));
Serial.println(gps.location.lat(), 6);

{

display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println(speedinkm);
display.display();
}

}

Without any braces to enclose a larger code block, this if statement only applies to the single line that follows it:

if (millis() > 5000 && gps.charsProcessed() < 10)

Serial.println(F("Speed"));

The following lines will then always be executed.

Subsequently, these braces do absolutely nothing:

{

display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println(speedinkm);
display.display();
}

Your main problem is that the code is constantly writing to the screen. Similar to the comment in the previous reply, this line is missing opening and closing curly braces, which negates its entire purpose:

if (gps.encode(ss.read()))

gps.encode() informs you when a valid GPS sentence has been received, and it is time to process it. So in loop(), your program outline should look like this:

if (gps.encode(ss.read())) {
// do stuff with the received sentence, and display the results
}

This is silly, and on AVR based Arduinos, Strings cause memory problems and program crashes. Avoid Strings.

f = round( gps.speed.kmph());
speedinkm = String(f);
Serial.print(speedinkm);

Instead, one line will do everything:

Serial.print(0.5+gps.speed.kmph(),0);

Furthermore, it is a waste of time to do the above every pass through loop. To save time, write to the screen only when numbers have changed.

mts247:
I'm very new to this so be gentle,

Do not do that. Take all you can, it will get you further in the long run. I am sure you can handle it. :slight_smile:

You used code tags in your post. Thank you. Well done. :slight_smile:

First, find the Tools -> Auto Format. This will format your code and show you some mistakes you have done, by aligning the lines. Try and you will see what I mean.

Next, go to File -> Preferences and makes sure Compiler Warnings is set to ALL. The compiler will tell you things that are potentially wrong.

Regarding your code:

I would avoid complex logic for now and focus on the individual statements e.g.

millis() > 5000 after 5 seconds this is always true.

gps.charsProcessed() < 10 this does not seem to be right, it’s a low level things, I would suspect you want something high level like isValid or isUpdated, does your application care about how many char are processed?

Do not combined these in one statement. Do two if() inside each other and print yourself short messages. See what happens.

Have a look at the File -> Examples -> 02.Digital -> BlinkWithoutDelay to see how millis() is used for regular intervals.

What Arduino are you using? If you have one with more UARTs. Do not use SoftwareSerial.

For constant values, I recommend using the ALL_CAPTIAL_WITH_UNDERSCORE notation. This is quite common across multiple languages and platforms. You used it for OLED_RESET why not for RXPin, GPSBaud

Do not save on a few characters? They are free. GPS_BAUDRATE, GPS_TX_PIN

Check your variable names and try to make them logical. speedinkm

Arduino recommends to use camelCase for variable and function names e.g. speedInKmph, Look at the library functions clearDisplay(), charsProcessed()

Global variables should not be single characters. f what is that?

Try to avoid global variables. Declare them inside the function if they are only used there. This allows you to copy the code to another project easier and saves memory.

Thank you so much. :slight_smile:

I'll need some time to take all that in, my code was pretty much the 2 examples from tinygps+ and adafruit library's mashed together with a hodge podge of 2 other GPS programs i found.

I'm using a arduino Nano v3

The .encode method returns true every time a complete NMEA sentence is received. There are about 8 sentences sent a second, by default, from a UBLOX GPS;

$GPGSA, $GPGSV, $GPGSV, $GPGSV, $GPGLL, $GPRMC, $GPVTG, $GPGGA,

Tiny GPS++ only decodes data from two sentences however; $GPGGA and $GPRMC.

So if you use the .encode method to decide there is new data to display, this will only be the case on 1 out of 4 ocaisions.

In the case of speed then only 1 in 8 of the sentence encodes will have an updated speed, since its read from $GPRMC, so there is probably little point in updating the display at every sentence.