GPS support added (experimental)
This commit is contained in:
parent
95be6bc192
commit
f7ee3f85b0
19
README.md
19
README.md
@ -159,10 +159,10 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts.
|
|||||||
1 = cumulative counter, mac counter is never reset
|
1 = cumulative counter, mac counter is never reset
|
||||||
2 = cyclic confirmed, like 0 but data is resent until confirmation by network received
|
2 = cyclic confirmed, like 0 but data is resent until confirmation by network received
|
||||||
|
|
||||||
0x03 (NOT YET IMPLEMENTED) set screen saver mode
|
0x03 set GPS on/off
|
||||||
|
|
||||||
0 = screen saver off [default]
|
0 = GPS off [default]
|
||||||
1 = screen saver on
|
1 = GPS on, GPS data set (if present) added to payload
|
||||||
|
|
||||||
0x04 set display on/off
|
0x04 set display on/off
|
||||||
|
|
||||||
@ -232,7 +232,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#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#L27-L45) 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)
|
||||||
@ -248,7 +248,8 @@ device answers with it's current configuration. The configuration is a C structu
|
|||||||
byte 13: Wifi antenna switch (0=internal, 1=external)
|
byte 13: Wifi antenna switch (0=internal, 1=external)
|
||||||
byte 14: Vendorfilter mode (0=disabled, 1=enabled)
|
byte 14: Vendorfilter mode (0=disabled, 1=enabled)
|
||||||
byte 15: RGB LED luminosity (0..100 %)
|
byte 15: RGB LED luminosity (0..100 %)
|
||||||
bytes 16-26: Software version (ASCII format, terminating with zero)
|
byte 16: GPS status (1=on, 0=off)
|
||||||
|
bytes 17-27: Software version (ASCII format, terminating with zero)
|
||||||
|
|
||||||
0x81 get device uptime
|
0x81 get device uptime
|
||||||
|
|
||||||
@ -262,6 +263,14 @@ device answers with it's current configuration. The configuration is a C structu
|
|||||||
|
|
||||||
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 (NOT YET IMPLEMENTED)
|
||||||
|
|
||||||
|
bytes 1-4: latitude
|
||||||
|
bytes 5-8: longitude
|
||||||
|
byte 9: number of satellites
|
||||||
|
byte 10: HDOP
|
||||||
|
bytes 11-12: altidute [meter]
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
Copyright 2018 Oliver Brandmueller <ob@sysadm.in>
|
Copyright 2018 Oliver Brandmueller <ob@sysadm.in>
|
||||||
|
@ -27,11 +27,12 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng
|
|||||||
[common_env_data]
|
[common_env_data]
|
||||||
platform_espressif32 = espressif32@>=1.0.2
|
platform_espressif32 = espressif32@>=1.0.2
|
||||||
board_build.partitions = no_ota.csv
|
board_build.partitions = no_ota.csv
|
||||||
board_upload.maximum_size = 2097152
|
|
||||||
lib_deps_display =
|
lib_deps_display =
|
||||||
U8g2@>=2.22.14
|
U8g2@>=2.22.14
|
||||||
lib_deps_rgbled =
|
lib_deps_rgbled =
|
||||||
SmartLeds
|
SmartLeds@>=1.1.3
|
||||||
|
lib_deps_gps =
|
||||||
|
TinyGPSPlus@>=1.0.0
|
||||||
build_flags =
|
build_flags =
|
||||||
; we need build_flag for logging, otherwise we can't use ESP_LOGx in arduino framework
|
; we need build_flag for logging, otherwise we can't use ESP_LOGx in arduino framework
|
||||||
; ---> NOTE: For production run set DEBUG_LEVEL level to NONE! <---
|
; ---> NOTE: For production run set DEBUG_LEVEL level to NONE! <---
|
||||||
@ -51,7 +52,6 @@ platform = ${common_env_data.platform_espressif32}
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
board = heltec_wifi_lora_32
|
board = heltec_wifi_lora_32
|
||||||
board_build.partitions = ${common_env_data.board_build.partitions}
|
board_build.partitions = ${common_env_data.board_build.partitions}
|
||||||
board_upload.maximum_size = ${common_env_data.board_upload.maximum_size}
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
||||||
lib_deps =
|
lib_deps =
|
||||||
@ -65,7 +65,6 @@ platform = ${common_env_data.platform_espressif32}
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
board_build.partitions = ${common_env_data.board_build.partitions}
|
board_build.partitions = ${common_env_data.board_build.partitions}
|
||||||
board_upload.maximum_size = ${common_env_data.board_upload.maximum_size}
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
||||||
lib_deps =
|
lib_deps =
|
||||||
@ -79,7 +78,6 @@ platform = ${common_env_data.platform_espressif32}
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
board_build.partitions = ${common_env_data.board_build.partitions}
|
board_build.partitions = ${common_env_data.board_build.partitions}
|
||||||
board_upload.maximum_size = ${common_env_data.board_upload.maximum_size}
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
lib_deps =
|
||||||
@ -93,7 +91,6 @@ platform = ${common_env_data.platform_espressif32}
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
board_build.partitions = ${common_env_data.board_build.partitions}
|
board_build.partitions = ${common_env_data.board_build.partitions}
|
||||||
board_upload.maximum_size = ${common_env_data.board_upload.maximum_size}
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
lib_deps =
|
||||||
@ -107,11 +104,11 @@ platform = ${common_env_data.platform_espressif32}
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
board_build.partitions = ${common_env_data.board_build.partitions}
|
board_build.partitions = ${common_env_data.board_build.partitions}
|
||||||
board_upload.maximum_size = ${common_env_data.board_upload.maximum_size}
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common_env_data.lib_deps_display}
|
${common_env_data.lib_deps_display}
|
||||||
|
${common_env_data.lib_deps_gps}
|
||||||
build_flags =
|
build_flags =
|
||||||
${common_env_data.build_flags}
|
${common_env_data.build_flags}
|
||||||
-include "src/hal/ttgobeam.h"
|
-include "src/hal/ttgobeam.h"
|
||||||
@ -121,7 +118,6 @@ platform = espressif32@1.0.1
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
board_build.partitions = ${common_env_data.board_build.partitions}
|
board_build.partitions = ${common_env_data.board_build.partitions}
|
||||||
board_upload.maximum_size = ${common_env_data.board_upload.maximum_size}
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
lib_deps =
|
||||||
@ -135,7 +131,6 @@ platform = ${common_env_data.platform_espressif32}
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
board_build.partitions = ${common_env_data.board_build.partitions}
|
board_build.partitions = ${common_env_data.board_build.partitions}
|
||||||
board_upload.maximum_size = ${common_env_data.board_upload.maximum_size}
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
lib_deps =
|
||||||
@ -149,7 +144,6 @@ platform = ${common_env_data.platform_espressif32}
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
board_build.partitions = ${common_env_data.board_build.partitions}
|
board_build.partitions = ${common_env_data.board_build.partitions}
|
||||||
board_upload.maximum_size = ${common_env_data.board_upload.maximum_size}
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
lib_deps =
|
||||||
@ -163,7 +157,6 @@ platform = ${common_env_data.platform_espressif32}
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
board = lolin32
|
board = lolin32
|
||||||
board_build.partitions = ${common_env_data.board_build.partitions}
|
board_build.partitions = ${common_env_data.board_build.partitions}
|
||||||
board_upload.maximum_size = ${common_env_data.board_upload.maximum_size}
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 256000
|
upload_speed = 256000
|
||||||
lib_deps =
|
lib_deps =
|
||||||
@ -177,7 +170,6 @@ platform = ${common_env_data.platform_espressif32}
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
board = lolin32
|
board = lolin32
|
||||||
board_build.partitions = ${common_env_data.board_build.partitions}
|
board_build.partitions = ${common_env_data.board_build.partitions}
|
||||||
board_upload.maximum_size = ${common_env_data.board_upload.maximum_size}
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
lib_deps =
|
||||||
|
@ -22,7 +22,7 @@ void defaultConfig() {
|
|||||||
cfg.txpower = 15; // 2-15, lora tx power
|
cfg.txpower = 15; // 2-15, lora tx power
|
||||||
cfg.adrmode = 1; // 0=disabled, 1=enabled
|
cfg.adrmode = 1; // 0=disabled, 1=enabled
|
||||||
cfg.screensaver = 0; // 0=disabled, 1=enabled
|
cfg.screensaver = 0; // 0=disabled, 1=enabled
|
||||||
cfg.screenon = 1; // 0=disbaled, 1=enabled
|
cfg.screenon = 1; // 0=disabled, 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.sendcycle = SEND_SECS; // payload send cycle [seconds/2]
|
cfg.sendcycle = SEND_SECS; // payload send cycle [seconds/2]
|
||||||
@ -32,6 +32,7 @@ void defaultConfig() {
|
|||||||
cfg.wifiant = 0; // 0=internal, 1=external (for LoPy/LoPy4)
|
cfg.wifiant = 0; // 0=internal, 1=external (for LoPy/LoPy4)
|
||||||
cfg.vendorfilter = 1; // 0=disabled, 1=enabled
|
cfg.vendorfilter = 1; // 0=disabled, 1=enabled
|
||||||
cfg.rgblum = RGBLUMINOSITY; // RGB Led luminosity (0..100%)
|
cfg.rgblum = RGBLUMINOSITY; // RGB Led luminosity (0..100%)
|
||||||
|
cfg.gpsmode = 1; // 0=disabled, 1=enabled
|
||||||
|
|
||||||
strncpy( cfg.version, PROGVERSION, sizeof(cfg.version)-1 );
|
strncpy( cfg.version, PROGVERSION, sizeof(cfg.version)-1 );
|
||||||
}
|
}
|
||||||
@ -120,6 +121,9 @@ void saveConfig() {
|
|||||||
if( nvs_get_i8(my_handle, "rgblum", &flash8) != ESP_OK || flash8 != cfg.rgblum )
|
if( nvs_get_i8(my_handle, "rgblum", &flash8) != ESP_OK || flash8 != cfg.rgblum )
|
||||||
nvs_set_i8(my_handle, "rgblum", 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_i16(my_handle, "rssilimit", &flash16) != ESP_OK || flash16 != cfg.rssilimit )
|
if( nvs_get_i16(my_handle, "rssilimit", &flash16) != ESP_OK || flash16 != cfg.rssilimit )
|
||||||
nvs_set_i16(my_handle, "rssilimit", cfg.rssilimit);
|
nvs_set_i16(my_handle, "rssilimit", cfg.rssilimit);
|
||||||
|
|
||||||
@ -284,6 +288,14 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( nvs_get_i8(my_handle, "gpsmode", &flash8) == ESP_OK ) {
|
||||||
|
cfg.gpsmode = flash8;
|
||||||
|
ESP_LOGI(TAG, "GPSmode = %d", flash8);
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "GPSmode set to default %d", cfg.gpsmode);
|
||||||
|
saveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
nvs_close(my_handle);
|
nvs_close(my_handle);
|
||||||
ESP_LOGI(TAG, "Done");
|
ESP_LOGI(TAG, "Done");
|
||||||
|
|
||||||
|
@ -11,6 +11,11 @@
|
|||||||
#include <U8x8lib.h>
|
#include <U8x8lib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//GPS
|
||||||
|
#ifdef HAS_GPS
|
||||||
|
#include <TinyGPS++.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// LMIC-Arduino LoRaWAN Stack
|
// LMIC-Arduino LoRaWAN Stack
|
||||||
#include <lmic.h>
|
#include <lmic.h>
|
||||||
#include <hal/hal.h>
|
#include <hal/hal.h>
|
||||||
@ -32,7 +37,7 @@ typedef struct {
|
|||||||
uint8_t screensaver; // 0=disabled, 1=enabled
|
uint8_t screensaver; // 0=disabled, 1=enabled
|
||||||
uint8_t screenon; // 0=disabled, 1=enabled
|
uint8_t screenon; // 0=disabled, 1=enabled
|
||||||
uint8_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!
|
||||||
uint8_t sendcycle; // payload send cycle [seconds/2]
|
uint8_t sendcycle; // payload send cycle [seconds/2]
|
||||||
uint8_t wifichancycle; // wifi channel switch cycle [seconds/100]
|
uint8_t wifichancycle; // wifi channel switch cycle [seconds/100]
|
||||||
uint8_t blescantime; // BLE scan cycle duration [seconds]
|
uint8_t blescantime; // BLE scan cycle duration [seconds]
|
||||||
@ -40,14 +45,29 @@ typedef struct {
|
|||||||
uint8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4)
|
uint8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4)
|
||||||
uint8_t vendorfilter; // 0=disabled, 1=enabled
|
uint8_t vendorfilter; // 0=disabled, 1=enabled
|
||||||
uint8_t rgblum; // RGB Led luminosity (0..100%)
|
uint8_t rgblum; // RGB Led luminosity (0..100%)
|
||||||
char version[10]; // Firmware version
|
uint8_t gpsmode; // 0=disabled, 1=enabled
|
||||||
|
char version[10]; // Firmware version
|
||||||
} configData_t;
|
} configData_t;
|
||||||
|
|
||||||
|
#ifdef HAS_GPS
|
||||||
|
typedef struct {
|
||||||
|
uint32_t latitude;
|
||||||
|
uint32_t longitude;
|
||||||
|
uint8_t hdop;
|
||||||
|
uint8_t satellites;
|
||||||
|
uint16_t altitude;
|
||||||
|
} gpsStatus_t;
|
||||||
|
extern gpsStatus_t gps_status; // struct for storing gps data
|
||||||
|
extern TinyGPSPlus my_gps; // Make TinyGPS++ instance globally availabe
|
||||||
|
#endif
|
||||||
|
|
||||||
extern configData_t cfg;
|
extern configData_t cfg;
|
||||||
extern uint64_t uptimecounter;
|
extern uint64_t uptimecounter;
|
||||||
extern osjob_t sendjob;
|
extern osjob_t sendjob, rcmdjob;
|
||||||
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 std::set<uint16_t> macs;
|
extern std::set<uint16_t> macs;
|
||||||
extern hw_timer_t * channelSwitch; // hardware timer used for wifi channel switching
|
extern hw_timer_t * channelSwitch; // hardware timer used for wifi channel switching
|
||||||
|
extern xref2u1_t rcmd_data; // buffer for rcommand results size
|
||||||
|
extern u1_t rcmd_data_size; // buffer for rcommand results size
|
||||||
|
27
src/gpsread.cpp
Normal file
27
src/gpsread.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifdef HAS_GPS
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
// Local logging tag
|
||||||
|
static const char TAG[] = "main";
|
||||||
|
|
||||||
|
// GPS Read FreeRTos Task
|
||||||
|
void gps_loop(void * pvParameters) {
|
||||||
|
|
||||||
|
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
|
||||||
|
|
||||||
|
HardwareSerial GPS_Serial(1);
|
||||||
|
//GPS_Serial.begin(9600, SERIAL_8N1, 12, 15);
|
||||||
|
GPS_Serial.begin(HAS_GPS);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
while (GPS_Serial.available()) {
|
||||||
|
my_gps.encode(GPS_Serial.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAS_GPS
|
@ -3,11 +3,10 @@
|
|||||||
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
|
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
|
||||||
|
|
||||||
#define HAS_LED 21 // on board green LED_G1
|
#define HAS_LED 21 // on board green LED_G1
|
||||||
#define HAS_BUTTON GPIO_NUM_39 // button on board next to battery indicator LED (other one is reset)
|
#define HAS_BUTTON GPIO_NUM_0 // on board button "BOOT" (next to reset button)
|
||||||
#define HAS_BATTERY_PROBE ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7
|
#define HAS_BATTERY_PROBE ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7
|
||||||
#define BATT_FACTOR 2 // voltage divider 100k/100k on board
|
#define BATT_FACTOR 2 // voltage divider 100k/100k on board
|
||||||
// #define HAS_GPS // to be done
|
#define HAS_GPS 9600, SERIAL_8N1, 12, 15 //17-TX 18-RX
|
||||||
// GSP serial (9600, SERIAL_8N1, 12, 15); //17-TX 18-RX
|
|
||||||
|
|
||||||
// re-define pin definitions of pins_arduino.h
|
// re-define pin definitions of pins_arduino.h
|
||||||
#define PIN_SPI_SS 18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input
|
#define PIN_SPI_SS 18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input
|
||||||
|
@ -109,7 +109,7 @@ void do_send(osjob_t* j){
|
|||||||
|
|
||||||
// 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, "OP_TXRXPEND, not sending");
|
ESP_LOGI(TAG, "LoRa busy, rescheduling");
|
||||||
sprintf(display_lmic, "LORA BUSY");
|
sprintf(display_lmic, "LORA BUSY");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@ -129,11 +129,25 @@ void do_send(osjob_t* j){
|
|||||||
mydata[3] = 0;
|
mydata[3] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare upstream data transmission at the next possible time.
|
|
||||||
LMIC_setTxData2(1, mydata, sizeof(mydata), (cfg.countermode & 0x02));
|
|
||||||
ESP_LOGI(TAG, "Packet queued");
|
|
||||||
sprintf(display_lmic, "PACKET QUEUED");
|
|
||||||
|
|
||||||
|
// Prepare upstream data transmission at the next possible time.
|
||||||
|
LMIC_setTxData2(COUNTERPORT, mydata, sizeof(mydata), (cfg.countermode & 0x02));
|
||||||
|
ESP_LOGI(TAG, "%d bytes queued to send", sizeof(mydata));
|
||||||
|
sprintf(display_lmic, "PACKET QUEUED");
|
||||||
|
|
||||||
|
#ifdef HAS_GPS
|
||||||
|
if (cfg.gpsmode && my_gps.location.isValid()) {
|
||||||
|
gps_status.latitude = my_gps.location.lat();
|
||||||
|
gps_status.longitude = my_gps.location.lng();
|
||||||
|
gps_status.satellites = my_gps.satellites.value();
|
||||||
|
gps_status.hdop = my_gps.hdop.value();
|
||||||
|
gps_status.altitude = my_gps.altitude.meters();
|
||||||
|
LMIC_setTxData2(GPSPORT, (byte*)&gps_status, sizeof(gps_status), (cfg.countermode & 0x02));
|
||||||
|
ESP_LOGI(TAG, "HDOP=%d, SATS=%d, LAT=%d, LON=%d", gps_status.hdop, gps_status.satellites, gps_status.latitude, gps_status.longitude );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// clear counter if not in cumulative counter mode
|
// clear counter if not in cumulative counter mode
|
||||||
if (cfg.countermode != 1) {
|
if (cfg.countermode != 1) {
|
||||||
reset_counters(); // clear macs container and reset all counters
|
reset_counters(); // clear macs container and reset all counters
|
||||||
@ -200,8 +214,9 @@ void onEvent (ev_t ev) {
|
|||||||
unsigned char* buffer = new unsigned char[MAX_LEN_FRAME];
|
unsigned char* buffer = new unsigned char[MAX_LEN_FRAME];
|
||||||
memcpy(buffer, LMIC.frame, MAX_LEN_FRAME); //Copy data from cfg to char*
|
memcpy(buffer, LMIC.frame, MAX_LEN_FRAME); //Copy data from cfg to char*
|
||||||
int i, k = LMIC.dataBeg, l = LMIC.dataBeg+LMIC.dataLen-2;
|
int i, k = LMIC.dataBeg, l = LMIC.dataBeg+LMIC.dataLen-2;
|
||||||
for (i=k; i<=l; i+=2)
|
for (i=k; i<=l; i+=2) {
|
||||||
rcommand(buffer[i], buffer[i+1]);
|
rcommand(buffer[i], buffer[i+1]);
|
||||||
|
}
|
||||||
delete[] buffer; //free memory
|
delete[] buffer; //free memory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
52
src/main.cpp
52
src/main.cpp
@ -39,7 +39,7 @@ Refer to LICENSE.txt file in repository for more details.
|
|||||||
|
|
||||||
// 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; // 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
|
||||||
@ -52,6 +52,13 @@ 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 = NULL; // configure hardware timer used for cyclic display refresh
|
||||||
hw_timer_t * channelSwitch = NULL; // configure hardware timer used for wifi channel switching
|
hw_timer_t * channelSwitch = NULL; // configure hardware timer used for wifi channel switching
|
||||||
|
xref2u1_t rcmd_data; // buffer for rcommand results size
|
||||||
|
u1_t rcmd_data_size; // buffer for rcommand results size
|
||||||
|
|
||||||
|
#ifdef HAS_GPS
|
||||||
|
gpsStatus_t gps_status; // struct for storing gps data
|
||||||
|
TinyGPSPlus my_gps; // create TinyGPS++ instance
|
||||||
|
#endif
|
||||||
|
|
||||||
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying shared variable DisplayIRQ
|
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying shared variable DisplayIRQ
|
||||||
|
|
||||||
@ -130,37 +137,14 @@ void lorawan_loop(void * pvParameters) {
|
|||||||
|
|
||||||
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
|
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
|
||||||
|
|
||||||
//static uint16_t lorawait = 0;
|
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
|
os_runloop_once(); // execute LMIC jobs
|
||||||
// execute LMIC jobs
|
vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog
|
||||||
os_runloop_once();
|
|
||||||
|
|
||||||
/*
|
|
||||||
// check if payload is sent
|
|
||||||
while(LMIC.opmode & OP_TXRXPEND) {
|
|
||||||
if(!lorawait)
|
|
||||||
sprintf(display_lora, "LoRa wait");
|
|
||||||
lorawait++;
|
|
||||||
// in case sending really fails: reset LMIC and rejoin network
|
|
||||||
if( (lorawait % MAXLORARETRY ) == 0) {
|
|
||||||
ESP_LOGI(TAG, "Payload not sent, resetting LMIC and rejoin");
|
|
||||||
lorawait = 0;
|
|
||||||
LMIC_reset(); // Reset the MAC state. Session and pending data transfers will be discarded.
|
|
||||||
};
|
|
||||||
vTaskDelay(1000/portTICK_PERIOD_MS);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
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
|
||||||
@ -498,7 +482,6 @@ void setup() {
|
|||||||
delay(1000);
|
delay(1000);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// initialize button handling if needed
|
// initialize button handling if needed
|
||||||
#ifdef HAS_BUTTON
|
#ifdef HAS_BUTTON
|
||||||
strcat(features, " BTN_");
|
strcat(features, " BTN_");
|
||||||
@ -521,6 +504,11 @@ void setup() {
|
|||||||
antenna_init();
|
antenna_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// initialize gps if present
|
||||||
|
#ifdef HAS_GPS
|
||||||
|
strcat(features, " GPS");
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_DISPLAY
|
#ifdef HAS_DISPLAY
|
||||||
strcat(features, " OLED");
|
strcat(features, " OLED");
|
||||||
// initialize display
|
// initialize display
|
||||||
@ -588,7 +576,15 @@ xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 2048, ( void * ) 1, 1, NULL
|
|||||||
start_BLEscan();
|
start_BLEscan();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// if device has GPS and GPS function is enabled, start GPS reader task on core 0
|
||||||
|
#ifdef HAS_GPS
|
||||||
|
if (cfg.gpsmode) {
|
||||||
|
ESP_LOGI(TAG, "Starting GPS task on core 0");
|
||||||
|
xTaskCreatePinnedToCore(gps_loop, "gpsreader", 2048, ( void * ) 1, 1, NULL, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// kickoff sendjob -> joins network and rescedules sendjob for cyclic transmitting payload
|
// kickoff sendjob -> joins network and rescedules sendjob for cyclic transmitting payload
|
||||||
do_send(&sendjob);
|
do_send(&sendjob);
|
||||||
|
|
||||||
|
11
src/main.h
11
src/main.h
@ -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.71" // use max 10 chars here!
|
#define PROGVERSION "1.3.8" // use max 10 chars here!
|
||||||
#define PROGNAME "PAXCNT"
|
#define PROGNAME "PAXCNT"
|
||||||
|
|
||||||
//--- Declarations ---
|
//--- Declarations ---
|
||||||
@ -42,6 +42,11 @@ void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type);
|
|||||||
|
|
||||||
// defined in blescan.cpp
|
// defined in blescan.cpp
|
||||||
#ifdef BLECOUNTER
|
#ifdef BLECOUNTER
|
||||||
void start_BLEscan(void);
|
void start_BLEscan(void);
|
||||||
void stop_BLEscan(void);
|
void stop_BLEscan(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//defined in gpsread.cpp
|
||||||
|
#ifdef HAS_GPS
|
||||||
|
void gps_loop(void * pvParameters);
|
||||||
#endif
|
#endif
|
@ -37,11 +37,14 @@
|
|||||||
// 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] low memory threshold triggering a send cycle
|
#define MEM_LOW 2048 // [Bytes] low memory threshold triggering a send cycle
|
||||||
|
#define RETRANSMIT_RCMD 5 // [seconds] wait time before retransmitting rcommand results
|
||||||
|
|
||||||
// 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
|
||||||
#define MAXLORARETRY 500 // maximum count of TX retries if LoRa busy
|
#define MAXLORARETRY 500 // maximum count of TX retries if LoRa busy
|
||||||
#define RCMDPORT 2 // LoRaWAN Port on which device listenes for remote commands
|
#define RCMDPORT 2 // LoRaWAN Port on which device listenes for remote commands
|
||||||
|
#define GPSPORT 3 // LoRaWAN Port on which device sends gps data
|
||||||
|
#define COUNTERPORT 1 // LoRaWAN Port on which device sends counts
|
||||||
|
|
||||||
// Default RGB LED luminosity (in %)
|
// Default RGB LED luminosity (in %)
|
||||||
#define RGBLUMINOSITY 30 // 30%
|
#define RGBLUMINOSITY 30 // 30%
|
||||||
|
@ -29,6 +29,25 @@ typedef struct {
|
|||||||
uint32_t read_voltage(void);
|
uint32_t read_voltage(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// function sends result of get commands to LoRaWAN network
|
||||||
|
void do_transmit(osjob_t* j){
|
||||||
|
// check if there is a pending TX/RX job running, if yes then reschedule transmission
|
||||||
|
if (LMIC.opmode & OP_TXRXPEND) {
|
||||||
|
ESP_LOGI(TAG, "LoRa busy, rescheduling");
|
||||||
|
sprintf(display_lmic, "LORA BUSY");
|
||||||
|
os_setTimedCallback(&rcmdjob, os_getTime()+sec2osticks(RETRANSMIT_RCMD), do_transmit);
|
||||||
|
}
|
||||||
|
LMIC_setTxData2(RCMDPORT, rcmd_data, rcmd_data_size, 0); // send data unconfirmed on RCMD Port
|
||||||
|
ESP_LOGI(TAG, "%d bytes queued to send", rcmd_data_size);
|
||||||
|
sprintf(display_lmic, "PACKET QUEUED");
|
||||||
|
}
|
||||||
|
|
||||||
|
// help function to transmit result of get commands, since callback function do_transmit() cannot have params
|
||||||
|
void transmit(xref2u1_t mydata, u1_t mydata_size){
|
||||||
|
rcmd_data = mydata;
|
||||||
|
rcmd_data_size = mydata_size;
|
||||||
|
do_transmit(&rcmdjob);
|
||||||
|
}
|
||||||
|
|
||||||
// help function to assign LoRa datarates to numeric spreadfactor values
|
// help function to assign LoRa datarates to numeric spreadfactor values
|
||||||
void switch_lora (uint8_t sf, uint8_t tx) {
|
void switch_lora (uint8_t sf, uint8_t tx) {
|
||||||
@ -141,6 +160,14 @@ void set_display(uint8_t val) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void set_gps(uint8_t val) {
|
||||||
|
ESP_LOGI(TAG, "Remote command: set GPS to %s", val ? "on" : "off");
|
||||||
|
switch (val) {
|
||||||
|
case 1: cfg.gpsmode = val; break;
|
||||||
|
default: cfg.gpsmode = 0; break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void set_lorasf(uint8_t 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);
|
||||||
@ -204,30 +231,20 @@ void set_lorapower(uint8_t val) {
|
|||||||
switch_lora(cfg.lorasf, val);
|
switch_lora(cfg.lorasf, val);
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_noop (uint8_t val) {
|
|
||||||
ESP_LOGI(TAG, "Remote command: noop - doing nothing");
|
|
||||||
};
|
|
||||||
|
|
||||||
void get_config (uint8_t 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);
|
transmit((byte*)&cfg, sizeof(cfg));
|
||||||
LMIC_setTxData2(RCMDPORT, (byte*)&cfg, size, 0); // send data unconfirmed on RCMD Port
|
|
||||||
ESP_LOGI(TAG, "%d bytes queued in send queue", size);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_uptime (uint8_t 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);
|
transmit((byte*)&uptimecounter, sizeof(uptimecounter));
|
||||||
LMIC_setTxData2(RCMDPORT, (byte*)&uptimecounter, size, 0); // send data unconfirmed on RCMD Port
|
|
||||||
ESP_LOGI(TAG, "%d bytes queued in send queue", size);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_cputemp (uint8_t 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);
|
transmit((byte*)&temp, sizeof(temp));
|
||||||
LMIC_setTxData2(RCMDPORT, (byte*)&temp, size, 0); // send data unconfirmed on RCMD Port
|
|
||||||
ESP_LOGI(TAG, "%d bytes queued in send queue", size);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_voltage (uint8_t val) {
|
void get_voltage (uint8_t val) {
|
||||||
@ -237,9 +254,20 @@ void get_voltage (uint8_t val) {
|
|||||||
#else
|
#else
|
||||||
uint16_t voltage = 0;
|
uint16_t voltage = 0;
|
||||||
#endif
|
#endif
|
||||||
int size = sizeof(voltage);
|
transmit((byte*)&voltage, sizeof(voltage));
|
||||||
LMIC_setTxData2(RCMDPORT, (byte*)&voltage, size, 0); // send data unconfirmed on RCMD Port
|
};
|
||||||
ESP_LOGI(TAG, "%d bytes queued in send queue", size);
|
|
||||||
|
void get_gps (uint8_t val) {
|
||||||
|
ESP_LOGI(TAG, "Remote command: get gps status");
|
||||||
|
#ifdef HAS_GPS
|
||||||
|
gps_status.latitude = my_gps.location.lat();
|
||||||
|
gps_status.longitude = my_gps.location.lng();
|
||||||
|
gps_status.satellites = my_gps.satellites.value();
|
||||||
|
gps_status.hdop = my_gps.hdop.value();
|
||||||
|
gps_status.altitude = my_gps.altitude.meters();
|
||||||
|
transmit((byte*)&gps_status, sizeof(gps_status));
|
||||||
|
ESP_LOGI(TAG, "HDOP=%d, SATS=%d, LAT=%d, LON=%d", gps_status.hdop, gps_status.satellites, gps_status.latitude, gps_status.longitude );
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -249,7 +277,7 @@ void get_voltage (uint8_t val) {
|
|||||||
cmd_t table[] = {
|
cmd_t table[] = {
|
||||||
{0x01, set_rssi, true},
|
{0x01, set_rssi, true},
|
||||||
{0x02, set_countmode, true},
|
{0x02, set_countmode, true},
|
||||||
{0x03, set_noop, false},
|
{0x03, set_gps, true},
|
||||||
{0x04, set_display, true},
|
{0x04, set_display, true},
|
||||||
{0x05, set_lorasf, true},
|
{0x05, set_lorasf, true},
|
||||||
{0x06, set_lorapower, true},
|
{0x06, set_lorapower, true},
|
||||||
@ -266,7 +294,8 @@ cmd_t table[] = {
|
|||||||
{0x80, get_config, false},
|
{0x80, get_config, false},
|
||||||
{0x81, get_uptime, false},
|
{0x81, get_uptime, false},
|
||||||
{0x82, get_cputemp, false},
|
{0x82, get_cputemp, false},
|
||||||
{0x83, get_voltage, false}
|
{0x83, get_voltage, false},
|
||||||
|
{0x84, get_gps, false}
|
||||||
};
|
};
|
||||||
|
|
||||||
// check and execute remote command
|
// check and execute remote command
|
||||||
|
Loading…
Reference in New Issue
Block a user