add distance interval

esp8266-bme280
noerw 8 years ago
parent e61cec10a1
commit 5a2189be15

@ -57,7 +57,7 @@ class TelnetPrint : public Print {
return 1;
}
// Is only called for Strings, not char arrays
// Is only called for Strings, not char arrays?
/*virtual size_t write(const char *buffer, size_t size) {
for(uint8_t i = 0; i < MAX_TELNET_CLIENTS; i++){
if (clients[i] && clients[i].connected()){

@ -1,12 +1,16 @@
#pragma once
/* GENERAL */
// interval of the measurements in ms. 0 for "as fast as possible"
#define MEASUREMENT_INTERVAL 10000
// interval of the measurements in millisec / meters
#define MEASUREMENT_INTERVAL 10000 // 0 for "as fast as possible"
#define MEASUREMENT_DISTANCE_ENABLED true
#define MEASUREMENT_DISTANCE 25
// pull this pin down to disable measurements (eg for quickly bulk uploading stored measurements)
#define PIN_MEASURE_MODE D14
// pull this pin down to disable uploads (eg for higher measurement rates when no realtime data is required)
#define PIN_UPLOAD_MODE D15
// should be higher than the number of sensors to avoid storage overflowing. tradeoff with the measurement interval
#define MAX_UPLOADS_PER_CYCLE 4

25
gps.h

