diff --git a/README.md b/README.md index 88a52486..213e83c4 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,6 @@ Hereafter described is the default *plain* format, which uses MSB bit numbering. byte 1-2: Number of unique pax, first seen on Wifi byte 3-4: Number of unique pax, first seen on Bluetooth [0 if BT disabled] - bytes 5-18: GPS data, format see Port #4 (appended only, if GPS is present and has a fix) **Port #2:** Device status query result @@ -177,12 +176,12 @@ Hereafter described is the default *plain* format, which uses MSB bit numbering. byte 13: Wifi antenna switch (0=internal, 1=external) [default 0] byte 14: Vendorfilter mode (0=disabled, 1=enabled) [default 0] byte 15: RGB LED luminosity (0..100 %) [default 30] - byte 16: GPS send data mode (1=on, 0=ff) [default 1] + byte 16: Payload filter mask byte 17: Beacon proximity alarm mode (1=on, 0=off) [default 0] bytes 18-28: Software version (ASCII format, terminating with zero) -**Port #4:** GPS query result +**Port #4:** GPS query result (device answers only if has GPS and GPS has a fix) bytes 1-4: Latitude bytes 5-8: Longitude diff --git a/include/bme680read.h b/include/bme680.h similarity index 84% rename from include/bme680read.h rename to include/bme680.h index 4573f22f..6b8e3827 100644 --- a/include/bme680read.h +++ b/include/bme680.h @@ -1,5 +1,5 @@ -#ifndef _HAS_BME -#define _HAS_BME +#ifndef _BME680_H +#define _BME680_H #include "globals.h" #include diff --git a/include/globals.h b/include/globals.h index 575bc931..8a10cc9f 100644 --- a/include/globals.h +++ b/include/globals.h @@ -9,6 +9,26 @@ #include #include +// bits in payloadmask for filtering payload data +#define GPS_DATA (0x01) +#define ALARM_DATA (0x02) +#define MEMS_DATA (0x04) +#define COUNT_DATA (0x08) +#define SENSOR1_DATA (0x10) +#define SENSOR2_DATA (0x20) +#define SENSOR3_DATA (0x40) +#define SENSOR4_DATA (0x80) + +// bits in configmask for device runmode control +#define GPS_MODE (0x01) +#define ALARM_MODE (0x02) +#define BEACON_MODE (0x04) +#define UPDATE_MODE (0x08) +#define FILTER_MODE (0x10) +#define ANTENNA_MODE (0x20) +#define BLE_MODE (0x40) +#define SCREEN_MODE (0x80) + // Struct holding devices's runtime configuration typedef struct { uint8_t lorasf; // 7-12, lora spreadfactor @@ -25,9 +45,9 @@ typedef struct { uint8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4) uint8_t vendorfilter; // 0=disabled, 1=enabled uint8_t rgblum; // RGB Led luminosity (0..100%) - uint8_t gpsmode; // 0=disabled, 1=enabled uint8_t monitormode; // 0=disabled, 1=enabled uint8_t runmode; // 0=normal, 1=update + uint8_t payloadmask; // bitswitches for payload data char version[10]; // Firmware version } configData_t; @@ -47,9 +67,9 @@ typedef struct { } gpsStatus_t; typedef struct { - float temperature; // Temperature in degrees Centigrade - uint16_t pressure; // Barometic pressure in hecto pascals - float humidity; // Relative humidity in percent + float temperature; // Temperature in degrees Centigrade + uint16_t pressure; // Barometic pressure in hecto pascals + float humidity; // Relative humidity in percent uint16_t gas_resistance; // Resistance in MOhms } bmeStatus_t; @@ -75,7 +95,7 @@ extern TaskHandle_t irqHandlerTask, wifiSwitchTask; #endif #ifdef HAS_BME -#include "bme680read.h" +#include "bme680.h" #endif #ifdef HAS_LORA diff --git a/platformio.ini b/platformio.ini index 55a4789f..c261bd38 100644 --- a/platformio.ini +++ b/platformio.ini @@ -29,7 +29,7 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 1.6.82 +release_version = 1.6.83 ; 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 = 0 diff --git a/src/TTN/packed_decoder.js b/src/TTN/packed_decoder.js index cd7e2014..0571bfa0 100644 --- a/src/TTN/packed_decoder.js +++ b/src/TTN/packed_decoder.js @@ -23,7 +23,7 @@ function Decoder(bytes, port) { if (port === 3) { // device config data - return decode(bytes, [uint8, uint8, uint16, uint8, uint8, uint8, uint8, bitmap, version], ['lorasf', 'txpower', 'rssilimit', 'sendcycle', 'wifichancycle', 'blescantime', 'rgblum', 'flags', 'version']); + return decode(bytes, [uint8, uint8, uint16, uint8, uint8, uint8, uint8, bitmap, bitmap, version], ['lorasf', 'txpower', 'rssilimit', 'sendcycle', 'wifichancycle', 'blescantime', 'rgblum', 'flags', 'payloadmask', 'version']); } if (port === 4) { @@ -157,7 +157,7 @@ var bitmap = function (byte) { } var i = bytesToInt(byte); var bm = ('00000000' + Number(i).toString(2)).substr(-8).split('').map(Number).map(Boolean); - return ['adr', 'screensaver', 'screen', 'countermode', 'blescan', 'antenna', 'filter', 'gpsmode'] + return ['adr', 'screensaver', 'screen', 'countermode', 'blescan', 'antenna', 'filter', 'alarm'] .reduce(function (obj, pos, index) { obj[pos] = +bm[index]; return obj; diff --git a/src/bme680read.cpp b/src/bme680.cpp similarity index 96% rename from src/bme680read.cpp rename to src/bme680.cpp index 5946a7a6..22c7b684 100644 --- a/src/bme680read.cpp +++ b/src/bme680.cpp @@ -1,6 +1,6 @@ #ifdef HAS_BME -#include "bme680read.h" +#include "bme680.h" // Local logging tag static const char TAG[] = "main"; diff --git a/src/configmanager.cpp b/src/configmanager.cpp index 8fa6b2f9..c90f0f4b 100644 --- a/src/configmanager.cpp +++ b/src/configmanager.cpp @@ -29,9 +29,9 @@ void defaultConfig() { cfg.wifiant = 0; // 0=internal, 1=external (for LoPy/LoPy4) cfg.vendorfilter = 1; // 0=disabled, 1=enabled cfg.rgblum = RGBLUMINOSITY; // RGB Led luminosity (0..100%) - cfg.gpsmode = 1; // 0=disabled, 1=enabled cfg.monitormode = 0; // 0=disabled, 1=enabled cfg.runmode = 0; // 0=normal, 1=update + cfg.payloadmask = 0xFF; // all payload switched on strncpy(cfg.version, PROGVERSION, sizeof(cfg.version) - 1); } @@ -136,9 +136,9 @@ void saveConfig() { flash8 != cfg.rgblum) nvs_set_i8(my_handle, "rgblum", cfg.rgblum); - if (nvs_get_i8(my_handle, "gpsmode", &flash8) != ESP_OK || - flash8 != cfg.gpsmode) - nvs_set_i8(my_handle, "gpsmode", cfg.gpsmode); + if (nvs_get_i8(my_handle, "payloadmask", &flash8) != ESP_OK || + flash8 != cfg.payloadmask) + nvs_set_i8(my_handle, "payloadmask", cfg.payloadmask); if (nvs_get_i8(my_handle, "monitormode", &flash8) != ESP_OK || flash8 != cfg.monitormode) @@ -315,11 +315,11 @@ void loadConfig() { saveConfig(); } - if (nvs_get_i8(my_handle, "gpsmode", &flash8) == ESP_OK) { - cfg.gpsmode = flash8; + if (nvs_get_i8(my_handle, "payloadmask", &flash8) == ESP_OK) { + cfg.payloadmask = flash8; ESP_LOGI(TAG, "GPS mode = %d", flash8); } else { - ESP_LOGI(TAG, "GPS mode set to default %d", cfg.gpsmode); + ESP_LOGI(TAG, "GPS mode set to default %d", cfg.payloadmask); saveConfig(); } diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 126f7739..bc5d4613 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -49,7 +49,7 @@ void gps_loop(void *pvParameters) { while (1) { - if (cfg.gpsmode) { + if (cfg.payloadmask && GPS_DATA) { #if defined GPS_SERIAL // feed GPS decoder with serial NMEA data from GPS device while (GPS_Serial.available()) { @@ -62,7 +62,7 @@ void gps_loop(void *pvParameters) { vTaskDelay(2 / portTICK_PERIOD_MS); // 2ms delay according L76 datasheet } #endif - } // if (cfg.gpsmode) + } // if vTaskDelay(2 / portTICK_PERIOD_MS); // yield to CPU diff --git a/src/payload.cpp b/src/payload.cpp index 5bb0339d..d6d405fb 100644 --- a/src/payload.cpp +++ b/src/payload.cpp @@ -47,7 +47,7 @@ void PayloadConvert::addConfig(configData_t value) { buffer[cursor++] = value.wifiant; buffer[cursor++] = value.vendorfilter; buffer[cursor++] = value.rgblum; - buffer[cursor++] = value.gpsmode; + buffer[cursor++] = value.payloadmask; buffer[cursor++] = value.monitormode; memcpy(buffer + cursor, value.version, 10); cursor += 10; @@ -142,7 +142,16 @@ void PayloadConvert::addConfig(configData_t value) { writeBitmap(value.adrmode ? true : false, value.screensaver ? true : false, value.screenon ? true : false, value.countermode ? true : false, value.blescan ? true : false, value.wifiant ? true : false, - value.vendorfilter ? true : false, value.gpsmode ? true : false); + value.vendorfilter ? true : false, + value.monitormode ? true : false); + writeBitmap(value.payloadmask && GPS_DATA ? true : false, + value.payloadmask && ALARM_DATA ? true : false, + value.payloadmask && MEMS_DATA ? true : false, + value.payloadmask && COUNT_DATA ? true : false, + value.payloadmask && SENSOR1_DATA ? true : false, + value.payloadmask && SENSOR2_DATA ? true : false, + value.payloadmask && SENSOR3_DATA ? true : false, + value.payloadmask && SENSOR4_DATA ? true : false); writeVersion(value.version); } diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 2c2dffc4..3918af5f 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -127,7 +127,11 @@ void set_display(uint8_t val[]) { void set_gps(uint8_t val[]) { ESP_LOGI(TAG, "Remote command: set GPS mode to %s", val[0] ? "on" : "off"); - cfg.gpsmode = val[0] ? 1 : 0; + if (val[0]) { + cfg.payloadmask |= (uint8_t)GPS_DATA; // set bit in mask + } else { + cfg.payloadmask &= ~(uint8_t)GPS_DATA; // clear bit in mask + } } void set_beacon(uint8_t val[]) { diff --git a/src/senddata.cpp b/src/senddata.cpp index b9bc467d..2331dbf4 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -21,43 +21,57 @@ void SendPayload(uint8_t port) { // interrupt triggered function to prepare payload to send void sendCounter() { - // append counter data to payload - payload.reset(); - payload.addCount(macs_wifi, cfg.blescan ? macs_ble : 0); - // append GPS data, if present + uint8_t bitmask = cfg.payloadmask; + uint8_t mask = 1; - // clear counter if not in cumulative counter mode - if (cfg.countermode != 1) { - reset_counters(); // clear macs container and reset all counters - get_salt(); // get new salt for salting hashes - ESP_LOGI(TAG, "Counter cleared"); - } + while (bitmask) { -#ifdef HAS_GPS - // show NMEA data in debug mode, useful for debugging GPS on board - // connection - ESP_LOGD(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d", - gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix()); - // log GPS position if we have a fix and gps data mode is enabled - if ((cfg.gpsmode) && (gps.location.isValid())) { - gps_read(); - payload.addGPS(gps_status); - ESP_LOGD(TAG, "lat=%.6f | lon=%.6f | %u Sats | HDOP=%.1f | Altitude=%um", - gps_status.latitude / (float)1e6, - gps_status.longitude / (float)1e6, gps_status.satellites, - gps_status.hdop / (float)100, gps_status.altitude); - } else { - ESP_LOGD(TAG, "No valid GPS position or GPS data mode disabled"); - } -#endif - SendPayload(COUNTERPORT); + payload.reset(); + switch (bitmask & mask) { -// if we have MEMS sensor, send sensor data in separate frame + case COUNT_DATA: + payload.addCount(macs_wifi, cfg.blescan ? macs_ble : 0); + SendPayload(COUNTERPORT); + // clear counter if not in cumulative counter mode + if (cfg.countermode != 1) { + reset_counters(); // clear macs container and reset all counters + get_salt(); // get new salt for salting hashes + ESP_LOGI(TAG, "Counter cleared"); + } + break; + + case MEMS_DATA: #ifdef HAS_BME - payload.reset(); - payload.addBME(bme_status); - SendPayload(BMEPORT); + payload.addBME(bme_status); + SendPayload(BMEPORT); #endif + break; + + case GPS_DATA: +#ifdef HAS_GPS + // show NMEA data in debug mode, useful for debugging GPS + ESP_LOGD(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d", + gps.passedChecksum(), gps.failedChecksum(), + gps.sentencesWithFix()); + // send GPS position only if we have a fix + if (gps.location.isValid()) { + ESP_LOGD(TAG, + "lat=%.6f | lon=%.6f | %u Sats | HDOP=%.1f | Altitude=%um", + gps_status.latitude / (float)1e6, + gps_status.longitude / (float)1e6, gps_status.satellites, + gps_status.hdop / (float)100, gps_status.altitude); + gps_read(); + payload.addGPS(gps_status); + SendPayload(GPSPORT); + } else + ESP_LOGD(TAG, "No valid GPS position"); +#endif + break; + + } // switch + bitmask &= ~mask; + mask <<= 1; + } // while (bitmask) } // sendCounter()