Hi, I'm busy with creating a Speed GPS. I'm using the Ultimate GPS from Adafruit. I want to show to Current Speed, and the MAX Speed. But MAX speed is not working.
Here is the code for the MAX speed.
What is wrong?
if (GPS.speed > SpeedMax){
SpeedMax = GPS.speed;
}
One thing I noticed: you don't initialize SpeedMax. Personally, I prefer explicit initialization values like this:
int SpeedMax = 0;
Also, I would move the max checking to where a new sentence has been parsed:
if (GPS.newNMEAreceived()) {
if (!GPS.parse(GPS.lastNMEA()))
return;
// else Good sentence received!
if (SpeedMax < GPS.speed){ // reordered to match next line...
SpeedMax = GPS.speed;
}
}
Changed it. But it still isn't working. GPS.speed is displayed as x.xx (2 decimals behind point). But SpeedMax keeps changing and won't display the max. Also is SpeedMax displayed as x (1 decimal).
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <U8glib.h>
int SpeedMax = 0;
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);
Adafruit_GPS GPS(&Serial);
HardwareSerial mySerial = Serial;
#define GPSECHO true
boolean usingInterrupt = false;
void useInterrupt(boolean);
void draw(void) {
u8g.setFont(u8g_font_unifont);
if (GPS.fix) {
u8g.setPrintPos(0, 10);
u8g.print("AVG");
u8g.setPrintPos(0, 22);
u8g.print("Max");
u8g.setPrintPos(0, 34);
u8g.print("Speed");
u8g.setPrintPos(65, 10);
u8g.print("XXX");
u8g.setPrintPos(65, 22);
u8g.print(SpeedMax);
u8g.setPrintPos(65, 34);
u8g.print(GPS.speed);
}
else{
u8g.setPrintPos(00, 34);
u8g.print("NO FIX");
}
}
void setup()
{
Serial.begin(115200);
Serial.println("Adafruit GPS library basic test!");
GPS.begin(9600);
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
GPS.sendCommand(PGCMD_ANTENNA);
useInterrupt(true);
delay(1000);
mySerial.println(PMTK_Q_RELEASE);
}
SIGNAL(TIMER0_COMPA_vect) {
char c = GPS.read();
#ifdef UDR0
if (GPSECHO)
if (c) UDR0 = c;
#endif
}
void useInterrupt(boolean v) {
if (v) {
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
usingInterrupt = true;
}
else {
TIMSK0 &= ~_BV(OCIE0A);
usingInterrupt = false;
}
}
uint32_t timer = millis();
void loop()
{
SpeedMax = 0;
if (GPS.speed > SpeedMax){
SpeedMax = GPS.speed;
}
if (! usingInterrupt) {
char c = GPS.read();
if (GPSECHO)
if (c) Serial.print(c);
}
if (GPS.newNMEAreceived()) {
if (!GPS.parse(GPS.lastNMEA()))
return;
// else Good sentence received!
if (SpeedMax < GPS.speed){ // reordered to match next line...
SpeedMax = GPS.speed;
}
}
if (timer > millis()) timer = millis();
if (millis() - timer > 2000) {
timer = millis();
if (GPS.fix) {
Serial.print("Speed (knots): ");
Serial.println(GPS.speed);
}
u8g.firstPage();
do {
draw();
}
while( u8g.nextPage() );
delay(500);
}
}
Great, it worked!! With the average. Is it possible with to dmake an average every 10 sec? Then I know how to display the best 10sec average every time.
cekstuffertz:
Is it possible to make an average every 10 sec? Then I know how to display the best 10sec average every time.
I'm not sure what the "best 10sec average" is, but I think what you want is a Moving Average. Then SpeedMax could remember the highest average instead of the highest GPS.speed.
The Simple Moving Average requires you to remember the last 10 speeds. This would require an array of speeds and an index to remember the oldest speed. The index would roll over using modulo arithmetic.
The Cumulative Moving Average is easier to implement because you don't have to remember the last 10 speeds.
The Modified or Running Moving Average is very simple, and very common.
Translating a concept like this into code is a great skill to have, and gets easier as you implement more of them. Let us know if you have any questions.
I want an average from the lest 10 sec. A 10sec AVG. I tried my best yesterday but it didnt work. So the average would be from the readings from the last 10 sec. This means it changes every 10 sec. But thats what I want. Can you help me? Is there a existing library for something like that?
So every 10s, the average speed updates? Ok, the basic idea is to have a counter that goes from 0 to 9 (we start at zero around here ), incrementing once for each new speed reading. This means you will do that inside this if statement:
if (GPS.newNMEAreceived()) {
At that time, add the new speed to an accumulator, and increment your counter:
Remember to declare the integer Readings and floating-point AccSpeed and AvgSpeed variables somewhere up above, and print the AvgSpeed in your draw routine.