Merge pull request #406 from cyberman54/development
maintenance and bug fixes
This commit is contained in:
commit
81bfea7c15
@ -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
BIN
img/Paxcounter-Clock.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 87 KiB |
@ -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
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
|
@ -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?
|
|
||||||
if (gps.passedChecksum() > 0) {
|
|
||||||
u8x8.setCursor(9, 2);
|
u8x8.setCursor(9, 2);
|
||||||
if (!gps.location.isValid()) // if no fix then display Sats value inverse
|
if (gps.location.age() < 1500) // if no fix then display Sats value inverse
|
||||||
{
|
u8x8.printf("Sats:%.2d", gps.satellites.value());
|
||||||
|
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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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?
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user