Merge pull request #53 from cyberman54/development

v1.3.4
This commit is contained in:
Verkehrsrot 2018-04-28 14:53:40 +02:00 committed by GitHub
commit d46bb5998b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 157 additions and 115 deletions

View File

@ -156,10 +156,10 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts.
1 = reset MAC counter to zero 1 = reset MAC counter to zero
2 = reset device to factory settings 2 = reset device to factory settings
0x0A set Wifi scan cycle and payload transmit cycle 0x0A set payload send cycle
0 ... 255 duration of a wifi scan cycle in seconds/2, after this payload is sent 0 ... 255 payload send cycle in seconds/2
e.g. 120 -> 1 cycle runs for 240 seconds [default] e.g. 120 -> payload is transmitted each 240 seconds [default]
0x0B set Wifi channel switch interval timer 0x0B set Wifi channel switch interval timer
@ -193,7 +193,7 @@ 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#L24-L41) 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#L27-L44) with the following definition:
byte 1: Lora SF (7..12) byte 1: Lora SF (7..12)
byte 2: Lora TXpower (2..15) byte 2: Lora TXpower (2..15)
@ -202,7 +202,7 @@ device answers with it's current configuration. The configuration is a C structu
byte 5: Display status (1=on, 0=off) byte 5: Display status (1=on, 0=off)
byte 6: Counter mode (0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed) byte 6: Counter mode (0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed)
bytes 7-8: RSSI limiter threshold value (negative) bytes 7-8: RSSI limiter threshold value (negative)
byte 9: Wifi scan cycle duration in seconds/2 (0..255) byte 9: Payload send cycle in seconds/2 (0..255)
byte 10: Wifi channel switch interval in seconds/100 (0..255) byte 10: Wifi channel switch interval in seconds/100 (0..255)
byte 11: BLE scan cycle duration in seconds (0..255) byte 11: BLE scan cycle duration in seconds (0..255)
byte 12: BLE scan mode (1=on, 0=0ff) byte 12: BLE scan mode (1=on, 0=0ff)

View File