@ -3,24 +3,22 @@
#include <Time.h>
#include "config.h"
// TODO: refactor updateXXX members to be protected and called by getXXX ?
class Gps {
protected:
TinyGPSPlus gps;
public:
void begin() {
Serial.begin(GPS_BAUD);
}
/**
/**
* parse all available bytes from the Serial input
* should be called frequently to avoid buffer overflows
*/
void pollGPS() {
while (Serial.available() > 0)
gps.encode(Serial.read());
gps.encode(Serial.read());
}
/**
@ -31,14 +29,14 @@ class Gps {
// abort if the GPS device does not push valid data within one update cycle
static const unsigned int timeout = 2 * GPS_INTERVAL;
unsigned long start = millis();
do {
pollGPS();
if (millis() - start > timeout) return false;
} while (!gps.location.isUpdated()); // TODO: check if is valid?
} while (!gps.location.isUpdated() && !gps.location.isValid());
return true;
}
/**
* poll until we have a valid date & time.
* retries at most once, returns success state
@ -48,23 +46,22 @@ class Gps {
static const unsigned int timeout = 2 * GPS_INTERVAL;
unsigned long start = millis();
// TODO: check if is valid?
do {
pollGPS();
if (millis() - start > timeout) return false;
} while ( !(gps.date.isUpdated() && gps.time.isUpdated()) );
} while ( !(gps.date.isUpdated() && gps.time.isUpdated() && gps.time.isValid() && gps.time.isValid()) );
// in case we didnt timeout, resync the local clock (Time.h)
setTime(gps.time.hour(), gps.time.minute(), gps.time.second(),
gps.date.day(), gps.date.month(), gps.date.year());
return true;
}
TinyGPSLocation& getLocation() {
return gps.location;
}
/**
* fill a char[20] with an iso8601 formatted date from now
*/

@ -1,3 +1,4 @@
#include <TinyGPS++.h>
#include "config.h"
#include "gps.h"
#include "wifi.h"
@ -14,6 +15,10 @@ TelnetPrint telnet = TelnetPrint();
OsemApi api = OsemApi();
Gps gps = Gps();
unsigned long cycleStart;
WifiState wifiState; // global, as both measure and upload need the state
TinyGPSLocation location;
bool storeMeasurement(float lat, float lng, float value, const char* timeStamp, const char* sensorID) {
Measurement m;
m.lat = lat;
@ -24,22 +29,21 @@ bool storeMeasurement(float lat, float lng, float value, const char* timeStamp,
return storage.add(m);
}
void measure(WifiState& wifiState) {
void measure(WifiState& wifiState, TinyGPSLocation& loc) {
char dateString[20];
// measure WiFi
wifiState = wifi.scan(WIFI_SSID);
// update gps position
// TODO: how to handle lost GPS fix?
// TODO: check if is data is valid?
// update gps position if we can't get a fix, skip the measurements
if(!gps.updateLocation() || !gps.updateTime()) {
DEBUG_OUT << "GPS timed out" << EOL;
digitalWrite(BUILTIN_LED, LOW);
} else {
digitalWrite(BUILTIN_LED, HIGH);
DEBUG_OUT << "GPS timed out, skipping measurements" << EOL;
digitalWrite(BUILTIN_LED, LOW); // turn status LED on
return;
}
TinyGPSLocation loc = gps.getLocation();
digitalWrite(BUILTIN_LED, HIGH);
loc = gps.getLocation();
gps.getISODate(dateString);
// print state
@ -100,13 +104,22 @@ void upload(WifiState& wifiState) {
// delay for a given duration (ms), rollover-safe implementation
// offset may be a duration which has been "used up" before, so the delay is adaptive,
// meaning that the interval of a adaptiveDelay() call is constant
void adaptiveDelay(unsigned long ms, unsigned long offset = 0) {
// returns earlier, if we moved more than MEASUREMENT_DISTANCE meters from our last fix
void adaptiveDelay(unsigned long ms, TinyGPSLocation& lastLoc, unsigned long offset = 0) {
unsigned long start = millis();
for (;;) {
// for some reason, operations have to be performed in this loop for
// proper operation, so we just do the polling to be done anyway
gps.pollGPS();
telnet.pollClients();
// update our location. if we moved MEASUREMENT_DISTANCE meters or more, return
TinyGPSLocation newLoc = gps.getLocation();
double distanceToPrevLoc = TinyGPSPlus::distanceBetween(lastLoc.lat(), lastLoc.lng(), newLoc.lat(), newLoc.lng());
if (MEASUREMENT_DISTANCE_ENABLED && distanceToPrevLoc >= MEASUREMENT_DISTANCE) {
DEBUG_OUT << "moved " << distanceToPrevLoc << "m, delay stopped." << EOL;
return;
}
unsigned long now = millis();
unsigned long elapsed = now - start + offset;
@ -135,6 +148,7 @@ void setup() {
// wait until we got a first fix from GPS, and thus an initial time
DEBUG_OUT << "Getting GPS fix..";
while (!gps.updateLocation()) { DEBUG_OUT << "."; }
location = gps.getLocation();
DEBUG_OUT << " done!" << EOL;
digitalWrite(BUILTIN_LED, HIGH);
@ -144,26 +158,22 @@ void setup() {
DEBUG_OUT << "SPIFF bytes free: " << bytesFree << EOL << EOL;
}
unsigned long cycleStart;
WifiState wifiState; // global, as both measure and upload need the state
void loop() {
cycleStart = millis();
if (digitalRead(PIN_MEASURE_MODE) == HIGH)
measure(wifiState);
measure(wifiState, location);
if (digitalRead(PIN_UPLOAD_MODE) == HIGH)
upload(wifiState);
if (digitalRead(PIN_MEASURE_MODE) == HIGH) {
// run the measurements in a fixed interval, using an adaptive delay
// IDEA: dont use time but distance interval? -> TinyGPSPlus::distanceBetween()
adaptiveDelay(MEASUREMENT_INTERVAL, millis() - cycleStart);
} else {
// run as fast as possible when not measuring.
// adaptiveDelay has to be called anyway, as some polling functions are run within
adaptiveDelay(0);
// the interval is defined by a duration and/or distance from our last fix
return adaptiveDelay(MEASUREMENT_INTERVAL, location, millis() - cycleStart);
}
// run as fast as possible when not measuring.
// smartDelay has to be called anyway, as some polling functions are run within
adaptiveDelay(0, location);
}

Loading…
Cancel
Save