Merge pull request #406 from cyberman54/development

maintenance and bug fixes
This commit is contained in:
Verkehrsrot 2019-07-28 23:55:43 +02:00 committed by GitHub
commit 81bfea7c15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 167 additions and 130 deletions

View File

@ -12,6 +12,7 @@ Tutorial (in german language): https://www.heise.de/select/make/2019/1/155109923
<img src="img/TTGO-case.jpg"> <img src="img/TTGO-case.jpg">
<img src="img/TTGO-curves.jpg"> <img src="img/TTGO-curves.jpg">
<img src="img/Paxcounter-LEDmatrix.jpg"> <img src="img/Paxcounter-LEDmatrix.jpg">
<img src="img/Paxcounter-Clock.png">
# Use case # Use case

BIN
img/Paxcounter-Clock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

View File

@ -18,10 +18,10 @@ extern gpsStatus_t
extern TaskHandle_t GpsTask; extern TaskHandle_t GpsTask;
int gps_init(void); int gps_init(void);
void IRAM_ATTR gps_storetime(gpsStatus_t &gps_store); void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store);
void gps_storelocation(gpsStatus_t &gps_store); void gps_storelocation(gpsStatus_t *gps_store);
void gps_loop(void *pvParameters); void gps_loop(void *pvParameters);
time_t get_gpstime(gpsStatus_t value); time_t fetch_gpsTime(gpsStatus_t value);
int gps_config(); int gps_config();
#endif #endif

View File

@ -5,7 +5,6 @@
#include "globals.h" #include "globals.h"
#include "battery.h" #include "battery.h"
//#include "update.h"
#include <Update.h> #include <Update.h>
#include <WiFi.h> #include <WiFi.h>
#include <WiFiClientSecure.h> #include <WiFiClientSecure.h>

View File

