Merge branch 'master' into feature/be-more-verbose-when-LoRa-TX-not-successful
This commit is contained in:
commit
fb1f46e892
@ -86,7 +86,11 @@ Supported external time sources are GPS, LORAWAN network time and LORAWAN applic
|
||||
|
||||
!!! tip
|
||||
|
||||
If your LORAWAN network does not support network time, you can run a Node-Red timeserver application using the enclosed [**Timeserver code**](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/src/Node-RED/Timeserver.json). Configure the MQTT nodes in Node-Red for the LORAWAN application used by your paxocunter device. Time can also be set without precision liability, by simple remote command, see section remote control.
|
||||
If your LORAWAN network does not support network time, you can run a Node-Red timeserver application using the enclosed [**Timeserver code**](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/src/Node-RED/Timeserver.json). Configure the MQTT nodes in Node-Red for the LORAWAN application used by your paxcounter device. Time can also be set without precision liability, by simple remote command, see section remote control.
|
||||
|
||||
## Syncing multiple paxcounters
|
||||
|
||||
A fleet of paxcounters can be synchronized to keep all devices wake up and start scanning at the same time. Synchronization is based on top-of-hour as common time point of reference. This feature requires time-of-day to be present on each device. Thus, `TIME_SYNC_INTERVAL` option, as explained above, must be enabled. Wake up syncing is enabled by setting `SYNCWAKEUP` in `paxcounter.conf` to a value X, in seconds, greater than zero, and smaller than `SLEEPCYCLE` (in seconds/10). This defines a time window, centered at top-of-hour, sized +/- X seconds. If a device, returning from sleep, would wakeup within this time window, it's wakeup will be adjusted to top-of-hour.
|
||||
|
||||
## Wall clock controller
|
||||
|
||||
|
@ -7,7 +7,7 @@ You can select different payload formats in [`paxcounter.conf`](https://github.c
|
||||
|
||||
- ***Packed*** uses little endian format and generates json fields
|
||||
|
||||
- [***CayenneLPP***](https://mydevices.com/cayenne/docs/lora/#lora-cayenne-low-power-payload-reference-implementation) generates MyDevices Cayenne readable fields
|
||||
- [***CayenneLPP***](https://developers.mydevices.com/cayenne/docs/lora/#lora-cayenne-low-power-payload) generates MyDevices Cayenne readable fields
|
||||
|
||||
|
||||
```c linenums="20" title="src/paxcounter_orig.conf"
|
||||
|
@ -91,6 +91,11 @@ Send for example `83` `86` as Downlink on Port 2 to get battery status and time/
|
||||
0 ... 255 duration for scanning a bluetooth advertising channel in seconds/100
|
||||
e.g. 8 -> each channel is scanned for 80 milliseconds [default]
|
||||
|
||||
#### 0x0D set wakeup sync window
|
||||
|
||||
bytes 1..2 = wakeup sync window size in seconds (MSB), 0..255 (0 = no wakuep sync)
|
||||
e.g. {0x02, 0x58} -> device adjusts it's wakeup time when it is +/- 5 minutes from top-of-hour [default = 0]
|
||||
|
||||
#### 0x0E set Bluetooth scanner
|
||||
|
||||
0 = disabled
|
||||
@ -106,6 +111,11 @@ Send for example `83` `86` as Downlink on Port 2 to get battery status and time/
|
||||
0 ... 100 percentage of luminosity (100% = full light)
|
||||
e.g. 50 -> 50% of luminosity [default]
|
||||
|
||||
#### 0x11 set Wifi scanner channel map bitmask
|
||||
|
||||
bytes 1..2 = wifi channel map bitmask (MSB), 0..8191
|
||||
e.g. 0b1010000001001 sets channels 1, 4, 11, 13
|
||||
|
||||
#### 0x13 set user sensor mode
|
||||
|
||||
byte 1 = user sensor number (1..3)
|
||||
|
@ -64,7 +64,9 @@ typedef struct __attribute__((packed)) {
|
||||
int16_t rssilimit; // threshold for rssilimiter, negative value!
|
||||
uint8_t sendcycle; // payload send cycle [seconds/2]
|
||||
uint16_t sleepcycle; // sleep cycle [seconds/10]
|
||||
uint16_t wakesync; // time window [seconds] to sync wakeup on top-of-hour
|
||||
uint8_t wifichancycle; // wifi channel switch cycle [seconds/100]
|
||||
uint16_t wifichanmap; // wifi channel hopping scheme
|
||||
uint8_t blescantime; // BLE scan cycle duration [seconds]
|
||||
uint8_t blescan; // 0=disabled, 1=enabled
|
||||
uint8_t wifiscan; // 0=disabled, 1=enabled
|
||||
@ -109,6 +111,6 @@ typedef struct {
|
||||
float pm25;
|
||||
} sdsStatus_t;
|
||||
|
||||
extern char clientId[20]; // unique clientID
|
||||
extern char clientId[20]; // unique clientID
|
||||
|
||||
#endif
|
@ -14,8 +14,8 @@
|
||||
void reset_rtc_vars(void);
|
||||
void do_reset(bool warmstart);
|
||||
void do_after_reset(void);
|
||||
void enter_deepsleep(const uint32_t wakeup_sec, const gpio_num_t wakeup_gpio);
|
||||
unsigned long long uptime(void);
|
||||
void enter_deepsleep(uint32_t wakeup_sec, const gpio_num_t wakeup_gpio);
|
||||
uint64_t uptime(void);
|
||||
|
||||
enum runmode_t {
|
||||
RUNMODE_POWERCYCLE,
|
||||
|
@ -15,7 +15,7 @@ void sendData(void);
|
||||
void checkSendQueues(void);
|
||||
void flushQueues(void);
|
||||
bool allQueuesEmtpy(void);
|
||||
void setSendIRQ(TimerHandle_t xTimer);
|
||||
//void setSendIRQ(TimerHandle_t xTimer);
|
||||
void setSendIRQ(void);
|
||||
|
||||
#endif // _SENDDATA_H_
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#define HAS_LORA_TIME \
|
||||
((HAS_LORA) && ((TIME_SYNC_LORASERVER) || (TIME_SYNC_LORAWAN)))
|
||||
#define HAS_TIME (TIME_SYNC_INTERVAL) && (HAS_LORA_TIME || HAS_GPS)
|
||||
|
||||
#define SECS_YR_2000 (946684800UL) // the time at the start of y2k
|
||||
#define GPS_UTC_DIFF 315964800UL // seconds diff between gps and utc epoch
|
||||
|
@ -47,7 +47,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I
|
||||
|
||||
[common]
|
||||
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
|
||||
release_version = 3.4.62
|
||||
release_version = 3.5.0
|
||||
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
|
||||
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
|
||||
debug_level = 3
|
||||
@ -55,13 +55,13 @@ extra_scripts = pre:src/build.py
|
||||
otakeyfile = ota.conf
|
||||
lorakeyfile = loraconf.h
|
||||
lmicconfigfile = lmic_config.h
|
||||
platform_espressif32 = espressif32@6.0.0
|
||||
platform_espressif32 = espressif32@6.0.1
|
||||
monitor_speed = 115200
|
||||
upload_speed = 115200 ; set by build.py and taken from hal file
|
||||
lib_deps_lora =
|
||||
mcci-catena/MCCI LoRaWAN LMIC library @ ^4.1.1
|
||||
lib_deps_display =
|
||||
bitbank2/OneBitDisplay @ ^2.3.0
|
||||
bitbank2/OneBitDisplay @ ^2.3.1
|
||||
bitbank2/bb_spi_lcd @ ^2.4.1
|
||||
ricmoo/QRCode @ ^0.0.1
|
||||
lib_deps_ledmatrix =
|
||||
@ -71,19 +71,19 @@ lib_deps_rgbled =
|
||||
lib_deps_gps =
|
||||
mikalhart/TinyGPSPlus @ ^1.0.3
|
||||
lib_deps_sensors =
|
||||
adafruit/Adafruit Unified Sensor @ ^1.1.7
|
||||
adafruit/Adafruit Unified Sensor @ ^1.1.9
|
||||
adafruit/Adafruit BME280 Library @ ^2.2.2
|
||||
adafruit/Adafruit BMP085 Library @ ^1.2.2
|
||||
boschsensortec/BSEC Software Library @ 1.6.1480
|
||||
boschsensortec/BSEC Software Library @ 1.8.1492
|
||||
lewapek/Nova Fitness Sds dust sensors library @ ^1.5.1
|
||||
lib_deps_basic =
|
||||
greyrook/libpax @ ^1.1.0
|
||||
https://github.com/SukkoPera/Arduino-Rokkit-Hash.git
|
||||
bblanchon/ArduinoJson @ ^6.20.0
|
||||
makuna/RTC @ ^2.3.5
|
||||
bblanchon/ArduinoJson @ ^6.21.2
|
||||
makuna/RTC @ ^2.3.7
|
||||
mathertel/OneButton @ ^2.0.3
|
||||
lewisxhe/XPowersLib @ ^0.1.5
|
||||
256dpi/MQTT @ ^2.5.0
|
||||
256dpi/MQTT @ ^2.5.1
|
||||
lib_deps_all =
|
||||
${common.lib_deps_basic}
|
||||
${common.lib_deps_lora}
|
||||
|
@ -10,7 +10,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I
|
||||
|
||||
[common]
|
||||
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
|
||||
release_version = 3.4.62
|
||||
release_version = 3.5.0
|
||||
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
|
||||
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
|
||||
debug_level = 3
|
||||
@ -18,7 +18,7 @@ extra_scripts = pre:src/build.py
|
||||
otakeyfile = ota.conf
|
||||
lorakeyfile = loraconf.h
|
||||
lmicconfigfile = lmic_config.h
|
||||
platform_espressif32 = espressif32@6.0.0
|
||||
platform_espressif32 = espressif32@6.0.1
|
||||
monitor_speed = 115200
|
||||
upload_speed = 115200 ; set by build.py and taken from hal file
|
||||
lib_deps_all =
|
||||
@ -27,9 +27,9 @@ lib_deps_all =
|
||||
fastled/FastLED @ ^3.5.0
|
||||
greyrook/libpax @ ^1.1.0
|
||||
https://github.com/SukkoPera/Arduino-Rokkit-Hash.git
|
||||
bblanchon/ArduinoJson @ ^6.20.0
|
||||
bblanchon/ArduinoJson @ ^6.21.2
|
||||
mathertel/OneButton @ ^2.0.3
|
||||
256dpi/MQTT @ ^2.5.0
|
||||
256dpi/MQTT @ ^2.5.1
|
||||
ricmoo/QRCode @ ^0.0.1
|
||||
build_flags_basic =
|
||||
-include "src/paxcounter.conf"
|
||||
|
@ -82,20 +82,20 @@ int bme_init(void) {
|
||||
int checkIaqSensorStatus(void) {
|
||||
int rslt = 1; // true = 1 = no error, false = 0 = error
|
||||
|
||||
if (iaqSensor.status != BSEC_OK) {
|
||||
if (iaqSensor.bsecStatus != BSEC_OK) {
|
||||
rslt = 0;
|
||||
if (iaqSensor.status < BSEC_OK)
|
||||
ESP_LOGE(TAG, "BSEC error %d", iaqSensor.status);
|
||||
if (iaqSensor.bsecStatus < BSEC_OK)
|
||||
ESP_LOGE(TAG, "BSEC error %d", iaqSensor.bsecStatus);
|
||||
else
|
||||
ESP_LOGW(TAG, "BSEC warning %d", iaqSensor.status);
|
||||
ESP_LOGW(TAG, "BSEC warning %d", iaqSensor.bsecStatus);
|
||||
}
|
||||
|
||||
if (iaqSensor.bme680Status != BME680_OK) {
|
||||
if (iaqSensor.bme68xStatus != BME68X_OK) {
|
||||
rslt = 0;
|
||||
if (iaqSensor.bme680Status < BME680_OK)
|
||||
ESP_LOGE(TAG, "BME680 error %d", iaqSensor.bme680Status);
|
||||
if (iaqSensor.bme68xStatus < BME68X_OK)
|
||||
ESP_LOGE(TAG, "BME680 error %d", iaqSensor.bme68xStatus);
|
||||
else
|
||||
ESP_LOGW(TAG, "BME680 warning %d", iaqSensor.bme680Status);
|
||||
ESP_LOGW(TAG, "BME680 warning %d", iaqSensor.bme68xStatus);
|
||||
}
|
||||
|
||||
return rslt;
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "globals.h"
|
||||
#include "configmanager.h"
|
||||
|
||||
|
||||
// namespace for device runtime preferences
|
||||
#define DEVCONFIG "paxcntcfg"
|
||||
|
||||
@ -38,8 +37,10 @@ static void defaultConfig(configData_t *myconfig) {
|
||||
myconfig->rssilimit = RSSILIMIT; // threshold for rssilimiter, negative value!
|
||||
myconfig->sendcycle = SENDCYCLE; // payload send cycle [seconds/2]
|
||||
myconfig->sleepcycle = SLEEPCYCLE; // sleep cycle [seconds/10]
|
||||
myconfig->wakesync = SYNCWAKEUP; // wakeup sync window [seconds]
|
||||
myconfig->wifichancycle =
|
||||
WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100]
|
||||
myconfig->wifichanmap = WIFI_CHANNEL_MAP; // wifi channel hopping scheme
|
||||
myconfig->blescantime =
|
||||
BLESCANINTERVAL /
|
||||
10; // BT channel scan cycle [seconds/100], default 1 (= 10ms)
|
||||
|
@ -37,7 +37,6 @@ MY_FONT_LARGE: 16x32px = 8 chars / line @ 2 lines
|
||||
#include "globals.h"
|
||||
#include "display.h"
|
||||
|
||||
|
||||
static uint8_t plotbuf[PLOTBUFFERSIZE] = {0};
|
||||
uint8_t DisplayIsOn = 0;
|
||||
hw_timer_t *displayIRQ = NULL;
|
||||
@ -374,7 +373,7 @@ void dp_refresh(bool nextPage) {
|
||||
#ifdef HAS_BUTTON
|
||||
dp_clear();
|
||||
break;
|
||||
#else // skip this page
|
||||
#else // skip this page and start over
|
||||
DisplayPage = 0;
|
||||
break;
|
||||
#endif
|
||||
|
@ -37,7 +37,7 @@
|
||||
// BME680 sensor on I2C bus
|
||||
#define HAS_BME 1 // Enable BME sensors in general
|
||||
#define HAS_BME680 GPIO_NUM_21, GPIO_NUM_22 // SDA, SCL
|
||||
#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND
|
||||
#define BME680_ADDR BME68X_I2C_ADDR_LOW // connect SDIO of BME680 to GND
|
||||
|
||||
// BME280 sensor on I2C bus
|
||||
//#define HAS_BME 1 // Enable BME sensors in general
|
||||
|
@ -18,7 +18,7 @@
|
||||
// Octopus32 has a pre-populated BME680 on i2c addr 0x76
|
||||
#define HAS_BME 1 // Enable BME sensors in general
|
||||
#define HAS_BME680 GPIO_NUM_23, GPIO_NUM_22 // SDA, SCL
|
||||
#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND
|
||||
#define BME680_ADDR BME68X_I2C_ADDR_LOW // connect SDIO of BME680 to GND
|
||||
|
||||
#define HAS_LED 13 // ESP32 GPIO12 (pin22) On Board LED
|
||||
//#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW
|
||||
|
@ -30,7 +30,7 @@
|
||||
// BME680 sensor on I2C bus
|
||||
//#define HAS_BME 1 // Enable BME sensors in general
|
||||
//#define HAS_BME680 SDA, SCL
|
||||
//#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // !! connect SDIO of BME680 to GND !!
|
||||
//#define BME680_ADDR BME68X_I2C_ADDR_LOW // !! connect SDIO of BME680 to GND !!
|
||||
|
||||
// display (if connected)
|
||||
//#define HAS_DISPLAY 1
|
||||
|
@ -52,7 +52,7 @@ Reset -> reset device
|
||||
// BME680 sensor on I2C bus
|
||||
//#define HAS_BME 1 // Enable BME sensors in general
|
||||
//#define HAS_BME680 SDA, SCL
|
||||
//#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // !! connect SDIO of BME680 to GND !!
|
||||
//#define BME680_ADDR BME68X_I2C_ADDR_LOW // !! connect SDIO of BME680 to GND !!
|
||||
|
||||
//#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
|
||||
|
||||
|
@ -71,7 +71,7 @@ PMUIRQ <- GPIO <- PMU chip
|
||||
Application IRQs fired by software:
|
||||
TIMESYNC_IRQ <- setTimeSyncIRQ() <- Ticker.h
|
||||
CYCLIC_IRQ <- setCyclicIRQ() <- Ticker.h
|
||||
SENDCYCLE_IRQ <- setSendIRQ() <- xTimer or libpax callback
|
||||
SENDCYCLE_IRQ <- setSendIRQ() <- libpax callback
|
||||
BME_IRQ <- setBMEIRQ() <- Ticker.h
|
||||
|
||||
*/
|
||||
@ -282,7 +282,7 @@ void setup() {
|
||||
// configure WIFI sniffing
|
||||
strcpy(configuration.wifi_my_country_str, WIFI_MY_COUNTRY);
|
||||
configuration.wificounter = cfg.wifiscan;
|
||||
configuration.wifi_channel_map = WIFI_CHANNEL_ALL;
|
||||
configuration.wifi_channel_map = cfg.wifichanmap;
|
||||
configuration.wifi_channel_switch_interval = cfg.wifichancycle;
|
||||
configuration.wifi_rssi_threshold = cfg.rssilimit;
|
||||
ESP_LOGI(TAG, "WIFISCAN: %s", cfg.wifiscan ? "on" : "off");
|
||||
@ -456,7 +456,7 @@ void setup() {
|
||||
#endif // HAS_BUTTON
|
||||
|
||||
// only if we have a timesource we do timesync
|
||||
#if ((HAS_LORA_TIME) || (HAS_GPS) || (HAS_RTC))
|
||||
#if ((HAS_LORA_TIME) || (HAS_GPS) || defined HAS_RTC)
|
||||
time_init();
|
||||
strcat_P(features, " TIME");
|
||||
#endif // timesync
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define SLEEPCYCLE 0 // sleep time after a send cycle [seconds/10], 0 .. 65535; 0 means no sleep [default = 0]
|
||||
#define PAYLOAD_ENCODER 2 // payload encoder: 1=Plain, 2=Packed, 3=Cayenne LPP dynamic, 4=Cayenne LPP packed
|
||||
#define COUNTERMODE 0 // 0=cyclic, 1=cumulative, 2=cyclic confirmed
|
||||
#define SYNCWAKEUP 300 // shifts sleep wakeup to top-of-hour, when +/- X seconds off [0=off]
|
||||
|
||||
// default settings for transmission of sensor data (first list = data on / second line = data off)
|
||||
#define PAYLOADMASK \
|
||||
@ -52,6 +53,7 @@
|
||||
// WiFi scan parameters
|
||||
#define WIFI_MY_COUNTRY "01" // select 2-letter locale for Wifi RF settings, e.g. "DE"; use "01" for world safe mode
|
||||
#define WIFI_CHANNEL_SWITCH_INTERVAL 50 // [seconds/100] -> 0,5 sec.
|
||||
#define WIFI_CHANNEL_MAP WIFI_CHANNEL_ALL // possible values see libpax_api.h
|
||||
|
||||
// LoRa payload default parameters
|
||||
#define MEM_LOW 2048 // [Bytes] low memory threshold triggering a send cycle
|
||||
|
@ -44,6 +44,7 @@ void PayloadConvert::addConfig(configData_t value) {
|
||||
buffer[cursor++] = lowByte(value.rssilimit);
|
||||
buffer[cursor++] = value.sendcycle;
|
||||
buffer[cursor++] = value.wifichancycle;
|
||||
//buffer[cursor++] = value.wifichanmap;
|
||||
buffer[cursor++] = value.blescantime;
|
||||
buffer[cursor++] = value.blescan;
|
||||
buffer[cursor++] = value.wifiant;
|
||||
@ -170,6 +171,7 @@ void PayloadConvert::addConfig(configData_t value) {
|
||||
writeUint16(value.rssilimit);
|
||||
writeUint8(value.sendcycle);
|
||||
writeUint8(value.wifichancycle);
|
||||
//writeUint8(value.wifichanmap);
|
||||
writeUint8(value.blescantime);
|
||||
writeUint16(value.sleepcycle);
|
||||
writeBitmap(value.adrmode ? true : false, value.screensaver ? true : false,
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include "globals.h"
|
||||
#include "rcommand.h"
|
||||
|
||||
|
||||
static QueueHandle_t RcmdQueue;
|
||||
TaskHandle_t rcmdTask;
|
||||
|
||||
@ -59,7 +58,7 @@ void set_rssi(uint8_t val[]) {
|
||||
current_config.ble_rssi_threshold = cfg.rssilimit;
|
||||
libpax_update_config(¤t_config);
|
||||
init_libpax();
|
||||
ESP_LOGI(TAG, "Remote command: set RSSI limit to %d", cfg.rssilimit);
|
||||
ESP_LOGI(TAG, "Remote command: set RSSI limit to %hd", cfg.rssilimit);
|
||||
}
|
||||
|
||||
void set_sendcycle(uint8_t val[]) {
|
||||
@ -67,7 +66,7 @@ void set_sendcycle(uint8_t val[]) {
|
||||
return;
|
||||
// update send cycle interrupt [seconds / 2]
|
||||
cfg.sendcycle = val[0];
|
||||
ESP_LOGI(TAG, "Remote command: set send cycle to %d seconds",
|
||||
ESP_LOGI(TAG, "Remote command: set send cycle to %u seconds",
|
||||
cfg.sendcycle * 2);
|
||||
libpax_counter_stop();
|
||||
init_libpax();
|
||||
@ -76,10 +75,16 @@ void set_sendcycle(uint8_t val[]) {
|
||||
void set_sleepcycle(uint8_t val[]) {
|
||||
// swap byte order from msb to lsb, note: this is a platform dependent hack
|
||||
cfg.sleepcycle = __builtin_bswap16(*(uint16_t *)(val));
|
||||
ESP_LOGI(TAG, "Remote command: set sleep cycle to %d seconds",
|
||||
ESP_LOGI(TAG, "Remote command: set sleep cycle to %hu seconds",
|
||||
cfg.sleepcycle * 10);
|
||||
}
|
||||
|
||||
void set_wakesync(uint8_t val[]) {
|
||||
// swap byte order from msb to lsb, note: this is a platform dependent hack
|
||||
cfg.wakesync = __builtin_bswap16(*(uint16_t *)(val));
|
||||
ESP_LOGI(TAG, "Remote command: set wakesync to %hu seconds", cfg.wakesync);
|
||||
}
|
||||
|
||||
void set_wifichancycle(uint8_t val[]) {
|
||||
cfg.wifichancycle = val[0];
|
||||
libpax_counter_stop();
|
||||
@ -101,6 +106,17 @@ void set_wifichancycle(uint8_t val[]) {
|
||||
init_libpax();
|
||||
}
|
||||
|
||||
void set_wifichanmap(uint8_t val[]) {
|
||||
// swap byte order from msb to lsb, note: this is a platform dependent hack
|
||||
cfg.wifichanmap = __builtin_bswap16(*(uint16_t *)(val));
|
||||
libpax_counter_stop();
|
||||
libpax_config_t current_config;
|
||||
libpax_get_current_config(¤t_config);
|
||||
current_config.wifi_channel_map = cfg.wifichanmap;
|
||||
libpax_update_config(¤t_config);
|
||||
init_libpax();
|
||||
}
|
||||
|
||||
void set_blescantime(uint8_t val[]) {
|
||||
cfg.blescantime = val[0];
|
||||
libpax_counter_stop();
|
||||
@ -193,7 +209,7 @@ void set_sensor(uint8_t val[]) {
|
||||
return; // invalid sensor number -> exit
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Remote command: set sensor #%d mode to %s", val[0],
|
||||
ESP_LOGI(TAG, "Remote command: set sensor #%u mode to %s", val[0],
|
||||
val[1] ? "on" : "off");
|
||||
|
||||
if (val[1])
|
||||
@ -213,7 +229,7 @@ void set_loradr(uint8_t val[]) {
|
||||
#if (HAS_LORA)
|
||||
if (validDR(val[0])) {
|
||||
cfg.loradr = val[0];
|
||||
ESP_LOGI(TAG, "Remote command: set LoRa Datarate to %d", cfg.loradr);
|
||||
ESP_LOGI(TAG, "Remote command: set LoRa Datarate to %u", cfg.loradr);
|
||||
LMIC_setDrTxpow(assertDR(cfg.loradr), KEEP_TXPOW);
|
||||
ESP_LOGI(TAG, "Radio parameters now %s / %s / %s",
|
||||
getSfName(updr2rps(LMIC.datarate)),
|
||||
@ -222,7 +238,7 @@ void set_loradr(uint8_t val[]) {
|
||||
} else
|
||||
ESP_LOGI(
|
||||
TAG,
|
||||
"Remote command: set LoRa Datarate called with illegal datarate %d",
|
||||
"Remote command: set LoRa Datarate called with illegal datarate %u",
|
||||
val[0]);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Remote command: LoRa not implemented");
|
||||
@ -275,15 +291,15 @@ void set_wifiant(uint8_t val[]) {
|
||||
void set_rgblum(uint8_t val[]) {
|
||||
// Avoid wrong parameters
|
||||
cfg.rgblum = (val[0] <= 100) ? (uint8_t)val[0] : RGBLUMINOSITY;
|
||||
ESP_LOGI(TAG, "Remote command: set RGB Led luminosity %d", cfg.rgblum);
|
||||
};
|
||||
ESP_LOGI(TAG, "Remote command: set RGB Led luminosity %u", cfg.rgblum);
|
||||
}
|
||||
|
||||
void set_lorapower(uint8_t val[]) {
|
||||
#if (HAS_LORA)
|
||||
// set data rate and transmit power only if we have no ADR
|
||||
if (!cfg.adrmode) {
|
||||
cfg.txpower = val[0];
|
||||
ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %d", cfg.txpower);
|
||||
ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %u", cfg.txpower);
|
||||
LMIC_setDrTxpow(assertDR(cfg.loradr), cfg.txpower);
|
||||
} else
|
||||
ESP_LOGI(
|
||||
@ -293,14 +309,14 @@ void set_lorapower(uint8_t val[]) {
|
||||
#else
|
||||
ESP_LOGW(TAG, "Remote command: LoRa not implemented");
|
||||
#endif // HAS_LORA
|
||||
};
|
||||
}
|
||||
|
||||
void get_config(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: get device configuration");
|
||||
payload.reset();
|
||||
payload.addConfig(cfg);
|
||||
SendPayload(CONFIGPORT);
|
||||
};
|
||||
}
|
||||
|
||||
void get_status(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: get device status");
|
||||
@ -315,7 +331,7 @@ void get_status(uint8_t val[]) {
|
||||
RTC_restarts);
|
||||
#endif
|
||||
SendPayload(STATUSPORT);
|
||||
};
|
||||
}
|
||||
|
||||
void get_gps(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: get gps status");
|
||||
@ -328,7 +344,7 @@ void get_gps(uint8_t val[]) {
|
||||
#else
|
||||
ESP_LOGW(TAG, "GPS function not supported");
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
void get_bme(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: get bme680 sensor data");
|
||||
@ -339,7 +355,7 @@ void get_bme(uint8_t val[]) {
|
||||
#else
|
||||
ESP_LOGW(TAG, "BME sensor not supported");
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
void get_batt(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: get battery voltage");
|
||||
@ -350,7 +366,7 @@ void get_batt(uint8_t val[]) {
|
||||
#else
|
||||
ESP_LOGW(TAG, "Battery voltage not supported");
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
void get_time(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: get time");
|
||||
@ -359,35 +375,35 @@ void get_time(uint8_t val[]) {
|
||||
payload.addTime(t);
|
||||
payload.addByte(sntp_get_sync_status() << 4 | timeSource);
|
||||
SendPayload(TIMEPORT);
|
||||
};
|
||||
}
|
||||
|
||||
void set_timesync(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: timesync requested");
|
||||
setTimeSyncIRQ();
|
||||
};
|
||||
}
|
||||
|
||||
void set_time(uint8_t val[]) {
|
||||
// swap byte order from msb to lsb, note: this is a platform dependent hack
|
||||
uint32_t t = __builtin_bswap32(*(uint32_t *)(val));
|
||||
ESP_LOGI(TAG, "Remote command: set time to %d", t);
|
||||
ESP_LOGI(TAG, "Remote command: set time to %lu", t);
|
||||
setMyTime(t, 0, _set);
|
||||
};
|
||||
}
|
||||
|
||||
void set_flush(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: flush");
|
||||
// does nothing
|
||||
// used to open receive window on LoRaWAN class a nodes
|
||||
};
|
||||
}
|
||||
|
||||
void set_loadconfig(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: load config from NVRAM");
|
||||
loadConfig();
|
||||
};
|
||||
}
|
||||
|
||||
void set_saveconfig(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: save config to NVRAM");
|
||||
saveConfig(false);
|
||||
};
|
||||
}
|
||||
|
||||
// assign previously defined functions to set of numeric remote commands
|
||||
// format: {opcode, function, number of function arguments}
|
||||
@ -399,8 +415,9 @@ static const cmd_t table[] = {
|
||||
{0x07, set_loraadr, 1}, {0x08, set_screensaver, 1},
|
||||
{0x09, set_reset, 1}, {0x0a, set_sendcycle, 1},
|
||||
{0x0b, set_wifichancycle, 1}, {0x0c, set_blescantime, 1},
|
||||
{0x0e, set_blescan, 1}, {0x0f, set_wifiant, 1},
|
||||
{0x10, set_rgblum, 1}, {0x13, set_sensor, 2},
|
||||
{0x0d, set_wakesync, 2}, {0x0e, set_blescan, 1},
|
||||
{0x0f, set_wifiant, 1}, {0x10, set_rgblum, 1},
|
||||
{0x11, set_wifichanmap, 2}, {0x13, set_sensor, 2},
|
||||
{0x14, set_payloadmask, 1}, {0x15, set_bme, 1},
|
||||
{0x16, set_batt, 1}, {0x17, set_wifiscan, 1},
|
||||
{0x18, set_flush, 0}, {0x19, set_sleepcycle, 2},
|
||||
@ -492,7 +509,7 @@ esp_err_t rcmd_init(void) {
|
||||
ESP_LOGE(TAG, "Could not create rcommand send queue. Aborting.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGI(TAG, "Rcommand send queue created, size %d Bytes",
|
||||
ESP_LOGI(TAG, "Rcommand send queue created, size %u Bytes",
|
||||
RCMD_QUEUE_SIZE * sizeof(RcmdBuffer_t));
|
||||
|
||||
xTaskCreatePinnedToCore(rcmd_process, // task function
|
||||
|
@ -5,20 +5,46 @@
|
||||
// Conversion factor for micro seconds to seconds
|
||||
#define uS_TO_S_FACTOR 1000000ULL
|
||||
|
||||
// RTC_NOINIT_ATTR -> keep value after a software restart or system crash
|
||||
// RTC_NOINIT_ATTR -> keeps value after a software restart or system crash
|
||||
RTC_NOINIT_ATTR runmode_t RTC_runmode;
|
||||
RTC_NOINIT_ATTR uint32_t RTC_restarts;
|
||||
// RTC_DATA_ATTR -> keep values after a wakeup from sleep
|
||||
RTC_DATA_ATTR struct timeval RTC_sleep_start_time;
|
||||
RTC_DATA_ATTR unsigned long long RTC_millis = 0;
|
||||
// RTC_DATA_ATTR -> keeps value after a wakeup from sleep
|
||||
RTC_DATA_ATTR struct timeval sleep_start_time;
|
||||
RTC_DATA_ATTR int64_t RTC_millis = 0;
|
||||
|
||||
timeval sleep_stop_time;
|
||||
struct timeval sleep_stop_time;
|
||||
|
||||
void reset_rtc_vars(void) {
|
||||
RTC_runmode = RUNMODE_POWERCYCLE;
|
||||
RTC_restarts = 0;
|
||||
}
|
||||
|
||||
#if (HAS_TIME)
|
||||
void adjust_wakeup(uint32_t *wakeuptime) {
|
||||
// only adjust wakeup if we have a valid time
|
||||
if ((timeSource == _unsynced) ||
|
||||
(sntp_get_sync_status() == SNTP_SYNC_STATUS_IN_PROGRESS)) {
|
||||
ESP_LOGI(TAG, "Syncwakeup: No valid time for sync");
|
||||
return;
|
||||
}
|
||||
|
||||
time_t now;
|
||||
time(&now);
|
||||
|
||||
// 1..3600 seconds between next wakeup time and following top-of-hour
|
||||
uint16_t shift_sec = 3600 - (now + *wakeuptime) % 3600;
|
||||
|
||||
if (shift_sec <= SYNCWAKEUP) {
|
||||
*wakeuptime += shift_sec; // delay wakeup to catch top-of-hour
|
||||
ESP_LOGI(TAG, "Syncwakeup: Wakeup %hu sec postponed", shift_sec);
|
||||
} else if (shift_sec >= (3600 - SYNCWAKEUP)) {
|
||||
*wakeuptime = 3600 - shift_sec; // shorten wake up to next top-of-hour
|
||||
ESP_LOGI(TAG, "Syncwakeup: Wakeup %hu sec preponed", shift_sec);
|
||||
} else
|
||||
ESP_LOGI(TAG, "Syncwakeup: Wakeup keeping unshifted");
|
||||
}
|
||||
#endif
|
||||
|
||||
void do_reset(bool warmstart) {
|
||||
if (warmstart) {
|
||||
ESP_LOGI(TAG, "restarting device (warmstart)");
|
||||
@ -36,7 +62,7 @@ void do_reset(bool warmstart) {
|
||||
|
||||
void do_after_reset(void) {
|
||||
struct timeval sleep_stop_time;
|
||||
uint64_t sleep_time_ms;
|
||||
int64_t sleep_time_ms;
|
||||
|
||||
// read (and initialize on first run) runtime settings from NVRAM
|
||||
loadConfig();
|
||||
@ -62,11 +88,13 @@ void do_after_reset(void) {
|
||||
case RESET_REASON_CORE_DEEP_SLEEP:
|
||||
// calculate time spent in deep sleep
|
||||
gettimeofday(&sleep_stop_time, NULL);
|
||||
sleep_time_ms =
|
||||
(sleep_stop_time.tv_sec - RTC_sleep_start_time.tv_sec) * 1000 +
|
||||
(sleep_stop_time.tv_usec - RTC_sleep_start_time.tv_usec) / 1000;
|
||||
sleep_time_ms = ((int64_t)sleep_stop_time.tv_sec * 1000000L +
|
||||
(int64_t)sleep_stop_time.tv_usec -
|
||||
(int64_t)sleep_start_time.tv_sec * 1000000L -
|
||||
(int64_t)sleep_start_time.tv_usec) /
|
||||
1000LL;
|
||||
RTC_millis += sleep_time_ms; // increment system monotonic time
|
||||
ESP_LOGI(TAG, "Time spent in deep sleep: %d ms", sleep_time_ms);
|
||||
ESP_LOGI(TAG, "Time spent in deep sleep: %llu ms", sleep_time_ms);
|
||||
// do we have a valid time? -> set global variable
|
||||
timeSource = timeIsValid(sleep_stop_time.tv_sec) ? _set : _unsynced;
|
||||
// set wakeup state, not if we have pending OTA update
|
||||
@ -81,7 +109,7 @@ void do_after_reset(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void enter_deepsleep(const uint32_t wakeup_sec, gpio_num_t wakeup_gpio) {
|
||||
void enter_deepsleep(uint32_t wakeup_sec, gpio_num_t wakeup_gpio) {
|
||||
ESP_LOGI(TAG, "Preparing to sleep...");
|
||||
|
||||
RTC_runmode = RUNMODE_SLEEP;
|
||||
@ -143,6 +171,11 @@ void enter_deepsleep(const uint32_t wakeup_sec, gpio_num_t wakeup_gpio) {
|
||||
// shutdown i2c bus
|
||||
i2c_deinit();
|
||||
|
||||
#if (HAS_TIME)
|
||||
if (cfg.wakesync && cfg.sleepcycle)
|
||||
adjust_wakeup(&wakeup_sec);
|
||||
#endif
|
||||
|
||||
// configure wakeup sources
|
||||
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/sleep_modes.html
|
||||
|
||||
@ -158,8 +191,8 @@ void enter_deepsleep(const uint32_t wakeup_sec, gpio_num_t wakeup_gpio) {
|
||||
}
|
||||
|
||||
// time stamp sleep start time and save system monotonic time. Deep sleep.
|
||||
gettimeofday(&RTC_sleep_start_time, NULL);
|
||||
RTC_millis += esp_timer_get_time() / 1000;
|
||||
gettimeofday(&sleep_start_time, NULL);
|
||||
RTC_millis += esp_timer_get_time() / 1000LL;
|
||||
ESP_LOGI(TAG, "Going to sleep, good bye.");
|
||||
|
||||
// flush & close sd card, if we have
|
||||
@ -170,6 +203,6 @@ void enter_deepsleep(const uint32_t wakeup_sec, gpio_num_t wakeup_gpio) {
|
||||
esp_deep_sleep_start();
|
||||
}
|
||||
|
||||
unsigned long long uptime() {
|
||||
return (RTC_millis + esp_timer_get_time() / 1000);
|
||||
uint64_t uptime() {
|
||||
return (uint64_t)(RTC_millis + esp_timer_get_time() / 1000LL);
|
||||
}
|
@ -8,7 +8,7 @@ RtcDS3231<TwoWire> Rtc(Wire); // RTC hardware i2c interface
|
||||
// initialize RTC
|
||||
uint8_t rtc_init(void) {
|
||||
Wire.begin(HAS_RTC);
|
||||
Rtc.Begin(MY_DISPLAY_SDA, MY_DISPLAY_SCL);
|
||||
Rtc.Begin(HAS_RTC);
|
||||
|
||||
// configure RTC chip
|
||||
Rtc.Enable32kHzPin(false);
|
||||
@ -22,7 +22,7 @@ uint8_t rtc_init(void) {
|
||||
#if (TIME_SYNC_COMPILEDATE)
|
||||
// initialize a blank RTC without battery backup with build time
|
||||
RtcDateTime tt = Rtc.GetDateTime();
|
||||
time_t t = tt.Epoch32Time(); // sec2000 -> epoch
|
||||
time_t t = tt.Unix32Time(); // sec2000 -> epoch
|
||||
|
||||
if (!Rtc.IsDateTimeValid() || !timeIsValid(t)) {
|
||||
ESP_LOGW(TAG, "RTC has no recent time, setting to compiletime");
|
||||
@ -53,7 +53,7 @@ time_t get_rtctime(uint16_t *msec) {
|
||||
*msec = 0;
|
||||
if (Rtc.IsDateTimeValid() && Rtc.GetIsRunning()) {
|
||||
RtcDateTime tt = Rtc.GetDateTime();
|
||||
t = tt.Epoch32Time(); // sec2000 -> epoch
|
||||
t = tt.Unix32Time(); // sec2000 -> epoch
|
||||
}
|
||||
|
||||
// if we have a RTC pulse, we calculate msec
|
||||
|
@ -174,8 +174,8 @@ bool sdcard_init(bool create) {
|
||||
#if (HAS_SDS011)
|
||||
fprintf(data_file, "%s", SDCARD_FILE_HEADER_SDS011);
|
||||
#endif
|
||||
fprintf(data_file, "\n");
|
||||
}
|
||||
fprintf(data_file, "\n");
|
||||
|
||||
} else {
|
||||
useSDCard = false;
|
||||
|
@ -1,12 +1,13 @@
|
||||
// Basic Config
|
||||
#include "senddata.h"
|
||||
|
||||
// void setSendIRQ(TimerHandle_t xTimer) {
|
||||
// xTaskNotify(irqHandlerTask, SENDCYCLE_IRQ, eSetBits);
|
||||
//}
|
||||
|
||||
void setSendIRQ(TimerHandle_t xTimer) {
|
||||
xTaskNotify(irqHandlerTask, SENDCYCLE_IRQ, eSetBits);
|
||||
}
|
||||
// void setSendIRQ(void) { setSendIRQ(NULL); }
|
||||
|
||||
void setSendIRQ(void) { setSendIRQ(NULL); }
|
||||
void setSendIRQ(void) { xTaskNotify(irqHandlerTask, SENDCYCLE_IRQ, eSetBits); }
|
||||
|
||||
// put data to send in RTos Queues used for transmit over channels Lora and SPI
|
||||
void SendPayload(uint8_t port) {
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
|
||||
// symbol to display current time source
|
||||
// G = GPS / R = RTC / L = LORA / * = no sync / ? = never synced
|
||||
const char timeSetSymbols[] = {'G', 'R', 'L', '*', '?'};
|
||||
// G = GPS / R = RTC / L = LORA / ? = unsynced / * = set
|
||||
const char timeSetSymbols[] = {'G', 'R', 'L', '?', '*'};
|
||||
|
||||
DRAM_ATTR bool TimePulseTick = false;
|
||||
#ifdef GPS_INT
|
||||
@ -82,7 +82,7 @@ void calibrateTime(void) {
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if ((HAS_GPS) || (HAS_RTC))
|
||||
#if ((HAS_GPS) || defined HAS_RTC)
|
||||
time_t t = 0;
|
||||
uint16_t t_msec = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user