@ -21,7 +21,7 @@ void antenna_init(void) {
gpio_config(&gpioconf); gpio_config(&gpioconf);
} }
void antenna_select (const int8_t _ant) { void antenna_select (const uint8_t _ant) {
if (HAS_ANTENNA_SWITCH < 32) { if (HAS_ANTENNA_SWITCH < 32) {
if (_ant == ANTENNA_EXT) { if (_ant == ANTENNA_EXT) {
GPIO_REG_WRITE(GPIO_OUT_W1TS_REG, 1 << HAS_ANTENNA_SWITCH); GPIO_REG_WRITE(GPIO_OUT_W1TS_REG, 1 << HAS_ANTENNA_SWITCH);

View File

@ -100,7 +100,7 @@ static void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_pa
{ {
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
{ // restart scan { // restart scan
status = esp_ble_gap_start_scanning(BLESCANTIME); status = esp_ble_gap_start_scanning(cfg.blescantime);
if (status != ESP_OK) if (status != ESP_OK)
{ {
ESP_LOGE(TAG, "esp_ble_gap_start_scanning: rc=%d", status); ESP_LOGE(TAG, "esp_ble_gap_start_scanning: rc=%d", status);
@ -112,7 +112,7 @@ static void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_pa
{ {
if ( p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_CMPL_EVT) // Inquiry complete, scan is done if ( p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_CMPL_EVT) // Inquiry complete, scan is done
{ // restart scan { // restart scan
status = esp_ble_gap_start_scanning (BLESCANTIME); status = esp_ble_gap_start_scanning (cfg.blescantime);
if (status != ESP_OK) if (status != ESP_OK)
{ {
ESP_LOGE(TAG, "esp_ble_gap_start_scanning: rc=%d", status); ESP_LOGE(TAG, "esp_ble_gap_start_scanning: rc=%d", status);
@ -286,8 +286,7 @@ void bt_loop(void * pvParameters)
while(1) while(1)
{ {
vTaskDelay(10/portTICK_PERIOD_MS); vTaskDelay(10/portTICK_PERIOD_MS); // reset watchdog
yield();
} }
end: end:

View File

@ -13,7 +13,7 @@ esp_err_t err;
// defined in antenna.cpp // defined in antenna.cpp
#ifdef HAS_ANTENNA_SWITCH #ifdef HAS_ANTENNA_SWITCH
void antenna_select(const int8_t _ant); void antenna_select(const uint8_t _ant);
#endif #endif
// populate cfg vars with factory settings // populate cfg vars with factory settings
@ -25,7 +25,7 @@ void defaultConfig() {
cfg.screenon = 1; // 0=disbaled, 1=enabled cfg.screenon = 1; // 0=disbaled, 1=enabled
cfg.countermode = 0; // 0=cyclic, 1=cumulative, 2=cyclic confirmed cfg.countermode = 0; // 0=cyclic, 1=cumulative, 2=cyclic confirmed
cfg.rssilimit = 0; // threshold for rssilimiter, negative value! cfg.rssilimit = 0; // threshold for rssilimiter, negative value!
cfg.wifiscancycle = SEND_SECS; // wifi scan cycle [seconds/2] cfg.sendcycle = SEND_SECS; // payload send cycle [seconds/2]
cfg.wifichancycle = WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100] cfg.wifichancycle = WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100]
cfg.blescantime = BLESCANTIME; // BLE scan cycle duration [seconds] cfg.blescantime = BLESCANTIME; // BLE scan cycle duration [seconds]
cfg.blescan = 1; // 0=disabled, 1=enabled cfg.blescan = 1; // 0=disabled, 1=enabled
@ -99,8 +99,8 @@ void saveConfig() {
if( nvs_get_i8(my_handle, "countermode", &flash8) != ESP_OK || flash8 != cfg.countermode ) if( nvs_get_i8(my_handle, "countermode", &flash8) != ESP_OK || flash8 != cfg.countermode )
nvs_set_i8(my_handle, "countermode", cfg.countermode); nvs_set_i8(my_handle, "countermode", cfg.countermode);
if( nvs_get_i8(my_handle, "wifiscancycle", &flash8) != ESP_OK || flash8 != cfg.wifiscancycle ) if( nvs_get_i8(my_handle, "sendcycle", &flash8) != ESP_OK || flash8 != cfg.sendcycle )
nvs_set_i8(my_handle, "wifiscancycle", cfg.wifiscancycle); nvs_set_i8(my_handle, "sendcycle", cfg.sendcycle);
if( nvs_get_i8(my_handle, "wifichancycle", &flash8) != ESP_OK || flash8 != cfg.wifichancycle ) if( nvs_get_i8(my_handle, "wifichancycle", &flash8) != ESP_OK || flash8 != cfg.wifichancycle )
nvs_set_i8(my_handle, "wifichancycle", cfg.wifichancycle); nvs_set_i8(my_handle, "wifichancycle", cfg.wifichancycle);
@ -220,11 +220,11 @@ void loadConfig() {
saveConfig(); saveConfig();
} }
if( nvs_get_i8(my_handle, "wifiscancycle", &flash8) == ESP_OK ) { if( nvs_get_i8(my_handle, "sendcycle", &flash8) == ESP_OK ) {
cfg.wifiscancycle = flash8; cfg.sendcycle = flash8;
ESP_LOGI(TAG, "wifiscancycle = %d", flash8); ESP_LOGI(TAG, "sendcycle = %d", flash8);
} else { } else {
ESP_LOGI(TAG, "WIFI scan cycle set to default %d", cfg.wifiscancycle); ESP_LOGI(TAG, "Payload send cycle set to default %d", cfg.sendcycle);
saveConfig(); saveConfig();
} }

View File

@ -26,33 +26,33 @@
// Struct holding devices's runtime configuration // Struct holding devices's runtime configuration
typedef struct { typedef struct {
int8_t lorasf; // 7-12, lora spreadfactor uint8_t lorasf; // 7-12, lora spreadfactor
int8_t txpower; // 2-15, lora tx power uint8_t txpower; // 2-15, lora tx power
int8_t adrmode; // 0=disabled, 1=enabled uint8_t adrmode; // 0=disabled, 1=enabled
int8_t screensaver; // 0=disabled, 1=enabled uint8_t screensaver; // 0=disabled, 1=enabled
int8_t screenon; // 0=disabled, 1=enabled uint8_t screenon; // 0=disabled, 1=enabled
int8_t countermode; // 0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed uint8_t countermode; // 0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed
int16_t rssilimit; // threshold for rssilimiter, negative value! int16_t rssilimit; // threshold for rssilimiter, negative value!
int8_t wifiscancycle; // wifi scan cycle [seconds/2] uint8_t sendcycle; // payload send cycle [seconds/2]
int8_t wifichancycle; // wifi channel switch cycle [seconds/100] uint8_t wifichancycle; // wifi channel switch cycle [seconds/100]
int8_t blescantime; // BLE scan cycle duration [seconds] uint8_t blescantime; // BLE scan cycle duration [seconds]
int8_t blescan; // 0=disabled, 1=enabled uint8_t blescan; // 0=disabled, 1=enabled
int8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4) uint8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4)
int8_t vendorfilter; // 0=disabled, 1=enabled uint8_t vendorfilter; // 0=disabled, 1=enabled
int8_t rgblum; // RGB Led luminosity (0..100%) uint8_t rgblum; // RGB Led luminosity (0..100%)
char version[10]; // Firmware version char version[10]; // Firmware version
} configData_t; } configData_t;
extern configData_t cfg; extern configData_t cfg;
extern uint8_t mydata[]; extern uint8_t mydata[];
extern uint64_t uptimecounter; extern uint64_t uptimecounter;
extern unsigned long currentMillis ;
extern osjob_t sendjob; extern osjob_t sendjob;
extern char display_lora[], display_lmic[]; extern char display_lora[], display_lmic[];
extern int countermode, screensaver, adrmode, lorasf, txpower, rlim; extern int countermode, screensaver, adrmode, lorasf, txpower, rlim;
extern uint16_t macs_total, macs_wifi, macs_ble; // MAC counters extern uint16_t macs_total, macs_wifi, macs_ble; // MAC counters
extern bool joinstate; extern bool joinstate;
extern std::set<uint16_t> macs; extern std::set<uint16_t> macs;
extern hw_timer_t * channelSwitch; // hardware timer used for wifi channel switching
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
extern HAS_DISPLAY u8x8; extern HAS_DISPLAY u8x8;

View File

@ -17,7 +17,7 @@
#define RST 14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger Input #define RST 14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger Input
#define DIO0 26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done #define DIO0 26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
#define DIO1 33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout #define DIO1 33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
#define DIO2 32 // ESP32 GPIO32 (Pin12) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only) #define DIO2 LMIC_UNUSED_PIN // 32 ESP32 GPIO32 (Pin12) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
// Hardware pin definitions for Heltec LoRa-32 Board with OLED SSD1306 I2C Display // Hardware pin definitions for Heltec LoRa-32 Board with OLED SSD1306 I2C Display
#define OLED_RST 16 // ESP32 GPIO16 (Pin16) -- SD1306 RST #define OLED_RST 16 // ESP32 GPIO16 (Pin16) -- SD1306 RST

View File

@ -25,8 +25,8 @@
#define RST 25 // ESP32 GPIO25 (Pin25) -- SX1276 NRESET (Pin7) Reset Trigger Input #define RST 25 // ESP32 GPIO25 (Pin25) -- SX1276 NRESET (Pin7) Reset Trigger Input
#define DIO0 27 // ESP32 GPIO27 (Pin27) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done #define DIO0 27 // ESP32 GPIO27 (Pin27) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
#define DIO1 26 // ESP32 GPIO26 (Pin26) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout #define DIO1 26 // ESP32 GPIO26 (Pin26) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
#define DIO2 4 // ESP32 GPIO4 (Pin4) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only) #define DIO2 LMIC_UNUSED_PIN // 4 ESP32 GPIO4 (Pin4) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
#define DIO5 35 // ESP32 GPIO35 (Pin35) -- SX1276 DIO5 not used by LMIC for LoRa (Timeout for FSK only) #define DIO5 LMIC_UNUSED_PIN // 35 ESP32 GPIO35 (Pin35) -- SX1276 DIO5 not used by LMIC for LoRa (Timeout for FSK only)
// Hardware pin definitions for LoRaNode32 Board with OLED I2C Display // Hardware pin definitions for LoRaNode32 Board with OLED I2C Display
#define OLED_RST U8X8_PIN_NONE // Not reset pin #define OLED_RST U8X8_PIN_NONE // Not reset pin

View File

@ -24,8 +24,8 @@
#define RST 25 // ESP32 GPIO25 (Pin25) -- SX1276 NRESET (Pin7) Reset Trigger Input #define RST 25 // ESP32 GPIO25 (Pin25) -- SX1276 NRESET (Pin7) Reset Trigger Input
#define DIO0 27 // ESP32 GPIO27 (Pin27) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done #define DIO0 27 // ESP32 GPIO27 (Pin27) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
#define DIO1 26 // ESP32 GPIO26 (Pin26) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout #define DIO1 26 // ESP32 GPIO26 (Pin26) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
#define DIO2 4 // ESP32 GPIO4 (Pin4) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only) #define DIO2 LMIC_UNUSED_PIN // 4 ESP32 GPIO4 (Pin4) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
#define DIO5 35 // ESP32 GPIO35 (Pin35) -- SX1276 DIO5 not used by LMIC for LoRa (Timeout for FSK only) #define DIO5 LMIC_UNUSED_PIN // 35 ESP32 GPIO35 (Pin35) -- SX1276 DIO5 not used by LMIC for LoRa (Timeout for FSK only)
// Hardware pin definitions for LoRaNode32 Board with OLED I2C Display // Hardware pin definitions for LoRaNode32 Board with OLED I2C Display
#define OLED_RST U8X8_PIN_NONE // Not reset pin #define OLED_RST U8X8_PIN_NONE // Not reset pin

View File

@ -12,7 +12,7 @@
#define RST 18 #define RST 18
#define DIO0 23 // LoRa IRQ #define DIO0 23 // LoRa IRQ
#define DIO1 23 // workaround #define DIO1 23 // workaround
#define DIO2 23 // workaround #define DIO2 LMIC_UNUSED_PIN // 23 workaround
// select WIFI antenna (internal = onboard / external = u.fl socket) // select WIFI antenna (internal = onboard / external = u.fl socket)
#define HAS_ANTENNA_SWITCH 16 // pin for switching wifi antenna #define HAS_ANTENNA_SWITCH 16 // pin for switching wifi antenna

View File

@ -12,7 +12,7 @@
#define RST LMIC_UNUSED_PIN #define RST LMIC_UNUSED_PIN
#define DIO0 23 // LoRa IRQ #define DIO0 23 // LoRa IRQ
#define DIO1 23 // workaround #define DIO1 23 // workaround
#define DIO2 23 // workaround #define DIO2 LMIC_UNUSED_PIN // 23 workaround
// select WIFI antenna (internal = onboard / external = u.fl socket) // select WIFI antenna (internal = onboard / external = u.fl socket)
#define HAS_ANTENNA_SWITCH 21 // pin for switching wifi antenna #define HAS_ANTENNA_SWITCH 21 // pin for switching wifi antenna

View File

@ -18,7 +18,7 @@
#define RST 14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger Input #define RST 14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger Input
#define DIO0 26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done #define DIO0 26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
#define DIO1 33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout #define DIO1 33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
#define DIO2 32 // ESP32 GPIO32 (Pin12) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only) #define DIO2 LMIC_UNUSED_PIN // 32 ESP32 GPIO32 (Pin12) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
// Hardware pin definitions for TTGOv1 Board with OLED SSD1306 I2C Display // Hardware pin definitions for TTGOv1 Board with OLED SSD1306 I2C Display
#define OLED_RST 16 // ESP32 GPIO16 (Pin16) -- SD1306 Reset #define OLED_RST 16 // ESP32 GPIO16 (Pin16) -- SD1306 Reset

View File

@ -19,7 +19,7 @@
#define RST LMIC_UNUSED_PIN // connected to ESP32 RST/EN #define RST LMIC_UNUSED_PIN // connected to ESP32 RST/EN
#define DIO0 26 // ESP32 GPIO26 wired on PCB to HPD13A #define DIO0 26 // ESP32 GPIO26 wired on PCB to HPD13A
#define DIO1 33 // HPDIO1 on pcb, needs to be wired external to GPIO33 #define DIO1 33 // HPDIO1 on pcb, needs to be wired external to GPIO33
#define DIO2 32 // HPDIO2 on pcb, needs to be wired external to GPIO32 (not necessary for LoRa, only FSK) #define DIO2 LMIC_UNUSED_PIN // 32 HPDIO2 on pcb, needs to be wired external to GPIO32 (not necessary for LoRa, only FSK)
// Hardware pin definitions for TTGO V2 Board with OLED SSD1306 0,96" I2C Display // Hardware pin definitions for TTGO V2 Board with OLED SSD1306 0,96" I2C Display
#define OLED_RST U8X8_PIN_NONE // connected to CPU RST/EN #define OLED_RST U8X8_PIN_NONE // connected to CPU RST/EN

View File

@ -14,8 +14,8 @@
static const char *TAG = "lorawan"; static const char *TAG = "lorawan";
// functions defined in rcommand.cpp // functions defined in rcommand.cpp
void rcommand(int cmd, int arg); void rcommand(uint8_t cmd, uint8_t arg);
void switch_lora(int sf, int tx); void switch_lora(uint8_t sf, uint8_t tx);
// DevEUI generator using devices's MAC address // DevEUI generator using devices's MAC address
void gen_lora_deveui(uint8_t *pdeveui) { void gen_lora_deveui(uint8_t *pdeveui) {
@ -140,7 +140,7 @@ void do_send(osjob_t* j){
} }
// Schedule next transmission // Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(SEND_SECS * 2), do_send); os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(cfg.sendcycle * 2), do_send);
} // do_send() } // do_send()

View File

@ -41,8 +41,6 @@ Refer to LICENSE.txt file in repository for more details.
configData_t cfg; // struct holds current device configuration configData_t cfg; // struct holds current device configuration
osjob_t sendjob, initjob; // LMIC jobs osjob_t sendjob, initjob; // LMIC jobs
uint64_t uptimecounter = 0; // timer global for uptime counter uint64_t uptimecounter = 0; // timer global for uptime counter
unsigned long currentMillis = millis(); // timer global for state machine
unsigned long previousDisplaymillis = currentMillis; // Display refresh for state machine
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
@ -54,11 +52,15 @@ 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
bool joinstate = false; // LoRa network joined? global flag bool joinstate = false; // LoRa network joined? global flag
bool blinkdone = true; // flag for state machine for blinking LED once bool blinkdone = true; // flag for state machine for blinking LED once
hw_timer_t * displaytimer = NULL; // configure hardware timer used for cyclic display refresh
hw_timer_t * channelSwitch = NULL; // configure hardware timer used for wifi channel switching
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying shared variable DisplayIRQ
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 variable 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 bool ButtonTriggered = false; static volatile int ButtonPressed = 0, DisplayTimerIRQ = 0, ChannelTimerIRQ = 0;
// local Tag for logging // local Tag for logging
static const char *TAG = "paxcnt"; static const char *TAG = "paxcnt";
@ -165,11 +167,9 @@ void lorawan_loop(void * pvParameters) {
LMIC_reset(); // Reset the MAC state. Session and pending data transfers will be discarded. LMIC_reset(); // Reset the MAC state. Session and pending data transfers will be discarded.
}; };
vTaskDelay(1000/portTICK_PERIOD_MS); vTaskDelay(1000/portTICK_PERIOD_MS);
yield();
} }
*/ */
vTaskDelay(10/portTICK_PERIOD_MS); vTaskDelay(10/portTICK_PERIOD_MS); // reset watchdog
yield();
} }
} }
@ -181,12 +181,18 @@ void lorawan_loop(void * pvParameters) {
#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
void IRAM_ATTR DisplayIRQ() {
portENTER_CRITICAL_ISR(&timerMux);
DisplayTimerIRQ++;
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 int8_t _ant); void antenna_select(const uint8_t _ant);
#endif #endif
#ifndef BLECOUNTER #ifndef BLECOUNTER
@ -194,12 +200,19 @@ void lorawan_loop(void * pvParameters) {
#endif #endif
#ifdef HAS_BUTTON #ifdef HAS_BUTTON
// Button Handling, board dependent -> perhaps to be moved to hal/<$board.h> // Button IRQ
// IRAM_ATTR necessary here, see https://github.com/espressif/arduino-esp32/issues/855 // IRAM_ATTR necessary here, see https://github.com/espressif/arduino-esp32/issues/855
void IRAM_ATTR isr_button_pressed(void) { void IRAM_ATTR ButtonIRQ() {
ButtonTriggered = true; } ButtonPressed++;
}
#endif #endif
void IRAM_ATTR ChannelSwitchIRQ() {
portENTER_CRITICAL(&timerMux);
ChannelTimerIRQ++;
portEXIT_CRITICAL(&timerMux);
}
/* end hardware specific parts -------------------------------------------------------- */ /* end hardware specific parts -------------------------------------------------------- */
@ -212,12 +225,16 @@ void sniffer_loop(void * pvParameters) {
while (1) { while (1) {
for (channel = 1; channel <= WIFI_CHANNEL_MAX; channel++) { if (ChannelTimerIRQ) {
// rotates variable channel 1..WIFI_CHANNEL_MAX portENTER_CRITICAL(&timerMux);
ChannelTimerIRQ--;
portEXIT_CRITICAL(&timerMux);
// rotates variable channel 1..WIFI_CHANNEL_MAX
channel = (channel % WIFI_CHANNEL_MAX) + 1;
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(cfg.wifichancycle*10 / portTICK_PERIOD_MS);
yield(); vTaskDelay(10/portTICK_PERIOD_MS); // reset watchdog
} }
} // end of infinite wifi channel rotation loop } // end of infinite wifi channel rotation loop
@ -313,16 +330,20 @@ uint64_t uptime() {
u8x8.printf("%-16s", "BLTH:off"); u8x8.printf("%-16s", "BLTH:off");
#endif #endif
// update free memory display (line 4) // update LoRa SF display (line 3)
u8x8.setCursor(10,4); u8x8.setCursor(11,3);
u8x8.printf("%4dKB", ESP.getFreeHeap() / 1024); u8x8.printf("SF:%c%c", lora_datarate[LMIC.datarate * 2], lora_datarate[LMIC.datarate * 2 + 1]);
// update RSSI limiter status & wifi channel display (line 5) // update wifi channel display (line 4)
u8x8.setCursor(0,5); u8x8.setCursor(11,4);
u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d", cfg.rssilimit);
u8x8.setCursor(11,5);
u8x8.printf("ch:%02d", channel); u8x8.printf("ch:%02d", channel);
// update RSSI limiter status & free memory display (line 5)
u8x8.setCursor(0,5);
u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d", cfg.rssilimit);
u8x8.setCursor(10,5);
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);
@ -333,26 +354,27 @@ uint64_t uptime() {
} }
void updateDisplay() { void updateDisplay() {
// timed display refresh according to refresh cycle setting // refresh display according to refresh cycle setting
if (DisplayTimerIRQ) {
if (currentMillis - previousDisplaymillis >= DISPLAYREFRESH_MS) { portENTER_CRITICAL(&timerMux);
DisplayTimerIRQ--;
portEXIT_CRITICAL(&timerMux);
refreshDisplay(); refreshDisplay();
previousDisplaymillis += DISPLAYREFRESH_MS;
} // set display on/off according to current device configuration
// set display on/off according to current device configuration if (DisplayState != cfg.screenon) {
if (DisplayState != cfg.screenon) { DisplayState = cfg.screenon;
DisplayState = cfg.screenon; 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 (ButtonTriggered) { if (ButtonPressed) {
ButtonTriggered = false; ButtonPressed--;
ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults"); ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults");
eraseConfig(); eraseConfig();
esp_restart(); esp_restart();
@ -497,12 +519,12 @@ void setup() {
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), isr_button_pressed, 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), isr_button_pressed, FALLING); attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, FALLING);
#endif #endif
#endif #endif
@ -529,9 +551,21 @@ void setup() {
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 IRQ, thanks to https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
displaytimer = timerBegin(0, 80, true); // prescaler 80 -> divides 80 MHz CPU 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
#endif #endif
// Display features compiled for // setup channel rotation IRQ, thanks to https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
channelSwitch = timerBegin(1, 80, true); // prescaler 80 -> divides 80 MHz CPU freq to 1 MHz, timer 1, count up
timerAttachInterrupt(channelSwitch, &ChannelSwitchIRQ, true); // interrupt handler, triggered by edge
timerAlarmWrite(channelSwitch, cfg.wifichancycle * 10000, true); // reload interrupt after each trigger of channel switch cycle
timerAlarmEnable(channelSwitch); // enable channel switching interrupt
// 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
@ -579,7 +613,6 @@ void loop() {
// simple state machine for controlling display, LED, button, etc. // simple state machine for controlling display, LED, button, etc.
uptimecounter = uptime() / 1000; // counts uptime in seconds (64bit) uptimecounter = uptime() / 1000; // counts uptime in seconds (64bit)
currentMillis = millis(); // timebase for state machine in milliseconds (32bit)
#if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED) #if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED)
led_loop(); led_loop();
@ -600,6 +633,8 @@ void loop() {
reset_salt(); // get new salt for salting hashes reset_salt(); // get new salt for salting hashes
} }
vTaskDelay(10/portTICK_PERIOD_MS); // reset watchdog
} }
/* end Aruino LOOP ------------------------------------------------------------ */ /* end Aruino LOOP ------------------------------------------------------------ */

View File

@ -1,6 +1,6 @@
// program version - note: increment version after modifications to configData_t struct!! // program version - note: increment version after modifications to configData_t struct!!
#define PROGVERSION "1.3.3" // use max 10 chars here! #define PROGVERSION "1.3.4" // use max 10 chars here!
#define PROGNAME "PAXCNT" #define PROGNAME "PAXCNT"
//--- Declarations --- //--- Declarations ---
@ -10,6 +10,12 @@ enum led_states {
LED_ON LED_ON
}; };
#if defined(CFG_eu868)
const char lora_datarate[] = {"1211100908077BFSNA"};
#elif defined(CFG_us915)
const char lora_datarate[] = {"100908078CNA121110090807"};
#endif
//--- Prototypes --- //--- Prototypes ---
// defined in main.cpp // defined in main.cpp

View File

@ -34,7 +34,7 @@
// LoRa payload send cycle --> take care of duty cycle of LoRaWAN network! <-- // LoRa payload send cycle --> take care of duty cycle of LoRaWAN network! <--
#define SEND_SECS 120 // [seconds/2] -> 240 sec. #define SEND_SECS 120 // [seconds/2] -> 240 sec.
#define MEM_LOW 2048 // [Bytes] memory threshold triggering send cycle #define MEM_LOW 2048 // [Bytes] low memory threshold triggering a send cycle
// Default LoRa Spreadfactor // Default LoRa Spreadfactor
#define LORASFDEFAULT 9 // 7 ... 12 SF, according to LoRaWAN specs #define LORASFDEFAULT 9 // 7 ... 12 SF, according to LoRaWAN specs
@ -45,7 +45,7 @@
#define RGBLUMINOSITY 30 // 30% #define RGBLUMINOSITY 30 // 30%
// OLED Display refresh cycle (in Milliseconds) // OLED Display refresh cycle (in Milliseconds)
#define DISPLAYREFRESH_MS 40 // e.g. 40ms -> 1000/40 = 25 frames per second #define DISPLAYREFRESH_MS 40 // e.g. 40ms -> 1000/40 = 25 frames per second
// LMIC settings // LMIC settings
// define hardware independent LMIC settings here, settings of standard library in /lmic/config.h will be ignored // define hardware independent LMIC settings here, settings of standard library in /lmic/config.h will be ignored

View File

@ -14,18 +14,18 @@ static const char *TAG = "rcommand";
// table of remote commands and assigned functions // table of remote commands and assigned functions
typedef struct { typedef struct {
const int nam; const uint8_t nam;
void (*func)(int); void (*func)(uint8_t);
const bool store; const bool store;
} cmd_t; } cmd_t;
// function defined in antenna.cpp // function defined in antenna.cpp
#ifdef HAS_ANTENNA_SWITCH #ifdef HAS_ANTENNA_SWITCH
void antenna_select(const int8_t _ant); void antenna_select(const uint8_t _ant);
#endif #endif
// help function to assign LoRa datarates to numeric spreadfactor values // help function to assign LoRa datarates to numeric spreadfactor values
void switch_lora (int sf, int tx) { void switch_lora (uint8_t sf, uint8_t tx) {
if ( tx > 20 ) return; if ( tx > 20 ) return;
cfg.txpower = tx; cfg.txpower = tx;
switch (sf) { switch (sf) {
@ -50,7 +50,7 @@ void switch_lora (int sf, int tx) {
} }
// set of functions that can be triggered by remote commands // set of functions that can be triggered by remote commands
void set_reset(int val) { void set_reset(uint8_t val) {
switch (val) { switch (val) {
case 0: // restart device case 0: // restart device
ESP_LOGI(TAG, "Remote command: restart device"); ESP_LOGI(TAG, "Remote command: restart device");
@ -72,27 +72,29 @@ void set_reset(int val) {
} }
}; };
void set_rssi(int val) { void set_rssi(uint8_t val) {
cfg.rssilimit = val * -1; cfg.rssilimit = val * -1;
ESP_LOGI(TAG, "Remote command: set RSSI limit to %d", cfg.rssilimit); ESP_LOGI(TAG, "Remote command: set RSSI limit to %d", cfg.rssilimit);
}; };
void set_wifiscancycle(int val) { void set_sendcycle(uint8_t val) {
cfg.wifiscancycle = val; cfg.sendcycle = val;
ESP_LOGI(TAG, "Remote command: set Wifi scan cycle duration to %d seconds", cfg.wifiscancycle*2); ESP_LOGI(TAG, "Remote command: set payload send cycle to %d seconds", cfg.sendcycle*2);
}; };
void set_wifichancycle(int val) { void set_wifichancycle(uint8_t val) {
cfg.wifichancycle = val; cfg.wifichancycle = val;
ESP_LOGI(TAG, "Remote command: set Wifi channel switch interval to %d seconds", cfg.wifichancycle/100); // modify wifi channel rotation IRQ
timerAlarmWrite(channelSwitch, cfg.wifichancycle * 10000, true); // reload interrupt after each trigger of channel switch cycle
ESP_LOGI(TAG, "Remote command: set Wifi channel switch interval to %.1f seconds", cfg.wifichancycle/float(100));
}; };
void set_blescantime(int val) { void set_blescantime(uint8_t val) {
cfg.blescantime = val; cfg.blescantime = val;
ESP_LOGI(TAG, "Remote command: set BLE scan time to %d seconds", cfg.blescantime); ESP_LOGI(TAG, "Remote command: set BLE scan time to %d seconds", cfg.blescantime);
}; };
void set_countmode(int val) { void set_countmode(uint8_t val) {
switch (val) { switch (val) {
case 0: // cyclic unconfirmed case 0: // cyclic unconfirmed
cfg.countermode = 0; cfg.countermode = 0;
@ -109,7 +111,7 @@ void set_countmode(int val) {
} }
}; };
void set_screensaver(int val) { void set_screensaver(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set screen saver to %s ", val ? "on" : "off"); ESP_LOGI(TAG, "Remote command: set screen saver to %s ", val ? "on" : "off");
switch (val) { switch (val) {
case 1: cfg.screensaver = val; break; case 1: cfg.screensaver = val; break;
@ -117,7 +119,7 @@ void set_screensaver(int val) {
} }
}; };
void set_display(int val) { void set_display(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set screen to %s", val ? "on" : "off"); ESP_LOGI(TAG, "Remote command: set screen to %s", val ? "on" : "off");
switch (val) { switch (val) {
case 1: cfg.screenon = val; break; case 1: cfg.screenon = val; break;
@ -125,12 +127,12 @@ void set_display(int val) {
} }
}; };
void set_lorasf(int val) { void set_lorasf(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set LoRa SF to %d", val); ESP_LOGI(TAG, "Remote command: set LoRa SF to %d", val);
switch_lora(val, cfg.txpower); switch_lora(val, cfg.txpower);
}; };
void set_loraadr(int val) { void set_loraadr(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set LoRa ADR mode to %s", val ? "on" : "off"); ESP_LOGI(TAG, "Remote command: set LoRa ADR mode to %s", val ? "on" : "off");
switch (val) { switch (val) {
case 1: cfg.adrmode = val; break; case 1: cfg.adrmode = val; break;
@ -139,7 +141,7 @@ void set_loraadr(int val) {
LMIC_setAdrMode(cfg.adrmode); LMIC_setAdrMode(cfg.adrmode);
}; };
void set_blescan(int val) { void set_blescan(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set BLE scan mode to %s", val ? "on" : "off"); ESP_LOGI(TAG, "Remote command: set BLE scan mode to %s", val ? "on" : "off");
switch (val) { switch (val) {
case 0: case 0:
@ -152,7 +154,7 @@ void set_blescan(int val) {
} }
}; };
void set_wifiant(int val) { void set_wifiant(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set Wifi antenna to %s", val ? "external" : "internal"); ESP_LOGI(TAG, "Remote command: set Wifi antenna to %s", val ? "external" : "internal");
switch (val) { switch (val) {
case 1: cfg.wifiant = val; break; case 1: cfg.wifiant = val; break;
@ -163,7 +165,7 @@ void set_wifiant(int val) {
#endif #endif
}; };
void set_vendorfilter(int val) { void set_vendorfilter(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set vendorfilter mode to %s", val ? "on" : "off"); ESP_LOGI(TAG, "Remote command: set vendorfilter mode to %s", val ? "on" : "off");
switch (val) { switch (val) {
case 1: cfg.vendorfilter = val; break; case 1: cfg.vendorfilter = val; break;
@ -171,22 +173,22 @@ void set_vendorfilter(int val) {
} }
}; };
void set_rgblum(int val) { void set_rgblum(uint8_t val) {
// Avoid wrong parameters // Avoid wrong parameters
cfg.rgblum = (val>=0 && val<=100) ? (uint8_t) val : RGBLUMINOSITY; cfg.rgblum = (val>=0 && val<=100) ? (uint8_t) val : RGBLUMINOSITY;
ESP_LOGI(TAG, "Remote command: set RGB Led luminosity %d", cfg.rgblum); ESP_LOGI(TAG, "Remote command: set RGB Led luminosity %d", cfg.rgblum);
}; };
void set_lorapower(int val) { void set_lorapower(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %d", val); ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %d", val);
switch_lora(cfg.lorasf, val); switch_lora(cfg.lorasf, val);
}; };
void set_noop (int val) { void set_noop (uint8_t val) {
ESP_LOGI(TAG, "Remote command: noop - doing nothing"); ESP_LOGI(TAG, "Remote command: noop - doing nothing");
}; };
void get_config (int val) { void get_config (uint8_t val) {
ESP_LOGI(TAG, "Remote command: get configuration"); ESP_LOGI(TAG, "Remote command: get configuration");
int size = sizeof(configData_t); int size = sizeof(configData_t);
// declare send buffer (char byte array) // declare send buffer (char byte array)
@ -198,7 +200,7 @@ void get_config (int val) {
ESP_LOGI(TAG, "%d bytes queued in send queue", size-1); ESP_LOGI(TAG, "%d bytes queued in send queue", size-1);
}; };
void get_uptime (int val) { void get_uptime (uint8_t val) {
ESP_LOGI(TAG, "Remote command: get uptime"); ESP_LOGI(TAG, "Remote command: get uptime");
int size = sizeof(uptimecounter); int size = sizeof(uptimecounter);
unsigned char *sendData = new unsigned char[size]; unsigned char *sendData = new unsigned char[size];
@ -208,7 +210,7 @@ void get_uptime (int val) {
ESP_LOGI(TAG, "%d bytes queued in send queue", size-1); ESP_LOGI(TAG, "%d bytes queued in send queue", size-1);
}; };
void get_cputemp (int val) { void get_cputemp (uint8_t val) {
ESP_LOGI(TAG, "Remote command: get cpu temperature"); ESP_LOGI(TAG, "Remote command: get cpu temperature");
float temp = temperatureRead(); float temp = temperatureRead();
int size = sizeof(temp); int size = sizeof(temp);
@ -232,7 +234,7 @@ cmd_t table[] = {
{0x07, set_loraadr, true}, {0x07, set_loraadr, true},
{0x08, set_screensaver, true}, {0x08, set_screensaver, true},
{0x09, set_reset, false}, {0x09, set_reset, false},
{0x0a, set_wifiscancycle, true}, {0x0a, set_sendcycle, true},
{0x0b, set_wifichancycle, true}, {0x0b, set_wifichancycle, true},
{0x0c, set_blescantime, true}, {0x0c, set_blescantime, true},
{0x0d, set_vendorfilter, false}, {0x0d, set_vendorfilter, false},
@ -245,7 +247,7 @@ cmd_t table[] = {
}; };
// check and execute remote command // check and execute remote command
void rcommand(int cmd, int arg) { void rcommand(uint8_t cmd, uint8_t arg) {
int i = sizeof(table) / sizeof(table[0]); // number of commands in command table int i = sizeof(table) / sizeof(table[0]); // number of commands in command table
bool store_flag = false; bool store_flag = false;
while(i--) { while(i--) {