@ -1,6 +1,8 @@
#ifndef _PAYLOAD_H_ #ifndef _PAYLOAD_H_
#define _PAYLOAD_H_ #define _PAYLOAD_H_
#include "paxcounter.conf"
// MyDevices CayenneLPP 1.0 channels for Synamic sensor payload format // MyDevices CayenneLPP 1.0 channels for Synamic sensor payload format
// all payload goes out on LoRa FPort 1 // all payload goes out on LoRa FPort 1
#if (PAYLOAD_ENCODER == 3) #if (PAYLOAD_ENCODER == 3)
@ -18,8 +20,6 @@
#define LPP_BAROMETER_CHANNEL 30 #define LPP_BAROMETER_CHANNEL 30
#define LPP_AIR_CHANNEL 31 #define LPP_AIR_CHANNEL 31
#endif
// MyDevices CayenneLPP 2.0 types for Packed Sensor Payload, not using channels, // MyDevices CayenneLPP 2.0 types for Packed Sensor Payload, not using channels,
// but different FPorts // but different FPorts
#define LPP_GPS 136 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01m #define LPP_GPS 136 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01m
@ -32,6 +32,8 @@
#define LPP_HUMIDITY 104 // 1 byte, 0.5 % unsigned #define LPP_HUMIDITY 104 // 1 byte, 0.5 % unsigned
#define LPP_BAROMETER 115 // 2 bytes, hPa unsigned MSB #define LPP_BAROMETER 115 // 2 bytes, hPa unsigned MSB
#endif
class PayloadConvert { class PayloadConvert {
public: public:
@ -54,20 +56,21 @@ public:
void addSensor(uint8_t[]); void addSensor(uint8_t[]);
void addTime(time_t value); void addTime(time_t value);
#if PAYLOAD_ENCODER == 1 // format plain #if (PAYLOAD_ENCODER == 1) // format plain
private: private:
uint8_t *buffer; uint8_t *buffer;
uint8_t cursor; uint8_t cursor;
#elif PAYLOAD_ENCODER == 2 // format packed #elif (PAYLOAD_ENCODER == 2) // format packed
private: private:
uint8_t *buffer; uint8_t *buffer;
uint8_t cursor; uint8_t cursor;
void intToBytes(uint8_t pos, int32_t i, uint8_t byteSize); void uintToBytes(uint64_t i, uint8_t byteSize);
void writeUptime(uint64_t unixtime); void writeUptime(uint64_t unixtime);
void writeLatLng(double latitude, double longitude); void writeLatLng(double latitude, double longitude);
void writeUint64(uint64_t i);
void writeUint32(uint32_t i); void writeUint32(uint32_t i);
void writeUint16(uint16_t i); void writeUint16(uint16_t i);
void writeUint8(uint8_t i); void writeUint8(uint8_t i);
@ -78,7 +81,7 @@ private:
void writeBitmap(bool a, bool b, bool c, bool d, bool e, bool f, bool g, void writeBitmap(bool a, bool b, bool c, bool d, bool e, bool f, bool g,
bool h); bool h);
#elif (PAYLOAD_ENCODER == 3 || PAYLOAD_ENCODER == 4) // format cayenne lpp #elif ((PAYLOAD_ENCODER == 3) || (PAYLOAD_ENCODER == 4)) // format cayenne lpp
private: private:
uint8_t *buffer; uint8_t *buffer;

View File

@ -20,11 +20,11 @@ function Decoder(bytes, port) {
} }
// combined wifi counter and gps data // combined wifi counter and gps data
if (bytes.length === 15) { if (bytes.length === 15) {
return decode(bytes, [uint16, latLng, latLng, uint8, hdop, uint16], ['wifi', 'latitude', 'longitude', 'sats', 'hdop', 'altitude']); return decode(bytes, [uint16, latLng, latLng, uint8, hdop, altitude], ['wifi', 'latitude', 'longitude', 'sats', 'hdop', 'altitude']);
} }
// combined wifi + ble counter and gps data // combined wifi + ble counter and gps data
if (bytes.length === 17) { if (bytes.length === 17) {
return decode(bytes, [uint16, uint16, latLng, latLng, uint8, hdop, uint16], ['wifi', 'ble', 'latitude', 'longitude', 'sats', 'hdop', 'altitude']); return decode(bytes, [uint16, uint16, latLng, latLng, uint8, hdop, altitude], ['wifi', 'ble', 'latitude', 'longitude', 'sats', 'hdop', 'altitude']);
} }
} }
@ -37,12 +37,12 @@ function Decoder(bytes, port) {
if (port === 3) { if (port === 3) {
// device config data // device config data
return decode(bytes, [uint8, uint8, uint16, uint8, uint8, uint8, uint8, bitmap1, bitmap2, version], ['lorasf', 'txpower', 'rssilimit', 'sendcycle', 'wifichancycle', 'blescantime', 'rgblum', 'flags', 'payloadmask', 'version']); return decode(bytes, [uint8, uint8, int16, uint8, uint8, uint8, uint8, bitmap1, bitmap2, version], ['lorasf', 'txpower', 'rssilimit', 'sendcycle', 'wifichancycle', 'blescantime', 'rgblum', 'flags', 'payloadmask', 'version']);
} }
if (port === 4) { if (port === 4) {
// gps data // gps data
return decode(bytes, [latLng, latLng, uint8, hdop, uint16], ['latitude', 'longitude', 'sats', 'hdop', 'altitude']); return decode(bytes, [latLng, latLng, uint8, hdop, altitude], ['latitude', 'longitude', 'sats', 'hdop', 'altitude']);
} }
if (port === 5) { if (port === 5) {
@ -52,12 +52,12 @@ function Decoder(bytes, port) {
if (port === 6) { if (port === 6) {
// beacon proximity alarm // beacon proximity alarm
return decode(bytes, [uint8, uint8], ['rssi', 'beacon']); return decode(bytes, [int8, uint8], ['rssi', 'beacon']);
} }
if (port === 7) { if (port === 7) {
// BME680 sensor data // BME680 sensor data
return decode(bytes, [float, uint16, ufloat, ufloat], ['temperature', 'pressure', 'humidity', 'air']); return decode(bytes, [float, pressure, ufloat, ufloat], ['temperature', 'pressure', 'humidity', 'air']);
} }
if (port === 8) { if (port === 8) {
@ -123,29 +123,72 @@ var uint32 = function (bytes) {
}; };
uint32.BYTES = 4; uint32.BYTES = 4;
var latLng = function (bytes) { var uint64 = function (bytes) {
if (bytes.length !== latLng.BYTES) { if (bytes.length !== uint64.BYTES) {
throw new Error('Lat/Long must have exactly 4 bytes'); throw new Error('uint64 must have exactly 8 bytes');
}
return bytesToInt(bytes) / 1e6;
};
latLng.BYTES = 4;
var uptime = function (bytes) {
if (bytes.length !== uptime.BYTES) {
throw new Error('Uptime must have exactly 8 bytes');
} }
return bytesToInt(bytes); return bytesToInt(bytes);
}; };
uptime.BYTES = 8; uint64.BYTES = 8;
var int8 = function (bytes) {
if (bytes.length !== int8.BYTES) {
throw new Error('int8 must have exactly 1 byte');
}
var value = +(bytesToInt(bytes));
if (value > 127) {
value -= 256;
}
return value;
};
int8.BYTES = 1;
var int16 = function (bytes) {
if (bytes.length !== int16.BYTES) {
throw new Error('int16 must have exactly 2 bytes');
}
var value = +(bytesToInt(bytes));
if (value > 32767) {
value -= 65536;
}
return value;
};
int16.BYTES = 2;
var int32 = function (bytes) {
if (bytes.length !== int32.BYTES) {
throw new Error('int32 must have exactly 4 bytes');
}
var value = +(bytesToInt(bytes));
if (value > 2147483647) {
value -= 4294967296;
}
return value;
};
int32.BYTES = 4;
var latLng = function (bytes) {
return +(int32(bytes) / 1e6).toFixed(6);
};
latLng.BYTES = int32.BYTES;
var uptime = function (bytes) {
return uint64(bytes);
};
uptime.BYTES = uint64.BYTES;
var hdop = function (bytes) { var hdop = function (bytes) {
if (bytes.length !== hdop.BYTES) { return +(uint16(bytes) / 100).toFixed(2);
throw new Error('hdop must have exactly 2 bytes');
}
return bytesToInt(bytes) / 100;
}; };
hdop.BYTES = 2; hdop.BYTES = uint16.BYTES;
var altitude = function (bytes) {
// Option to increase altitude resolution (also on encoder side)
// return +(int16(bytes) / 4 - 1000).toFixed(1);
return +(int16(bytes));
};
altitude.BYTES = int16.BYTES;
var float = function (bytes) { var float = function (bytes) {
if (bytes.length !== float.BYTES) { if (bytes.length !== float.BYTES) {
@ -168,29 +211,19 @@ var float = function (bytes) {
if (isNegative) { if (isNegative) {
t = -t; t = -t;
} }
return +(t / 100).toFixed(1); return +(t / 100).toFixed(2);
}; };
float.BYTES = 2; float.BYTES = 2;
var ufloat = function (bytes) { var ufloat = function (bytes) {
if (bytes.length !== ufloat.BYTES) { return +(uint16(bytes) / 100).toFixed(2);
throw new Error('Ufloat must have exactly 2 bytes');
}
var h = bytesToInt(bytes);
return +(h / 100).toFixed(1);
}; };
ufloat.BYTES = 2; ufloat.BYTES = uint16.BYTES;
var pressure = function (bytes) { var pressure = function (bytes) {
if (bytes.length !== pressure.BYTES) { return +(uint16(bytes) / 10).toFixed(1);
throw new Error('Pressure must have exactly 2 bytes');
}
var h = bytesToInt(bytes);
return +(h / 10).toFixed(1);
}; };
pressure.BYTES = 2; pressure.BYTES = uint16.BYTES;
var bitmap1 = function (byte) { var bitmap1 = function (byte) {
if (byte.length !== bitmap1.BYTES) { if (byte.length !== bitmap1.BYTES) {
@ -247,12 +280,16 @@ if (typeof module === 'object' && typeof module.exports !== 'undefined') {
uint8: uint8, uint8: uint8,
uint16: uint16, uint16: uint16,
uint32: uint32, uint32: uint32,
int8: int8,
int16: int16,
int32: int32,
uptime: uptime, uptime: uptime,
float: float, float: float,
ufloat: ufloat, ufloat: ufloat,
pressure: pressure, pressure: pressure,
latLng: latLng, latLng: latLng,
hdop: hdop, hdop: hdop,
altitude: altitude,
bitmap1: bitmap1, bitmap1: bitmap1,
bitmap2: bitmap2, bitmap2: bitmap2,
version: version, version: version,

View File

@ -20,7 +20,7 @@ function Decoder(bytes, port) {
decoded.longitude = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]); decoded.longitude = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]);
decoded.sats = bytes[i++]; decoded.sats = bytes[i++];
decoded.hdop = (bytes[i++] << 8) | (bytes[i++]); decoded.hdop = (bytes[i++] << 8) | (bytes[i++]);
decoded.altitude = (bytes[i++] << 8) | (bytes[i++]); decoded.altitude = ((bytes[i++] << 8) | (bytes[i++]));
} }
} }
@ -41,7 +41,7 @@ function Decoder(bytes, port) {
decoded.longitude = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]); decoded.longitude = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]);
decoded.sats = bytes[i++]; decoded.sats = bytes[i++];
decoded.hdop = (bytes[i++] << 8) | (bytes[i++]); decoded.hdop = (bytes[i++] << 8) | (bytes[i++]);
decoded.altitude = (bytes[i++] << 8) | (bytes[i++]); decoded.altitude = ((bytes[i++] << 8) | (bytes[i++]));
} }
if (port === 5) { if (port === 5) {

View File

@ -146,15 +146,17 @@ void bme_loop(void *pvParameters) {
// block i2c bus access // block i2c bus access
if (I2C_MUTEX_LOCK()) { if (I2C_MUTEX_LOCK()) {
if (iaqSensor.run()) { // If new data is available if (iaqSensor.run()) { // If new data is available
bme_status.raw_temperature = iaqSensor.rawTemperature; bme_status.raw_temperature =
iaqSensor.rawTemperature; // Temperature in degree celsius
bme_status.raw_humidity = iaqSensor.rawHumidity; bme_status.raw_humidity = iaqSensor.rawHumidity;
bme_status.temperature = iaqSensor.temperature; bme_status.temperature = iaqSensor.temperature;
bme_status.humidity = iaqSensor.humidity; bme_status.humidity =
bme_status.pressure = iaqSensor.humidity; // Humidity in % relative humidity x1000
bme_status.pressure = // Pressure in Pascal
(iaqSensor.pressure / 100.0); // conversion Pa -> hPa (iaqSensor.pressure / 100.0); // conversion Pa -> hPa
bme_status.iaq = iaqSensor.iaqEstimate; bme_status.iaq = iaqSensor.iaqEstimate;
bme_status.iaq_accuracy = iaqSensor.iaqAccuracy; bme_status.iaq_accuracy = iaqSensor.iaqAccuracy;
bme_status.gas = iaqSensor.gasResistance; bme_status.gas = iaqSensor.gasResistance; // Gas resistance in Ohms
updateState(); updateState();
} }
I2C_MUTEX_UNLOCK(); I2C_MUTEX_UNLOCK();

View File

@ -63,7 +63,7 @@ void init_display(const char *Productname, const char *Version) {
// block i2c bus access // block i2c bus access
if (!I2C_MUTEX_LOCK()) if (!I2C_MUTEX_LOCK())
ESP_LOGD(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0); ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
else { else {
// show startup screen // show startup screen
uint8_t buf[32]; uint8_t buf[32];
@ -143,7 +143,7 @@ void refreshTheDisplay(bool nextPage) {
// block i2c bus access // block i2c bus access
if (!I2C_MUTEX_LOCK()) if (!I2C_MUTEX_LOCK())
ESP_LOGD(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0); ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
else { else {
// set display on/off according to current device configuration // set display on/off according to current device configuration
if (DisplayIsOn != cfg.screenon) { if (DisplayIsOn != cfg.screenon) {
@ -195,16 +195,13 @@ void draw_page(time_t t, uint8_t page) {
// update GPS status (line 2) // update GPS status (line 2)
#if (HAS_GPS) #if (HAS_GPS)
// have we ever got valid gps data? u8x8.setCursor(9, 2);
if (gps.passedChecksum() > 0) { if (gps.location.age() < 1500) // if no fix then display Sats value inverse
u8x8.setCursor(9, 2); u8x8.printf("Sats:%.2d", gps.satellites.value());
if (!gps.location.isValid()) // if no fix then display Sats value inverse else {
{ u8x8.setInverseFont(1);
u8x8.setInverseFont(1); u8x8.printf("Sats:%.2d", gps.satellites.value());
u8x8.printf("Sats:%.2d", gps.satellites.value()); u8x8.setInverseFont(0);
u8x8.setInverseFont(0);
} else
u8x8.printf("Sats:%.2d", gps.satellites.value());
} }
#endif #endif
@ -252,12 +249,11 @@ void draw_page(time_t t, uint8_t page) {
u8x8.setInverseFont(1); u8x8.setInverseFont(1);
u8x8.printf("%c", timeState); u8x8.printf("%c", timeState);
u8x8.setInverseFont(0); u8x8.setInverseFont(0);
u8x8.printf(" %2d.%3s", day(t), printmonth[month(t)]);
#else #else
u8x8.printf("%02d:%02d:%02d%c %2d.%3s", hour(t), minute(t), second(t), u8x8.printf("%02d:%02d:%02d%c", hour(t), minute(t), second(t), timeState);
timeState, day(t), printmonth[month(t)]);
#endif // HAS_DCF77 || HAS_IF482 #endif // HAS_DCF77 || HAS_IF482
if (timeSource != _unsynced)
u8x8.printf(" %2d.%3s", day(t), printmonth[month(t)]);
#else // update LoRa status display #else // update LoRa status display
#if (HAS_LORA) #if (HAS_LORA)
u8x8.printf("%-16s", display_line6); u8x8.printf("%-16s", display_line6);

View File

@ -66,53 +66,50 @@ int gps_config() {
} }
// store current GPS location data in struct // store current GPS location data in struct
void gps_storelocation(gpsStatus_t &gps_store) { void gps_storelocation(gpsStatus_t *gps_store) {
gps_store.latitude = (int32_t)(gps.location.lat() * 1e6); if (gps.location.isUpdated() && gps.location.isValid() &&
gps_store.longitude = (int32_t)(gps.location.lng() * 1e6); (gps.time.age() < 1500)) {
gps_store.satellites = (uint8_t)gps.satellites.value(); gps_store->latitude = (int32_t)(gps.location.lat() * 1e6);
gps_store.hdop = (uint16_t)gps.hdop.value(); gps_store->longitude = (int32_t)(gps.location.lng() * 1e6);
gps_store.altitude = (int16_t)gps.altitude.meters(); gps_store->satellites = (uint8_t)gps.satellites.value();
gps_store->hdop = (uint16_t)gps.hdop.value();
gps_store->altitude = (int16_t)gps.altitude.meters();
}
} }
// store current GPS timedate in struct // store current GPS timedate in struct
void IRAM_ATTR gps_storetime(gpsStatus_t &gps_store) { void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store) {
if (gps.time.isUpdated() && gps.date.isValid() && (gps.time.age() < 1000)) { if (gps.time.isUpdated() && gps.date.isValid() && (gps.time.age() < 1000)) {
// nmea telegram serial delay compensation; not sure if we need this? // nmea telegram serial delay compensation; not sure if we need this?
/* /*
if (gps.time.age() > nmea_txDelay_ms) if (gps.time.age() > nmea_txDelay_ms)
gps_store.timedate.Second = gps.time.second() + 1; gps_store->timedate.Second = gps.time.second() + 1;
else else
gps_store.timedate.Second = gps.time.second(); gps_store->timedate.Second = gps.time.second();
*/ */
gps_store.timedate.Second = gps.time.second(); gps_store->timedate.Second = gps.time.second();
gps_store.timedate.Minute = gps.time.minute(); gps_store->timedate.Minute = gps.time.minute();
gps_store.timedate.Hour = gps.time.hour(); gps_store->timedate.Hour = gps.time.hour();
gps_store.timedate.Day = gps.date.day(); gps_store->timedate.Day = gps.date.day();
gps_store.timedate.Month = gps.date.month(); gps_store->timedate.Month = gps.date.month();
gps_store.timedate.Year = gps_store->timedate.Year =
CalendarYrToTm(gps.date.year()); // year offset from 1970 in microTime.h CalendarYrToTm(gps.date.year()); // year offset from 1970 in microTime.h
} else } else
gps_store.timedate = {0}; gps_store->timedate = {0};
} }
// function to fetch current time from struct; note: this is costly // function to fetch current time from struct; note: this is costly
time_t get_gpstime(gpsStatus_t value) { time_t fetch_gpsTime(gpsStatus_t value) {
time_t t = timeIsValid(makeTime(value.timedate)); time_t t = timeIsValid(makeTime(value.timedate));
ESP_LOGD(TAG, "GPS time: %d", t);
// show NMEA data in verbose mode, useful for debugging GPS
ESP_LOGD(
TAG,
"GPS time: %d | GPS NMEA data: passed %d / failed: %d / with fix: %d", t,
gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix());
return t; return t;
} // get_gpstime() } // fetch_gpsTime()
// GPS serial feed FreeRTos Task // GPS serial feed FreeRTos Task
void gps_loop(void *pvParameters) { void gps_loop(void *pvParameters) {
@ -136,6 +133,11 @@ void gps_loop(void *pvParameters) {
#endif #endif
} // if } // if
// show NMEA data in verbose mode, useful for debugging GPS
ESP_LOGV(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d",
gps.passedChecksum(), gps.failedChecksum(),
gps.sentencesWithFix());
delay(2); // yield to CPU delay(2); // yield to CPU
} // end of infinite loop } // end of infinite loop

View File

@ -55,7 +55,7 @@
// GPS settings // GPS settings
#define HAS_GPS 1 // use on board GPS #define HAS_GPS 1 // use on board GPS
#define GPS_SERIAL 9600, SERIAL_8N1, GPIO_NUM_12, GPIO_NUM_15 // UBlox NEO 6M #define GPS_SERIAL 9600, SERIAL_8N1, GPIO_NUM_12, GPIO_NUM_15 // UBlox NEO 6M RX, TX
#define GPS_INT GPIO_NUM_13 // 30ns accurary timepulse, to be external wired on pcb: NEO 6M Pin#3 -> GPIO13 #define GPS_INT GPIO_NUM_13 // 30ns accurary timepulse, to be external wired on pcb: NEO 6M Pin#3 -> GPIO13
// Pins for I2C interface of OLED Display // Pins for I2C interface of OLED Display

View File

@ -48,7 +48,7 @@ void irqHandler(void *pvParameters) {
// gps refresh buffer? // gps refresh buffer?
#if (HAS_GPS) #if (HAS_GPS)
if (InterruptStatus & GPS_IRQ) if (InterruptStatus & GPS_IRQ)
gps_storelocation(gps_status); gps_storelocation(&gps_status);
#endif #endif
// are cyclic tasks due? // are cyclic tasks due?

View File

@ -438,6 +438,11 @@ void setup() {
#warning you did not specify a time source, time will not be synched #warning you did not specify a time source, time will not be synched
#endif #endif
// initialize gps time
#if (HAS_GPS)
gps_storetime(&gps_status);
#endif
#if (defined HAS_IF482 || defined HAS_DCF77) #if (defined HAS_IF482 || defined HAS_DCF77)
ESP_LOGI(TAG, "Starting Clock Controller..."); ESP_LOGI(TAG, "Starting Clock Controller...");
clock_init(); clock_init();

View File

@ -16,7 +16,7 @@ uint8_t *PayloadConvert::getBuffer(void) { return buffer; }
/* ---------------- plain format without special encoding ---------- */ /* ---------------- plain format without special encoding ---------- */
#if PAYLOAD_ENCODER == 1 #if (PAYLOAD_ENCODER == 1)
void PayloadConvert::addByte(uint8_t value) { buffer[cursor++] = (value); } void PayloadConvert::addByte(uint8_t value) { buffer[cursor++] = (value); }
@ -141,7 +141,7 @@ void PayloadConvert::addTime(time_t value) {
// derived from // derived from
// https://github.com/thesolarnomad/lora-serialization/blob/master/src/LoraEncoder.cpp // https://github.com/thesolarnomad/lora-serialization/blob/master/src/LoraEncoder.cpp
#elif PAYLOAD_ENCODER == 2 #elif (PAYLOAD_ENCODER == 2)
void PayloadConvert::addByte(uint8_t value) { writeUint8(value); } void PayloadConvert::addByte(uint8_t value) { writeUint8(value); }
@ -227,15 +227,19 @@ void PayloadConvert::addTime(time_t value) {
writeUint32(time); writeUint32(time);
} }
void PayloadConvert::intToBytes(uint8_t pos, int32_t i, uint8_t byteSize) { void PayloadConvert::uintToBytes(uint64_t value, uint8_t byteSize) {
for (uint8_t x = 0; x < byteSize; x++) { for (uint8_t x = 0; x < byteSize; x++) {
buffer[x + pos] = (byte)(i >> (x * 8)); byte next = 0;
if (sizeof(value) > x) {
next = static_cast<byte>((value >> (x * 8)) & 0xFF);
}
buffer[cursor] = next;
++cursor;
} }
cursor += byteSize;
} }
void PayloadConvert::writeUptime(uint64_t uptime) { void PayloadConvert::writeUptime(uint64_t uptime) {
intToBytes(cursor, uptime, 8); writeUint64(uptime);
} }
void PayloadConvert::writeVersion(char *version) { void PayloadConvert::writeVersion(char *version) {
@ -244,24 +248,25 @@ void PayloadConvert::writeVersion(char *version) {
} }
void PayloadConvert::writeLatLng(double latitude, double longitude) { void PayloadConvert::writeLatLng(double latitude, double longitude) {
intToBytes(cursor, latitude, 4); // Tested to at least work with int32_t, which are processed correctly.
intToBytes(cursor, longitude, 4); writeUint32(latitude);
writeUint32(longitude);
} }
void PayloadConvert::writeUint32(uint32_t i) { intToBytes(cursor, i, 4); } void PayloadConvert::writeUint64(uint64_t i) { uintToBytes(i, 8); }
void PayloadConvert::writeUint16(uint16_t i) { intToBytes(cursor, i, 2); } void PayloadConvert::writeUint32(uint32_t i) { uintToBytes(i, 4); }
void PayloadConvert::writeUint8(uint8_t i) { intToBytes(cursor, i, 1); } void PayloadConvert::writeUint16(uint16_t i) { uintToBytes(i, 2); }
void PayloadConvert::writeUint8(uint8_t i) { uintToBytes(i, 1); }
void PayloadConvert::writeUFloat(float value) { void PayloadConvert::writeUFloat(float value) {
int16_t h = (int16_t)(value * 100); writeUint16(value * 100);
intToBytes(cursor, h, 2);
} }
void PayloadConvert::writePressure(float value) { void PayloadConvert::writePressure(float value) {
int16_t h = (int16_t)(value); writeUint16(value * 10);
intToBytes(cursor, h, 2);
} }
/** /**
@ -301,7 +306,7 @@ void PayloadConvert::writeBitmap(bool a, bool b, bool c, bool d, bool e, bool f,
// FPort 1 PAYLOAD_ENCODER == 4 -> Packed Sensor Payload, not using channels -> // FPort 1 PAYLOAD_ENCODER == 4 -> Packed Sensor Payload, not using channels ->
// FPort 2 // FPort 2
#elif (PAYLOAD_ENCODER == 3 || PAYLOAD_ENCODER == 4) #elif ((PAYLOAD_ENCODER == 3) || (PAYLOAD_ENCODER == 4))
void PayloadConvert::addByte(uint8_t value) { void PayloadConvert::addByte(uint8_t value) {
/* /*
@ -412,7 +417,7 @@ void PayloadConvert::addSensor(uint8_t buf[]) {
memcpy(buffer, buf+1, length); memcpy(buffer, buf+1, length);
cursor += length; // length of buffer cursor += length; // length of buffer
*/ */
#endif #endif // HAS_SENSORS
} }
void PayloadConvert::addBME(bmeStatus_t value) { void PayloadConvert::addBME(bmeStatus_t value) {
@ -481,6 +486,4 @@ void PayloadConvert::addTime(time_t value) {
#endif #endif
} }
#else
#error No valid payload converter defined!
#endif #endif

View File

@ -18,10 +18,6 @@ const char timeSetSymbols[] = {'G', 'R', 'L', '?'};
HardwareSerial IF482(2); // use UART #2 (#1 may be in use for serial GPS) HardwareSerial IF482(2); // use UART #2 (#1 may be in use for serial GPS)
#endif #endif
#if (HAS_GPS)
static gpsStatus_t gps_pps_status;
#endif
Ticker timesyncer; Ticker timesyncer;
void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); } void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); }
@ -32,7 +28,7 @@ time_t timeProvider(void) {
#if (HAS_GPS) #if (HAS_GPS)
// fetch recent time from last NMEA record // fetch recent time from last NMEA record
t = get_gpstime(gps_pps_status); t = fetch_gpsTime(gps_status);
if (t) { if (t) {
#ifdef HAS_RTC #ifdef HAS_RTC
set_rtctime(t, do_mutex); // calibrate RTC set_rtctime(t, do_mutex); // calibrate RTC
@ -44,7 +40,7 @@ time_t timeProvider(void) {
} }
#endif #endif
// no GPS -> fallback to RTC time while trying lora sync // no time from GPS -> fallback to RTC time while trying lora sync
#ifdef HAS_RTC #ifdef HAS_RTC
t = get_rtctime(); t = get_rtctime();
if (t) { if (t) {
@ -123,11 +119,6 @@ void timepulse_start(void) {
timerAlarmEnable(ppsIRQ); timerAlarmEnable(ppsIRQ);
#endif #endif
// initialize gps time
#if (HAS_GPS)
gps_storetime(gps_pps_status);
#endif
// start cyclic time sync // start cyclic time sync
timeSync(); // init systime by RTC or GPS or LORA timeSync(); // init systime by RTC or GPS or LORA
timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync);
@ -142,9 +133,7 @@ void IRAM_ATTR CLOCKIRQ(void) {
// store recent gps time, and try to get gps time if time is not synced // store recent gps time, and try to get gps time if time is not synced
#if (HAS_GPS) #if (HAS_GPS)
gps_storetime(gps_pps_status); gps_storetime(&gps_status);
if (timeSource == _unsynced)
timeSync();
#endif #endif
// advance wall clock, if we have // advance wall clock, if we have