gps logger a comando

Salve a tutti,

vengo con il cappello in mano a chiedere il vs aiuto.
ho bisogno di creare un sistema che logga la posizione ricavata dal modulo gps su una SD ma non in continuo come migliaia di esempi ma solo conseguentemente a uno specifico evento.

ho disegnato uno schema concettuale di quello che dovrebbe essere il flusso “logico”

Provando a scrivere qualche linea di codice prendendo esempio da altri sketch il primo problema che riscontro è sulla variazione di stato dell’interruttore. Se il ciclo di controllo è troppo lento potrei perdermi una pressione del tasto, se troppo veloce mi genera più condizioni verificate se la pressione del tasto eè troppo lunga.

il tipo di interruttore che materialmente mi serve è proprio quello nell’immagine.

spero di essermi spiegato bene e vi ringrazio dell’aiuto

codice.txt (579 Bytes)

Ciao.
Hai usato il termine esatto: variazione di stato.
Nello sketch che hai allegato tu però non controlli la variazione, controlli solo lo stato.
Per sapere se una cosa è cambiata la confronti con il suo stato precedente; se lo stato precedente è diverso dallo stato attuale allora c'è una variazione di stato.

Quindi:

  • crei una variabile per memorizzare lo stato precedente;
    -leggi l'ingresso e lo confronti con lo stato precedente
    se è uguale non hai cambiamenti di stato; se è diverso allora il cambiamento c'è quindi memorizzati il nuovo stato precedente e poi fai fare allo sketch quello che deve fare.

Ciao
pippo72

quando si parla di tempo bisogna rimuovere la funzione delay( NUM ) con un bel blocco if che controlli che non sono passati almeno NUM milli secondi dall'ultima lettura. in questo modo ad ogni loop non ti si imbambola il micro per 100 millis , ma (ipotizzando che esegue il loop in 1 millis) controlla 100 volte che è passato il tempo.

Verifica quello che ho scritto facendo delle print a un baudrate di 155200 di Serial.println(millis()-lastLoopExecuted); utilizzando lo sketch che trovi in esempi->blink without delay e il tuo.

noterai una bella differenza

vi ringrazio molto per queste prime risposte.

io avevo pensato una cosa del genere

se (pulse==1 && check==0)
istruzioni per loggare la posizione una sola volta (fix)
check =1
deley(x) //per evitare il rimbalzo

se (pulse ==0)
check==0

Salve a tutti,
ho fatto una piccola pausa dal forum ma sono andato avanti con il mio progetto solo che mi trovo davanti a delle problematiche che non riesco a capire perché e quindi risolvere.

Spiego il punto…
prendendo spunto da altri esempi e mettendo tutto insieme sono riuscito a mettere su un sistema che se escludo il pulsante il log della posizione fila liscio ogni secondo.
Come detto però quello che serve a me è un singolo fix a comando quindi ecco il tasto, e qui nascono i problemi…
Quando premo il tasto non ho sempre il log della posizione, nel senso che anche se il gps riceve i dati quando premo questi non vengono scritti sulla sd ignorando la pressione del tasto.

vi allego immagine dello schema e file .ino vi prego di dirmi dove sbaglio

vi do qualche altra info
il led l’ho messo perche volevo capire quale era il tempo di apertura/scrittura/chiusura del file perche pensavo che li ci fosse un collo d’oca nel flusso e invece non mi sembra in quanto l’operazione è rapidissima.

io vorrei avere la certezza che anche se premo il tasto una volta al sec non mi salta un fix ma non mi serve loggare in modo continuo una volta al secondo

vi ringrazio per ogni commento e suggerimento

gps.ino (4 KB)

TinyGPS supporta la HDOP: gps.hdop().

