questo il codice sistemato. controllato adesso in tutte le direzioni e funziona bene.
ho sostituito Co con He in quanto credo sia più corretto considerare la bussola i gradi e heading la direzione verso il punto cardinale.
ho notato però che questa versione ci potrebbe mettere un pochino più tempo per riportare il dato heading/compass la catena di IF mi sembra più veloce con un dato un filo più brioso che viene aggiornato più spesso.
non so perchè alcuno dati sono istantanei mentre altri possono rimanere invariati anche per minuti.. tipo l'altitudine.. si aggiorna davvero di rado e spesso è sbagliata. l'errore lo imputo al fix 3d ma non cpaisco perchè debba aggiornarsi anche dopo 10 minuti dove magari ho percorso un dislivello.
avrò modo di confrontare la velocità die dati bussola anche perchè dipende molto dal meteo, se provo il gps di notte col cielo stellato funziona sempre meglio.
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <NMEAGPS.h>
#include <NeoSWSerial.h>
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
#define MAX_CHARS 24
#define RX_pin 5
#define TX_pin 4
#define SHOW_INTERVAL 1
#define GPS_baud 9600
SSD1306AsciiWire oled;
NMEAGPS gps;
gps_fix fix;
float odo, Speed, alt, Dist, head, maxs = 0;
unsigned int Sat = 0;
unsigned long tmp, var = 0;
int secondi, minuti = 0, ore = 0, fct = 2, fcl = 1;
NeoGPS::Location_t lastLoc, base;
bool stScan = true, lastLocOK = false;
bool altOK = false;
bool Satok = false;
static NeoSWSerial gpsPort(RX_pin, TX_pin);
static constexpr int INITIAL_SHOW = (2 * SHOW_INTERVAL) - 1;
int show = INITIAL_SHOW;
const int LED_PIN = 3;
const float SPEED_LIMIT = 0.1; // speed limit value
void disp(int c, int r) {
oled.clear();
oled.setCursor(c, r);
}
const char* strBussola[8] = {"N ", "NE", "E ", "SE", "S ", "SO", "O ", "NO"};
int index;
int trovaIndice(float angolo) {
int _index;
for (_index = 0; _index < 8; _index++) {
float angoloDirezione = _index * 45.0 + 22.50;
float angoloMin = angoloDirezione - 22.50;
float angoloMax = angoloDirezione + 22.50;
if (angolo >= angoloMin && angolo <= angoloMax)
return _index;
}
return _index;
}
void setup() {
pinMode (LED_PIN, OUTPUT);
Serial.begin(9600);
gpsPort.begin(GPS_baud);
Wire.begin();
oled.begin(&SH1106_128x64, I2C_ADDRESS);
oled.setFont(ZevvPeep8x16);
oled.displayRemap(true); // inversione dello schermo display
disp(15, 2);
oled.println("tuo.nome GPS");
delay(2000);
oled.clear();
const int cs_sd = 2;
if (!SD.begin (cs_sd)) {
oled.clear();
disp(50, 2);
oled.print("NO SD");
delay(10000);
oled.clear();
}
File data = SD.open("L.csv", FILE_WRITE);
data.println("");
data.println(F("Da Hr Tm La Lo At Km Di Ve Co He Sa" ));
data.close();
}
void loop() {
tmp = (millis() / 1000);
secondi = tmp - (var * 10) + fct;
if (secondi > 60) {
secondi = secondi - 60;
}
if (secondi == 60) {
minuti = minuti + 1;
var = var + 6;
}
if (((minuti == 10) || (minuti == 20) || (minuti == 30) || (minuti == 40) || (minuti == 50) || (minuti == 60)) && (secondi == 1)) {
fct = fct + fcl;
}
if (minuti >= 60) {
minuti = 0;
ore = ore + 1;
}
if (ore >= 24) {
ore = 0;
}
if (gps.available( gpsPort )) {
gps_fix fix = gps.read();
show = (show + 1) % SHOW_INTERVAL;
if (fix.valid.speed && (fix.speed_kph() > SPEED_LIMIT)) {
digitalWrite( LED_PIN, HIGH );
} else {
digitalWrite( LED_PIN, LOW );
}
if (fix.valid.location) {
if (lastLocOK) {
odo += fix.location.DistanceKm( lastLoc );
Speed = fix.speed_kph();
}
lastLoc = fix.location;
lastLocOK = true;
if (stScan) {
stScan = false;
base = fix.location;
} else {
Dist = ( fix.location.DistanceKm( base ) );
}
}
if ( Speed > maxs) maxs = Speed;
if (fix.valid.satellites ) {
Sat = fix.satellites ;
Satok = true;
}
if (fix.valid.heading ) {
head = fix.heading() ;
index = trovaIndice(head);
}
if (fix.valid.altitude) {
alt = fix.altitude();
altOK = true;
}
if (show == 0) {
char displayBufffer[MAX_CHARS];
oled.setCursor(0, 0);
snprintf(displayBufffer, MAX_CHARS, "Km:%2d.%1d", (int)odo, (int)(odo * 100) % 100);
oled.println(displayBufffer);
oled.setCursor(65, 0);
snprintf(displayBufffer, MAX_CHARS, "Di:%2d.%1d", (int)Dist, (int)(Dist * 100) % 100);
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, "Ve:%2d.%1d", (int)Speed, (int)(Speed * 10) % 10);
oled.println(displayBufffer);
oled.setCursor(65, 2);
snprintf(displayBufffer, MAX_CHARS, "Al:%2d.%1d", (int)alt, (int)(alt * 100) % 100);
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, "Vm:%2d.%1d", (int)maxs, (int)(maxs * 10) % 10);
oled.println(displayBufffer);
oled.setCursor(65, 4);
snprintf(displayBufffer, MAX_CHARS, "He: %s\n", (strBussola[index]));
oled.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, "%d:%d:%d ", (int)ore, (int)minuti, (int)secondi);
oled.println(displayBufffer);
oled.setCursor(65, 6);
snprintf(displayBufffer, MAX_CHARS, "Co:%2d.%1d", (int)head, (int)(head * 100) % 100);
oled.println(displayBufffer);
}
File data = SD.open("L.csv", FILE_WRITE);
data.print(fix.dateTime.hours + 2);
data.print(":");
data.print(fix.dateTime.minutes);
data.print(" ");
data.print(fix.dateTime.date);
data.print("/");
data.print(fix.dateTime.month);
data.print(" ");
data.print(ore);
data.print(":");
data.print(minuti);
data.print(":");
data.print(secondi);
data.print(" ");
data.print(fix.latitude(), 6);
data.print(" ");
data.print(fix.longitude(), 6);
data.print(" ");
data.print(alt);
data.print(" ");
data.print(odo);
data.print(" ");
data.print(Dist);
data.print(" ");
data.print(Speed);
data.print(" ");
data.print(head);
data.print(" ");
data.print(strBussola[index]);
data.print(" ");
data.print(Sat);
data.println();
data.close();
}
}
grazie per l'aiuto.