Go Down

Topic: Schleifen für Sensorabfrage (Read 259 times) previous topic - next topic

Teletrabi

Moin,

kleine Verständnisfrage - was macht dieser Code?

Code: [Select]

GeoLoc checkGPS() {
  Serial.println("checkGPS()");
  bool newdata = false;
  unsigned long start = millis();
  while ((millis() - start) < GPS_UPDATE_INTERVAL) {
    if (feedgps()) {
      newdata = true;
    }
  }
  if (newdata) {
    return gpsdump(gps);
  }


Sehe ich das richtig, dass solange die Abfrageintervalzeit noch nicht erreicht ist, das GPS andauernd mit Anfragen gelöchert wird, von der nach Intervalzeit mal eine nach Ausbruch aus der Schleife verarbeitet wird?
Welchen Vorteil hat das gegenüber einer GPS-Abfrage bei jedem Hauptshcleifendurchlauf?
Bzw wenn das GÜs nicht hinterherkommt gegebenenfalls bei jedem x.ten Durchlauf?

Doc_Arduino

Hallo,

ja sie wird bei Aufruf solange ausgeführt, bis die verstrichene Zeit seit Aufruf größer der Intervallzeit ist.
Das ist irreführend und bestimmt nicht so gedacht. Entnehme ich dem Variablennamen.
Wenn es wirklich nach jeden Intervall einmalig aufgerufen bzw. abgearbeitet werden soll, dann eher so.
Das letzte if und bool kann man einsparen.


Code: [Select]

void GeoLoc checkGPS ()
{  
 
  static unsigned long last_ms = 0;
  const unsigned int GPS_UPDATE_INTERVAL = 5000;
  
  if ( (millis() - last_ms < GPS_UPDATE_INTERVAL)  return;  // Zeit noch nicht erreicht, Abbruch
  
  last_ms += GPS_UPDATE_INTERVAL;
  
  Serial.println("checkGPS()");
  
  if (feedgps()) {
      return gpsdump(gps);
  }
}  
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Teletrabi

Danke, kam mir in der Code-Vorlage etwas sinnlos vor.

Wie ist allerdings der Rückgabe-Wert bei deinem Beispiel?
(Nehme an das void ist versehentlich da reingerutscht? Rückgabetyp müsste eine GeoLoc-structure sein)
Wenn jetzt die Zeit noch nicht um ist - was wird beim return-Abbruch zurückgegeben? 0? vorheriger return-Wert? zufall?

Verwendung erfolgt Kontext ist
Ortsvariable = checkgps();
Da bräuchte ich also eine sicher gültige Rückgabe. Oder muss sie über eine Zwischenvariable auf Gültigkeit prüfen, bevor die Ortsvariable darauf gesetzt wird.


Was ist da am sinnigsten?
Error-Wert für das erste Return festlegen und Rückgabe in Zwischenvariable darauf abprüfen bevor Otsvariable gesetzt wird?
Ortsvariable nur bei gültiger Rückgabe überschreiben?
Statt Rückgabe bei Erfolg globale Ortsvariable überschreiben?
Statt Rückgabe auf übergebene Ortsvariablenadresse schreiben?
Gar nichts nötig, da returnwert bei Abbruch "zufällig" dem letztem gültigen Returnwert bleibt?

Letzteres: geht das überhaupt? was liefert return ohne returnwert zurück??
Nr 3 und 4: verändert die Verwendung der Funktion, möchte ich meiden, wenn kein signifikanter Vorteil daraus entsteht.
Nr 2: Ort= if (checkgps()!= error) checkgps() else Ort.
 Würde erwarten, dass hier checkgps () dann zweimal unabhängig ausgeführt wird und damit die Gültigkeitsprüfung wertlos für den zu setzenden Ortswert is? Oder denkt der Compiler hier weit genug mit?

Doc_Arduino

Hallo,

upps, da war ich mal wieder zu schnell. Der Rückgabewert muss dem Datentyp entsprechen. Das struct kann man bestimmt auch als struct Zeiger zurückgeben. Welcher Datentyp das genau ist, kann ich nicht sagen, müsstest du nachschauen was die GPS Funktion macht. Um ein Problem mit dem Intervall Return zu umgehen, bauen wir einfach die Funktion um. Return weg, eine Klammer mehr.

Man könnte (ungetestet) es vielleicht so machen. Den Code NULL musste dann wiederrum beim Aufrufer auswerten. Es gibt laut meines Wissens 3 definierte Rückgabewerte für solche Dinge. Weiß aber im Moment nicht wo ich das nachschlagen muss. ERROR ist glaube ich auch einer davon. Ich sehe aber das es immer komplizierter wird. Wäre es nicht besser wenn du dir eine Datenstruktur aufbaust und die Funktion aktualisiert immer nur den einen Wert? Ohne Rückgabewert der Funktion.

Code: [Select]

struct checkGPS ()
{  
 
  static unsigned long last_ms = 0;
  const unsigned int INTERVAL = 5000;
  
  if ( (millis() - last_ms > INTERVAL) {    
    last_ms = millis();
    Serial.println("checkGPS()");
    if (feedgps()) {
      return gpsdump(gps);
    }
    else {
      return NULL;
    }
  }
}  


Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

postmaster-ino

Hi

Ich vertsehe den Code in #0 so, daß alle x ms das GPS 1x neue Daten sendet und wir eben diese Zeit MAXIMAL warten wollen.
Wenn neue Daten kamen, wird ein Flag gesetzt und die neuen Daten zurück gegeben.
Wenn keine neuen Daten kamen, wird dieses Flag nicht gesetzt und wir können wohl davon ausgehen, daß das GPS aus gegangen ist.

Meine Interpretation des Sniped

MfG

Doc_Arduino

Hallo,

nö. Die while wird mit jedem Funktionsaufruf immer sofort gültig. start gleich aktuellen millis. Der if Vergleich wird solange "endlos" abgefragt wie eben Intervall in ms definiert ist. Im Grunde ist das ein delay

Code: [Select]
  unsigned long start = millis();
  while ((millis() - start) < GPS_UPDATE_INTERVAL) {
    if (feedgps()) {
      newdata = true;
    }
  }
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

postmaster-ino

Hi

Stimmt - fehlt ein break; um schneller aus der Sache raus zu kommen.

MfG

uxomm

Die while wird mit jedem Funktionsaufruf immer sofort gültig. start gleich aktuellen millis. Der if Vergleich wird solange "endlos" abgefragt wie eben Intervall in ms definiert ist. Im Grunde ist das ein delay
Da hat wohl jemand den Satz "delay ist böse - mach es besser mit millis!" ernst genommen... :)

[duck und weg]

Always decouple electronic circuitry.

Teletrabi

Und noch ein obskures Fragment:


Code: [Select]
// Feed data as it becomes available
bool feedgps() {
  while (nss.available()) {
    if (gps.encode(nss.read()))
      return true;
  }
  return false;
}



Das ist jetzt auch nur eine möglichst komplizierte if-Verzweigung, oder?

combie

#9
May 18, 2018, 01:37 pm Last Edit: May 18, 2018, 01:42 pm by combie
Quote
Das ist jetzt auch nur eine möglichst komplizierte if-Verzweigung, oder?
Nöö, das ist schon ganz ok so.

Würde bei mir auch kaum anders aussehen.
----

>  while (nss.available())
Solange serielle Daten anliegen

>if (gps.encode(nss.read()))
Lese 1 Zeichen und verarbeite Eingabe

> return true;
Vollständiger Datensatz wurde gelesen und für korrekt befunden


>return false;
Es liegt noch kein vollständiger Datensatz zur Weiterverarbeitung bereit.

Man kann sich darüber in die Wolle bekommen, ob es "erlaubt" ist 2 Return in einer Funktion zu haben.
Oder ob einem der Einrückungsstil gefällt.
Aber sonst?

Wie würdest du es besser machen?
Das größte Problem, ist die Wahl der richtigen Gedanken.

Go Up