Merge pull request #94 from cyberman54/development

v1.3.81
This commit is contained in:
Verkehrsrot 2018-06-12 12:44:47 +02:00 committed by GitHub
commit e60f8b03b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 887 additions and 699 deletions

108
.clang-format Normal file
View File

@ -0,0 +1,108 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...

View File

@ -264,41 +264,42 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts.
0x80 get device configuration 0x80 get device configuration
device answers with it's current configuration. The configuration is a C structure declared in file [globals.h](src/globals.h#L27-L44) with the following definition: device answers with it's current configuration. The configuration is a C structure declared in file [globals.h](src/globals.h#L32-L50) with the following definition:
byte 1: Lora SF (7..12) byte 1: Lora SF (7..12) [default 9]
byte 2: Lora TXpower (2..15) byte 2: Lora TXpower (2..15) [default 15]
byte 3: Lora ADR (1=on, 0=off) byte 3: Lora ADR (1=on, 0=off) [default 1]
byte 4: Screensaver status (1=on, 0=off) byte 4: Screensaver status (1=on, 0=off) [default 0]
byte 5: Display status (1=on, 0=off) byte 5: Display status (1=on, 0=off) [default 0]
byte 6: Counter mode (0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed) byte 6: Counter mode (0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed) [default 0]
bytes 7-8: RSSI limiter threshold value (negative) bytes 7-8: RSSI limiter threshold value (negative) [default 0]
byte 9: Lora Payload send cycle in seconds/2 (0..255) byte 9: Lora Payload send cycle in seconds/2 (0..255) [default 120]
byte 10: Wifi channel switch interval in seconds/100 (0..255) byte 10: Wifi channel switch interval in seconds/100 (0..255) [default 50]
byte 11: Bluetooth channel switch interval in seconds/100 (0..255) byte 11: Bluetooth channel switch interval in seconds/100 (0..255) [efault 10]
byte 12: Bluetooth scanner status (1=on, 0=0ff) byte 12: Bluetooth scanner status (1=on, 0=0ff) [default 1]
byte 13: Wifi antenna switch (0=internal, 1=external) byte 13: Wifi antenna switch (0=internal, 1=external) [default 0]
byte 14: Vendorfilter mode (0=disabled, 1=enabled) byte 14: Vendorfilter mode (0=disabled, 1=enabled) [default 0]
byte 15: RGB LED luminosity (0..100 %) byte 15: RGB LED luminosity (0..100 %) [default 30]
bytes 16-26: Software version (ASCII format, terminating with zero) byte 16: GPS send data mode (1=on, 0=ff) [default 1]
bytes 17-27: Software version (ASCII format, terminating with zero)
0x81 get device uptime 0x81 get device uptime
bytes 1-8: uptime in seconds (little endian format) bytes 1-8: Uptime in seconds (little endian format)
0x82 get device cpu temperature 0x82 get device cpu temperature
bytes 1-4: chip temperature in degrees celsius (little endian format) bytes 1-4: Chip temperature in degrees celsius (little endian format)
0x83 get device battery voltage 0x83 get device battery voltage
bytes 1-2: battery voltage in millivolt, 0 if unreadable (little endian format) bytes 1-2: Battery voltage in millivolt, 0 if unreadable (little endian format)
0x84 get device GPS status 0x84 get device GPS status
bytes 1-4: latitude bytes 1-4: Latitude
bytes 5-8: longitude bytes 5-8: Longitude
byte 9-10: number of satellites byte 9-10: Number of satellites
byte 11-12: HDOP byte 11-12: HDOP
bytes 13-14: altidute [meter] bytes 13-14: altidute [meter]

View File

@ -11,11 +11,11 @@
; ---> SELECT TARGET PLATFORM HERE! <--- ; ---> SELECT TARGET PLATFORM HERE! <---
[platformio] [platformio]
env_default = heltec ;env_default = heltec
;env_default = ttgov1 ;env_default = ttgov1
;env_default = ttgov2 ;env_default = ttgov2
;env_default = ttgov21 ;env_default = ttgov21
;env_default = ttgobeam env_default = ttgobeam
;env_default = lopy ;env_default = lopy
;env_default = lopy4 ;env_default = lopy4
;env_default = fipy ;env_default = fipy

View File

@ -18,5 +18,7 @@
// non arduino pin definitions // non arduino pin definitions
#define RST LMIC_UNUSED_PIN // connected to ESP32 RST/EN #define RST LMIC_UNUSED_PIN // connected to ESP32 RST/EN
#define DIO0 GPIO_NUM_26 // ESP32 GPIO26 <-> HPD13A IO0 #define DIO0 GPIO_NUM_26 // ESP32 GPIO26 <-> HPD13A IO0
#define DIO1 GPIO_NUM_33 // Lora1 <-> HPD13A IO1 // !! NEEDS EXTERNAL WIRING !! #define DIO1 GPIO_NUM_32 // Lora1 <-> HPD13A IO1 // !! NEEDS EXTERNAL WIRING !!
#define DIO2 LMIC_UNUSED_PIN // Lora2 <-> HPD13A IO2 // needs external wiring, but not necessary for LoRa, only FSK #define DIO2 \
LMIC_UNUSED_PIN // Lora2 <-> HPD13A IO2 // needs external wiring, but not
// necessary for LoRa, only FSK

View File

@ -105,13 +105,16 @@ void printKeys(void) {
#endif // VERBOSE #endif // VERBOSE
void do_send(osjob_t* j){ void do_send(osjob_t *j) {
// Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(cfg.sendcycle * 2),
do_send);
// Check if there is a pending TX/RX job running // Check if there is a pending TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) { if (LMIC.opmode & OP_TXRXPEND) {
ESP_LOGI(TAG, "LoRa busy, rescheduling"); ESP_LOGI(TAG, "LoRa busy, rescheduling");
sprintf(display_lmic, "LORA BUSY"); sprintf(display_lmic, "LORA BUSY");
goto end; return;
} }
// prepare payload with sum of unique WIFI MACs seen // prepare payload with sum of unique WIFI MACs seen
@ -129,6 +132,29 @@ void do_send(osjob_t* j){
mydata[3] = 0; mydata[3] = 0;
} }
#ifdef HAS_GPS
static uint8_t gpsdata[18];
if (cfg.gpsmode && gps.location.isValid()) {
gps_read();
memcpy(gpsdata, mydata, 4);
memcpy(gpsdata + 4, &gps_status, sizeof(gps_status));
ESP_LOGI(TAG, "lat=%.6f / lon=%.6f | %u Sats | HDOP=%.1f | Altitude=%u m",
gps_status.latitude / (float)1000000,
gps_status.longitude / (float)1000000, gps_status.satellites,
gps_status.hdop / (float)100, gps_status.altitude);
LMIC_setTxData2(COUNTERPORT, gpsdata, sizeof(gpsdata),
(cfg.countermode & 0x02));
ESP_LOGI(TAG, "%d bytes queued to send", sizeof(gpsdata));
} else {
#endif
LMIC_setTxData2(COUNTERPORT, mydata, sizeof(mydata),
(cfg.countermode & 0x02));
ESP_LOGI(TAG, "%d bytes queued to send", sizeof(mydata));
#ifdef HAS_GPS
}
#endif
sprintf(display_lmic, "PACKET QUEUED");
#ifdef HAS_GPS #ifdef HAS_GPS
static uint8_t gpsdata[18]; static uint8_t gpsdata[18];
if (cfg.gpsmode && gps.location.isValid()) { if (cfg.gpsmode && gps.location.isValid()) {
@ -161,10 +187,6 @@ void do_send(osjob_t* j){
ESP_LOGI(TAG, "Counter cleared (countermode = %d)", cfg.countermode); ESP_LOGI(TAG, "Counter cleared (countermode = %d)", cfg.countermode);
} }
// Schedule next transmission
end:
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(cfg.sendcycle * 2), do_send);
} // do_send() } // do_send()
void onEvent (ev_t ev) { void onEvent (ev_t ev) {

View File

@ -1,5 +1,7 @@
/* /*
Copyright 2018 Oliver Brandmueller <ob@sysadm.in> Copyright 2018 Oliver Brandmueller <ob@sysadm.in>
Copyright 2018 Klaus Wilting <verkehrsrot@arcor.de> Copyright 2018 Klaus Wilting <verkehrsrot@arcor.de>
@ -16,8 +18,8 @@ Copyright 2018 Klaus Wilting <verkehrsrot@arcor.de>
limitations under the License. limitations under the License.
NOTICE: NOTICE:
Parts of the source files in this repository are made available under different licenses. Parts of the source files in this repository are made available under different
Refer to LICENSE.txt file in repository for more details. licenses. Refer to LICENSE.txt file in repository for more details.
*/ */
@ -29,50 +31,58 @@ Refer to LICENSE.txt file in repository for more details.
// LMIC-Arduino LoRaWAN Stack // LMIC-Arduino LoRaWAN Stack
#include "loraconf.h" #include "loraconf.h"
#include <lmic.h>
#include <hal/hal.h> #include <hal/hal.h>
#include <lmic.h>
// ESP32 lib Functions // ESP32 lib Functions
#include <esp32-hal-log.h> // needed for ESP_LOGx on arduino framework
#include <esp_event_loop.h> // needed for Wifi event handler #include <esp_event_loop.h> // needed for Wifi event handler
#include <esp_spi_flash.h> // needed for reading ESP32 chip attributes #include <esp_spi_flash.h> // needed for reading ESP32 chip attributes
#include <esp32-hal-log.h> // needed for ESP_LOGx on arduino framework
// Initialize global variables // Initialize global variables
configData_t cfg; // struct holds current device configuration configData_t cfg; // struct holds current device configuration
osjob_t sendjob, rcmdjob; // LMIC job handler osjob_t sendjob, rcmdjob; // LMIC job handler
uint64_t uptimecounter = 0; // timer global for uptime counter uint64_t uptimecounter = 0; // timer global for uptime counter
uint8_t DisplayState = 0; // globals for state machine uint8_t DisplayState = 0; // globals for state machine
uint16_t macs_total = 0, macs_wifi = 0, macs_ble = 0; // MAC counters globals for display uint16_t macs_total = 0, macs_wifi = 0,
macs_ble = 0; // MAC counters globals for display
uint8_t channel = 0; // wifi channel rotation counter global for display uint8_t channel = 0; // wifi channel rotation counter global for display
char display_lora[16], display_lmic[16]; // display buffers char display_lora[16], display_lmic[16]; // display buffers
led_states LEDState = LED_OFF; // LED state global for state machine led_states LEDState = LED_OFF; // LED state global for state machine
led_states previousLEDState = LED_ON; // This will force LED to be off at boot since State is OFF led_states previousLEDState =
LED_ON; // This will force LED to be off at boot since State is OFF
unsigned long LEDBlinkStarted = 0; // When (in millis() led blink started) unsigned long LEDBlinkStarted = 0; // When (in millis() led blink started)
uint16_t LEDBlinkDuration = 0; // How long the blink need to be uint16_t LEDBlinkDuration = 0; // How long the blink need to be
uint16_t LEDColor = COLOR_NONE; // state machine variable to set RGB LED color uint16_t LEDColor = COLOR_NONE; // state machine variable to set RGB LED color
hw_timer_t * displaytimer = NULL; // configure hardware timer used for cyclic display refresh hw_timer_t *displaytimer =
hw_timer_t * channelSwitch = NULL; // configure hardware timer used for wifi channel switching NULL; // configure hardware timer used for cyclic display refresh
hw_timer_t *channelSwitch =
NULL; // configure hardware timer used for wifi channel switching
xref2u1_t rcmd_data; // buffer for rcommand results size xref2u1_t rcmd_data; // buffer for rcommand results size
u1_t rcmd_data_size; // buffer for rcommand results size u1_t rcmd_data_size; // buffer for rcommand results size
#ifdef HAS_GPS #ifdef HAS_GPS
gpsStatus_t gps_status; // struct for storing gps data gpsStatus_t gps_status; // struct for storing gps data
TinyGPSPlus gps; // create TinyGPS++ instance TinyGPSPlus gps; // create TinyGPS++ instance
#endif #endif
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying IRQ handler shared variables portMUX_TYPE timerMux =
portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying IRQ
// handler shared variables
std::set<uint16_t> macs; // associative container holds total of unique MAC adress hashes (Wifi + BLE) std::set<uint16_t> macs; // associative container holds total of unique MAC
// adress hashes (Wifi + BLE)
// this variables will be changed in the ISR, and read in main loop // this variables will be changed in the ISR, and read in main loop
static volatile int ButtonPressedIRQ = 0, DisplayTimerIRQ = 0, ChannelTimerIRQ = 0; static volatile int ButtonPressedIRQ = 0, DisplayTimerIRQ = 0,
ChannelTimerIRQ = 0;
// local Tag for logging // local Tag for logging
static const char TAG[] = "main"; static const char TAG[] = "main";
#ifndef VERBOSE #ifndef VERBOSE
int redirect_log(const char * fmt, va_list args) { int redirect_log(const char *fmt, va_list args) {
//do nothing // do nothing
return 0; return 0;
} }
#endif #endif
@ -84,27 +94,25 @@ void reset_counters() {
macs_ble = 0; macs_ble = 0;
} }
/* begin LMIC specific parts ------------------------------------------------------------ */ /* begin LMIC specific parts
* ------------------------------------------------------------ */
#ifdef VERBOSE #ifdef VERBOSE
void printKeys(void); void printKeys(void);
#endif // VERBOSE #endif // VERBOSE
// LMIC callback functions // LMIC callback functions
void os_getDevKey (u1_t *buf) { void os_getDevKey(u1_t *buf) { memcpy(buf, APPKEY, 16); }
memcpy(buf, APPKEY, 16);
}
void os_getArtEui (u1_t *buf) { void os_getArtEui(u1_t *buf) {
memcpy(buf, APPEUI, 8); memcpy(buf, APPEUI, 8);
RevBytes(buf, 8); // TTN requires it in LSB First order, so we swap bytes RevBytes(buf, 8); // TTN requires it in LSB First order, so we swap bytes
} }
void os_getDevEui (u1_t* buf) { void os_getDevEui(u1_t *buf) {
int i=0, k=0; int i = 0, k = 0;
memcpy(buf, DEVEUI, 8); // get fixed DEVEUI from loraconf.h memcpy(buf, DEVEUI, 8); // get fixed DEVEUI from loraconf.h
for (i=0; i<8 ; i++) { for (i = 0; i < 8; i++) {
k += buf[i]; k += buf[i];
} }
if (k) { if (k) {
@ -113,65 +121,63 @@ void os_getDevEui (u1_t* buf) {
gen_lora_deveui(buf); // generate DEVEUI from device's MAC gen_lora_deveui(buf); // generate DEVEUI from device's MAC
} }
// Get MCP 24AA02E64 hardware DEVEUI (override default settings if found) // Get MCP 24AA02E64 hardware DEVEUI (override default settings if found)
#ifdef MCP_24AA02E64_I2C_ADDRESS #ifdef MCP_24AA02E64_I2C_ADDRESS
get_hard_deveui(buf); get_hard_deveui(buf);
RevBytes(buf, 8); // swap bytes to LSB format RevBytes(buf, 8); // swap bytes to LSB format
#endif #endif
} }
// LMIC enhanced Pin mapping // LMIC enhanced Pin mapping
const lmic_pinmap lmic_pins = { const lmic_pinmap lmic_pins = {.mosi = PIN_SPI_MOSI,
.mosi = PIN_SPI_MOSI,
.miso = PIN_SPI_MISO, .miso = PIN_SPI_MISO,
.sck = PIN_SPI_SCK, .sck = PIN_SPI_SCK,
.nss = PIN_SPI_SS, .nss = PIN_SPI_SS,
.rxtx = LMIC_UNUSED_PIN, .rxtx = LMIC_UNUSED_PIN,
.rst = RST, .rst = RST,
.dio = {DIO0, DIO1, DIO2} .dio = {DIO0, DIO1, DIO2}};
};
// LMIC FreeRTos Task // LMIC FreeRTos Task
void lorawan_loop(void * pvParameters) { void lorawan_loop(void *pvParameters) {
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
while(1) { while (1) {
os_runloop_once(); // execute LMIC jobs os_runloop_once(); // execute LMIC jobs
vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog vTaskDelay(1 / portTICK_PERIOD_MS); // reset watchdog
} }
} }
/* end LMIC specific parts --------------------------------------------------------------- */ /* end LMIC specific parts
* --------------------------------------------------------------- */
/* beginn hardware specific parts -------------------------------------------------------- */ /* beginn hardware specific parts
* -------------------------------------------------------- */
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
HAS_DISPLAY u8x8(OLED_RST, OLED_SCL, OLED_SDA); HAS_DISPLAY u8x8(OLED_RST, OLED_SCL, OLED_SDA);
// Display Refresh IRQ // Display Refresh IRQ
void IRAM_ATTR DisplayIRQ() { void IRAM_ATTR DisplayIRQ() {
portENTER_CRITICAL_ISR(&timerMux); portENTER_CRITICAL_ISR(&timerMux);
DisplayTimerIRQ++; DisplayTimerIRQ++;
portEXIT_CRITICAL_ISR(&timerMux); portEXIT_CRITICAL_ISR(&timerMux);
} }
#endif #endif
#ifdef HAS_ANTENNA_SWITCH #ifdef HAS_ANTENNA_SWITCH
// defined in antenna.cpp // defined in antenna.cpp
void antenna_init(); void antenna_init();
void antenna_select(const uint8_t _ant); void antenna_select(const uint8_t _ant);
#endif #endif
#ifndef BLECOUNTER #ifndef BLECOUNTER
bool btstop = btStop(); bool btstop = btStop();
#endif #endif
// Button IRQ Handler Routine, IRAM_ATTR necessary here, see https://github.com/espressif/arduino-esp32/issues/855 // Button IRQ Handler Routine, IRAM_ATTR necessary here, see
// https://github.com/espressif/arduino-esp32/issues/855
#ifdef HAS_BUTTON #ifdef HAS_BUTTON
void IRAM_ATTR ButtonIRQ() { void IRAM_ATTR ButtonIRQ() { ButtonPressedIRQ++; }
ButtonPressedIRQ++;
}
#endif #endif
// Wifi Channel Rotation Timer IRQ Handler Routine // Wifi Channel Rotation Timer IRQ Handler Routine
@ -181,15 +187,16 @@ void IRAM_ATTR ChannelSwitchIRQ() {
portEXIT_CRITICAL(&timerMux); portEXIT_CRITICAL(&timerMux);
} }
/* end hardware specific parts -------------------------------------------------------- */ /* end hardware specific parts
* -------------------------------------------------------- */
/* begin wifi specific parts
/* begin wifi specific parts ---------------------------------------------------------- */ * ---------------------------------------------------------- */
// Sniffer Task // Sniffer Task
void sniffer_loop(void * pvParameters) { void sniffer_loop(void *pvParameters) {
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
while (1) { while (1) {
@ -202,36 +209,38 @@ void sniffer_loop(void * pvParameters) {
wifi_sniffer_set_channel(channel); wifi_sniffer_set_channel(channel);
ESP_LOGD(TAG, "Wifi set channel %d", channel); ESP_LOGD(TAG, "Wifi set channel %d", channel);
vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog vTaskDelay(1 / portTICK_PERIOD_MS); // reset watchdog
} }
} // end of infinite wifi channel rotation loop } // end of infinite wifi channel rotation loop
} }
/* end wifi specific parts ------------------------------------------------------------ */ /* end wifi specific parts
* ------------------------------------------------------------ */
// uptime counter 64bit to prevent millis() rollover after 49 days // uptime counter 64bit to prevent millis() rollover after 49 days
uint64_t uptime() { uint64_t uptime() {
static uint32_t low32, high32; static uint32_t low32, high32;
uint32_t new_low32 = millis(); uint32_t new_low32 = millis();
if (new_low32 < low32) high32++; if (new_low32 < low32)
high32++;
low32 = new_low32; low32 = new_low32;
return (uint64_t) high32 << 32 | low32; return (uint64_t)high32 << 32 | low32;
} }
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
// Print a key on display // Print a key on display
void DisplayKey(const uint8_t * key, uint8_t len, bool lsb) { void DisplayKey(const uint8_t *key, uint8_t len, bool lsb) {
const uint8_t * p ; const uint8_t *p;
for (uint8_t i=0; i<len ; i++) { for (uint8_t i = 0; i < len; i++) {
p = lsb ? key+len-i-1 : key+i; p = lsb ? key + len - i - 1 : key + i;
u8x8.printf("%02X", *p); u8x8.printf("%02X", *p);
} }
u8x8.printf("\n"); u8x8.printf("\n");
} }
void init_display(const char *Productname, const char *Version) { void init_display(const char *Productname, const char *Version) {
uint8_t buf[32]; uint8_t buf[32];
u8x8.begin(); u8x8.begin();
u8x8.setFont(u8x8_font_chroma48medium8_r); u8x8.setFont(u8x8_font_chroma48medium8_r);
@ -253,78 +262,92 @@ uint64_t uptime() {
u8x8.setFlipMode(0); u8x8.setFlipMode(0);
u8x8.clear(); u8x8.clear();
#ifdef DISPLAY_FLIP #ifdef DISPLAY_FLIP
u8x8.setFlipMode(1); u8x8.setFlipMode(1);
#endif #endif
// Display chip information // Display chip information
#ifdef VERBOSE #ifdef VERBOSE
esp_chip_info_t chip_info; esp_chip_info_t chip_info;
esp_chip_info(&chip_info); esp_chip_info(&chip_info);
u8x8.printf("ESP32 %d cores\nWiFi%s%s\n", u8x8.printf("ESP32 %d cores\nWiFi%s%s\n", chip_info.cores,
chip_info.cores,
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
u8x8.printf("ESP Rev.%d\n", chip_info.revision); u8x8.printf("ESP Rev.%d\n", chip_info.revision);
u8x8.printf("%dMB %s Flash\n", spi_flash_get_chip_size() / (1024 * 1024), u8x8.printf("%dMB %s Flash\n", spi_flash_get_chip_size() / (1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int." : "ext."); (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int." : "ext.");
#endif // VERBOSE #endif // VERBOSE
u8x8.print(Productname); u8x8.print(Productname);
u8x8.print(" v"); u8x8.print(" v");
u8x8.println(PROGVERSION); u8x8.println(PROGVERSION);
u8x8.println("DEVEUI:"); u8x8.println("DEVEUI:");
os_getDevEui((u1_t*) buf); os_getDevEui((u1_t *)buf);
DisplayKey(buf, 8, true); DisplayKey(buf, 8, true);
delay(5000); delay(5000);
u8x8.clear(); u8x8.clear();
} }
void refreshDisplay() { void refreshDisplay() {
// update counter display (lines 0-4) // update counter (lines 0-1)
char buff[16]; char buff[16];
snprintf(buff, sizeof(buff), "PAX:%-4d", (int) macs.size()); // convert 16-bit MAC counter to decimal counter value snprintf(
u8x8.draw2x2String(0, 0, buff); // display number on unique macs total Wifi + BLE buff, sizeof(buff), "PAX:%-4d",
u8x8.setCursor(0,4); (int)macs.size()); // convert 16-bit MAC counter to decimal counter value
u8x8.printf("WIFI:%-4d", macs_wifi); u8x8.draw2x2String(0, 0,
buff); // display number on unique macs total Wifi + BLE
#ifdef BLECOUNTER // update GPS status (line 2)
u8x8.setCursor(0,3); #ifdef HAS_GPS
u8x8.setCursor(7, 2);
if (!gps.location.isValid()) // if no fix then display Sats value inverse
{
u8x8.setInverseFont(1);
u8x8.printf("Sats: %.3d", gps.satellites.value());
u8x8.setInverseFont(0);
} else
u8x8.printf("Sats: %.3d", gps.satellites.value());
#endif
// update bluetooth counter + LoRa SF (line 3)
#ifdef BLECOUNTER
u8x8.setCursor(0, 3);
if (cfg.blescan) if (cfg.blescan)
u8x8.printf("BLTH:%-4d", macs_ble); u8x8.printf("BLTH:%-4d", macs_ble);
else else
u8x8.printf("%s", "BLTH:off"); u8x8.printf("%s", "BLTH:off");
#endif #endif
u8x8.setCursor(11, 3);
// update LoRa SF display (line 3)
u8x8.setCursor(11,3);
u8x8.printf("SF:"); u8x8.printf("SF:");
if (cfg.adrmode) // if ADR=on then display SF value inverse if (cfg.adrmode) // if ADR=on then display SF value inverse
u8x8.setInverseFont(1); u8x8.setInverseFont(1);
u8x8.printf("%c%c", lora_datarate[LMIC.datarate * 2], lora_datarate[LMIC.datarate * 2 + 1]); u8x8.printf("%c%c", lora_datarate[LMIC.datarate * 2],
lora_datarate[LMIC.datarate * 2 + 1]);
if (cfg.adrmode) // switch off inverse if it was turned on if (cfg.adrmode) // switch off inverse if it was turned on
u8x8.setInverseFont(0); u8x8.setInverseFont(0);
// update wifi channel display (line 4) // update wifi counter + channel display (line 4)
u8x8.setCursor(11,4); u8x8.setCursor(0, 4);
u8x8.printf("WIFI:%-4d", macs_wifi);
u8x8.setCursor(11, 4);
u8x8.printf("ch:%02d", channel); u8x8.printf("ch:%02d", channel);
// update RSSI limiter status & free memory display (line 5) // update RSSI limiter status & free memory display (line 5)
u8x8.setCursor(0,5); u8x8.setCursor(0, 5);
u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d", cfg.rssilimit); u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d", cfg.rssilimit);
u8x8.setCursor(10,5); u8x8.setCursor(10, 5);
u8x8.printf("%4dKB", ESP.getFreeHeap() / 1024); u8x8.printf("%4dKB", ESP.getFreeHeap() / 1024);
// update LoRa status display (line 6) // update LoRa status display (line 6)
u8x8.setCursor(0,6); u8x8.setCursor(0, 6);
u8x8.printf("%-16s", display_lora); u8x8.printf("%-16s", display_lora);
// update LMiC event display (line 7) // update LMiC event display (line 7)
u8x8.setCursor(0,7); u8x8.setCursor(0, 7);
u8x8.printf("%-16s", display_lmic); u8x8.printf("%-16s", display_lmic);
} }
void updateDisplay() { void updateDisplay() {
// refresh display according to refresh cycle setting // refresh display according to refresh cycle setting
if (DisplayTimerIRQ) { if (DisplayTimerIRQ) {
portENTER_CRITICAL(&timerMux); portENTER_CRITICAL(&timerMux);
@ -339,11 +362,11 @@ uint64_t uptime() {
u8x8.setPowerSave(!cfg.screenon); u8x8.setPowerSave(!cfg.screenon);
} }
} }
} // updateDisplay() } // updateDisplay()
#endif // HAS_DISPLAY #endif // HAS_DISPLAY
#ifdef HAS_BUTTON #ifdef HAS_BUTTON
void readButton() { void readButton() {
if (ButtonPressedIRQ) { if (ButtonPressedIRQ) {
portENTER_CRITICAL(&timerMux); portENTER_CRITICAL(&timerMux);
ButtonPressedIRQ--; ButtonPressedIRQ--;
@ -353,31 +376,31 @@ uint64_t uptime() {
eraseConfig(); eraseConfig();
esp_restart(); esp_restart();
} }
} }
#endif #endif
#if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED) #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
void blink_LED(uint16_t set_color, uint16_t set_blinkduration) { void blink_LED(uint16_t set_color, uint16_t set_blinkduration) {
LEDColor = set_color; // set color for RGB LED LEDColor = set_color; // set color for RGB LED
LEDBlinkDuration = set_blinkduration; // duration LEDBlinkDuration = set_blinkduration; // duration
LEDBlinkStarted = millis(); // Time Start here LEDBlinkStarted = millis(); // Time Start here
LEDState = LED_ON; // Let main set LED on LEDState = LED_ON; // Let main set LED on
} }
void led_loop() { void led_loop() {
// Custom blink running always have priority other LoRaWAN led management // Custom blink running always have priority other LoRaWAN led management
if ( LEDBlinkStarted && LEDBlinkDuration) { if (LEDBlinkStarted && LEDBlinkDuration) {
//ESP_LOGI(TAG, "Start=%ld for %g",LEDBlinkStarted, LEDBlinkDuration ); // ESP_LOGI(TAG, "Start=%ld for %g",LEDBlinkStarted, LEDBlinkDuration );
// Custom blink is finished, let this order, avoid millis() overflow // Custom blink is finished, let this order, avoid millis() overflow
if ( (millis() - LEDBlinkStarted) >= LEDBlinkDuration) { if ((millis() - LEDBlinkStarted) >= LEDBlinkDuration) {
// Led becomes off, and stop blink // Led becomes off, and stop blink
LEDState = LED_OFF; LEDState = LED_OFF;
LEDBlinkStarted = 0; LEDBlinkStarted = 0;
LEDBlinkDuration = 0; LEDBlinkDuration = 0;
LEDColor = COLOR_NONE ; LEDColor = COLOR_NONE;
} else { } else {
// In case of LoRaWAN led management blinked off // In case of LoRaWAN led management blinked off
LEDState = LED_ON; LEDState = LED_ON;
@ -387,7 +410,7 @@ uint64_t uptime() {
} else { } else {
// LED indicators for viusalizing LoRaWAN state // LED indicators for viusalizing LoRaWAN state
if ( LMIC.opmode & (OP_JOINING | OP_REJOIN) ) { if (LMIC.opmode & (OP_JOINING | OP_REJOIN)) {
LEDColor = COLOR_YELLOW; LEDColor = COLOR_YELLOW;
// quick blink 20ms on each 1/5 second // quick blink 20ms on each 1/5 second
LEDState = ((millis() % 200) < 20) ? LED_ON : LED_OFF; // TX data pending LEDState = ((millis() % 200) < 20) ? LED_ON : LED_OFF; // TX data pending
@ -396,7 +419,8 @@ uint64_t uptime() {
// small blink 10ms on each 1/2sec (not when joining) // small blink 10ms on each 1/2sec (not when joining)
LEDState = ((millis() % 500) < 20) ? LED_ON : LED_OFF; LEDState = ((millis() % 500) < 20) ? LED_ON : LED_OFF;
// This should not happen so indicate a problem // This should not happen so indicate a problem
} else if ( LMIC.opmode & ((OP_TXDATA | OP_TXRXPEND | OP_JOINING | OP_REJOIN) == 0 ) ) { } else if (LMIC.opmode &
((OP_TXDATA | OP_TXRXPEND | OP_JOINING | OP_REJOIN) == 0)) {
LEDColor = COLOR_RED; LEDColor = COLOR_RED;
// heartbeat long blink 200ms on each 2 seconds // heartbeat long blink 200ms on each 2 seconds
LEDState = ((millis() % 2000) < 200) ? LED_ON : LED_OFF; LEDState = ((millis() % 2000) < 200) ? LED_ON : LED_OFF;
@ -407,31 +431,33 @@ uint64_t uptime() {
} }
} }
//ESP_LOGI(TAG, "state=%d previous=%d Color=%d",LEDState, previousLEDState, LEDColor ); // ESP_LOGI(TAG, "state=%d previous=%d Color=%d",LEDState, previousLEDState,
// LEDColor );
// led need to change state? avoid digitalWrite() for nothing // led need to change state? avoid digitalWrite() for nothing
if (LEDState != previousLEDState) { if (LEDState != previousLEDState) {
if (LEDState == LED_ON) { if (LEDState == LED_ON) {
rgb_set_color(LEDColor); rgb_set_color(LEDColor);
#ifdef LED_ACTIVE_LOW #ifdef LED_ACTIVE_LOW
digitalWrite(HAS_LED, LOW); digitalWrite(HAS_LED, LOW);
#else #else
digitalWrite(HAS_LED, HIGH); digitalWrite(HAS_LED, HIGH);
#endif #endif
} else { } else {
rgb_set_color(COLOR_NONE); rgb_set_color(COLOR_NONE);
#ifdef LED_ACTIVE_LOW #ifdef LED_ACTIVE_LOW
digitalWrite(HAS_LED, HIGH); digitalWrite(HAS_LED, HIGH);
#else #else
digitalWrite(HAS_LED, LOW); digitalWrite(HAS_LED, LOW);
#endif #endif
} }
previousLEDState = LEDState; previousLEDState = LEDState;
} }
}; // led_loop() }; // led_loop()
#endif #endif
/* begin Aruino SETUP ------------------------------------------------------------ */ /* begin Aruino SETUP
* ------------------------------------------------------------ */
void setup() { void setup() {
char features[64] = ""; char features[64] = "";
@ -439,7 +465,7 @@ void setup() {
// disable brownout detection // disable brownout detection
#ifdef DISABLE_BROWNOUT #ifdef DISABLE_BROWNOUT
// register with brownout is at address DR_REG_RTCCNTL_BASE + 0xd4 // register with brownout is at address DR_REG_RTCCNTL_BASE + 0xd4
(*((volatile uint32_t *)ETS_UNCACHED_ADDR((DR_REG_RTCCNTL_BASE+0xd4)))) = 0; (*((volatile uint32_t *)ETS_UNCACHED_ADDR((DR_REG_RTCCNTL_BASE + 0xd4)))) = 0;
#endif #endif
// setup debug output or silence device // setup debug output or silence device
@ -454,19 +480,22 @@ void setup() {
ESP_LOGI(TAG, "Starting %s %s", PROGNAME, PROGVERSION); ESP_LOGI(TAG, "Starting %s %s", PROGNAME, PROGVERSION);
// initialize system event handler for wifi task, needed for wifi_sniffer_init() // initialize system event handler for wifi task, needed for
// wifi_sniffer_init()
esp_event_loop_init(NULL, NULL); esp_event_loop_init(NULL, NULL);
// print chip information on startup if in verbose mode // print chip information on startup if in verbose mode
#ifdef VERBOSE #ifdef VERBOSE
esp_chip_info_t chip_info; esp_chip_info_t chip_info;
esp_chip_info(&chip_info); esp_chip_info(&chip_info);
ESP_LOGI(TAG, "This is ESP32 chip with %d CPU cores, WiFi%s%s, silicon revision %d, %dMB %s Flash", ESP_LOGI(TAG,
chip_info.cores, "This is ESP32 chip with %d CPU cores, WiFi%s%s, silicon revision "
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", "%d, %dMB %s Flash",
chip_info.cores, (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "", (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "",
chip_info.revision, spi_flash_get_chip_size() / (1024 * 1024), chip_info.revision, spi_flash_get_chip_size() / (1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded"
: "external");
ESP_LOGI(TAG, "ESP32 SDK: %s", ESP.getSdkVersion()); ESP_LOGI(TAG, "ESP32 SDK: %s", ESP.getSdkVersion());
#endif #endif
@ -491,17 +520,17 @@ void setup() {
// initialize button handling if needed // initialize button handling if needed
#ifdef HAS_BUTTON #ifdef HAS_BUTTON
strcat(features, " BTN_"); strcat(features, " BTN_");
#ifdef BUTTON_PULLUP #ifdef BUTTON_PULLUP
strcat(features, "PU"); strcat(features, "PU");
// install button interrupt (pullup mode) // install button interrupt (pullup mode)
pinMode(HAS_BUTTON, INPUT_PULLUP); pinMode(HAS_BUTTON, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, RISING); attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, RISING);
#else #else
strcat(features, "PD"); strcat(features, "PD");
// install button interrupt (pulldown mode) // install button interrupt (pulldown mode)
pinMode(HAS_BUTTON, INPUT_PULLDOWN); pinMode(HAS_BUTTON, INPUT_PULLDOWN);
attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, FALLING); attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, FALLING);
#endif #endif
#endif #endif
// initialize wifi antenna if needed // initialize wifi antenna if needed
@ -522,59 +551,69 @@ void setup() {
DisplayState = cfg.screenon; DisplayState = cfg.screenon;
u8x8.setPowerSave(!cfg.screenon); // set display off if disabled u8x8.setPowerSave(!cfg.screenon); // set display off if disabled
u8x8.draw2x2String(0, 0, "PAX:0"); u8x8.draw2x2String(0, 0, "PAX:0");
u8x8.setCursor(0,4); #ifdef BLECOUNTER
u8x8.printf("WIFI:0"); u8x8.setCursor(0, 3);
#ifdef BLECOUNTER
u8x8.setCursor(0,3);
u8x8.printf("BLTH:0"); u8x8.printf("BLTH:0");
#endif #endif
u8x8.setCursor(0,5); u8x8.setCursor(0, 4);
u8x8.printf("WIFI:0");
u8x8.setCursor(0, 5);
u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%d", cfg.rssilimit); u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%d", cfg.rssilimit);
sprintf(display_lora, "Join wait"); sprintf(display_lora, "Join wait");
// setup display refresh trigger IRQ using esp32 hardware timer 0 // setup display refresh trigger IRQ using esp32 hardware timer 0
// for explanation see https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/ // for explanation see
displaytimer = timerBegin(0, 80, true); // prescaler 80 -> divides 80 MHz CPU freq to 1 MHz, timer 0, count up // https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
timerAttachInterrupt(displaytimer, &DisplayIRQ, true); // interrupt handler DisplayIRQ, triggered by edge displaytimer = timerBegin(0, 80, true); // prescaler 80 -> divides 80 MHz CPU
timerAlarmWrite(displaytimer, DISPLAYREFRESH_MS * 1000, true); // reload interrupt after each trigger of display refresh cycle // freq to 1 MHz, timer 0, count up
timerAttachInterrupt(displaytimer, &DisplayIRQ,
true); // interrupt handler DisplayIRQ, triggered by edge
timerAlarmWrite(
displaytimer, DISPLAYREFRESH_MS * 1000,
true); // reload interrupt after each trigger of display refresh cycle
timerAlarmEnable(displaytimer); // enable display interrupt timerAlarmEnable(displaytimer); // enable display interrupt
#endif #endif
// setup channel rotation trigger IRQ using esp32 hardware timer 1 // setup channel rotation trigger IRQ using esp32 hardware timer 1
channelSwitch = timerBegin(1, 80, true); channelSwitch = timerBegin(1, 80, true);
timerAttachInterrupt(channelSwitch, &ChannelSwitchIRQ, true); timerAttachInterrupt(channelSwitch, &ChannelSwitchIRQ, true);
timerAlarmWrite(channelSwitch, cfg.wifichancycle * 10000, true); timerAlarmWrite(channelSwitch, cfg.wifichancycle * 10000, true);
timerAlarmEnable(channelSwitch); timerAlarmEnable(channelSwitch);
// show compiled features // show compiled features
ESP_LOGI(TAG, "Features %s", features); ESP_LOGI(TAG, "Features %s", features);
// output LoRaWAN keys to console // output LoRaWAN keys to console
#ifdef VERBOSE #ifdef VERBOSE
printKeys(); printKeys();
#endif #endif
// initialize LoRaWAN LMIC run-time environment // initialize LoRaWAN LMIC run-time environment
os_init(); os_init();
// reset LMIC MAC state // reset LMIC MAC state
LMIC_reset(); LMIC_reset();
// This tells LMIC to make the receive windows bigger, in case your clock is 1% faster or slower. // This tells LMIC to make the receive windows bigger, in case your clock is
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100); // 1% faster or slower.
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
// start lmic runloop in rtos task on core 1 (note: arduino main loop runs on core 1, too) // start lmic runloop in rtos task on core 1 (note: arduino main loop runs on
// https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/ // core 1, too)
// https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/
ESP_LOGI(TAG, "Starting Lora task on core 1"); ESP_LOGI(TAG, "Starting Lora task on core 1");
xTaskCreatePinnedToCore(lorawan_loop, "loratask", 2048, ( void * ) 1, ( 5 | portPRIVILEGE_BIT ), NULL, 1); xTaskCreatePinnedToCore(lorawan_loop, "loratask", 2048, (void *)1,
(5 | portPRIVILEGE_BIT), NULL, 1);
// start wifi in monitor mode and start channel rotation task on core 0 // start wifi in monitor mode and start channel rotation task on core 0
ESP_LOGI(TAG, "Starting Wifi task on core 0"); ESP_LOGI(TAG, "Starting Wifi task on core 0");
wifi_sniffer_init(); wifi_sniffer_init();
// initialize salt value using esp_random() called by random() in arduino-esp32 core // initialize salt value using esp_random() called by random() in
// note: do this *after* wifi has started, since function gets it's seed from RF noise // arduino-esp32 core note: do this *after* wifi has started, since function
reset_salt(); // get new 16bit for salting hashes // gets it's seed from RF noise
xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 2048, ( void * ) 1, 1, NULL, 0); reset_salt(); // get new 16bit for salting hashes
xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 2048, (void *)1, 1, NULL,
0);
// start BLE scan callback if BLE function is enabled in NVRAM configuration // start BLE scan callback if BLE function is enabled in NVRAM configuration
#ifdef BLECOUNTER #ifdef BLECOUNTER
@ -583,61 +622,70 @@ xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 2048, ( void * ) 1, 1, NULL
} }
#endif #endif
// if device has GPS and GPS function is enabled, start GPS reader task on core 0 // if device has GPS and GPS function is enabled, start GPS reader task on core
// 0
#ifdef HAS_GPS #ifdef HAS_GPS
if (cfg.gpsmode) { if (cfg.gpsmode) {
ESP_LOGI(TAG, "Starting GPS task on core 0"); ESP_LOGI(TAG, "Starting GPS task on core 0");
xTaskCreatePinnedToCore(gps_loop, "gpsfeed", 2048, ( void * ) 1, 1, NULL, 0); xTaskCreatePinnedToCore(gps_loop, "gpsfeed", 2048, (void *)1, 1, NULL, 0);
} }
#endif #endif
// kickoff sendjob -> joins network and rescedules sendjob for cyclic transmitting payload // kickoff sendjob -> joins network and rescedules sendjob for cyclic
do_send(&sendjob); // transmitting payload
do_send(&sendjob);
} }
/* end Arduino SETUP ------------------------------------------------------------ */ /* end Arduino SETUP
* ------------------------------------------------------------ */
/* begin Arduino main loop ------------------------------------------------------ */ /* begin Arduino main loop
* ------------------------------------------------------ */
void loop() { void loop() {
while (1) { while (1) {
// simple state machine for controlling uptime, display, LED, button, memory. // simple state machine for controlling uptime, display, LED, button,
// memory.
uptimecounter = uptime() / 1000; // counts uptime in seconds (64bit) uptimecounter = uptime() / 1000; // counts uptime in seconds (64bit)
#if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED) #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
led_loop(); led_loop();
#endif #endif
#ifdef HAS_BUTTON #ifdef HAS_BUTTON
readButton(); readButton();
#endif #endif
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
updateDisplay(); updateDisplay();
#endif #endif
// check free memory // check free memory
if (esp_get_minimum_free_heap_size() <= MEM_LOW) { if (esp_get_minimum_free_heap_size() <= MEM_LOW) {
ESP_LOGI(TAG, "Memory full, counter cleared (heap low water mark = %d Bytes / free heap = %d bytes)", \ ESP_LOGI(TAG,
"Memory full, counter cleared (heap low water mark = %d Bytes / "
"free heap = %d bytes)",
esp_get_minimum_free_heap_size(), ESP.getFreeHeap()); esp_get_minimum_free_heap_size(), ESP.getFreeHeap());
do_send(&sendjob); // send count do_send(&sendjob); // send count
reset_counters(); // clear macs container and reset all counters reset_counters(); // clear macs container and reset all counters
reset_salt(); // get new salt for salting hashes reset_salt(); // get new salt for salting hashes
} }
#ifdef HAS_GPS #ifdef HAS_GPS
// log NMEA status every 30 seconds, useful for debugging GPS connection // log NMEA status every 30 seconds, useful for debugging GPS connection
if ( (uptime() % 30000) == 0 ) if ((uptime() % 30000) == 0)
ESP_LOGD(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix()); ESP_LOGI(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d",
#endif gps.passedChecksum(), gps.failedChecksum(),
gps.sentencesWithFix());
#endif
vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog vTaskDelay(1 / portTICK_PERIOD_MS); // reset watchdog
} // end of infinite main loop } // end of infinite main loop
} }
/* end Arduino main loop ------------------------------------------------------------ */ /* end Arduino main loop
* ------------------------------------------------------------ */

View File

@ -3,8 +3,9 @@
#include "lorawan.h" #include "lorawan.h"
#include "macsniff.h" #include "macsniff.h"
// program version - note: increment version after modifications to configData_t struct!! // program version - note: increment version after modifications to configData_t
#define PROGVERSION "1.3.8" // use max 10 chars here! // struct!!
#define PROGVERSION "1.3.81" // use max 10 chars here!
#define PROGNAME "PAXCNT" #define PROGNAME "PAXCNT"
//--- Declarations --- //--- Declarations ---
@ -36,6 +37,12 @@ void led_loop(void);
//defined in gpsread.cpp //defined in gpsread.cpp
#ifdef HAS_GPS #ifdef HAS_GPS
<<<<<<< HEAD
void gps_read(void);
void gps_loop(void *pvParameters);
#endif
=======
void gps_read(void); void gps_read(void);
void gps_loop(void * pvParameters); void gps_loop(void * pvParameters);
#endif #endif
>>>>>>> master