A livello hardware ... ma perche' non usi una rete RC per il debounce e poi leghi lo switch al "rising" (o "falling", dipende da come l'hai collegato) ? ... in quel modo ti dovrebbe rilevare solo il momento della chiusura, quello in cui cambi stato da aperto a chiuso ... poi nella ISR ti limiti a cambiare valore ad una flag, e quella flag la usi nello sketch per dirgli cosa fare, esempio (se nella ISR l'hai messa ad uno), finche e' zero la ignori, quando diventa uno fai il log e la rimetti a zero ...

SukkoPera grazie infatti ho modificato subito dopo il post, non mi ero accorto ma è già nel listato.

Etemenanki, leggendo la tua risposta mi sono sentito piccolo e ignorante... non ho capito una parola.
Io praticamente ho iniziato da due mesi scarsi seguendo tutorial su youtube e online...

diciamo che devo accontentarmi di quanto messo in tavola, oltre quello che hai visto al momento non so andare. spero che questo basti per il mio scopo...

Tranquillo, neppure io sono un programmatore ... per rete RC intendo un condensatore da 100n fra il pin e GND, ed una resistenza da 100 ohm fra lo switch ed il pin ... in questo modo ti eliminerebbe i rimbalzi senza bisogno di routines software nello sketch ...

Per l'interrupt pensavo potessi usarlo meglio di un semplice controllo con la digitalread e gli if, perche' e' indipendente dal loop e perche' puo essere associato a diversi stati, high, low, change, rising, falling ... quindi usarlo ti eliminerebbe anche la necessita' di discriminare quale stato hai al momento ... se ad esempio tu usassi un'ingresso con la pullup (magari attivando quella interna), e collegassi lo switch verso massa, usando un'interrupt settato per il "falling", automaticamente ti rileverebbe solo il momento della chiusura dello switch, ignorando poi sia il tempo in cui rimane chiuso, sia la riapertura ... se invece usi lo switch che chiude verso VCC e la resistenza di pulldown verso massa, basta impostarlo per il "rising" ... per cui pensavo ti potesse semplificare tutto quanto ... :wink:

salve a tutti, ritorno su questo argomento.

non riesco a venirne fuori…
ho provato a portare fuori dalla funzione che decodifica le stringhe gps sul loop principale pensando che una volta "riempite"siano sempre disponibili per essere registrate.

ho messo in stampa sul monitor seriale i valori, ma ho notato che scrive una riga due volte (lo si capisce dai sec) e che ogni tanto manca la decodifica. Vi allego un’immagine

Ho messo quindi il controllo sullo stato del tasto premuto o no dopo la decodifica, secondo la mia logica, un update al secondo della posizione, se anche viene ripremuto dopo mezzo secondo ho comunque le variabili che hanno un valore decodificato dal secondo precedente…e invece niente…
anche se premo il tasto avvolte registra la pos sul file di log altre no…

vi allego il file.

Immagine.png

gps_button.ino (6.65 KB)

ho modificato lo script con l’interrupt
ma ancora non ci siamo…
Se ho risolto il problema della mancata registrazione anche se premevo il tasto, ora, quando premo il tasto registra sempre (ho anche un problema di rimbalzo ma è il meno, la doppia registrazione è facilmente eliminabile in fase di elaborazione dati)

il problema adesso è che una volta premuto il tasto il modulo gps smette di funzionare e riprende a funzionare dopo un paio di sec.

dove sbaglio?

gps_interrup.ino (5.79 KB)

NON entro nel merito del tuo pogramma, ma ti segnalo che stai usando gli “interrupt” in modo errato

Una ISR (la routine chiamata dall’interrupt) DEVE essere la più breve possibile, NON deve usare delay, porta seriale ed altro (studia QUI) e deve terminare il prima possibile … con queste premesse capisci da solo che, la cosa migliore, è che la ISR, quando scatta, semplicemente alzi una “flag” per indicare l’avvenuto interrupt ed esca.

E’ poi nel loop() che si controlla tale “flag” e che si fa ciò che si deve fare se la si trova attiva.

Vedi quindi di modificare in tal senso il tuo programma ed inserisci un “debouncing” hardware sul tuo pulsante, dato che, con le ISR, NON si deve fare via software.

Guglielmo

suggerimenti molto interessanti.
provvederò a fare le modifiche da te suggerite.

grazie e vediamo a cosa arrivo

io però vorrei entrare nel merito del programma per dirti a cosa mi serve e magari poter avere qualche suggerimento o cambio di prospettiva che non fa affatto male. magari io mi sto concentrando su alcune cose e tralasciando altro..
Io devo rilasciare delle capsule su un percorso prestabilito solo che posso controllare che tutto sia andato a buon termine solo alla fine del percorso. Se qualcosa si inceppa devo vedere quale è la posizione dell'ultima capsula rilasciata per poi poter riprendere da quella posizione.

ecco quindi il perché della registrazione a comando e non in continuo.

Direi che la logica è semplice e mi sembra ch tu stia facendo qualche cosa di simile ...

... io leggerei comunque in continuazione il GPS e metterei l'ultima "sentenza" valida in un buffer che, mano mano, sovrascrivo con la successiva che arriva.

Se non succede nulla, vado avanti a leggere "sentenze" ed a memorizzare l'ultima, se trovo la "flag" alzata (... quindi c'è stato un'interrupt) scrivo il buffer che contiene l'ultima sentenza valida sulla SD ed il ciclo riprende.

Guglielmo

non va…

ho provato in questo modo…
ma prima anche senza premere il tasto partiva sparato a loggare… numeri a caso…bho chissa dove li prendeva…

poi ho messo qua e la dei comandi flag=0 per cercare di frenarlo ma niente…
al momento non parte a registrare a tutta birra ma ogni tanto registra da solo una posizione (sempre senza premere il tasto… potrei cambiare il tasto)

e se schiaccio il tasto non fa nulla…

e allego quello che registra…
lat e long ok, data e ora ok, altezza, num sat e hdop valori a capocchia…

non so che fare…abbiate pazienza

gps_interrup_2.ino (5.44 KB)

FIX.TXT (402 Bytes)

O segui quello che ti dico o fai di testa tua. Per cui, se vuoi ...

... scrivi EX NOVO, pulito ed ordinato un programma che legge SOLAMENTE il GPS e se trova una "sentenza" valida la salva da qualche parte.

Quando avrai fatto un programma pulito, leggibile e funzionante che fa SOLO questo, si va avanti ... perché cercare di arrabbattare le cose partendo da un affare fatto male è tempo perso.

Guglielmo

...fatto e funziona adesso.
ora ogni volta che pigio il tasto logga e se pigio due volte velocemente prima che il gps si aggiorni logga la stessa posizione (come ovvio che sia)

finalmente!!