From ac710ea6c849871e15e25265301060171f8ce94f Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Thu, 7 Jun 2018 22:49:35 +0200 Subject: [PATCH 01/35] readme.md updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 00efc562..3bb285e5 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ function Converter(decoded, port) { The device listenes for remote control commands on LoRaWAN Port 2. Each command is followed by exactly one parameter. -Multiple command/parameter pairs can be concatenated and sent in one single payload downlink. +For "set" commands, multiple command/parameter pairs can be concatenated and sent in one downlink, all commands are executed. For "get" commands, only one command/parameter pair is processed per downlink. Note: all settings are stored in NVRAM and will be reloaded when device starts. To reset device to factory settings press button (if device has one), or send remote command 09 02 09 00 unconfirmed(!) once. From da13c25e1db00852574643dcc82370088840e28b Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Thu, 7 Jun 2018 22:50:44 +0200 Subject: [PATCH 02/35] readme.md updated --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3bb285e5..fa21dcf2 100644 --- a/README.md +++ b/README.md @@ -140,11 +140,11 @@ function Converter(decoded, port) { } ``` -# Remote command set +# Remote control The device listenes for remote control commands on LoRaWAN Port 2. Each command is followed by exactly one parameter. -For "set" commands, multiple command/parameter pairs can be concatenated and sent in one downlink, all commands are executed. For "get" commands, only one command/parameter pair is processed per downlink. +For "set" commands, multiple command/parameter pairs can be concatenated and sent in one downlink, all commands are executed. For "get" commands, only one command/parameter pair per downlink is processed. Note: all settings are stored in NVRAM and will be reloaded when device starts. To reset device to factory settings press button (if device has one), or send remote command 09 02 09 00 unconfirmed(!) once. From f7ee3f85b0daac2c713dc6e3c3b8924cc58790ca Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Fri, 8 Jun 2018 22:41:37 +0200 Subject: [PATCH 03/35] GPS support added (experimental) --- README.md | 19 +++++++++---- platformio.ini | 16 +++-------- src/configmanager.cpp | 14 +++++++++- src/globals.h | 28 ++++++++++++++++--- src/gpsread.cpp | 27 ++++++++++++++++++ src/hal/ttgobeam.h | 5 ++-- src/lorawan.cpp | 27 ++++++++++++++---- src/main.cpp | 52 ++++++++++++++++------------------ src/main.h | 11 ++++++-- src/paxcounter.conf | 3 ++ src/rcommand.cpp | 65 +++++++++++++++++++++++++++++++------------ 11 files changed, 187 insertions(+), 80 deletions(-) create mode 100644 src/gpsread.cpp diff --git a/README.md b/README.md index fa21dcf2..255dcde6 100644 --- a/README.md +++ b/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 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] - 1 = screen saver on + 0 = GPS off [default] + 1 = GPS on, GPS data set (if present) added to payload 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 -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 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 14: Vendorfilter mode (0=disabled, 1=enabled) 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 @@ -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) +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 Copyright 2018 Oliver Brandmueller diff --git a/platformio.ini b/platformio.ini index 3fb30f06..a3eb86d6 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,11 +27,12 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng [common_env_data] platform_espressif32 = espressif32@>=1.0.2 board_build.partitions = no_ota.csv -board_upload.maximum_size = 2097152 lib_deps_display = U8g2@>=2.22.14 lib_deps_rgbled = - SmartLeds + SmartLeds@>=1.1.3 +lib_deps_gps = + TinyGPSPlus@>=1.0.0 build_flags = ; 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! <--- @@ -51,7 +52,6 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = heltec_wifi_lora_32 board_build.partitions = ${common_env_data.board_build.partitions} -board_upload.maximum_size = ${common_env_data.board_upload.maximum_size} monitor_speed = 115200 upload_speed = 115200 lib_deps = @@ -65,7 +65,6 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} -board_upload.maximum_size = ${common_env_data.board_upload.maximum_size} monitor_speed = 115200 upload_speed = 115200 lib_deps = @@ -79,7 +78,6 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} -board_upload.maximum_size = ${common_env_data.board_upload.maximum_size} monitor_speed = 115200 upload_speed = 921600 lib_deps = @@ -93,7 +91,6 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} -board_upload.maximum_size = ${common_env_data.board_upload.maximum_size} monitor_speed = 115200 upload_speed = 921600 lib_deps = @@ -107,11 +104,11 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} -board_upload.maximum_size = ${common_env_data.board_upload.maximum_size} monitor_speed = 115200 upload_speed = 921600 lib_deps = ${common_env_data.lib_deps_display} + ${common_env_data.lib_deps_gps} build_flags = ${common_env_data.build_flags} -include "src/hal/ttgobeam.h" @@ -121,7 +118,6 @@ platform = espressif32@1.0.1 framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} -board_upload.maximum_size = ${common_env_data.board_upload.maximum_size} monitor_speed = 115200 upload_speed = 921600 lib_deps = @@ -135,7 +131,6 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} -board_upload.maximum_size = ${common_env_data.board_upload.maximum_size} monitor_speed = 115200 upload_speed = 921600 lib_deps = @@ -149,7 +144,6 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = esp32dev board_build.partitions = ${common_env_data.board_build.partitions} -board_upload.maximum_size = ${common_env_data.board_upload.maximum_size} monitor_speed = 115200 upload_speed = 921600 lib_deps = @@ -163,7 +157,6 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = lolin32 board_build.partitions = ${common_env_data.board_build.partitions} -board_upload.maximum_size = ${common_env_data.board_upload.maximum_size} monitor_speed = 115200 upload_speed = 256000 lib_deps = @@ -177,7 +170,6 @@ platform = ${common_env_data.platform_espressif32} framework = arduino board = lolin32 board_build.partitions = ${common_env_data.board_build.partitions} -board_upload.maximum_size = ${common_env_data.board_upload.maximum_size} monitor_speed = 115200 upload_speed = 921600 lib_deps = diff --git a/src/configmanager.cpp b/src/configmanager.cpp index 97ae1ee5..867a071f 100644 --- a/src/configmanager.cpp +++ b/src/configmanager.cpp @@ -22,7 +22,7 @@ void defaultConfig() { cfg.txpower = 15; // 2-15, lora tx power cfg.adrmode = 1; // 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.rssilimit = 0; // threshold for rssilimiter, negative value! 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.vendorfilter = 1; // 0=disabled, 1=enabled cfg.rgblum = RGBLUMINOSITY; // RGB Led luminosity (0..100%) + cfg.gpsmode = 1; // 0=disabled, 1=enabled 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 ) 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 ) nvs_set_i16(my_handle, "rssilimit", cfg.rssilimit); @@ -284,6 +288,14 @@ void loadConfig() { 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); ESP_LOGI(TAG, "Done"); diff --git a/src/globals.h b/src/globals.h index 275f1c3b..420481fe 100644 --- a/src/globals.h +++ b/src/globals.h @@ -11,6 +11,11 @@ #include #endif +//GPS +#ifdef HAS_GPS + #include +#endif + // LMIC-Arduino LoRaWAN Stack #include #include @@ -32,7 +37,7 @@ typedef struct { uint8_t screensaver; // 0=disabled, 1=enabled uint8_t screenon; // 0=disabled, 1=enabled 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 wifichancycle; // wifi channel switch cycle [seconds/100] 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 vendorfilter; // 0=disabled, 1=enabled 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; +#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 uint64_t uptimecounter; -extern osjob_t sendjob; +extern osjob_t sendjob, rcmdjob; extern char display_lora[], display_lmic[]; extern int countermode, screensaver, adrmode, lorasf, txpower, rlim; extern uint16_t macs_total, macs_wifi, macs_ble; // MAC counters extern std::set macs; -extern hw_timer_t * channelSwitch; // hardware timer used for wifi channel switching \ No newline at end of file +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 diff --git a/src/gpsread.cpp b/src/gpsread.cpp new file mode 100644 index 00000000..9f5545c9 --- /dev/null +++ b/src/gpsread.cpp @@ -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 \ No newline at end of file diff --git a/src/hal/ttgobeam.h b/src/hal/ttgobeam.h index e47baa4c..ec6ba7e1 100644 --- a/src/hal/ttgobeam.h +++ b/src/hal/ttgobeam.h @@ -3,11 +3,10 @@ #define CFG_sx1276_radio 1 // HPD13A LoRa SoC #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 BATT_FACTOR 2 // voltage divider 100k/100k on board -// #define HAS_GPS // to be done -// GSP serial (9600, SERIAL_8N1, 12, 15); //17-TX 18-RX +#define HAS_GPS 9600, SERIAL_8N1, 12, 15 //17-TX 18-RX // re-define pin definitions of pins_arduino.h #define PIN_SPI_SS 18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input diff --git a/src/lorawan.cpp b/src/lorawan.cpp index ec80d252..dca47d95 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -109,7 +109,7 @@ void do_send(osjob_t* j){ // Check if there is a pending TX/RX job running if (LMIC.opmode & OP_TXRXPEND) { - ESP_LOGI(TAG, "OP_TXRXPEND, not sending"); + ESP_LOGI(TAG, "LoRa busy, rescheduling"); sprintf(display_lmic, "LORA BUSY"); goto end; } @@ -129,11 +129,25 @@ void do_send(osjob_t* j){ 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 if (cfg.countermode != 1) { 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]; memcpy(buffer, LMIC.frame, MAX_LEN_FRAME); //Copy data from cfg to char* 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]); + } delete[] buffer; //free memory } } diff --git a/src/main.cpp b/src/main.cpp index 9d169e01..e76efc26 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,7 +39,7 @@ Refer to LICENSE.txt file in repository for more details. // Initialize global variables 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 uint8_t DisplayState = 0; // globals for state machine 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 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 +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 @@ -130,37 +137,14 @@ void lorawan_loop(void * pvParameters) { configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check - //static uint16_t lorawait = 0; - while(1) { - - // execute LMIC jobs - 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 + os_runloop_once(); // execute LMIC jobs + vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog } } - /* end LMIC specific parts --------------------------------------------------------------- */ - /* beginn hardware specific parts -------------------------------------------------------- */ #ifdef HAS_DISPLAY @@ -498,7 +482,6 @@ void setup() { delay(1000); #endif - // initialize button handling if needed #ifdef HAS_BUTTON strcat(features, " BTN_"); @@ -521,6 +504,11 @@ void setup() { antenna_init(); #endif +// initialize gps if present +#ifdef HAS_GPS + strcat(features, " GPS"); +#endif + #ifdef HAS_DISPLAY strcat(features, " OLED"); // initialize display @@ -588,7 +576,15 @@ xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 2048, ( void * ) 1, 1, NULL start_BLEscan(); } #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 do_send(&sendjob); diff --git a/src/main.h b/src/main.h index d0ba04c2..f0be62a3 100644 --- a/src/main.h +++ b/src/main.h @@ -1,6 +1,6 @@ // 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" //--- Declarations --- @@ -42,6 +42,11 @@ void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); // defined in blescan.cpp #ifdef BLECOUNTER - void start_BLEscan(void); - void stop_BLEscan(void); + void start_BLEscan(void); + void stop_BLEscan(void); +#endif + +//defined in gpsread.cpp +#ifdef HAS_GPS + void gps_loop(void * pvParameters); #endif \ No newline at end of file diff --git a/src/paxcounter.conf b/src/paxcounter.conf index bc709486..47432573 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -37,11 +37,14 @@ // LoRa payload send cycle --> take care of duty cycle of LoRaWAN network! <-- #define SEND_SECS 120 // [seconds/2] -> 240 sec. #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 #define LORASFDEFAULT 9 // 7 ... 12 SF, according to LoRaWAN specs #define MAXLORARETRY 500 // maximum count of TX retries if LoRa busy #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 %) #define RGBLUMINOSITY 30 // 30% diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 816820c5..ff7a245c 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -29,6 +29,25 @@ typedef struct { uint32_t read_voltage(void); #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 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) { ESP_LOGI(TAG, "Remote command: set LoRa SF to %d", val); switch_lora(val, cfg.txpower); @@ -204,30 +231,20 @@ void set_lorapower(uint8_t 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) { ESP_LOGI(TAG, "Remote command: get configuration"); - int size = sizeof(configData_t); - LMIC_setTxData2(RCMDPORT, (byte*)&cfg, size, 0); // send data unconfirmed on RCMD Port - ESP_LOGI(TAG, "%d bytes queued in send queue", size); + transmit((byte*)&cfg, sizeof(cfg)); }; void get_uptime (uint8_t val) { ESP_LOGI(TAG, "Remote command: get uptime"); - int size = 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); + transmit((byte*)&uptimecounter, sizeof(uptimecounter)); }; void get_cputemp (uint8_t val) { ESP_LOGI(TAG, "Remote command: get cpu temperature"); float temp = temperatureRead(); - int size = 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); + transmit((byte*)&temp, sizeof(temp)); }; void get_voltage (uint8_t val) { @@ -237,9 +254,20 @@ void get_voltage (uint8_t val) { #else uint16_t voltage = 0; #endif - int size = 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); + transmit((byte*)&voltage, sizeof(voltage)); +}; + +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[] = { {0x01, set_rssi, true}, {0x02, set_countmode, true}, - {0x03, set_noop, false}, + {0x03, set_gps, true}, {0x04, set_display, true}, {0x05, set_lorasf, true}, {0x06, set_lorapower, true}, @@ -266,7 +294,8 @@ cmd_t table[] = { {0x80, get_config, false}, {0x81, get_uptime, false}, {0x82, get_cputemp, false}, - {0x83, get_voltage, false} + {0x83, get_voltage, false}, + {0x84, get_gps, false} }; // check and execute remote command From ef03acd29fceadef060d5c743d9999366ba67a8f Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Fri, 8 Jun 2018 22:43:49 +0200 Subject: [PATCH 04/35] GPS support added (experimental) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 255dcde6..763b8694 100644 --- a/README.md +++ b/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 2 = cyclic confirmed, like 0 but data is resent until confirmation by network received -0x03 set GPS on/off +0x03 set GPS on/off (NOT YET IMPLEMENTED) 0 = GPS off [default] - 1 = GPS on, GPS data set (if present) added to payload + 1 = GPS on, GPS data set (if present) is added to payload 0x04 set display on/off From 59cbe6939b88235b9a19121ef1ba13c0352c428b Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sat, 9 Jun 2018 10:42:12 +0200 Subject: [PATCH 05/35] testing --- src/gpsread.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 9f5545c9..38fd3627 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -11,13 +11,14 @@ 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); + //GPS_Serial.begin(HAS_GPS); + GPS_Serial.begin(9600, SERIAL_8N1, 12, 15 ); while(1) { while (GPS_Serial.available()) { my_gps.encode(GPS_Serial.read()); + ESP_LOGI(TAG, "GSP checksum passed / failed: %d / %d", my_gps.passedChecksum(), my_gps.failedChecksum()); } vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog From 4f2139a715c4174adb46804469feb7946ed0e6e0 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sat, 9 Jun 2018 13:18:59 +0200 Subject: [PATCH 06/35] testing GPS --- src/globals.h | 4 ++-- src/gpsread.cpp | 15 ++++++++++++--- src/hal/ttgobeam.h | 20 ++++++++++---------- src/lorawan.cpp | 8 ++------ src/main.cpp | 24 +++++++++++++++--------- src/main.h | 1 + src/rcommand.cpp | 8 +++----- 7 files changed, 45 insertions(+), 35 deletions(-) diff --git a/src/globals.h b/src/globals.h index 420481fe..e92e44a6 100644 --- a/src/globals.h +++ b/src/globals.h @@ -54,11 +54,11 @@ typedef struct { uint32_t latitude; uint32_t longitude; uint8_t hdop; - uint8_t satellites; + uint32_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 + extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe #endif extern configData_t cfg; diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 38fd3627..f396d8b7 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -5,7 +5,17 @@ // Local logging tag static const char TAG[] = "main"; -// GPS Read FreeRTos Task +// GPS read data to global struct + +void gps_read(){ + gps_status.latitude = gps.location.lat(); + gps_status.longitude = gps.location.lng(); + gps_status.satellites = (uint8_t) gps.satellites.value(); + gps_status.hdop = (uint8_t) (gps.hdop.value() / 100); + gps_status.altitude = (uint16_t) gps.altitude.meters(); +} + +// GPS serial feed FreeRTos Task void gps_loop(void * pvParameters) { configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check @@ -17,8 +27,7 @@ void gps_loop(void * pvParameters) { while(1) { while (GPS_Serial.available()) { - my_gps.encode(GPS_Serial.read()); - ESP_LOGI(TAG, "GSP checksum passed / failed: %d / %d", my_gps.passedChecksum(), my_gps.failedChecksum()); + gps.encode(GPS_Serial.read()); } vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog diff --git a/src/hal/ttgobeam.h b/src/hal/ttgobeam.h index ec6ba7e1..9a05de26 100644 --- a/src/hal/ttgobeam.h +++ b/src/hal/ttgobeam.h @@ -2,20 +2,20 @@ #define CFG_sx1276_radio 1 // HPD13A LoRa SoC -#define HAS_LED 21 // on board green LED_G1 -#define HAS_BUTTON GPIO_NUM_0 // on board button "BOOT" (next to reset button) +#define HAS_LED GPIO_NUM_21 // on board green LED_G1 +//#define HAS_BUTTON GPIO_NUM_39 // on board button "BOOT" (next to reset button) !! seems not to work!! #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 HAS_GPS 9600, SERIAL_8N1, 12, 15 //17-TX 18-RX +#define HAS_GPS 9600, SERIAL_8N1, 12, 15 // 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_MOSI 27 // ESP32 GPIO27 (Pin27) -- HPD13A MOSI/DSI (Pin6) SPI Data Input -#define PIN_SPI_MISO 19 // ESP32 GPIO19 (Pin19) -- HPD13A MISO/DSO (Pin7) SPI Data Output -#define PIN_SPI_SCK 5 // ESP32 GPIO5 (Pin5) -- HPD13A SCK (Pin5) SPI Clock Input +#define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input +#define PIN_SPI_MOSI GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- HPD13A MOSI/DSI (Pin6) SPI Data Input +#define PIN_SPI_MISO GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- HPD13A MISO/DSO (Pin7) SPI Data Output +#define PIN_SPI_SCK GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- HPD13A SCK (Pin5) SPI Clock Input // non arduino pin definitions #define RST LMIC_UNUSED_PIN // connected to ESP32 RST/EN -#define DIO0 26 // ESP32 GPIO26 <-> HPD13A IO0 -#define DIO1 33 // Lora1 <-> HPD13A IO1 // !! NEEDS EXTERNAL WIRING !! -#define DIO2 32 // Lora2 <-> HPD13A IO2 // needs external wiring, but not necessary for LoRa, only FSK +#define DIO0 GPIO_NUM_26 // ESP32 GPIO26 <-> HPD13A IO0 +#define DIO1 GPIO_NUM_33 // Lora1 <-> HPD13A IO1 // !! NEEDS EXTERNAL WIRING !! +#define DIO2 LMIC_UNUSED_PIN // Lora2 <-> HPD13A IO2 // needs external wiring, but not necessary for LoRa, only FSK diff --git a/src/lorawan.cpp b/src/lorawan.cpp index dca47d95..b1079c0f 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -137,12 +137,8 @@ void do_send(osjob_t* j){ 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(); + if (cfg.gpsmode && gps.location.isValid()) { + gps_read(); 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 ); } diff --git a/src/main.cpp b/src/main.cpp index e76efc26..61fd74e9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -57,15 +57,15 @@ 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 + TinyGPSPlus 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 IRQ handler shared variables std::set 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 -static volatile int ButtonPressed = 0, DisplayTimerIRQ = 0, ChannelTimerIRQ = 0; +static volatile int ButtonPressedIRQ = 0, DisplayTimerIRQ = 0, ChannelTimerIRQ = 0; // local Tag for logging static const char TAG[] = "main"; @@ -167,14 +167,14 @@ void lorawan_loop(void * pvParameters) { bool btstop = btStop(); #endif +// Button IRQ Handler Routine, IRAM_ATTR necessary here, see https://github.com/espressif/arduino-esp32/issues/855 #ifdef HAS_BUTTON - // Button IRQ - // IRAM_ATTR necessary here, see https://github.com/espressif/arduino-esp32/issues/855 void IRAM_ATTR ButtonIRQ() { - ButtonPressed++; + ButtonPressedIRQ++; } #endif +// Wifi Channel Rotation Timer IRQ Handler Routine void IRAM_ATTR ChannelSwitchIRQ() { portENTER_CRITICAL(&timerMux); ChannelTimerIRQ++; @@ -344,11 +344,14 @@ uint64_t uptime() { #ifdef HAS_BUTTON void readButton() { - if (ButtonPressed) { - ButtonPressed--; + if (ButtonPressedIRQ) { + portENTER_CRITICAL(&timerMux); + ButtonPressedIRQ--; + portEXIT_CRITICAL(&timerMux); + ESP_LOGI(TAG, "Button pressed"); ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults"); eraseConfig(); - esp_restart(); + esp_restart(); } } #endif @@ -623,6 +626,9 @@ void loop() { reset_salt(); // get new salt for salting hashes } + if ( (uptime() % 10000) == 0 ) + ESP_LOGI(TAG, "GPS NMEA data passed %d / failed: %d / with fix: %d || Sats: %d / HDOP: %d", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix(), gps.satellites.value(), gps.hdop.value()); + vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog } // end of infinite main loop diff --git a/src/main.h b/src/main.h index f0be62a3..18b9bfb8 100644 --- a/src/main.h +++ b/src/main.h @@ -48,5 +48,6 @@ void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); //defined in gpsread.cpp #ifdef HAS_GPS + void gps_read(void); void gps_loop(void * pvParameters); #endif \ No newline at end of file diff --git a/src/rcommand.cpp b/src/rcommand.cpp index ff7a245c..e01860fb 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -260,13 +260,11 @@ void get_voltage (uint8_t val) { 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(); + if (gps.location.isValid()) { + gps_read(); 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 }; From b43834a962f4ea89e6c37a37e23f32aad59db476 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sat, 9 Jun 2018 16:52:51 +0200 Subject: [PATCH 07/35] testing gps --- src/globals.h | 2 +- src/gpsread.cpp | 7 +++---- src/hal/ttgobeam.h | 3 ++- src/lorawan.cpp | 2 ++ src/main.cpp | 21 ++++++++++++++------- src/rcommand.cpp | 2 ++ 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/globals.h b/src/globals.h index e92e44a6..30dfd98b 100644 --- a/src/globals.h +++ b/src/globals.h @@ -58,7 +58,7 @@ typedef struct { uint16_t altitude; } gpsStatus_t; extern gpsStatus_t gps_status; // struct for storing gps data - extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe + //extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe #endif extern configData_t cfg; diff --git a/src/gpsread.cpp b/src/gpsread.cpp index f396d8b7..ee9880af 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -4,9 +4,8 @@ // Local logging tag static const char TAG[] = "main"; - +/* // GPS read data to global struct - void gps_read(){ gps_status.latitude = gps.location.lat(); gps_status.longitude = gps.location.lng(); @@ -15,7 +14,7 @@ void gps_read(){ gps_status.altitude = (uint16_t) gps.altitude.meters(); } -// GPS serial feed FreeRTos Task +/// GPS serial feed FreeRTos Task void gps_loop(void * pvParameters) { configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check @@ -33,5 +32,5 @@ void gps_loop(void * pvParameters) { vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog } } - +*/ #endif // HAS_GPS \ No newline at end of file diff --git a/src/hal/ttgobeam.h b/src/hal/ttgobeam.h index 9a05de26..d9e9c5e5 100644 --- a/src/hal/ttgobeam.h +++ b/src/hal/ttgobeam.h @@ -6,7 +6,8 @@ //#define HAS_BUTTON GPIO_NUM_39 // on board button "BOOT" (next to reset button) !! seems not to work!! #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 HAS_GPS 9600, SERIAL_8N1, 12, 15 +//#define HAS_GPS 9600, SERIAL_8N1, 12, 15 +#define HAS_GPS 1 // re-define pin definitions of pins_arduino.h #define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input diff --git a/src/lorawan.cpp b/src/lorawan.cpp index b1079c0f..967007b5 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -136,6 +136,7 @@ void do_send(osjob_t* j){ ESP_LOGI(TAG, "%d bytes queued to send", sizeof(mydata)); sprintf(display_lmic, "PACKET QUEUED"); + /* #ifdef HAS_GPS if (cfg.gpsmode && gps.location.isValid()) { gps_read(); @@ -143,6 +144,7 @@ void do_send(osjob_t* j){ 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 if (cfg.countermode != 1) { diff --git a/src/main.cpp b/src/main.cpp index 61fd74e9..f7b69266 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -57,7 +57,7 @@ u1_t rcmd_data_size; // buffer for rcommand results size #ifdef HAS_GPS gpsStatus_t gps_status; // struct for storing gps data - TinyGPSPlus gps; // create TinyGPS++ instance + TinyGPSPlus gps; // create TinyGPS++ instance #endif portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying IRQ handler shared variables @@ -482,7 +482,6 @@ void setup() { #ifdef HAS_RGB_LED rgb_set_color(COLOR_PINK); strcat(features, " RGB"); - delay(1000); #endif // initialize button handling if needed @@ -582,10 +581,10 @@ xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 2048, ( void * ) 1, 1, NULL // 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); - } + //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 @@ -599,6 +598,9 @@ do_send(&sendjob); void loop() { + HardwareSerial GPS_Serial(1); + GPS_Serial.begin(9600, SERIAL_8N1, 12, 15 ); + while (1) { // simple state machine for controlling uptime, display, LED, button, memory. @@ -626,8 +628,13 @@ void loop() { reset_salt(); // get new salt for salting hashes } + // read gps + while (GPS_Serial.available()) { + gps.encode(GPS_Serial.read()); + } + if ( (uptime() % 10000) == 0 ) - ESP_LOGI(TAG, "GPS NMEA data passed %d / failed: %d / with fix: %d || Sats: %d / HDOP: %d", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix(), gps.satellites.value(), gps.hdop.value()); + ESP_LOGI(TAG, "GPS NMEA data passed %d / failed: %d / with fix: %d || Sats: %d / HDOP: %d || m/s: %d / %d", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix(), gps.satellites.value(), gps.hdop.value(), gps.time.minute(), gps.time.second() ); vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog diff --git a/src/rcommand.cpp b/src/rcommand.cpp index e01860fb..9d4d1a23 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -259,6 +259,7 @@ void get_voltage (uint8_t val) { void get_gps (uint8_t val) { ESP_LOGI(TAG, "Remote command: get gps status"); + /* #ifdef HAS_GPS if (gps.location.isValid()) { gps_read(); @@ -266,6 +267,7 @@ void get_gps (uint8_t val) { ESP_LOGI(TAG, "HDOP=%d, SATS=%d, LAT=%d, LON=%d", gps_status.hdop, gps_status.satellites, gps_status.latitude, gps_status.longitude ); } #endif + */ }; From 77431dbdde33f0a48326f0d4a03b4086064ee02a Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sat, 9 Jun 2018 17:59:59 +0200 Subject: [PATCH 08/35] GPS testing --- platformio.ini | 2 +- src/globals.h | 2 +- src/gpsread.cpp | 3 +-- src/lorawan.cpp | 2 -- src/main.cpp | 13 ++++--------- src/rcommand.cpp | 2 -- 6 files changed, 7 insertions(+), 17 deletions(-) diff --git a/platformio.ini b/platformio.ini index a3eb86d6..eb008f51 100644 --- a/platformio.ini +++ b/platformio.ini @@ -32,7 +32,7 @@ lib_deps_display = lib_deps_rgbled = SmartLeds@>=1.1.3 lib_deps_gps = - TinyGPSPlus@>=1.0.0 + https://github.com/mikalhart/TinyGPSPlus.git build_flags = ; 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! <--- diff --git a/src/globals.h b/src/globals.h index 30dfd98b..e92e44a6 100644 --- a/src/globals.h +++ b/src/globals.h @@ -58,7 +58,7 @@ typedef struct { uint16_t altitude; } gpsStatus_t; extern gpsStatus_t gps_status; // struct for storing gps data - //extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe + extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe #endif extern configData_t cfg; diff --git a/src/gpsread.cpp b/src/gpsread.cpp index ee9880af..752b1d2e 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -4,7 +4,7 @@ // Local logging tag static const char TAG[] = "main"; -/* + // GPS read data to global struct void gps_read(){ gps_status.latitude = gps.location.lat(); @@ -32,5 +32,4 @@ void gps_loop(void * pvParameters) { vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog } } -*/ #endif // HAS_GPS \ No newline at end of file diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 967007b5..b1079c0f 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -136,7 +136,6 @@ void do_send(osjob_t* j){ ESP_LOGI(TAG, "%d bytes queued to send", sizeof(mydata)); sprintf(display_lmic, "PACKET QUEUED"); - /* #ifdef HAS_GPS if (cfg.gpsmode && gps.location.isValid()) { gps_read(); @@ -144,7 +143,6 @@ void do_send(osjob_t* j){ 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 if (cfg.countermode != 1) { diff --git a/src/main.cpp b/src/main.cpp index f7b69266..87fe4ffb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -581,10 +581,10 @@ xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 2048, ( void * ) 1, 1, NULL // 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); - //} + 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 @@ -628,11 +628,6 @@ void loop() { reset_salt(); // get new salt for salting hashes } - // read gps - while (GPS_Serial.available()) { - gps.encode(GPS_Serial.read()); - } - if ( (uptime() % 10000) == 0 ) ESP_LOGI(TAG, "GPS NMEA data passed %d / failed: %d / with fix: %d || Sats: %d / HDOP: %d || m/s: %d / %d", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix(), gps.satellites.value(), gps.hdop.value(), gps.time.minute(), gps.time.second() ); diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 9d4d1a23..e01860fb 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -259,7 +259,6 @@ void get_voltage (uint8_t val) { void get_gps (uint8_t val) { ESP_LOGI(TAG, "Remote command: get gps status"); - /* #ifdef HAS_GPS if (gps.location.isValid()) { gps_read(); @@ -267,7 +266,6 @@ void get_gps (uint8_t val) { ESP_LOGI(TAG, "HDOP=%d, SATS=%d, LAT=%d, LON=%d", gps_status.hdop, gps_status.satellites, gps_status.latitude, gps_status.longitude ); } #endif - */ }; From a43da889d194c57540f0544ac830643443c85ae1 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sat, 9 Jun 2018 19:20:34 +0200 Subject: [PATCH 09/35] testing GPS --- README.md | 2 +- platformio.ini | 1 + src/globals.h | 10 +++++----- src/gpsread.cpp | 35 ++++++++++++++++++++++++----------- src/hal/ttgobeam.h | 3 +-- src/lorawan.cpp | 2 -- src/main.cpp | 5 +---- 7 files changed, 33 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 763b8694..3925f72c 100644 --- a/README.md +++ b/README.md @@ -232,7 +232,7 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts. 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-L45) 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 2: Lora TXpower (2..15) diff --git a/platformio.ini b/platformio.ini index eb008f51..076c7674 100644 --- a/platformio.ini +++ b/platformio.ini @@ -33,6 +33,7 @@ lib_deps_rgbled = SmartLeds@>=1.1.3 lib_deps_gps = https://github.com/mikalhart/TinyGPSPlus.git +;beware of TinyGPSplus in PlatformIO library manager, it loads old v.092 labeled as 1.0.0 !! build_flags = ; 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! <--- diff --git a/src/globals.h b/src/globals.h index e92e44a6..e9c2fb5b 100644 --- a/src/globals.h +++ b/src/globals.h @@ -51,14 +51,14 @@ typedef struct { #ifdef HAS_GPS typedef struct { - uint32_t latitude; - uint32_t longitude; - uint8_t hdop; + double latitude; + double longitude; + double hdop; uint32_t satellites; - uint16_t altitude; + double altitude; } gpsStatus_t; extern gpsStatus_t gps_status; // struct for storing gps data - extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe + extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe #endif extern configData_t cfg; diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 752b1d2e..15b5ed50 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -9,9 +9,9 @@ static const char TAG[] = "main"; void gps_read(){ gps_status.latitude = gps.location.lat(); gps_status.longitude = gps.location.lng(); - gps_status.satellites = (uint8_t) gps.satellites.value(); - gps_status.hdop = (uint8_t) (gps.hdop.value() / 100); - gps_status.altitude = (uint16_t) gps.altitude.meters(); + gps_status.satellites = gps.satellites.value(); + gps_status.hdop = gps.hdop.value(); + gps_status.altitude = gps.altitude.meters(); } /// GPS serial feed FreeRTos Task @@ -19,17 +19,30 @@ void gps_loop(void * pvParameters) { configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check - HardwareSerial GPS_Serial(1); - //GPS_Serial.begin(HAS_GPS); - GPS_Serial.begin(9600, SERIAL_8N1, 12, 15 ); + HardwareSerial GPS_Serial(1); while(1) { - while (GPS_Serial.available()) { - gps.encode(GPS_Serial.read()); + if (cfg.gpsmode) + { + // if GPS function is enabled try serial connect to GPS device + GPS_Serial.begin(HAS_GPS); + + while(cfg.gpsmode) { + // feed GPS decoder with serial NMEA data from GPS device + while (GPS_Serial.available()) { + gps.encode(GPS_Serial.read()); + vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog + } + } + // after GPS function was disabled, close connect to GPS device + GPS_Serial.end(); } - + vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog - } -} + + } // end of infinite loop + +} // gps_loop() + #endif // HAS_GPS \ No newline at end of file diff --git a/src/hal/ttgobeam.h b/src/hal/ttgobeam.h index d9e9c5e5..9a05de26 100644 --- a/src/hal/ttgobeam.h +++ b/src/hal/ttgobeam.h @@ -6,8 +6,7 @@ //#define HAS_BUTTON GPIO_NUM_39 // on board button "BOOT" (next to reset button) !! seems not to work!! #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 HAS_GPS 9600, SERIAL_8N1, 12, 15 -#define HAS_GPS 1 +#define HAS_GPS 9600, SERIAL_8N1, 12, 15 // re-define pin definitions of pins_arduino.h #define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input diff --git a/src/lorawan.cpp b/src/lorawan.cpp index b1079c0f..24f7cb1d 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -129,8 +129,6 @@ void do_send(osjob_t* j){ mydata[3] = 0; } - - // 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)); diff --git a/src/main.cpp b/src/main.cpp index 87fe4ffb..4ab492d5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -598,9 +598,6 @@ do_send(&sendjob); void loop() { - HardwareSerial GPS_Serial(1); - GPS_Serial.begin(9600, SERIAL_8N1, 12, 15 ); - while (1) { // simple state machine for controlling uptime, display, LED, button, memory. @@ -629,7 +626,7 @@ void loop() { } if ( (uptime() % 10000) == 0 ) - ESP_LOGI(TAG, "GPS NMEA data passed %d / failed: %d / with fix: %d || Sats: %d / HDOP: %d || m/s: %d / %d", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix(), gps.satellites.value(), gps.hdop.value(), gps.time.minute(), gps.time.second() ); + ESP_LOGI(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix()); vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog From f5eb8cdc7695e4a62c927ac948aeec86bbd49216 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sat, 9 Jun 2018 21:15:35 +0200 Subject: [PATCH 10/35] testing GPS --- src/globals.h | 10 +++++----- src/gpsread.cpp | 12 +++++++----- src/hal/fipy.h | 18 +++++++++--------- src/hal/heltec.h | 20 ++++++++++---------- src/hal/lopy.h | 16 ++++++++-------- src/hal/lopy4.h | 14 +++++++------- src/hal/ttgobeam.h | 2 +- src/hal/ttgov1.h | 20 ++++++++++---------- src/hal/ttgov2.h | 16 ++++++++-------- src/hal/ttgov21.h | 20 ++++++++++---------- src/rcommand.cpp | 5 +++-- 11 files changed, 78 insertions(+), 75 deletions(-) diff --git a/src/globals.h b/src/globals.h index e9c2fb5b..711f0bd9 100644 --- a/src/globals.h +++ b/src/globals.h @@ -51,11 +51,11 @@ typedef struct { #ifdef HAS_GPS typedef struct { - double latitude; - double longitude; - double hdop; - uint32_t satellites; - double altitude; + float latitude; + float longitude; + float hdop; + uint8_t satellites; + uint16_t altitude; } gpsStatus_t; extern gpsStatus_t gps_status; // struct for storing gps data extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 15b5ed50..6669b80b 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -7,11 +7,13 @@ static const char TAG[] = "main"; // GPS read data to global struct void gps_read(){ - gps_status.latitude = gps.location.lat(); - gps_status.longitude = gps.location.lng(); - gps_status.satellites = gps.satellites.value(); - gps_status.hdop = gps.hdop.value(); - gps_status.altitude = gps.altitude.meters(); + gps_status.latitude = (float) gps.location.lat(); + gps_status.longitude = (float) gps.location.lng(); + gps_status.satellites = (uint8_t) gps.satellites.value(); + gps_status.hdop = (float) gps.hdop.value(); + gps_status.altitude = (uint16_t) gps.altitude.meters(); + ESP_LOGI(TAG, "Lat: %f / Lon: %f", gps_status.latitude, gps_status.longitude); + ESP_LOGI(TAG, "Sats: %d / HDOP: %f / Alti: %d", gps_status.satellites, gps_status.hdop, gps_status.altitude); } /// GPS serial feed FreeRTos Task diff --git a/src/hal/fipy.h b/src/hal/fipy.h index 7622d811..9f88928d 100644 --- a/src/hal/fipy.h +++ b/src/hal/fipy.h @@ -2,18 +2,18 @@ #define CFG_sx1272_radio 1 #define HAS_LED NOT_A_PIN // FiPy has no on board LED, so we use RGB LED -#define HAS_RGB_LED 0 // WS2812B RGB LED on GPIO0 +#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0 // Hardware pin definitions for Pycom FiPy board -#define PIN_SPI_SS 18 -#define PIN_SPI_MOSI 27 -#define PIN_SPI_MISO 19 -#define PIN_SPI_SCK 5 +#define PIN_SPI_SS GPIO_NUM_18 +#define PIN_SPI_MOSI GPIO_NUM_27 +#define PIN_SPI_MISO GPIO_NUM_19 +#define PIN_SPI_SCK GPIO_NUM_5 #define RST LMIC_UNUSED_PIN -#define DIO0 23 // LoRa IRQ -#define DIO1 23 // workaround +#define DIO0 GPIO_NUM_23 // LoRa IRQ +#define DIO1 GPIO_NUM_23 // workaround #define DIO2 LMIC_UNUSED_PIN // select WIFI antenna (internal = onboard / external = u.fl socket) -#define HAS_ANTENNA_SWITCH 21 // pin for switching wifi antenna -#define WIFI_ANTENNA 0 // 0 = internal, 1 = external +#define HAS_ANTENNA_SWITCH GPIO_NUM_21 // pin for switching wifi antenna +#define WIFI_ANTENNA 0 // 0 = internal, 1 = external diff --git a/src/hal/heltec.h b/src/hal/heltec.h index ed2e63db..74bdb89a 100644 --- a/src/hal/heltec.h +++ b/src/hal/heltec.h @@ -8,18 +8,18 @@ #define HAS_BUTTON GPIO_NUM_0 // button "PROG" on board // re-define pin definitions of pins_arduino.h -#define PIN_SPI_SS 18 // ESP32 GPIO18 (Pin18) -- SX1276 NSS (Pin19) SPI Chip Select Input -#define PIN_SPI_MOSI 27 // ESP32 GPIO27 (Pin27) -- SX1276 MOSI (Pin18) SPI Data Input -#define PIN_SPI_MISO 19 // ESP32 GPIO19 (Pin19) -- SX1276 MISO (Pin17) SPI Data Output -#define PIN_SPI_SCK 5 // ESP32 GPIO5 (Pin5) -- SX1276 SCK (Pin16) SPI Clock Input +#define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- SX1276 NSS (Pin19) SPI Chip Select Input +#define PIN_SPI_MOSI GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- SX1276 MOSI (Pin18) SPI Data Input +#define PIN_SPI_MISO GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- SX1276 MISO (Pin17) SPI Data Output +#define PIN_SPI_SCK GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- SX1276 SCK (Pin16) SPI Clock Input // non arduino pin definitions -#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 DIO1 33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout +#define RST GPIO_NUM_14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger Input +#define DIO0 GPIO_NUM_26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done +#define DIO1 GPIO_NUM_33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout #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 -#define OLED_RST 16 // ESP32 GPIO16 (Pin16) -- SD1306 RST -#define OLED_SDA 4 // ESP32 GPIO4 (Pin4) -- SD1306 D1+D2 -#define OLED_SCL 15 // ESP32 GPIO15 (Pin15) -- SD1306 D0 +#define OLED_RST GPIO_NUM_16 // ESP32 GPIO16 (Pin16) -- SD1306 RST +#define OLED_SDA GPIO_NUM_4 // ESP32 GPIO4 (Pin4) -- SD1306 D1+D2 +#define OLED_SCL GPIO_NUM_15 // ESP32 GPIO15 (Pin15) -- SD1306 D0 diff --git a/src/hal/lopy.h b/src/hal/lopy.h index 219a3a96..137c8e53 100644 --- a/src/hal/lopy.h +++ b/src/hal/lopy.h @@ -2,16 +2,16 @@ #define CFG_sx1272_radio 1 #define HAS_LED NOT_A_PIN // LoPy4 has no on board LED, so we use RGB LED on LoPy4 -#define HAS_RGB_LED 0 // WS2812B RGB LED on GPIO0 +#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0 // Hardware pin definitions for Pycom LoPy board -#define PIN_SPI_SS 17 -#define PIN_SPI_MOSI 27 -#define PIN_SPI_MISO 19 -#define PIN_SPI_SCK 5 -#define RST 18 -#define DIO0 23 // LoRa IRQ -#define DIO1 23 // workaround +#define PIN_SPI_SS GPIO_NUM_17 +#define PIN_SPI_MOSI GPIO_NUM_27 +#define PIN_SPI_MISO GPIO_NUM_19 +#define PIN_SPI_SCK GPIO_NUM_5 +#define RST GPIO_NUM_18 +#define DIO0 GPIO_NUM_23 // LoRa IRQ +#define DIO1 GPIO_NUM_23 // workaround #define DIO2 LMIC_UNUSED_PIN // select WIFI antenna (internal = onboard / external = u.fl socket) diff --git a/src/hal/lopy4.h b/src/hal/lopy4.h index aaed263a..586f1bb2 100644 --- a/src/hal/lopy4.h +++ b/src/hal/lopy4.h @@ -2,16 +2,16 @@ #define CFG_sx1276_radio 1 #define HAS_LED NOT_A_PIN // LoPy4 has no on board LED, so we use RGB LED on LoPy4 -#define HAS_RGB_LED 0 // WS2812B RGB LED on GPIO0 +#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0 // Hardware pin definitions for Pycom LoPy4 board -#define PIN_SPI_SS 18 -#define PIN_SPI_MOSI 27 -#define PIN_SPI_MISO 19 -#define PIN_SPI_SCK 5 +#define PIN_SPI_SS GPIO_NUM_18 +#define PIN_SPI_MOSI GPIO_NUM_27 +#define PIN_SPI_MISO GPIO_NUM_19 +#define PIN_SPI_SCK GPIO_NUM_5 #define RST LMIC_UNUSED_PIN -#define DIO0 23 // LoRa IRQ -#define DIO1 23 // workaround +#define DIO0 GPIO_NUM_23 // LoRa IRQ +#define DIO1 GPIO_NUM_23 // workaround #define DIO2 LMIC_UNUSED_PIN // select WIFI antenna (internal = onboard / external = u.fl socket) diff --git a/src/hal/ttgobeam.h b/src/hal/ttgobeam.h index 9a05de26..fb5dae8b 100644 --- a/src/hal/ttgobeam.h +++ b/src/hal/ttgobeam.h @@ -6,7 +6,7 @@ //#define HAS_BUTTON GPIO_NUM_39 // on board button "BOOT" (next to reset button) !! seems not to work!! #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 HAS_GPS 9600, SERIAL_8N1, 12, 15 +#define HAS_GPS 9600, SERIAL_8N1, GPIO_NUM_12, GPIO_NUM_15 // UBlox NEO 6M or 7M // re-define pin definitions of pins_arduino.h #define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input diff --git a/src/hal/ttgov1.h b/src/hal/ttgov1.h index c8e1a12d..df5735b5 100644 --- a/src/hal/ttgov1.h +++ b/src/hal/ttgov1.h @@ -9,18 +9,18 @@ #define HAS_BUTTON GPIO_NUM_0 // button "PRG" on board // re-define pin definitions of pins_arduino.h -#define PIN_SPI_SS 18 // ESP32 GPIO18 (Pin18) -- SX1276 NSS (Pin19) SPI Chip Select Input -#define PIN_SPI_MOSI 27 // ESP32 GPIO27 (Pin27) -- SX1276 MOSI (Pin18) SPI Data Input -#define PIN_SPI_MISO 19 // ESP32 GPIO19 (Pin19) -- SX1276 MISO (Pin17) SPI Data Output -#define PIN_SPI_SCK 5 // ESP32 GPIO5 (Pin5) -- SX1276 SCK (Pin16) SPI Clock Input +#define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- SX1276 NSS (Pin19) SPI Chip Select Input +#define PIN_SPI_MOSI GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- SX1276 MOSI (Pin18) SPI Data Input +#define PIN_SPI_MISO GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- SX1276 MISO (Pin17) SPI Data Output +#define PIN_SPI_SCK GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- SX1276 SCK (Pin16) SPI Clock Input // non arduino pin definitions -#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 DIO1 33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout +#define RST GPIO_NUM_14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger Input +#define DIO0 GPIO_NUM_26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done +#define DIO1 GPIO_NUM_33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout #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 -#define OLED_RST 16 // ESP32 GPIO16 (Pin16) -- SD1306 Reset -#define OLED_SDA 4 // ESP32 GPIO4 (Pin4) -- SD1306 Data -#define OLED_SCL 15 // ESP32 GPIO15 (Pin15) -- SD1306 Clock +#define OLED_RST GPIO_NUM_16 // ESP32 GPIO16 (Pin16) -- SD1306 Reset +#define OLED_SDA GPIO_NUM_4 // ESP32 GPIO4 (Pin4) -- SD1306 Data +#define OLED_SCL GPIO_NUM_15 // ESP32 GPIO15 (Pin15) -- SD1306 Clock diff --git a/src/hal/ttgov2.h b/src/hal/ttgov2.h index ebdfe87d..e4bb49b4 100644 --- a/src/hal/ttgov2.h +++ b/src/hal/ttgov2.h @@ -10,21 +10,21 @@ #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature // 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_MOSI 27 // ESP32 GPIO27 (Pin27) -- HPD13A MOSI/DSI (Pin6) SPI Data Input -#define PIN_SPI_MISO 19 // ESP32 GPIO19 (Pin19) -- HPD13A MISO/DSO (Pin7) SPI Data Output -#define PIN_SPI_SCK 5 // ESP32 GPIO5 (Pin5) -- HPD13A SCK (Pin5) SPI Clock Input +#define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input +#define PIN_SPI_MOSI GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- HPD13A MOSI/DSI (Pin6) SPI Data Input +#define PIN_SPI_MISO GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- HPD13A MISO/DSO (Pin7) SPI Data Output +#define PIN_SPI_SCK GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- HPD13A SCK (Pin5) SPI Clock Input // non arduino pin definitions #define RST LMIC_UNUSED_PIN // connected to ESP32 RST/EN -#define DIO0 26 // ESP32 GPIO26 wired on PCB to HPD13A -#define DIO1 33 // HPDIO1 on pcb, needs to be wired external to GPIO33 +#define DIO0 GPIO_NUM_26 // ESP32 GPIO26 wired on PCB to HPD13A +#define DIO1 GPIO_NUM_33 // HPDIO1 on pcb, needs to be wired external to GPIO33 #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 #define OLED_RST U8X8_PIN_NONE // connected to CPU RST/EN -#define OLED_SDA 21 // ESP32 GPIO4 (Pin4) -- SD1306 D1+D2 -#define OLED_SCL 22 // ESP32 GPIO15 (Pin15) -- SD1306 D0 +#define OLED_SDA GPIO_NUM_21 // ESP32 GPIO4 (Pin4) -- SD1306 D1+D2 +#define OLED_SCL GPIO_NUM_22 // ESP32 GPIO15 (Pin15) -- SD1306 D0 /* diff --git a/src/hal/ttgov21.h b/src/hal/ttgov21.h index ebedf11b..1e3b38ec 100644 --- a/src/hal/ttgov21.h +++ b/src/hal/ttgov21.h @@ -4,23 +4,23 @@ #define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C #define DISPLAY_FLIP 1 // rotated display -#define HAS_LED 23 // green on board LED_G3 (not in initial board version) +#define HAS_LED GPIO_NUM_23 // green on board LED_G3 (not in initial board version) #define HAS_BATTERY_PROBE ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 #define BATT_FACTOR 2 // voltage divider 100k/100k on board // 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_MOSI 27 // ESP32 GPIO27 (Pin27) -- HPD13A MOSI/DSI (Pin6) SPI Data Input -#define PIN_SPI_MISO 19 // ESP32 GPIO19 (Pin19) -- HPD13A MISO/DSO (Pin7) SPI Data Output -#define PIN_SPI_SCK 5 // ESP32 GPIO5 (Pin5) -- HPD13A SCK (Pin5) SPI Clock Input +#define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input +#define PIN_SPI_MOSI GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- HPD13A MOSI/DSI (Pin6) SPI Data Input +#define PIN_SPI_MISO GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- HPD13A MISO/DSO (Pin7) SPI Data Output +#define PIN_SPI_SCK GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- HPD13A SCK (Pin5) SPI Clock Input // non arduino pin definitions #define RST LMIC_UNUSED_PIN // connected to ESP32 RST/EN -#define DIO0 26 // ESP32 GPIO26 <-> HPD13A IO0 -#define DIO1 33 // ESP32 GPIO33 <-> HPDIO1 <-> HPD13A IO1 -#define DIO2 32 // ESP32 GPIO32 <-> HPDIO2 <-> HPD13A IO2 +#define DIO0 GPIO_NUM_26 // ESP32 GPIO26 <-> HPD13A IO0 +#define DIO1 GPIO_NUM_33 // ESP32 GPIO33 <-> HPDIO1 <-> HPD13A IO1 +#define DIO2 GPIO_NUM_32 // ESP32 GPIO32 <-> HPDIO2 <-> HPD13A IO2 // 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_SDA 21 // ESP32 GPIO4 (Pin4) -- SD1306 D1+D2 -#define OLED_SCL 22 // ESP32 GPIO15 (Pin15) -- SD1306 D0 \ No newline at end of file +#define OLED_SDA GPIO_NUM_21 // ESP32 GPIO4 (Pin4) -- SD1306 D1+D2 +#define OLED_SCL GPIO_NUM_22 // ESP32 GPIO15 (Pin15) -- SD1306 D0 \ No newline at end of file diff --git a/src/rcommand.cpp b/src/rcommand.cpp index e01860fb..926795a5 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -260,12 +260,13 @@ void get_voltage (uint8_t val) { void get_gps (uint8_t val) { ESP_LOGI(TAG, "Remote command: get gps status"); #ifdef HAS_GPS - if (gps.location.isValid()) { gps_read(); 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 ); - } + #else + ESP_LOGE(TAG, "No GPS device present"); #endif + }; From 485b4fb2f04ce0e837df390bb4a19dc4f4b88bc9 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sat, 9 Jun 2018 22:21:23 +0200 Subject: [PATCH 11/35] GPS support (experimental) --- src/globals.h | 2 +- src/gpsread.cpp | 16 +++++++--------- src/lorawan.cpp | 2 +- src/main.cpp | 6 +++++- src/rcommand.cpp | 6 ++---- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/globals.h b/src/globals.h index 711f0bd9..cb7b720f 100644 --- a/src/globals.h +++ b/src/globals.h @@ -53,8 +53,8 @@ typedef struct { typedef struct { float latitude; float longitude; - float hdop; uint8_t satellites; + uint16_t hdop; uint16_t altitude; } gpsStatus_t; extern gpsStatus_t gps_status; // struct for storing gps data diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 6669b80b..99c3b02e 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -5,18 +5,16 @@ // Local logging tag static const char TAG[] = "main"; -// GPS read data to global struct +// read GPS data and cast to global struct void gps_read(){ - gps_status.latitude = (float) gps.location.lat(); - gps_status.longitude = (float) gps.location.lng(); - gps_status.satellites = (uint8_t) gps.satellites.value(); - gps_status.hdop = (float) gps.hdop.value(); - gps_status.altitude = (uint16_t) gps.altitude.meters(); - ESP_LOGI(TAG, "Lat: %f / Lon: %f", gps_status.latitude, gps_status.longitude); - ESP_LOGI(TAG, "Sats: %d / HDOP: %f / Alti: %d", gps_status.satellites, gps_status.hdop, gps_status.altitude); + gps_status.latitude = (float) gps.location.lat(); + gps_status.longitude = (float) gps.location.lng(); + gps_status.satellites = (uint8_t) gps.satellites.value(); + gps_status.hdop = (uint16_t) gps.hdop.value(); + gps_status.altitude = (uint16_t) gps.altitude.meters(); } -/// GPS serial feed FreeRTos Task +// GPS serial feed FreeRTos Task void gps_loop(void * pvParameters) { configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 24f7cb1d..c2565e22 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -138,7 +138,7 @@ void do_send(osjob_t* j){ if (cfg.gpsmode && gps.location.isValid()) { gps_read(); 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 ); + ESP_LOGI(TAG, "HDOP=%d, SATS=%d, LAT=%f, LON=%f", gps_status.hdop, gps_status.satellites, gps_status.latitude, gps_status.longitude ); } #endif diff --git a/src/main.cpp b/src/main.cpp index 4ab492d5..e722ad72 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -470,6 +470,10 @@ void setup() { ESP_LOGI(TAG, "ESP32 SDK: %s", ESP.getSdkVersion()); #endif +#ifdef HAS_GPS + ESP_LOGI(TAG, "TinyGPS+ version %s", TinyGPSPlus::libraryVersion()); +#endif + // read settings from NVRAM loadConfig(); // includes initialize if necessary @@ -583,7 +587,7 @@ xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 2048, ( void * ) 1, 1, NULL #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); + xTaskCreatePinnedToCore(gps_loop, "gpsfeed", 2048, ( void * ) 1, 1, NULL, 0); } #endif diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 926795a5..de2ec09a 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -262,14 +262,12 @@ void get_gps (uint8_t val) { #ifdef HAS_GPS gps_read(); 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 ); + ESP_LOGI(TAG, "HDOP=%d, SATS=%d, LAT=%f, LON=%f", gps_status.hdop, gps_status.satellites, gps_status.latitude, gps_status.longitude ); #else - ESP_LOGE(TAG, "No GPS device present"); + ESP_LOGE(TAG, "GPS not present"); #endif - }; - // assign previously defined functions to set of numeric remote commands // format: opcode, function, flag (1 = do make settings persistent / 0 = don't) // From c036b044c005d80e55cd37be719f5584df022dad Mon Sep 17 00:00:00 2001 From: Florian Ludwig Date: Sat, 9 Jun 2018 22:28:20 +0200 Subject: [PATCH 12/35] move header into seperate files and have include guards --- src/configmanager.h | 8 ++++++++ src/lorawan.h | 10 ++++++++++ src/macsniff.h | 5 +++++ src/main.h | 20 ++++---------------- 4 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 src/configmanager.h create mode 100644 src/lorawan.h diff --git a/src/configmanager.h b/src/configmanager.h new file mode 100644 index 00000000..f9c5d3fa --- /dev/null +++ b/src/configmanager.h @@ -0,0 +1,8 @@ +#ifndef CONFIGMANAGER_H +#define CONFIGMANAGER_H + +void eraseConfig(void); +void saveConfig(void); +void loadConfig(void); + +#endif \ No newline at end of file diff --git a/src/lorawan.h b/src/lorawan.h new file mode 100644 index 00000000..de54b6e8 --- /dev/null +++ b/src/lorawan.h @@ -0,0 +1,10 @@ +#ifndef LORAWAN_H +#define LORAWAN_H + +void onEvent(ev_t ev); +void do_send(osjob_t* j); +void gen_lora_deveui(uint8_t * pdeveui); +void RevBytes(unsigned char* b, size_t c); +void get_hard_deveui(uint8_t *pdeveui); + +#endif \ No newline at end of file diff --git a/src/macsniff.h b/src/macsniff.h index a92046df..5eb07f30 100644 --- a/src/macsniff.h +++ b/src/macsniff.h @@ -1,3 +1,6 @@ +#ifndef MACSNIFF_H +#define MACSNIFF_H + // ESP32 Functions #include @@ -26,3 +29,5 @@ void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); // function defined in rokkithash.cpp uint32_t rokkit(const char * , int ); + +#endif \ No newline at end of file diff --git a/src/main.h b/src/main.h index 18b9bfb8..a2e0eeb0 100644 --- a/src/main.h +++ b/src/main.h @@ -1,4 +1,8 @@ +#include "configmanager.h" +#include "lorawan.h" +#include "macsniff.h" + // program version - note: increment version after modifications to configData_t struct!! #define PROGVERSION "1.3.8" // use max 10 chars here! #define PROGNAME "PAXCNT" @@ -23,22 +27,6 @@ void reset_counters(void); void blink_LED(uint16_t set_color, uint16_t set_blinkduration); void led_loop(void); -// defined in configmanager.cpp -void eraseConfig(void); -void saveConfig(void); -void loadConfig(void); - -// defined in lorawan.cpp -void onEvent(ev_t ev); -void do_send(osjob_t* j); -void gen_lora_deveui(uint8_t * pdeveui); -void RevBytes(unsigned char* b, size_t c); -void get_hard_deveui(uint8_t *pdeveui); - -// defined in wifisniffer.cpp -void wifi_sniffer_init(void); -void wifi_sniffer_set_channel(uint8_t channel); -void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); // defined in blescan.cpp #ifdef BLECOUNTER From 600ba2bd71c361d72afc69bddf6cf574bd675732 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sat, 9 Jun 2018 23:10:40 +0200 Subject: [PATCH 13/35] testing GPS (experimental) --- src/globals.h | 4 ++-- src/gpsread.cpp | 39 +++++++++++++++++++++++++-------------- src/hal/lopy.h | 5 +++++ src/hal/lopy4.h | 5 +++++ src/hal/ttgobeam.h | 3 ++- 5 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/globals.h b/src/globals.h index cb7b720f..04ef15d7 100644 --- a/src/globals.h +++ b/src/globals.h @@ -51,8 +51,8 @@ typedef struct { #ifdef HAS_GPS typedef struct { - float latitude; - float longitude; + uint32_t latitude; + uint32_t longitude; uint8_t satellites; uint16_t hdop; uint16_t altitude; diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 99c3b02e..4747f7a6 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -7,8 +7,8 @@ static const char TAG[] = "main"; // read GPS data and cast to global struct void gps_read(){ - gps_status.latitude = (float) gps.location.lat(); - gps_status.longitude = (float) gps.location.lng(); + gps_status.latitude = (uint32_t) gps.location.lat() * 100; + gps_status.longitude = (uint32_t) gps.location.lng() * 100; gps_status.satellites = (uint8_t) gps.satellites.value(); gps_status.hdop = (uint16_t) gps.hdop.value(); gps_status.altitude = (uint16_t) gps.altitude.meters(); @@ -25,18 +25,29 @@ void gps_loop(void * pvParameters) { if (cfg.gpsmode) { - // if GPS function is enabled try serial connect to GPS device - GPS_Serial.begin(HAS_GPS); - - while(cfg.gpsmode) { - // feed GPS decoder with serial NMEA data from GPS device - while (GPS_Serial.available()) { - gps.encode(GPS_Serial.read()); - vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog - } - } - // after GPS function was disabled, close connect to GPS device - GPS_Serial.end(); + #ifdef GPS_SERIAL + // serial connect to GPS device + GPS_Serial.begin(GPS_SERIAL); + + while(cfg.gpsmode) { + // feed GPS decoder with serial NMEA data from GPS device + while (GPS_Serial.available()) { + gps.encode(GPS_Serial.read()); + vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog + } + } + // after GPS function was disabled, close connect to GPS device + GPS_Serial.end(); + #endif + + #ifdef GPS_I2C + // I2C connect to GPS device + + /* + to be done + */ + + #endif } vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog diff --git a/src/hal/lopy.h b/src/hal/lopy.h index 137c8e53..dd5a0b7b 100644 --- a/src/hal/lopy.h +++ b/src/hal/lopy.h @@ -4,6 +4,11 @@ #define HAS_LED NOT_A_PIN // LoPy4 has no on board LED, so we use RGB LED on LoPy4 #define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0 +// use only if your LoPy lives on a Pytrack expansion board +//#define HAS_GPS 1 +//#define GPS_I2C GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL +//#define HAS_BUTTON GPIO_NUM_4 + // Hardware pin definitions for Pycom LoPy board #define PIN_SPI_SS GPIO_NUM_17 #define PIN_SPI_MOSI GPIO_NUM_27 diff --git a/src/hal/lopy4.h b/src/hal/lopy4.h index 586f1bb2..721b11ef 100644 --- a/src/hal/lopy4.h +++ b/src/hal/lopy4.h @@ -4,6 +4,11 @@ #define HAS_LED NOT_A_PIN // LoPy4 has no on board LED, so we use RGB LED on LoPy4 #define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0 +// use only if your LoPy lives on a Pytrack expansion board +//#define HAS_GPS 1 +//#define GPS_I2C GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL +//#define HAS_BUTTON GPIO_NUM_4 + // Hardware pin definitions for Pycom LoPy4 board #define PIN_SPI_SS GPIO_NUM_18 #define PIN_SPI_MOSI GPIO_NUM_27 diff --git a/src/hal/ttgobeam.h b/src/hal/ttgobeam.h index fb5dae8b..aafbb3a9 100644 --- a/src/hal/ttgobeam.h +++ b/src/hal/ttgobeam.h @@ -6,7 +6,8 @@ //#define HAS_BUTTON GPIO_NUM_39 // on board button "BOOT" (next to reset button) !! seems not to work!! #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 HAS_GPS 9600, SERIAL_8N1, GPIO_NUM_12, GPIO_NUM_15 // UBlox NEO 6M or 7M +#define HAS_GPS 1 // use on board GPS +#define GPS_SERIAL 9600, SERIAL_8N1, GPIO_NUM_12, GPIO_NUM_15 // UBlox NEO 6M or 7M with default configuration // re-define pin definitions of pins_arduino.h #define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input From 21c387c0289d595bdcc2cc8ca365fd7146149908 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 10 Jun 2018 00:45:27 +0200 Subject: [PATCH 14/35] GPS testing (experimental) --- src/gpsread.cpp | 12 +++++++++--- src/lorawan.cpp | 2 +- src/rcommand.cpp | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 4747f7a6..0cedc315 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -7,8 +7,8 @@ static const char TAG[] = "main"; // read GPS data and cast to global struct void gps_read(){ - gps_status.latitude = (uint32_t) gps.location.lat() * 100; - gps_status.longitude = (uint32_t) gps.location.lng() * 100; + gps_status.latitude = (uint32_t) (gps.location.lat() * 1000000); + gps_status.longitude = (uint32_t) (gps.location.lng() * 1000000); gps_status.satellites = (uint8_t) gps.satellites.value(); gps_status.hdop = (uint16_t) gps.hdop.value(); gps_status.altitude = (uint16_t) gps.altitude.meters(); @@ -19,7 +19,13 @@ void gps_loop(void * pvParameters) { configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check - HardwareSerial GPS_Serial(1); + #ifdef GPS_SERIAL + HardwareSerial GPS_Serial(1); + #endif + + #ifdef GPS_I2C + // to be done + #endif while(1) { diff --git a/src/lorawan.cpp b/src/lorawan.cpp index c2565e22..92d2f61c 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -138,7 +138,7 @@ void do_send(osjob_t* j){ if (cfg.gpsmode && gps.location.isValid()) { gps_read(); LMIC_setTxData2(GPSPORT, (byte*)&gps_status, sizeof(gps_status), (cfg.countermode & 0x02)); - ESP_LOGI(TAG, "HDOP=%d, SATS=%d, LAT=%f, LON=%f", gps_status.hdop, gps_status.satellites, gps_status.latitude, gps_status.longitude ); + ESP_LOGI(TAG, "lat=%f / lon=%f | Sats=%u | HDOP=%u | Alti=%u", gps_status.latitude / 1000000, gps_status.longitude / 1000000, gps_status.satellites, gps_status.hdop, gps_status.altitude); } #endif diff --git a/src/rcommand.cpp b/src/rcommand.cpp index de2ec09a..fa061f9f 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -262,7 +262,7 @@ void get_gps (uint8_t val) { #ifdef HAS_GPS gps_read(); transmit((byte*)&gps_status, sizeof(gps_status)); - ESP_LOGI(TAG, "HDOP=%d, SATS=%d, LAT=%f, LON=%f", gps_status.hdop, gps_status.satellites, gps_status.latitude, gps_status.longitude ); + ESP_LOGI(TAG, "lat=%f / lon=%f | Sats=%u | HDOP=%u | Alti=%u", gps_status.latitude / 1000000, gps_status.longitude / 1000000, gps_status.satellites, gps_status.hdop, gps_status.altitude); #else ESP_LOGE(TAG, "GPS not present"); #endif From e6db7ad314576cc94b7dcfa4181ec55748fdc765 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 10 Jun 2018 00:56:22 +0200 Subject: [PATCH 15/35] testing GPS (experimental) --- README.md | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3925f72c..4bbcbb7c 100644 --- a/README.md +++ b/README.md @@ -119,12 +119,24 @@ Decoder: ```javascript function Decoder(bytes, port) { - var decoded = {}; - if (port === 1) { - decoded.wifi = (bytes[0] << 8) | bytes[1]; - decoded.ble = (bytes[2] << 8) | bytes[3]; - } - return decoded; + // Decode an uplink message from a buffer + // (array) of bytes to an object of fields. + var decoded = {}; + + if (port === 1) { + decoded.wifi = (bytes[0] << 8) | bytes[1]; + decoded.ble = (bytes[2] << 8) | bytes[3]; + } + + if (port === 2) { + decoded.latitude = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]; + decoded.longitude = (bytes[7] << 24) | (bytes[6] << 16) | (bytes[5] << 8) | bytes[4]; + decoded.satellites = (bytes[9] << 8) | bytes[8]; + decoded.hdop = (bytes[11] << 8) | bytes[10]; + decoded.altitude = (bytes[13] << 8) | bytes[12]; + } + + return decoded; } ``` @@ -136,6 +148,10 @@ function Converter(decoded, port) { if (port === 1) { converted.pax = converted.ble + converted.wifi; } + if (port === 2) { + converted.latitude = converted.latitude / 100000; + converted.longitude = converted.longitude / 100000; + converted.hdop = converted.hdop / 100; return converted; } ``` From fadb38ef84306fc7df3bbf291823a1f2a167cdff Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 10 Jun 2018 01:02:11 +0200 Subject: [PATCH 16/35] testing GPS (experimental) --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4bbcbb7c..063d6ed4 100644 --- a/README.md +++ b/README.md @@ -119,8 +119,7 @@ Decoder: ```javascript function Decoder(bytes, port) { - // Decode an uplink message from a buffer - // (array) of bytes to an object of fields. + // decode counter messages var decoded = {}; if (port === 1) { @@ -128,7 +127,8 @@ function Decoder(bytes, port) { decoded.ble = (bytes[2] << 8) | bytes[3]; } - if (port === 2) { + // decode GPS messages + if (port === 3) { decoded.latitude = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]; decoded.longitude = (bytes[7] << 24) | (bytes[6] << 16) | (bytes[5] << 8) | bytes[4]; decoded.satellites = (bytes[9] << 8) | bytes[8]; @@ -145,10 +145,12 @@ Converter: ```javascript function Converter(decoded, port) { var converted = decoded; + // sum up ble + wifi counters if (port === 1) { converted.pax = converted.ble + converted.wifi; } - if (port === 2) { + // convert some GPS values + if (port === 3) { converted.latitude = converted.latitude / 100000; converted.longitude = converted.longitude / 100000; converted.hdop = converted.hdop / 100; From a8f55ed1b0e89f31557a5a4e750a04f3b88895d0 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 10 Jun 2018 01:07:37 +0200 Subject: [PATCH 17/35] readme.md --- README.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 063d6ed4..1a8130df 100644 --- a/README.md +++ b/README.md @@ -102,17 +102,25 @@ Legend for RGB LED (LoPy/LoPy4/FiPy/Lolin32 only): # Payload -FPort1: +LoRaWAN Port #1: Counter data - byte 1: 16-bit WiFi counter, MSB - byte 2: 16-bit WiFi counter, LSB - byte 3: 16-bit BLE counter, MSB - byte 4: 16-bit BLE counter, LSB + byte 1: WiFi counter, MSB + byte 2: WiFi counter, LSB + byte 3: BLE counter, MSB + byte 4: BLE counter, LSB -FPort2: +LoRaWAN Port #2: Remote commands see remote command set +LoRaWAN Port #3: GPS data + + bytes 1-4: Latitude + bytes 4-8: Longitude + bytes 9-10: Satellites + bytes 11-12: HDOP + bytes 13-14: Altitude + If you're using [TheThingsNetwork](https://www.thethingsnetwork.org/) you may want to use a payload converter. Go to TTN Console - Application - Payload Formats and paste the code example below in tabs Decoder and Converter. Make sure that your application parses the fields `pax`, `ble` and `wifi`. Decoder: From 89afc4cbdf98bdd5902603e8d43269eda5b7cd71 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 10 Jun 2018 01:09:20 +0200 Subject: [PATCH 18/35] readme.md updated --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1a8130df..e8562b2e 100644 --- a/README.md +++ b/README.md @@ -115,11 +115,11 @@ LoRaWAN Port #2: Remote commands LoRaWAN Port #3: GPS data - bytes 1-4: Latitude - bytes 4-8: Longitude - bytes 9-10: Satellites - bytes 11-12: HDOP - bytes 13-14: Altitude + bytes 1-4: Latitude + bytes 4-8: Longitude + bytes 9-10: Satellites + bytes 11-12: HDOP + bytes 13-14: Altitude If you're using [TheThingsNetwork](https://www.thethingsnetwork.org/) you may want to use a payload converter. Go to TTN Console - Application - Payload Formats and paste the code example below in tabs Decoder and Converter. Make sure that your application parses the fields `pax`, `ble` and `wifi`. From 6a23e175e4b1edaf909c44393b7f0a268bc26dca Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 10 Jun 2018 01:09:58 +0200 Subject: [PATCH 19/35] readme.md updated --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e8562b2e..8fa619c2 100644 --- a/README.md +++ b/README.md @@ -118,8 +118,8 @@ LoRaWAN Port #3: GPS data bytes 1-4: Latitude bytes 4-8: Longitude bytes 9-10: Satellites - bytes 11-12: HDOP - bytes 13-14: Altitude + bytes 11-12: HDOP + bytes 13-14: Altitude If you're using [TheThingsNetwork](https://www.thethingsnetwork.org/) you may want to use a payload converter. Go to TTN Console - Application - Payload Formats and paste the code example below in tabs Decoder and Converter. Make sure that your application parses the fields `pax`, `ble` and `wifi`. From b69e90762b1ea55ebbfdc1a262bd3ba3d939a872 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 10 Jun 2018 01:10:51 +0200 Subject: [PATCH 20/35] readme.md updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8fa619c2..75c4fe32 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ LoRaWAN Port #1: Counter data LoRaWAN Port #2: Remote commands - see remote command set + *see remote control* LoRaWAN Port #3: GPS data From 49fc3fd9344ef92118d4e23afc2583d2891c9816 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 10 Jun 2018 01:13:30 +0200 Subject: [PATCH 21/35] readme.md updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 75c4fe32..54f20320 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ LoRaWAN Port #1: Counter data LoRaWAN Port #2: Remote commands - *see remote control* + see remote control LoRaWAN Port #3: GPS data From 3321931a465ba65c5daeb9d921e3285f80248802 Mon Sep 17 00:00:00 2001 From: Florian Ludwig Date: Sun, 10 Jun 2018 13:24:56 +0200 Subject: [PATCH 22/35] fix build on devices without gps --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index e722ad72..e20b3c25 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -629,8 +629,10 @@ void loop() { reset_salt(); // get new salt for salting hashes } + #ifdef HAS_GPS if ( (uptime() % 10000) == 0 ) ESP_LOGI(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix()); + #endif vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog From aa1b4172fed92c5391b13f2a8cfbecfda04ea241 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 10 Jun 2018 15:34:21 +0200 Subject: [PATCH 23/35] GPS testing --- README.md | 68 ++++++++++++++++++++++--------------------------- src/gpsread.cpp | 41 +++++++++++++++++++---------- src/hal/lopy.h | 8 ++++-- src/hal/lopy4.h | 8 ++++-- src/lorawan.cpp | 27 +++++++++++--------- src/main.cpp | 4 +-- 6 files changed, 87 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 54f20320..bb6fbcac 100644 --- a/README.md +++ b/README.md @@ -102,50 +102,43 @@ Legend for RGB LED (LoPy/LoPy4/FiPy/Lolin32 only): # Payload -LoRaWAN Port #1: Counter data +LoRaWAN Port #1: - byte 1: WiFi counter, MSB - byte 2: WiFi counter, LSB - byte 3: BLE counter, MSB - byte 4: BLE counter, LSB + byte 1: Paxcount Wifi, MSB + byte 2: Paxcount WiFi, LSB + byte 3: Paxcount Bluetooth, MSB + byte 4: Paxcount Bluetooth, LSB + bytes 5-8: GPS latitude + bytes 9-12: GPS longitude + bytes 13-14: GPS satellites + bytes 15-16: GPS HDOP + bytes 17-18: GPS altitude -LoRaWAN Port #2: Remote commands +LoRaWAN Port #2: see remote control -LoRaWAN Port #3: GPS data - - bytes 1-4: Latitude - bytes 4-8: Longitude - bytes 9-10: Satellites - bytes 11-12: HDOP - bytes 13-14: Altitude - If you're using [TheThingsNetwork](https://www.thethingsnetwork.org/) you may want to use a payload converter. Go to TTN Console - Application - Payload Formats and paste the code example below in tabs Decoder and Converter. Make sure that your application parses the fields `pax`, `ble` and `wifi`. Decoder: ```javascript function Decoder(bytes, port) { - // decode counter messages var decoded = {}; if (port === 1) { decoded.wifi = (bytes[0] << 8) | bytes[1]; decoded.ble = (bytes[2] << 8) | bytes[3]; - } - - // decode GPS messages - if (port === 3) { - decoded.latitude = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]; - decoded.longitude = (bytes[7] << 24) | (bytes[6] << 16) | (bytes[5] << 8) | bytes[4]; - decoded.satellites = (bytes[9] << 8) | bytes[8]; - decoded.hdop = (bytes[11] << 8) | bytes[10]; - decoded.altitude = (bytes[13] << 8) | bytes[12]; + decoded.latitude = ((bytes[7] << 24) | (bytes[6] << 16) | (bytes[5] << 8) | bytes[4]); + decoded.longitude = ((bytes[11] << 24) | (bytes[10] << 16) | (bytes[9] << 8) | bytes[8]); + decoded.satellites = (bytes[13] << 8) | bytes[12]; + decoded.hdop = (bytes[15] << 8) | bytes[14]; + decoded.altitude = (bytes[17] << 8) | bytes[16]; } return decoded; } +} ``` Converter: @@ -153,24 +146,24 @@ Converter: ```javascript function Converter(decoded, port) { var converted = decoded; - // sum up ble + wifi counters + if (port === 1) { converted.pax = converted.ble + converted.wifi; + converted.hdop /= 100; + converted.latitude /= 1000000; + converted.longitude /= 1000000; } - // convert some GPS values - if (port === 3) { - converted.latitude = converted.latitude / 100000; - converted.longitude = converted.longitude / 100000; - converted.hdop = converted.hdop / 100; + return converted; } +} ``` -# Remote control +# Remote command set The device listenes for remote control commands on LoRaWAN Port 2. Each command is followed by exactly one parameter. -For "set" commands, multiple command/parameter pairs can be concatenated and sent in one downlink, all commands are executed. For "get" commands, only one command/parameter pair per downlink is processed. +Multiple command/parameter pairs can be concatenated and sent in one single payload downlink. Note: all settings are stored in NVRAM and will be reloaded when device starts. To reset device to factory settings press button (if device has one), or send remote command 09 02 09 00 unconfirmed(!) once. @@ -185,10 +178,10 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts. 1 = cumulative counter, mac counter is never reset 2 = cyclic confirmed, like 0 but data is resent until confirmation by network received -0x03 set GPS on/off (NOT YET IMPLEMENTED) +0x03 (NOT YET IMPLEMENTED) set screen saver mode - 0 = GPS off [default] - 1 = GPS on, GPS data set (if present) is added to payload + 0 = screen saver off [default] + 1 = screen saver on 0x04 set display on/off @@ -258,7 +251,7 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts. 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#L32-L50) 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 2: Lora TXpower (2..15) @@ -274,8 +267,7 @@ device answers with it's current configuration. The configuration is a C structu byte 13: Wifi antenna switch (0=internal, 1=external) byte 14: Vendorfilter mode (0=disabled, 1=enabled) byte 15: RGB LED luminosity (0..100 %) - byte 16: GPS status (1=on, 0=off) - bytes 17-27: Software version (ASCII format, terminating with zero) + bytes 16-26: Software version (ASCII format, terminating with zero) 0x81 get device uptime diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 0cedc315..eb38eb73 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -6,7 +6,7 @@ static const char TAG[] = "main"; // read GPS data and cast to global struct -void gps_read(){ +void gps_read() { gps_status.latitude = (uint32_t) (gps.location.lat() * 1000000); gps_status.longitude = (uint32_t) (gps.location.lng() * 1000000); gps_status.satellites = (uint8_t) gps.satellites.value(); @@ -19,11 +19,10 @@ void gps_loop(void * pvParameters) { configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check - #ifdef GPS_SERIAL + // initialize and, if needed, configure, GPS + #if defined GPS_SERIAL HardwareSerial GPS_Serial(1); - #endif - - #ifdef GPS_I2C + #elif defined GPS_I2C // to be done #endif @@ -31,7 +30,8 @@ void gps_loop(void * pvParameters) { if (cfg.gpsmode) { - #ifdef GPS_SERIAL + #if defined GPS_SERIAL + // serial connect to GPS device GPS_Serial.begin(GPS_SERIAL); @@ -39,19 +39,34 @@ void gps_loop(void * pvParameters) { // feed GPS decoder with serial NMEA data from GPS device while (GPS_Serial.available()) { gps.encode(GPS_Serial.read()); - vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog } + vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog } // after GPS function was disabled, close connect to GPS device GPS_Serial.end(); - #endif - #ifdef GPS_I2C - // I2C connect to GPS device + #elif defined GPS_I2C - /* - to be done - */ + // I2C connect to GPS device with 100 kHz + Wire.begin(GPS_I2C_PINS, 100000); + Wire.beginTransmission(GPS_I2C_ADDRESS_WRITE); + Wire.write(0x00); + + i2c_ret == Wire.beginTransmission(GPS_I2C_ADDRESS_READ); + if (i2c_ret == 0) { // check if device seen on i2c bus + while(cfg.gpsmode) { + // feed GPS decoder with serial NMEA data from GPS device + while (Wire.available()) { + Wire.requestFrom(GPS_I2C_ADDRESS_READ, 255); + gps.encode(Wire.read()); + vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog + } + } + // after GPS function was disabled, close connect to GPS device + + Wire.endTransmission(); + Wire.setClock(400000); // Set back to 400KHz to speed up OLED + } #endif } diff --git a/src/hal/lopy.h b/src/hal/lopy.h index dd5a0b7b..d54004f6 100644 --- a/src/hal/lopy.h +++ b/src/hal/lopy.h @@ -4,9 +4,13 @@ #define HAS_LED NOT_A_PIN // LoPy4 has no on board LED, so we use RGB LED on LoPy4 #define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0 -// use only if your LoPy lives on a Pytrack expansion board +// !!EXPERIMENTAL - not tested yet!! +// uncomment this only if your LoPy lives on a Pytrack expansion board with GPS +// see http://www.quectel.com/UploadImage/Downlad/Quectel_L76-L_I2C_Application_Note_V1.0.pdf //#define HAS_GPS 1 -//#define GPS_I2C GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL +//#define GPS_I2C_PINS GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL +//#define GPS_I2C_ADDRESS_READ 0x21 +//#define GPS_I2C_ADDRESS_WRITE 0x20 //#define HAS_BUTTON GPIO_NUM_4 // Hardware pin definitions for Pycom LoPy board diff --git a/src/hal/lopy4.h b/src/hal/lopy4.h index 721b11ef..708a861d 100644 --- a/src/hal/lopy4.h +++ b/src/hal/lopy4.h @@ -4,9 +4,13 @@ #define HAS_LED NOT_A_PIN // LoPy4 has no on board LED, so we use RGB LED on LoPy4 #define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0 -// use only if your LoPy lives on a Pytrack expansion board +// !!EXPERIMENTAL - not tested yet!!f +// uncomment this only if your LoPy lives on a Pytrack expansion board with GPS +// see http://www.quectel.com/UploadImage/Downlad/Quectel_L76-L_I2C_Application_Note_V1.0.pdf //#define HAS_GPS 1 -//#define GPS_I2C GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL +//#define GPS_I2C_PINS GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL +//#define GPS_I2C_ADDRESS_READ 0x21 +//#define GPS_I2C_ADDRESS_WRITE 0x20 //#define HAS_BUTTON GPIO_NUM_4 // Hardware pin definitions for Pycom LoPy4 board diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 92d2f61c..8fd1b86f 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -116,7 +116,7 @@ void do_send(osjob_t* j){ // prepare payload with sum of unique WIFI MACs seen static uint8_t mydata[4]; - + mydata[0] = (macs_wifi & 0xff00) >> 8; mydata[1] = macs_wifi & 0xff; @@ -129,19 +129,26 @@ void do_send(osjob_t* j){ mydata[3] = 0; } - // 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 + static uint8_t gpsdata[18]; if (cfg.gpsmode && gps.location.isValid()) { gps_read(); - LMIC_setTxData2(GPSPORT, (byte*)&gps_status, sizeof(gps_status), (cfg.countermode & 0x02)); + memcpy (gpsdata+4, &gps_status, sizeof(gps_status)); + memcpy (gpsdata, mydata, 4); ESP_LOGI(TAG, "lat=%f / lon=%f | Sats=%u | HDOP=%u | Alti=%u", gps_status.latitude / 1000000, gps_status.longitude / 1000000, gps_status.satellites, gps_status.hdop, 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)); + sprintf(display_lmic, "PACKET QUEUED"); + + #ifdef HAS_GPS + } + #endif + // clear counter if not in cumulative counter mode if (cfg.countermode != 1) { reset_counters(); // clear macs container and reset all counters @@ -178,10 +185,6 @@ void onEvent (ev_t ev) { strcpy_P(buff, PSTR("JOINED")); sprintf(display_lora, " "); // clear previous lmic status message from display - // Disable link check validation (automatically enabled - // during join, but not supported by TTN at this time). -> do we need this? - // LMIC_setLinkCheckMode(0); - // set data rate adaptation LMIC_setAdrMode(cfg.adrmode); // Set data rate and transmit power (note: txpower seems to be ignored by the library) diff --git a/src/main.cpp b/src/main.cpp index e722ad72..240474bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -586,8 +586,8 @@ xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 2048, ( void * ) 1, 1, NULL // 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, "gpsfeed", 2048, ( void * ) 1, 1, NULL, 0); + ESP_LOGI(TAG, "Starting GPS task on core 0"); + xTaskCreatePinnedToCore(gps_loop, "gpsfeed", 2048, ( void * ) 1, 1, NULL, 0); } #endif From e30e133bf1be712c66313536a0c51166952931e5 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 10 Jun 2018 16:00:11 +0200 Subject: [PATCH 24/35] GPS integration now fully functional --- README.md | 20 +++++++++----------- platformio.ini | 3 +-- src/lorawan.cpp | 9 +++++++-- src/main.cpp | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index bb6fbcac..9f08846e 100644 --- a/README.md +++ b/README.md @@ -104,15 +104,13 @@ Legend for RGB LED (LoPy/LoPy4/FiPy/Lolin32 only): LoRaWAN Port #1: - byte 1: Paxcount Wifi, MSB - byte 2: Paxcount WiFi, LSB - byte 3: Paxcount Bluetooth, MSB - byte 4: Paxcount Bluetooth, LSB - bytes 5-8: GPS latitude + byte 1-2: Number of unique pax, first seen on Wifi + byte 3-4: Number of unique pax, first seen on Bluetooth [0 if BT disabled] + bytes 5-8: GPS latitude bytes 9-12: GPS longitude - bytes 13-14: GPS satellites + bytes 13-14: GPS number of satellites bytes 15-16: GPS HDOP - bytes 17-18: GPS altitude + bytes 17-18: GPS altitude [meter] LoRaWAN Port #2: @@ -281,13 +279,13 @@ 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) -0x84 get device GPS status (NOT YET IMPLEMENTED) +0x84 get device GPS status bytes 1-4: latitude bytes 5-8: longitude - byte 9: number of satellites - byte 10: HDOP - bytes 11-12: altidute [meter] + byte 9-10: number of satellites + byte 11-12: HDOP + bytes 13-14: altidute [meter] # License diff --git a/platformio.ini b/platformio.ini index 076c7674..1a9fae0e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -32,8 +32,7 @@ lib_deps_display = lib_deps_rgbled = SmartLeds@>=1.1.3 lib_deps_gps = - https://github.com/mikalhart/TinyGPSPlus.git -;beware of TinyGPSplus in PlatformIO library manager, it loads old v.092 labeled as 1.0.0 !! + TinyGPSPlus@>=1.0.2 build_flags = ; 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! <--- diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 8fd1b86f..b832b311 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -133,9 +133,14 @@ void do_send(osjob_t* j){ static uint8_t gpsdata[18]; if (cfg.gpsmode && gps.location.isValid()) { gps_read(); - memcpy (gpsdata+4, &gps_status, sizeof(gps_status)); memcpy (gpsdata, mydata, 4); - ESP_LOGI(TAG, "lat=%f / lon=%f | Sats=%u | HDOP=%u | Alti=%u", gps_status.latitude / 1000000, gps_status.longitude / 1000000, gps_status.satellites, gps_status.hdop, gps_status.altitude); + 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)); } diff --git a/src/main.cpp b/src/main.cpp index 240474bb..c95ef652 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -630,7 +630,7 @@ void loop() { } if ( (uptime() % 10000) == 0 ) - ESP_LOGI(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix()); + ESP_LOGD(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix()); vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog From 3f8820a8dc69c0b332855dbc5bd4110b482b6ac6 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 10 Jun 2018 16:04:13 +0200 Subject: [PATCH 25/35] v1.3.8 RC --- src/main.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c95ef652..a6216a3c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -629,8 +629,11 @@ void loop() { reset_salt(); // get new salt for salting hashes } - if ( (uptime() % 10000) == 0 ) - ESP_LOGD(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix()); + #ifdef HAS_GPS + // log NMEA status every 30 seconds, useful for debugging GPS connection + if ( (uptime() % 30000) == 0 ) + ESP_LOGD(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix()); + #endif vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog From 67de5257271ce9645535aab968165b9a221f5d8a Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 10 Jun 2018 16:13:35 +0200 Subject: [PATCH 26/35] v1.3.8 RC --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 1a9fae0e..be9dda45 100644 --- a/platformio.ini +++ b/platformio.ini @@ -11,11 +11,11 @@ ; ---> SELECT TARGET PLATFORM HERE! <--- [platformio] -;env_default = heltec +env_default = heltec ;env_default = ttgov1 ;env_default = ttgov2 ;env_default = ttgov21 -env_default = ttgobeam +;env_default = ttgobeam ;env_default = lopy ;env_default = lopy4 ;env_default = fipy From 4b6efba3fe9a7308614c04f3674349121b53e4a1 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 10 Jun 2018 16:35:10 +0200 Subject: [PATCH 27/35] Update README.md --- README.md | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 9f08846e..168e81c7 100644 --- a/README.md +++ b/README.md @@ -20,18 +20,23 @@ This can all be done with a single small and cheap ESP32 board for less than $20 # Hardware Supported ESP32 based LoRa IoT boards: -- Heltec LoRa-32 {1} -- TTGOv1 {1} -- TTGOv2 {1}{4} -- TTGOv2.1 {1}{5} -- TTGO T-Beam {4}{5} -- Pycom LoPy {2} -- Pycom LoPy4 {2} -- Pycom FiPy {2} -- LoLin32 with [LoraNode32 shield](https://github.com/hallard/LoLin32-Lora) {2}{3} -- LoLin32 Lite with [LoraNode32-Lite shield](https://github.com/hallard/LoLin32-Lite-Lora) {2}{3} +- Heltec LoRa-32 a) +- TTGOv1 a) +- TTGOv2 a,d) +- TTGOv2.1 a),e) +- TTGO T-Beam d),e),f) +- Pycom LoPy b) +- Pycom LoPy4 b) +- Pycom FiPy b) +- LoLin32 with [LoraNode32 shield](https://github.com/hallard/LoLin32-Lora) b),c) +- LoLin32 Lite with [LoraNode32-Lite shield](https://github.com/hallard/LoLin32-Lite-Lora) b),c) -{1} on board OLED Display supported; {2} on board RGB LED supported; {3} on board Hardware unique DEVEUI supported; {4} special wiring needed, see instructions in file /hal/.h; {5} battery voltage monitoring supported +a) on board OLED Display supported; +b) on board RGB LED supported; +c) on board Hardware unique DEVEUI supported; +d) external wiring needed, see instructions in file /hal/.h; +e) battery voltage monitoring supported; +f) on board GPS supported Target platform must be selected in [platformio.ini](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/platformio.ini).
Hardware dependent settings (pinout etc.) are stored in board files in /hal directory.
@@ -136,7 +141,6 @@ function Decoder(bytes, port) { return decoded; } -} ``` Converter: @@ -154,7 +158,6 @@ function Converter(decoded, port) { return converted; } -} ``` # Remote command set From aa008edfbeade86a332e0057a88f1390160b1db4 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 10 Jun 2018 16:37:48 +0200 Subject: [PATCH 28/35] Update README.md --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 168e81c7..c347c370 100644 --- a/README.md +++ b/README.md @@ -20,23 +20,23 @@ This can all be done with a single small and cheap ESP32 board for less than $20 # Hardware Supported ESP32 based LoRa IoT boards: -- Heltec LoRa-32 a) -- TTGOv1 a) -- TTGOv2 a,d) -- TTGOv2.1 a),e) -- TTGO T-Beam d),e),f) -- Pycom LoPy b) -- Pycom LoPy4 b) -- Pycom FiPy b) -- LoLin32 with [LoraNode32 shield](https://github.com/hallard/LoLin32-Lora) b),c) -- LoLin32 Lite with [LoraNode32-Lite shield](https://github.com/hallard/LoLin32-Lite-Lora) b),c) +- **Heltec LoRa-32** a) +- **TTGOv1** a) +- **TTGOv2** a,d) +- **TTGOv2.1** a),e) +- **TTGO T-Beam** d),e),f) +- **Pycom LoPy** b),f)* +- **Pycom LoPy4** b),f)* +- **Pycom FiPy** b),f)* +- **LoLin32** with [LoraNode32 shield](https://github.com/hallard/LoLin32-Lora) b),c) +- **LoLin32 Lite** with [LoraNode32-Lite shield](https://github.com/hallard/LoLin32-Lite-Lora) b),c) a) on board OLED Display supported; b) on board RGB LED supported; c) on board Hardware unique DEVEUI supported; d) external wiring needed, see instructions in file /hal/.h; e) battery voltage monitoring supported; -f) on board GPS supported +f) on board GPS supported, *for Pycom devices with additional PyTrack board Target platform must be selected in [platformio.ini](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/platformio.ini).
Hardware dependent settings (pinout etc.) are stored in board files in /hal directory.
From 1b6b0377ea034952a0a52c2186a7b1b2acb6a991 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 10 Jun 2018 16:40:12 +0200 Subject: [PATCH 29/35] Update README.md --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c347c370..5d40afd4 100644 --- a/README.md +++ b/README.md @@ -107,19 +107,24 @@ Legend for RGB LED (LoPy/LoPy4/FiPy/Lolin32 only): # Payload -LoRaWAN Port #1: +**LoRaWAN Port #1:** + + Paxcounter data byte 1-2: Number of unique pax, first seen on Wifi byte 3-4: Number of unique pax, first seen on Bluetooth [0 if BT disabled] + + GPS data (only, if GPS is present and has a fix) + bytes 5-8: GPS latitude - bytes 9-12: GPS longitude + bytes 9-12: GPS longitude bytes 13-14: GPS number of satellites bytes 15-16: GPS HDOP bytes 17-18: GPS altitude [meter] -LoRaWAN Port #2: +**LoRaWAN Port #2:** - see remote control + - see remote control - If you're using [TheThingsNetwork](https://www.thethingsnetwork.org/) you may want to use a payload converter. Go to TTN Console - Application - Payload Formats and paste the code example below in tabs Decoder and Converter. Make sure that your application parses the fields `pax`, `ble` and `wifi`. @@ -288,7 +293,7 @@ device answers with it's current configuration. The configuration is a C structu bytes 5-8: longitude byte 9-10: number of satellites byte 11-12: HDOP - bytes 13-14: altidute [meter] + bytes 13-14: altidute [meter] # License From 85d3e31cd32f32fa78068ca5fa5183e7a12559c1 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 10 Jun 2018 16:46:07 +0200 Subject: [PATCH 30/35] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d40afd4..72a5db04 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,9 @@ Legend for RGB LED (LoPy/LoPy4/FiPy/Lolin32 only): - see remote control - -If you're using [TheThingsNetwork](https://www.thethingsnetwork.org/) you may want to use a payload converter. Go to TTN Console - Application - Payload Formats and paste the code example below in tabs Decoder and Converter. Make sure that your application parses the fields `pax`, `ble` and `wifi`. +If you're using [TheThingsNetwork](https://www.thethingsnetwork.org/) (TTN) you may want to use a payload converter. Go to TTN Console - Application - Payload Formats and paste the code example below in tabs Decoder and Converter. Make sure that your application parses the fields `pax`, `ble` and `wifi`. + +To map a GPS capable paxcounter device and at the same time contribute to TTN coverage mapping, you simply activate the [TTNmapper integration](https://www.thethingsnetwork.org/docs/applications/ttnmapper/) in TTN Console. Paxcounter generates ttnmapper compatible data fields. Decoder: From 6b4effde7cc75bc7e24deec2b0d265c442b406cf Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 10 Jun 2018 16:55:21 +0200 Subject: [PATCH 31/35] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 72a5db04..dadfdfa5 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ function Decoder(bytes, port) { decoded.ble = (bytes[2] << 8) | bytes[3]; decoded.latitude = ((bytes[7] << 24) | (bytes[6] << 16) | (bytes[5] << 8) | bytes[4]); decoded.longitude = ((bytes[11] << 24) | (bytes[10] << 16) | (bytes[9] << 8) | bytes[8]); - decoded.satellites = (bytes[13] << 8) | bytes[12]; + decoded.sats = (bytes[13] << 8) | bytes[12]; decoded.hdop = (bytes[15] << 8) | bytes[14]; decoded.altitude = (bytes[17] << 8) | bytes[16]; } From 416c0f21196bd69ace8c77518b18deb455e328fb Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 10 Jun 2018 18:43:56 +0200 Subject: [PATCH 32/35] Update README.md --- README.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index dadfdfa5..7303cc09 100644 --- a/README.md +++ b/README.md @@ -137,13 +137,16 @@ function Decoder(bytes, port) { var decoded = {}; if (port === 1) { - decoded.wifi = (bytes[0] << 8) | bytes[1]; - decoded.ble = (bytes[2] << 8) | bytes[3]; - decoded.latitude = ((bytes[7] << 24) | (bytes[6] << 16) | (bytes[5] << 8) | bytes[4]); - decoded.longitude = ((bytes[11] << 24) | (bytes[10] << 16) | (bytes[9] << 8) | bytes[8]); - decoded.sats = (bytes[13] << 8) | bytes[12]; - decoded.hdop = (bytes[15] << 8) | bytes[14]; - decoded.altitude = (bytes[17] << 8) | bytes[16]; + var i = 0; + decoded.wifi = (bytes[i++] << 8) | bytes[i++]; + decoded.ble = (bytes[i++] << 8) | bytes[i++]; + if (bytes.length > 4) { + decoded.latitude = ( (bytes[i++]) | (bytes[i++] << 8) | (bytes[i++] << 16) | bytes[i++] << 24 ); + decoded.longitude = ( (bytes[i++]) | (bytes[i++] << 8) | (bytes[i++] << 16) | bytes[i++] << 24 ); + decoded.sats = ( bytes[i++] | (bytes[i++] << 8) ); + decoded.hdop = ( bytes[i++] | (bytes[i++] << 8) ); + decoded.altitude = ( bytes[i++] | (bytes[i++] << 8) ); + } } return decoded; @@ -154,13 +157,16 @@ Converter: ```javascript function Converter(decoded, port) { + var converted = decoded; if (port === 1) { converted.pax = converted.ble + converted.wifi; - converted.hdop /= 100; - converted.latitude /= 1000000; - converted.longitude /= 1000000; + if (converted.length > 4){ + converted.hdop /= 100; + converted.latitude /= 1000000; + converted.longitude /= 1000000; + } } return converted; From 589f37981bed135196b48878bcbc3d4c4b1520c8 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 10 Jun 2018 18:44:49 +0200 Subject: [PATCH 33/35] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7303cc09..55abe1ff 100644 --- a/README.md +++ b/README.md @@ -141,11 +141,11 @@ function Decoder(bytes, port) { decoded.wifi = (bytes[i++] << 8) | bytes[i++]; decoded.ble = (bytes[i++] << 8) | bytes[i++]; if (bytes.length > 4) { - decoded.latitude = ( (bytes[i++]) | (bytes[i++] << 8) | (bytes[i++] << 16) | bytes[i++] << 24 ); + decoded.latitude = ( (bytes[i++]) | (bytes[i++] << 8) | (bytes[i++] << 16) | bytes[i++] << 24 ); decoded.longitude = ( (bytes[i++]) | (bytes[i++] << 8) | (bytes[i++] << 16) | bytes[i++] << 24 ); - decoded.sats = ( bytes[i++] | (bytes[i++] << 8) ); - decoded.hdop = ( bytes[i++] | (bytes[i++] << 8) ); - decoded.altitude = ( bytes[i++] | (bytes[i++] << 8) ); + decoded.sats = ( bytes[i++] | (bytes[i++] << 8) ); + decoded.hdop = ( bytes[i++] | (bytes[i++] << 8) ); + decoded.altitude = ( bytes[i++] | (bytes[i++] << 8) ); } } From f6ae0ea08aeb100eb1a43240ade285bc5c6cad37 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 10 Jun 2018 18:59:24 +0200 Subject: [PATCH 34/35] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55abe1ff..68f588de 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,7 @@ function Converter(decoded, port) { if (port === 1) { converted.pax = converted.ble + converted.wifi; - if (converted.length > 4){ + if (converted.hdop) { converted.hdop /= 100; converted.latitude /= 1000000; converted.longitude /= 1000000; From 0c1331b3dc628f5b78520a348ccc85cff6b35dab Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 10 Jun 2018 19:00:17 +0200 Subject: [PATCH 35/35] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 68f588de..3010e460 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ If you're using [TheThingsNetwork](https://www.thethingsnetwork.org/) (TTN) you To map a GPS capable paxcounter device and at the same time contribute to TTN coverage mapping, you simply activate the [TTNmapper integration](https://www.thethingsnetwork.org/docs/applications/ttnmapper/) in TTN Console. Paxcounter generates ttnmapper compatible data fields. -Decoder: +**Decoder:** ```javascript function Decoder(bytes, port) { @@ -153,7 +153,7 @@ function Decoder(bytes, port) { } ``` -Converter: +**Converter:** ```javascript function Converter(decoded, port) {