Assolutamente si
Farei anche altre prove. Ad esempio la sola connessione I2c offre maggiore grado di libertà e soprattutto sotto il sensore u-blox non ci saranno circuiti. Lo stesso grado di libertà lo si può ottenere collegando la shield attraverso 5 fili. 2 sono l'alimentazione +3.3V (pin 12) e GND (pin 11). Altre tre fili sono RX(9), TX(8) e EXTINT(2).
Nel fare i collegamenti volanti devi fare rifermento allo schema teorico allegato prima in pdf. Come vedi il pin 1 si trova in basso a destra, salendo tutti gli altri fino al pin 14.
A rigor di logica questa connessione volante ci mette nelle stesse identiche condizioni vantaggiose della connessione via I2c.
Ciao.
Ho risolto!!! Ovviamente era colpa mia! Dunque ho rimesso il cavo per la connessione I2C anche se ho lasciato la shield impilata perché è più funzionale al mio progetto. Ho lasciato solo GPS.available() . Nel programma, ho messo tutto (richiesta dati shield ENV, scrittura su seriale, scrittura su SD) dentro all'IF GPS.available(). Quindi all'inizio non fa nient'altro se non collegarsi al GPS. Una volta agganciato si mette al lavoro con il resto.
Ho messo un unico delay ma sempre all'interno del IF. Ho pensato che nelle mie prove precedenti non aspettavo abbastanza. Quindi finchè non aggancia il GPS lavora a ritmo sostenuto. Una volta agganciato (dentro l'IF) rallenta con i dati.
Credo che questo sia stato il mio errore quando avevo fatto le prove precedenti. Con il delay fuori non aspettavo abbastanza. Grazie veramente Maurotec per il tuo sostegno!
Ottimo direi, se posti anche il codice che hai usato farai cosa gradita ad altri utenti con le stesse perplessità.
PS: Sai che questo u-blox è altamente configurabile, ad esempio alcuni satelliti di default sono disabilitati, inoltre si può configurare per posizione statica, dinamica a piedi, automobile e persino aereo.
Prego, ora ne sappiamo qualcosa in più, anche grazie a te.
Ciao.
#include <Arduino_MKRENV.h>
#include <Arduino_MKRGPS.h>
float latitude;
float longitude;
float altitude;
float speed;
int satellites;
float dateTime;
float temperature;
float humidity;
float pressure;
float illuminance;
void setup() {
// initialize serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// If you are using the MKR GPS as shield, change the next line to pass
// the GPS_MODE_SHIELD parameter to the GPS.begin(...)
if (!GPS.begin()) {
Serial.println("Failed to initialize GPS!");
while (1);
}
if (!ENV.begin()) {
Serial.println("Failed to initialize MKR ENV Shield!");
while (1);
}
}
void loop() {
// put your main code here, to run repeatedly:
if (GPS.available()) {
// read GPS values
latitude = GPS.latitude();
longitude = GPS.longitude();
altitude = GPS.altitude();
speed = GPS.speed();
satellites = GPS.satellites();
temperature = ENV.readTemperature();
humidity = ENV.readHumidity();
pressure = ENV.readPressure();
illuminance = ENV.readIlluminance();
Serial.print(temperature);
Serial.print("\t\t\t");
Serial.print(pressure);
Serial.print("\t\t");
Serial.print(humidity);
Serial.print("\t\t");
Serial.print(illuminance);
Serial.print("\t\t");
Serial.print(latitude, 7);
Serial.print("\t\t");
Serial.print(longitude,7);
Serial.print("\t");
Serial.print(altitude);
Serial.print("\t");
Serial.print(speed);
Serial.println("\t\t");
delay(500);
}
}
Ancora grazie!
Ok, prego, ma basta non mi ringraziare più. ![]()
#include <Arduino_MKRENV.h>
#include <Arduino_MKRGPS.h>
float latitude;
float longitude;
float altitude;
float speed;
int satellites;
float dateTime;
float temperature;
float humidity;
float pressure;
float illuminance;
bool queryGps = true;
uint32_t saveMillis;
void setup() {
// initialize serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// If you are using the MKR GPS as shield, change the next line to pass
// the GPS_MODE_SHIELD parameter to the GPS.begin(...)
if (!GPS.begin()) {
Serial.println("Failed to initialize GPS!");
while (1);
}
if (!ENV.begin()) {
Serial.println("Failed to initialize MKR ENV Shield!");
while (1);
}
}
void loop() {
if (queryGps == true) {
if (GPS.available()) {
// read GPS values
latitude = GPS.latitude();
longitude = GPS.longitude();
altitude = GPS.altitude();
speed = GPS.speed();
satellites = GPS.satellites();
temperature = ENV.readTemperature();
humidity = ENV.readHumidity();
pressure = ENV.readPressure();
illuminance = ENV.readIlluminance();
Serial.print(temperature);
Serial.print("\t\t\t");
Serial.print(pressure);
Serial.print("\t\t");
Serial.print(humidity);
Serial.print("\t\t");
Serial.print(illuminance);
Serial.print("\t\t");
Serial.print(latitude, 7);
Serial.print("\t\t");
Serial.print(longitude, 7);
Serial.print("\t");
Serial.print(altitude);
Serial.print("\t");
Serial.print(speed);
Serial.println("\t\t");
queryGps = false;
saveMillis = millis();
}
} else { // queryGps is false
if (millis() - saveMillis >= 500) {
queryGps = true;
}
}
}
Questo dovrebbe permetterti di inserire altro codice nel loop che verrà eseguito sempre e comunque. Il delay anche se interno alla if blocca tutto per 500ms. La MCU montata sulla mkr è un ARM potente e veloce, mortificare le sue prestazioni con un delay e un delitto. ![]()
Ciao.
Bongiorno Mauro(?), torno di nuovo a farti domande
. Ok GPS funziona, ok ENV funziona. Ma! ENV funziona solo se si trova dentro un IF GPS.available().
Se metto una chiamata fuori dal controllo, per esempio nell’ELSE, il GPS non si aggancia più.
Questo mi crea problemi perché se il programma perdesse la sincronizzazione con il gps, ecco che anche il modulo ENV smetterebbe di dare dati. Perché succede questo? Ci sarà un modo per farli lavorare in modo indipendente l’uno dall’altro sempre nella comunicazione I2C ?
Succede perché questo è quello che gli abbiamo chiesto di fare, questa condizione:
if (queryGps == true) {
if (GPS.available()) {
è equivalente a:
( (queryGps == true) && (GPS.available()) )
______true_______ && ______true______
Questa porzione di codice più la stampa deve trovarsi fuori dalla condizione if.
temperature = ENV.readTemperature();
humidity = ENV.readHumidity();
pressure = ENV.readPressure();
illuminance = ENV.readIlluminance();
Per rendere asincrona la lettura della ENV è sufficiente creare una temporizzazione di 1 secondo. Per temporizzare codice serve una variabile per temporizzatore, saveMillis è usata per il GPS. Una nuova variabile saveMillis1 temporizza la lettura della ENV.
uint32_t saveMillis1; // dichiarata globale come per saveMillis
void loop() {
// qui il codice precedente
if (queryGps == true) {
if (GPS.available()) {
ecc...
}
}
if (millis() - saveMillis1 >= 1000) {
saveMillis1 = millis(); // salva il contatore di millis
temperature = ENV.readTemperature();
humidity = ENV.readHumidity();
pressure = ENV.readPressure();
illuminance = ENV.readIlluminance();
// qui il codice per stampare i dati della ENV
}
}
In questo modo interroghi il GPS continuamente fino a che non risponde che ha dati, salvi il tempo in saveMillis e con queryGps = false disabilito l'interrogazione. A questo punto entra in gioco l'else e 500ms dopo avere ricevuto i dati queryGps torna al valore inziale true abilitando nuovamente l'interrogazione.
L'altra temporizzazione di 1 secondo interroga la ENV, questa interrogazione potrebbe avvenire anche durante l'interrogazione del GPS, ma sarà una sola ogni secondo.
Ok, questo è un problema ricorrente in tutte le applicazione pratiche, il tempo di ciclo è dipendente dalla somma dei tempi di ogni compito complesso, ci sono compiti come quello del GPS che impegnano la CPU per più tempo e altri come la EVN che la impegnano per poco tempo.
Per misurare i tempi di esecuzione:
Abbreviando si dice: "prendere le metriche" che si traduce nel scrivere codice di test mirato a verificare le tempistiche e farsi una idea millisecondo più millisecondo meno.
Una introduzione alle macchine a stati finiti semplici basate su switch case:
Sostanzialmente permette di eseguire dei compiti in base al valore di una variabile detta di stato che può assumere qualunque valore in genere 0÷255.
L'uso della funzione millis() è motivo di confusione da parte del principiante, ma basta dedicargli il tempo per allenare il cervello a fare ciò che non ha mai fatto prima. Poi vengono i primi dubbi sul overflow del contatore di millis che nel caso della MKR ricordo essere a 64-bit (non ne sono sicuro), comunque anche con arduino uno il problema dell'overflow è gestibile come descritto qui:
PS: Questa è una community dove si vuole condividere il sapere. Ogni post da l'opportunità a qualcuno di esprimersi. Io dovrei ringraziare te per avermi dato l'opportunità di esprimermi, dall'altro lato tu ringrazi me per averti risolto un problema, ad ogni post dovremmo scrivere grazie grazie, ecco perché ho scritto:
Ciao.
Finalmente ho provato (e studiato!) il tuo programma e finalmente funziona tutto (quasi
). Non voglio ripetermi con i ringraziamenti ma una considerazione è d'obbligo. Oggi gli studenti (in generale tutti quelli che studiano, non solo i miei alunni) hanno davvero tanti mezzi per imparare. Certe volte noi docenti ci sentiamo 'depositari del sapere' ma uno studente volenteroso ha davvero mille mezzi per fare a meno di noi. Magari la mia generazione aveva molta più determinazione ma questa è un'altra storia. Ora cerco di risolvere il nuovo problema che mi si è creato e se non riesco, apro una nuova chat e ti chiamo!
Ciao
Benissimo, tieni conto che le librerie nascondono i dettagli e questi sono di importanza strategica. Le guide non sono sufficientemente dettagliate per coprire tutte le varianti d'uso.
Io ad esempio non ho approfondito cosa fa il chip del GPS e ho il dubbio che una volta fatta la prima interrogazione, dopo avere notificato che ci sono dati, non si ferma e continua a sputare dati. Questo non sarebbe un problema se non fosse che la libreria wire ha un buffer in memoria grande 32-byte gestito ad interrupt. Se questo buffer si riempie non idea di cosa accade, potrebbe essere gestito come un buffer ad anello (buffer ring), in sostanza non ho la completa conoscenza (teorica/pratica) di cosa accade. Bene nella libreria GPS hanno previsto i metodi:
standby() e wakeup(). Il primo mette a nanna il chip e il secondo lo sveglia. C'è anche il metodo end() per dire "ok ho finito con te per adesso", ma dopo la chiamata ad end() per iniziare nuovamente serve una chiamata a begin() come quella messa nel setup().
![]()
il sapere è infinito e non può risiedere in una sola persona, per quanto insegnate di professione.
Qualcosa di simile accade da ragazzini, mamma cosa vuole dire "fifone", la risposta era quasi sempre, prendi il vocabolario e cerca. Volevamo e vogliamo la soluzione al minor costo di impegno possibile. Oggi che l'oracolo sembra realtà a molti, questi tutti li a chiedere alle AI. ![]()
Ciao.
Eccomi di nuovo! Sono tornata! Ho alimentato la scheda con una batteria Lipo. Dopo vari tentativi, letture e accidenti vari (tipo dover cambiare lo spinotto), adesso va quasi tutto bene. Si alimenta con la batteria e prende i dati MA! mi sembra che GPS e batteria esterna abbiano delle incomprensioni. Ho trovato un metodo che funziona ma che non capisco.
Faccio partire la scheda con la USB e aspetto che il GPS si agganci. A questo punto inserisco la batteria e stacco l'USB. Ma perché così funziona? Qual è il senso? Di nuovo problemi di temporizzazione sulla comunicazione I2C?
All'inizio la batteria deve proprio essere scollegata! Per 'sentire' il GPS la scheda vuole solo l'alimentazione USB. Avevo provato a metterle entrambe inizialmente, scollegando poi l'USB ma così il GPS non viene agganciato. Ripeto, per quello che mi serve, ho trovato un metodo che funziona (in fondo voglio usare la batteria solo occasionalmente), però non capisco.
Così su due piedi, viene in mente che la batteria non è carica o che è inferiore a 1024mAh come consigliato nella documentazione tecnica. Una volta collegata la batteria e l'alimentazione alla scheda, il chip bq24157 dovrebbe iniziare a caricare la batteria e cessare quando carica. Scollegando l'alimentazione il chip in automatico preleva la tensione della batteria e la converte a 3.3V. In sostanza rimuovendo l'alimentazione funziona come un UPS (o gruppo di continuità).
Il chip è connesso via I2c anche per cui lo si può interrogare circa il suo stato, ma di più non so. Se hai un multimetro potresti misurare la d.d.p della batteria sia sotto carico che senza.
La misura sotto carico potrebbe essere più semplice se sulla scheda ci fossero dei TP (test point) e potrebbero esserci ma non ho verificato.
Evoco gli altri utenti esperti così hai forse maggiori info.
@Etemenanki, @gpb01, @nid69ita, @cotestatnt, @docdoc, @fabpolli, Claudio_FF, @ilguargua.
Ciao.
La batteria è di 1100 mAh ed è carica. Ma contrariamente a quanto avevo già scritto, il GPS appena stacco l’USB si blocca e non si aggiorna. Avevo fatto solo prove da ferma e quindi non mi ero accorta che non aggiornava i valori. Quindi sono ad un punto morto, con la batteria il GPS non va.
Potrebbe essere che la gps shield non la impili sulla mkr1310.
Se invece la impili e non funziona comunque, non ho proprio idea di dove andare a parare.
PS: Visto che la usb è rimossa non stamperà nulla,
in che modo di rendi conto che il gps non aggancia?
Ciao.
Se ne hai uno a disposizione, prova ad usare un power bank, lo colleghi all'USB e quindi tutto dovrebbe funzionare, l'unico problema è che in genere i power bank vogliono un minimo di assorbimento, altrimenti dopo poco si spengono. Quanto sia il "minimo" ed il "poco" che durano ovviamente dipende dal power bank...
Ciao, Ale.
Confermo che con la power bank il GPS viene agganciato subito. Posso usare quella anche se la batteria Lipo mi piaceva di più perché più piccola.
Vabbè, è un compromesso, se l'uso come dici è occasionale, come si dice dalle mie parti, accontentati... ![]()
Ciao, Ale.