diff --git a/README.md b/README.md index 7e50234..30f4262 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ You can also interface your GPS to [uBlox u-center](https://www.u-blox.com/en/pr ### Daily Usage 1. Turn on the ESP32 and wait a few minutes for the GPS to get a fix on position (on BN devices, the red led will blink every second) -2. Open your preferred mobile app and connect it to your BonoGPS-*ABCD* device +2. Open your preferred mobile app and connect it to your BonoGPS-*ABCD* device (ABCD is a combination of 4 letters and numbers unique to your ESP32 device) 3. Enjoy your ride! Most runtime configurations are managed via its web-based interface: you can use your phone or any device with a web browser which is able to connect to either the built-in Access Point the BonoGPS provides or (if you are home and on you have configured the WiFi Client credentials) [http://bonogps.local](http://bonogps.local) @@ -93,7 +93,7 @@ There are many mobile apps to log lap times, few accept custom devices, in parti | iOS | **BLE**, TCP-IP | | | | Android | **BT-SPP**, TCP-IP | BT-SPP | BT-SPP | BT-SPP | -See more info in each subfolder of **connecting**. +See more info in each subfolder of **[connecting](software/connecting)**. You can load a preset configuration from the configuration page selecting *Device > Load Preset* and then choosing your mobile phone device and app combination (when there are alternatives, the recommended option is in bold) @@ -121,11 +121,11 @@ Examples are in [hardware/assembled](hardware/assembled) Thanks to needs of a very active drone community, there are a lot of inexpensive GPS receivers: some considerations on performance/accuracy/cost are reported [in the hardware/GPS folder](hardware/GPS). -What you need to configure is documented [in the hardware/GPS folder](hardware/GPS). You can restore a pre-saved configuration from the same page. +What you need to configure is documented [in the hardware/GPS folder](hardware/GPS): this is **important**, the performances of your GPS won't be optimal until you do. ## Software build instructions -This code is developed specifically for ESP32, and tested with [PlatformIO](https://platformio.org/) (main development platform) and the [Arduino IDE (1.8.13)](https://www.arduino.cc/en/software). More information on what libraries are needed and software organization [in the software folder](software). +This code is developed specifically for ESP32, and tested with [PlatformIO](https://platformio.org/) (main development platform) and the [Arduino IDE (1.8.13)](https://www.arduino.cc/en/software). More information on what libraries are needed and software organization [in the software/building folder](software/building). ## Possible enhancements and ideas diff --git a/git_rev_macro.py b/git_rev_macro.py index 6ac51a4..54d1c6c 100644 --- a/git_rev_macro.py +++ b/git_rev_macro.py @@ -18,6 +18,7 @@ .strip() .decode("utf-8") .replace('.git', '') + .replace('https://github.com/','') ) repolink = re.sub(r'(v[\d+\.a-zA-Z]+)-.*', r"\1", revision) diff --git a/hardware/esp32/lolin_d32_pro.md b/hardware/esp32/lolin_d32_pro.md index 2237230..4e79396 100644 --- a/hardware/esp32/lolin_d32_pro.md +++ b/hardware/esp32/lolin_d32_pro.md @@ -1,4 +1,4 @@ -# LOLIN D32 PRO +# LOLIN D32 PRO - [No BOOT Button](#no-boot-button) - [Serial2 PINs need to be assigned](#serial2-pins-need-to-be-assigned) @@ -30,4 +30,6 @@ This is the simple function used to collect voltage analogRead(GPIO_BATTERY) / 4096.0 * 7.445 ``` -Percentage is based on the common LiPo values as charged by its [TP4054](https://datasheetspdf.com/pdf/1090540/NanJingTopPower/TP4054/1): linear scale from 3.3V (0%) to 4.2V (100%). \ No newline at end of file +Percentage is based on the common LiPo values as charged by its [TP4054](https://datasheetspdf.com/pdf/1090540/NanJingTopPower/TP4054/1): linear scale from 3.3V (0%) to 4.2V (100%). + +These are enabled by the preprocessing macro `SHOWBATTERY` diff --git a/include/README.md b/include/README.md index 596c423..f90369a 100644 --- a/include/README.md +++ b/include/README.md @@ -1,3 +1,18 @@ + # Include files -[include/bonogps_board_settings.h](include/bonogps_board_settings.h) includes board settings (PINS mostly) that are specific to a tested board. +- [include/bonogps_board_settings.h](bonogps_board_settings.h) includes board settings (PINS mostly) that are specific to a tested board. + +## Generated files + +These header files are generated so you should not manually modify them. Regenerate them with [generate_css.sh](../generate_css.sh) + +- [include/bonogps_css_base.h](bonogps_css_base.h) preprocessing macro that defines the strings returned by the `http://bonogps.local/css` url in the portal +- [include/bonogps_css_base_battery.h](bonogps_css_base_battery.h) preprocessing macro that defines the strings returned by the `http://bonogps.local/css` url in the portal with additional definitions to show the battery (no need to increase the flash size if you don't need a battery gauge). This is used when macro `SHOWBATTERY` is used + +## Source files + +Apply your customizations to CSS files here in their native format: they are minimized when imported in the source code. + +- [include/style_base.css](style_base.css) CSS definitions for the web portal +- [include/style_base_battery.css](style_base_battery.css) CSS definitions required to display the battery gauge in the web portal diff --git a/include/bonogps_board_settings.h b/include/bonogps_board_settings.h index c4665a0..7b9cdf4 100644 --- a/include/bonogps_board_settings.h +++ b/include/bonogps_board_settings.h @@ -17,7 +17,6 @@ #if defined(ARDUINO_LOLIN_D32_PRO) -#define BOARD_NAME "Lolin D32 PRO" // Display in information page // Where is Serial2 connected - for Lolin we reconfigure to 2 free pins // until https://github.com/espressif/arduino-esp32/pull/4520 is in place, we need to manually define it #define RX2 GPIO_NUM_4 // 12 @@ -34,7 +33,6 @@ #elif defined(ARDUINO_ESP32_DEV) -#define BOARD_NAME "esp32-devkit" // Display in information page #define RX2 16 // Standard label Rx2 on board #define TX2 17 // Standard label Tx2 on board #define WIFI_MODE_BUTTON 0 // default is: use the boot button to switch wifi modes @@ -42,7 +40,6 @@ #else -#define BOARD_NAME "esp32-custom" // Display in information page // #define RX2 GPIO_NUM_17 // Serial2 standard location on devkit // #define TX2 GPIO_NUM_16 // Serial2 standard location on devkit #define LED_BUILTIN 2 // usually 2 or 5 diff --git a/platformio.ini b/platformio.ini index 5b5ffe3..0a7bdab 100644 --- a/platformio.ini +++ b/platformio.ini @@ -29,6 +29,8 @@ build_flags = !python git_rev_macro.py lib_ldf_mode = chain+ [env:esp32dev] +; basic configuration for a production build without logging +; OTA is disabled board = esp32dev monitor_port = /dev/cu.usbserial-0001 upload_port = /dev/cu.usbserial-0001 @@ -41,6 +43,8 @@ build_flags = -DNO_GLOBAL_ARDUINOOTA [env:esp32dev_ota] +; basic configuration for a production build without logging +; Update is OTA, OTA is enabled without timeout board = esp32dev upload_protocol = espota upload_port = bonogps.local @@ -54,6 +58,8 @@ build_flags = -DBUILD_ENV_NAME='"Prod build - OTA"' [env:esp32dev_debug] +; basic configuration for a troublshooting/debug build without verbose logging +; OTA is enabled without timeout board = esp32dev monitor_port = /dev/cu.usbserial-0001 upload_port = /dev/cu.usbserial-0001 @@ -78,9 +84,8 @@ build_flags = ${env.build_flags} -DLOG_LOCAL_LEVEL=ESP_LOG_NONE -DCORE_DEBUG_LEVEL=0 - -DBUILD_ENV_NAME='"Prod build"' -DNO_GLOBAL_ARDUINOOTA - -DARDUINO_LOLIN_D32_PRO + -DBUILD_ENV_NAME='"Prod build"' ; -DBOARD_HAS_PSRAM ; -mfix-esp32-psram-cache-issue @@ -96,10 +101,9 @@ build_flags = ${env.build_flags} -DLOG_LOCAL_LEVEL=ESP_LOG_NONE -DCORE_DEBUG_LEVEL=0 - -DBUILD_ENV_NAME='"Prod build - OTA"' - -D ENABLE_OTA + -DENABLE_OTA -DOTA_AVAILABILITY_SECS=-1 - -DARDUINO_LOLIN_D32_PRO + -DBUILD_ENV_NAME='"Prod build - OTA"' [env:lolind32pro_debug] ; lolind32 pro target with extended logging @@ -113,9 +117,8 @@ build_flags = ${env.build_flags} -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=4 - -D ENABLE_OTA + -DENABLE_OTA -DOTA_AVAILABILITY_SECS=-1 -DBUILD_ENV_NAME='"Test build - OTA"' - -DARDUINO_LOLIN_D32_PRO ; -DBOARD_HAS_PSRAM ; -mfix-esp32-psram-cache-issue \ No newline at end of file diff --git a/platformio_custom.ini.template b/platformio_custom.ini.template index fb82ca9..36930bd 100644 --- a/platformio_custom.ini.template +++ b/platformio_custom.ini.template @@ -34,8 +34,7 @@ build_flags = ${env.build_flags} -DLOG_LOCAL_LEVEL=ESP_LOG_NONE -DCORE_DEBUG_LEVEL=0 - -DBUILD_ENV_NAME='"Prod build - OTA"' -DENABLE_OTA -DOTA_AVAILABILITY_SECS=-1 - -DARDUINO_LOLIN_D32_PRO + -DBUILD_ENV_NAME='"Prod build - OTA"' diff --git a/software/README.md b/software/README.md index 39cc2e4..f4753e9 100644 --- a/software/README.md +++ b/software/README.md @@ -1,130 +1,7 @@ -# Software development and build +# Documentation on Software -- [IDE options/suggestions: Arduino IDE or VS Code+Platformio](#ide-optionssuggestions-arduino-ide-or-vs-codeplatformio) - - [Arduino IDE (recommended if you are new to the 'maker' approach)](#arduino-ide-recommended-if-you-are-new-to-the-maker-approach) - - [PlatformIO](#platformio) -- [Libraries](#libraries) - - [External Libraries](#external-libraries) - - [Optional external libraries](#optional-external-libraries) - - [Built-in libraries](#built-in-libraries) -- [Build options](#build-options) - - [Large use of preprocessing macro](#large-use-of-preprocessing-macro) - - [Logging facilities](#logging-facilities) - - [How to enable OTA build](#how-to-enable-ota-build) - - [OTA on Arduino IDE](#ota-on-arduino-ide) - - [OTA on PlatformIO](#ota-on-platformio) - - [Important: Partition size](#important-partition-size) +How to develop/build/upload the source code in [building](building) -## IDE options/suggestions: Arduino IDE or VS Code+Platformio +How to connect your running bonogps device to a mobile app in [connecting](connecting) -Development is active on the [VS Code + Platformio](https://platformio.org/install/ide?install=vscode) combination: you can download the complete repository and work directly. - -### Arduino IDE (recommended if you are new to the 'maker' approach) - -Code is written to be compatible with the Arduino IDE, there are a couple of steps required, starting from the assumption you have already installed and setup the Arduino IDE for ESP32 (if you have not, [here a nice tutorial](https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/)) - -- install 'External libraries' listed below -- create an empty project -- copy the content of `src/bonogps.cpp` in the `.ino` file just created -- copy `include/bonogps_board_settings.h` in the same folder -- choose your board: "ESP32 Dev Module" (the generic board that everyone has, often tagged DOIT) or ["LOLIN D32 PRO" are supported](hardware/esp32/lolin_d32_pro.md), otherwise you might have to redefine your pins in `bonogps_board_settings.h` -- choose a partition schema with enough space (e.g. the Minimal SPIFSS with 1.9Mb of flash space) - -The rest is common to any other build on the Arduino IDE. - -IF you are unsure of what board you are running, [check this introductory tutorial](https://randomnerdtutorials.com/getting-started-with-esp32/). - -You can update software OTA, check a later paragraph here on how as it's not enabled by default. - -### PlatformIO - -Beside install PlatformIO (on VS Code as a recommendation), the build system uses a custom **python** script to determine the current software release version: `git_rev_macro.py` and it expects the project folder to be downloaded from github directly to build up the `GIT_REV` and `GIT_REPO` macro variables correctly. - -If you are having issues, you can remove the line that invokes `git_rev_macro.py` and optionally set the 2 macro `GIT_REV` and `GIT_REPO` manually. - -If you would like to define custom targets for your build, I recommend using a `platformio_custom.ini` file (there is a template in `platformio_custom.ini.template`). - -## Libraries - -### External Libraries - -- [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino): 1.0.2 or better latest github version directly (default in platformio from v1.1 of bonogps) -- [Uptime Library](https://github.com/YiannisBourkelis/Uptime-Library) ^1.0.0 -- [EasyButton](https://easybtn.earias.me/) ^2.0.1 -- [Task Scheduler](https://github.com/arkhipenko/TaskScheduler) ^3.2.0 - -From v1.1 of this code and using the latest code of NimBLE-Arduino (after this [commit](https://github.com/h2zero/NimBLE-Arduino/commit/569eb8a188c78fe780f4c2a24cf9247532cf55ea)), unnecessary BLE code is not compiled in. This reduces flash size by ~30kb of Nimble-Arduino disabling roles `CONFIG_BT_NIMBLE_ROLE_CENTRAL` and `CONFIG_BT_NIMBLE_ROLE_OBSERVER`. Up to version 1.0.2 of NimBLE-Arduino, you can manually uncomment those roles in `nimconfig.h` . - -### Optional external libraries - -Included via `#define` options - -- [NeoGPS](https://github.com/SlashDevin/NeoGPS) [not included right now, but coded and available for some additional cases] - -### Built-in libraries - -Always included - -- WebServer -- FS -- Preferences -- WiFi -- DNSServer -- ESPmDNS -- Update -- BluetoothSerial - -Included via `#define` - -- ArduinoOTA: this really depends on how you prefer to update software on your device. It adds size to the flash and it uses some memory, so if you don't plan on using it, don't include it. - -## Build options - -### Large use of preprocessing macro - -To keep flash size small and to avoid several versions of the software, almost all features are enabled/disabled via macro preprocessing - -For example, if you don't need BT-SPP or BLE, you can remove them. The most important ones are - -- `BTSPPENABLED` Include BT-SPP capabilities (default: enabled) -- `BLEENABLED` Include BLE capabilities (default: enabled) -- `ENABLE_OTA` Include OTA capabilities (default: disabled) - -### Logging facilities - -All logging on Serial Port is managed with `log_()` functions (read more at [ESP32 Logging](https://thingpulse.com/esp32-logging/)). You can control how much logging is enabled within the Arduino IDE from the `Tools > Core Debug Level` menu. - -![arduino_ide_logging_level](building/arduino_ide_logging_level.png) - -### How to enable OTA build - -OTA libraries are not enabled by default, to keep the binary size smaller and to have less software running at all times (it's a miracle there are no RAM issues with all tasks running). - -Since updating via OTA is extremely convenient when you are testing, here is how to activate it via two preprocessing macro variables - -- `ENABLE_OTA` if defined, libraries and code is builtin, if undefined no OTA is included -- `OTA_AVAILABILITY_SECS` defines for how long OTA is available after boot, either `-1` (forever) or a finite number of seconds. If undefined, it's `300`, to avoid any mistake on the field where you might mistakenly start flashing a firmare you are actually using - -#### OTA on Arduino IDE - -- uncomment `// #define ENABLE_OTA` at the beginning of `src/bonogps.cpp` (which you might have renamed to `bonogps.ino`) -- optionally, change for how long OTA is available definining `OTA_AVAILABILITY_SECS` - -#### OTA on PlatformIO - -- There are a couple of build targets ending in `_ota` that contain the command line define statements. If you need more build targets, I recommend using a local `platformio_custom.ini` that is not sync'd with the git repository -- you can also permanently enable it changing the source code as for the Arduino case (not recommended) - -### Important: Partition size - -You have to select a partitioning schema with 1.7 Mb of programming space (e.g. Minimal SPIFF with 1.9Mb), as the app with its libraries tend to be pretty large due to BT stacks. - -Within PlatformIO, use the [platformio.ini](platformio.ini) available configuration - -```ini -board_build.partitions = min_spiffs.csv -``` - -Within the Arduino IDE, from `Tools > Partition Scheme` - -![Partition settings](software/building/partition_setting.png +Everyday usage and configurations in [using](using) diff --git a/software/building/README.md b/software/building/README.md new file mode 100644 index 0000000..7ad0d16 --- /dev/null +++ b/software/building/README.md @@ -0,0 +1,133 @@ +# Software development and build + +- [IDE options/suggestions: Arduino IDE or VS Code+Platformio](#ide-optionssuggestions-arduino-ide-or-vs-codeplatformio) + - [Arduino IDE (recommended if you are new to the 'maker' approach)](#arduino-ide-recommended-if-you-are-new-to-the-maker-approach) + - [PlatformIO](#platformio) +- [Libraries](#libraries) + - [External Libraries](#external-libraries) + - [Optional external libraries](#optional-external-libraries) + - [Built-in libraries](#built-in-libraries) +- [Build options](#build-options) + - [Large use of preprocessing macro](#large-use-of-preprocessing-macro) + - [Logging facilities](#logging-facilities) + - [How to enable OTA build](#how-to-enable-ota-build) + - [OTA on Arduino IDE](#ota-on-arduino-ide) + - [OTA on PlatformIO](#ota-on-platformio) + - [Important: Partition size](#important-partition-size) + +## IDE options/suggestions: Arduino IDE or VS Code+Platformio + +Development is active on the [VS Code + Platformio](https://platformio.org/install/ide?install=vscode) combination: you can download the complete repository and work directly. + +### Arduino IDE (recommended if you are new to the 'maker' approach) + +Code is written to be compatible with the Arduino IDE, there are a couple of steps required, starting from the assumption you have already installed and setup the Arduino IDE for ESP32 (if you have not, [here a nice tutorial](https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/)) + +- install 'External libraries' listed below +- create an empty project +- copy the content of `src/bonogps.cpp` in the `.ino` file just created +- copy all the header files `include/*.h` in the same folder +- choose your board: "ESP32 Dev Module" (the generic board that everyone has, often tagged DOIT) or ["LOLIN D32 PRO" are supported](hardware/esp32/lolin_d32_pro.md), otherwise you might have to redefine your pins in `bonogps_board_settings.h` +- choose a partition schema with enough space (e.g. the Minimal SPIFSS with 1.9Mb of flash space) + +The rest is common to any other build on the Arduino IDE. + +IF you are unsure of what board you are running, [check this introductory tutorial](https://randomnerdtutorials.com/getting-started-with-esp32/). + +You can update software OTA, check a later paragraph here on how as it's not enabled by default. + +Please note that you will receive several warnings about redefined macros when building the NimBLE-Arduino library if you are not using the latest as of Jan 21, 2021 version 1.1.1: they are harmless. + +### PlatformIO + +Beside install PlatformIO (on VS Code as a recommendation), the build system uses a custom **python** script to determine the current software release version: `git_rev_macro.py` and it expects the project folder to be downloaded from github directly to build up the `GIT_REV` and `GIT_REPO` macro variables correctly. + +If you are having issues, you can remove the line that invokes `git_rev_macro.py` and optionally set the 2 macro `GIT_REV` and `GIT_REPO` manually. + +If you would like to define custom targets for your build, I recommend using a `platformio_custom.ini` file (there is a template in `platformio_custom.ini.template`). + +## Libraries + +### External Libraries + +- [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino): 1.0.2 or better latest github version directly (default in platformio from v1.1 of bonogps) +- [Uptime Library](https://github.com/YiannisBourkelis/Uptime-Library) ^1.0.0 +- [EasyButton](https://easybtn.earias.me/) ^2.0.1 +- [Task Scheduler](https://github.com/arkhipenko/TaskScheduler) ^3.2.0 + +From v1.1 of this code and using the latest code of NimBLE-Arduino (after this [commit](https://github.com/h2zero/NimBLE-Arduino/commit/569eb8a188c78fe780f4c2a24cf9247532cf55ea)), unnecessary BLE code is not compiled in. This reduces flash size by ~30kb of Nimble-Arduino disabling roles `CONFIG_BT_NIMBLE_ROLE_CENTRAL` and `CONFIG_BT_NIMBLE_ROLE_OBSERVER`. Up to version 1.0.2 of NimBLE-Arduino, you can manually uncomment those roles in `nimconfig.h` . + +### Optional external libraries + +Included via `#define` options + +- [NeoGPS](https://github.com/SlashDevin/NeoGPS) [not included right now, but coded and available for some additional cases] + +### Built-in libraries + +Always included + +- WebServer +- FS +- Preferences +- WiFi +- DNSServer +- ESPmDNS +- Update +- BluetoothSerial + +Included via `#define` + +- ArduinoOTA: this really depends on how you prefer to update software on your device. It adds size to the flash and it uses some memory, so if you don't plan on using it, don't include it. + +## Build options + +### Large use of preprocessing macro + +To keep flash size small and to avoid several versions of the software, almost all features are enabled/disabled via macro preprocessing + +For example, if you don't need BT-SPP or BLE, you can remove them. The most important ones are + +- `BTSPPENABLED` Include BT-SPP capabilities (default: enabled) +- `BLEENABLED` Include BLE capabilities (default: enabled) +- `ENABLE_OTA` Include OTA capabilities (default: disabled) +- `SHOWBATTERY` Display battery status for boards that have built-in (like [LOLIN D32 PRO](../hardware/esp32/lolin_d32_pro.md)]) + +### Logging facilities + +All logging on Serial Port is managed with `log_()` functions (read more at [ESP32 Logging](https://thingpulse.com/esp32-logging/)). You can control how much logging is enabled within the Arduino IDE from the `Tools > Core Debug Level` menu. + +![arduino_ide_logging_level](arduino_ide_logging_level.png) + +### How to enable OTA build + +OTA libraries are not enabled by default, to keep the binary size smaller and to have less software running at all times (it's a miracle there are no RAM issues with all tasks running). + +Since updating via OTA is extremely convenient when you are testing, here is how to activate it via two preprocessing macro variables + +- `ENABLE_OTA` if defined, libraries and code is builtin, if undefined no OTA is included +- `OTA_AVAILABILITY_SECS` defines for how long OTA is available after boot, either `-1` (forever) or a finite number of seconds. If undefined, it's `300`, to avoid any mistake on the field where you might mistakenly start flashing a firmare you are actually using + +#### OTA on Arduino IDE + +- uncomment `// #define ENABLE_OTA` at the beginning of `src/bonogps.cpp` (which you might have renamed to `bonogps.ino`) +- optionally, change for how long OTA is available definining `OTA_AVAILABILITY_SECS` + +#### OTA on PlatformIO + +- There are a couple of build targets ending in `_ota` that contain the command line define statements. If you need more build targets, I recommend using a local `platformio_custom.ini` that is not sync'd with the git repository +- you can also permanently enable it changing the source code as for the Arduino case (not recommended) + +### Important: Partition size + +You have to select a partitioning schema with 1.7 Mb of programming space (e.g. Minimal SPIFF with 1.9Mb), as the app with its libraries tend to be pretty large due to BT stacks. + +Within PlatformIO, use the [platformio.ini](platformio.ini) available configuration + +```ini +board_build.partitions = min_spiffs.csv +``` + +Within the Arduino IDE, from `Tools > Partition Scheme` + +![Partition settings](partition_setting.png) diff --git a/software/connecting/README.md b/software/connecting/README.md new file mode 100644 index 0000000..f7e58ef --- /dev/null +++ b/software/connecting/README.md @@ -0,0 +1,6 @@ +# Setup and configuration of mobile apps + +- [Harry Lap Timer](harrylaptimer) +- [TrackAddict](trackaddit) +- [RaceChrono](racechrono) +- [Racetime](racetime) diff --git a/software/connecting/harrylaptimer/README.md b/software/connecting/harrylaptimer/README.md index 9ddfa58..70a2c3f 100644 --- a/software/connecting/harrylaptimer/README.md +++ b/software/connecting/harrylaptimer/README.md @@ -1,5 +1,6 @@ # Connecting to Harry's LapTimer +- [Features](#features) - [iOS Bluetooth Low Energy setup](#ios-bluetooth-low-energy-setup) - [iOS and Android TCP/IP setup](#ios-and-android-tcpip-setup) - [Android BT-SPP Setup](#android-bt-spp-setup) @@ -9,18 +10,19 @@ More info at [https://www.gps-laptimer.de/](https://www.gps-laptimer.de/), where ![Example](hlt_lagunaseca.png) -Features: +## Features - NMEA parsing offered by HLT directly: `GxRMC`+`GxGGA`+`GxGBS` messages - Enable or Disable `GxGSV`+`GxGSA` as needed, with a lower update frequency selectable for 1, 2, or 5 sec (as [instructed by Harry](http://forum.gps-laptimer.de/viewtopic.php?t=4359)) - tested with v24 +- from v1.2 of BonoGPS, battery information on certain ESP32 boards (for example LOLIN D32 PRO) is available so that HLT can provide it back to you while using the app Connections - -- iOS and Android: TCP/IP port 8118. This is the easier option, yet it prevents connecting other devices to your mobile phone (e.g. an action camera or an ODBII device) -- iOS: BLE atested on iPhone (tested with 7). BLE handles 5Hz and 10Hz GPS update rates when `GSV`/`GSA` streaming disabled, ok with polling at low frequencies (e.g. every few seconds) -- Android: BT-SPP tested on Android - + +- iOS and Android: TCP/IP port 8118. This is the easier option, yet it prevents connecting other devices to your mobile phone (e.g. an action camera or an ODBII device) so it's not recommended +- iOS: BLE tested on iPhone (tested with 7). BLE nicely handles up to 10Hz GPS update rates when `GSV`/`GSA` streaming is disabled or polled at low frequencies (e.g. every few seconds) +- Android: BT-SPP tested on Android, 10Hz and `GSV`/`GSA` at higher polling frequency (streaming saturates the UART connection on the GPS itself) + After configuring the connection, your unit shows up in the Sensors List as 'Custom [BTLE/TCP-IP] GNSS' device ![Configured](hlt-ble-configured.png) @@ -44,6 +46,11 @@ Go to *Administration > Settings > Expert Settings* and ![BLE](hlt-ble.jpeg) +Click on the (i) to see more information about what HLT collects +![BLE with battery](hlt-ble-check.png) + +If your ESP32 board has a battery and you have enabled the `SHOWBATTERY` feature, it will be reported as battery %. + ## iOS and Android TCP/IP setup Go to *Administration > Settings > Expert Settings* and diff --git a/software/connecting/harrylaptimer/hlt-ble-check.png b/software/connecting/harrylaptimer/hlt-ble-check.png new file mode 100644 index 0000000..c9f75b5 Binary files /dev/null and b/software/connecting/harrylaptimer/hlt-ble-check.png differ diff --git a/software/using/webinterface_loadpreset.png b/software/using/webinterface_loadpreset.png index a63c550..8d1d796 100644 Binary files a/software/using/webinterface_loadpreset.png and b/software/using/webinterface_loadpreset.png differ diff --git a/src/bonogps.cpp b/src/bonogps.cpp index 6ca9651..d86ce05 100644 --- a/src/bonogps.cpp +++ b/src/bonogps.cpp @@ -9,7 +9,7 @@ // For PlatformIO we need to include the Arduino framework #include // load PINout definitions from this header file -#include +#include "bonogps_board_settings.h" /* Enable or disable compiling features @@ -37,7 +37,11 @@ #define BONOGPS_FIRMWARE_VER GIT_REV #else // the following define is needed to display version when building this with the Arduino IDE -#define BONOGPS_FIRMWARE_VER "v1.1" +#define BONOGPS_FIRMWARE_VER "v1.2beta" +#endif +// GIT_REPO is used to build links to online software release notes and documentation +#ifndef GIT_REPO +#define GIT_REPO "renatobo/bonogps" #endif // Bonjour DNS name, access the GPS configuration page by appending .local as DNS #define BONOGPS_MDNS "bonogps" @@ -54,12 +58,6 @@ // TCP Port for NMEA sentences repeater, used for Harry's LapTimer mostly, but also for proxying with uBlox #define NMEA_TCP_PORT 1818 -// Disabling GPS over NBP as it does not override phone data within TrackAddict right now, so kind of useless mostly -// #define NUMERICAL_BROADCAST_PROTOCOL -#ifdef NUMERICAL_BROADCAST_PROTOCOL -#define NEED_NEOGPS -#define NBP_TCP_PORT 35000 -#endif // Define configuration of Bluetooth Low Energy #define BLE_DEVICE_ID "BonoGPS" @@ -147,7 +145,6 @@ bool gps_powersave = false; // The next section is used to parse the content of messages locally instead of proxying them // This can be used for -// - NBP: unused right now // - Creating a custom binary packed format #ifdef NEED_NEOGPS // add libraries to parse GPS responses @@ -194,6 +191,12 @@ gps_fix my_fix; Scheduler ts; #endif +// if we have both, we can define a task to check period OTA requests +#if defined(ENABLE_OTA) && defined(TASK_SCHEDULER) +// we will define its charateristics later +Task tOTA; +#endif + // BLueTooth classic stack (Android) #ifdef BTSPPENABLED #include "BluetoothSerial.h" @@ -214,10 +217,10 @@ void bt_callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param); #define CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME BONOGPS_MDNS #include // ble runtime -String ble_client = ""; bool ble_deviceConnected = false; void ble_start(); void ble_stop(); +String ble_client_address; #endif #if defined(BLEENABLED) || defined(BTSPPENABLED) @@ -226,17 +229,18 @@ char ble_device_id[MAX_AP_NAME_SIZE]; // Respond to button #ifdef BUTTON +// remove unneeded feature to trim down library size #define EASYBUTTON_DO_NOT_USE_SEQUENCES #include // Instance of the button to switch wifi mode EasyButton button(WIFI_MODE_BUTTON); #endif -#if defined(ARDUINO_LOLIN_D32_PRO) -// Enable reading battery level on LOLIN D32 Pro +#if defined(SHOWBATTERY) +// Right now this is tailored to the TP4054 charging available on GPIO35 for LOLIN D32 Pro // check https://www.youtube.com/watch?t=88&v=yZjpYmWVLh8&feature=youtu.be for how +// This could be extended to other solutions as needed -#include "services/bas/ble_svc_bas.h" float ReadBatteryVoltage() { return analogRead(GPIO_BATTERY) / 4096.0 * 7.445; @@ -262,7 +266,7 @@ uint8_t LiPoChargePercentage(float voltage) } return returnvalue; } -#endif +#endif //#if defined(SHOWBATTERY) /******************************** * @@ -292,6 +296,24 @@ void OTA_stop(); #else #define BONO_GPS_VERSION BONOGPS_FIRMWARE_VER " [Arduino]" #endif + +void poweroff() { +#ifdef BTSPPENABLED + bt_spp_stop(); +#endif +#ifdef BLEENABLED + ble_stop(); +#endif + wifi_OFF(); + + // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/sleep_modes.html + // rtc_gpio_isolate(GPIO_NUM_12); + esp_sleep_pd_config(ESP_PD_DOMAIN_MAX, ESP_PD_OPTION_OFF); + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF); + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_OFF); + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF); + esp_deep_sleep_start(); +} /******************************** GPS Settings @@ -339,9 +361,10 @@ const char UBLOX_BAUD_38400[] PROGMEM = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x0 const char UBLOX_BAUD_115200[] PROGMEM = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x5E}; // power saving // enable power saving mode for 1800 or 3600 seconds -// UBX - RXM - PMREQ request +// UBX-RXM-PMREQ request const char UBLOX_PWR_SAVE_30MIN[] PROGMEM = {0xB5, 0x62, 0x02, 0x41, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x77, 0x1B, 0x00, 0x02, 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x0F, 0xF6}; const char UBLOX_PWR_SAVE_1HR[] PROGMEM = {0xB5, 0x62, 0x02, 0x41, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xEE, 0x36, 0x00, 0x02, 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0xE1, 0x21}; +const char UBLOX_PWR_OFF[] PROGMEM = { 0xB5, 0x62, 0x02, 0x41, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x5D, 0x4B}; //, 0xrestart UBX-CFG-RST with controlled GNSS only software, hotstart (<4 hrs) so that ephemeris still valid const char UBLOX_WARMSTART[] PROGMEM = {0xB5, 0x62, 0x06, 0x04, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x68}; // Display precision in some apps @@ -363,7 +386,7 @@ void push_gps_message(const char message[], int message_size = 0) { log_d("Disable powermode"); gpsPort.end(); - delay(1000); + delay(250); // assumes stored_preferences global gps_powersave = false; gps_initialize_settings(); @@ -425,11 +448,8 @@ void control_poll_GSA_GSV(int frequency) Task trestart_after_sleep(0, 1, restart_after_sleep, &ts, false); void restart_after_sleep() { - gps_powersave = false; - push_gps_message(UBLOX_WARMSTART, sizeof(UBLOX_WARMSTART)); - delay(1000); gpsPort.end(); - delay(1000); + delay(250); // assumes 'stored_preferences' is global gps_initialize_settings(); trestart_after_sleep.disable(); @@ -691,13 +711,7 @@ void gps_enable_racechrono() stored_preferences.nmeaGSAGSVpolling = 0; #endif stored_preferences.racechrono = true; -} - -#ifdef NUMERICAL_BROADCAST_PROTOCOL -const uint NBPServerPort = NBP_TCP_PORT; -WiFiServer NBPServer(NBPServerPort); -WiFiClient NBPRemoteClient; -#endif +} const uint NMEAServerPort = NMEA_TCP_PORT; WiFiServer NMEAServer(NMEAServerPort); @@ -736,8 +750,7 @@ void NMEACheckForConnections() else { NMEARemoteClient = NMEAServer.available(); - // TODO not printing strings correctly, try https://stackoverflow.com/questions/42355735/esp8266-send-client-remoteip-to-client - log_d("NMEA TCP Connection accepted from client: %s", NMEARemoteClient.remoteIP().toString()); + log_d("NMEA TCP Connection accepted from client: %s", NMEARemoteClient.remoteIP().toString().c_str()); } } } @@ -754,38 +767,15 @@ void stop_NMEA_server() NMEAServer.stop(); } -#ifdef NUMERICAL_BROADCAST_PROTOCOL -unsigned long nbptimer = 0; -void NBPCheckForConnections() -{ - if (NBPServer.hasClient()) - { - // If we are already connected to another computer, then reject the new connection. Otherwise accept the connection. - if (NBPRemoteClient.connected()) - { - log_w("NBP TCP Connection rejected"); - NBPServer.available().stop(); - } - else - { - NBPRemoteClient = NBPServer.available(); - log_i("NBP TCP Connection accepted from client: %s", NBPRemoteClient.remoteIP().toString()); - } - } -} -void start_NBP_server() -{ - log_i("Start NBP TCP/IP Service"); - NBPServer.begin(); - NBPServer.setNoDelay(true); -} -#endif - // Start STATION mode to connect to a well-known Access Point void wifi_STA() { if (stored_preferences.nmeaTcpServer) stop_NMEA_server(); + + log_i("Stop Web Portal"); + WebConfig_stop(); + // WiFi Access WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP // start ticker_wifi with 50 ms because we start in STA mode and try to connect @@ -822,13 +812,7 @@ void wifi_STA() // WLAN Server for GNSS data if (stored_preferences.nmeaTcpServer) start_NMEA_server(); -#ifdef NUMERICAL_BROADCAST_PROTOCOL - // WLAN Server for GNSS data - start_NBP_server(); -#endif - MyIP = WiFi.localIP(); - #ifdef BUTTON button.onPressed(wifi_OFF); #endif @@ -846,6 +830,9 @@ void wifi_AP() // WiFi Access if (stored_preferences.nmeaTcpServer) stop_NMEA_server(); + + log_i("Stop Web Portal"); + WebConfig_stop(); // explicitly set mode, esp defaults to STA+AP WiFi.mode(WIFI_AP); @@ -888,7 +875,7 @@ void wifi_AP() WebConfig_start(); #ifdef TASK_SCHEDULER - log_d("Start blinking"); + log_d("Start blinking slowly 1sec frequency"); tLedBlink.setInterval(1000); tLedBlink.enable(); #endif @@ -896,10 +883,6 @@ void wifi_AP() // WLAN Server for GNSS data if (stored_preferences.nmeaTcpServer) start_NMEA_server(); -#ifdef NUMERICAL_BROADCAST_PROTOCOL - // WLAN Server for GNSS data - start_NBP_server(); -#endif #ifdef BUTTON button.onPressed(wifi_STA); @@ -919,10 +902,7 @@ void wifi_OFF() log_i("Stop OTA service"); OTA_stop(); #endif -#ifdef NUMERICAL_BROADCAST_PROTOCOL - // WLAN Server for GNSS data - stop_NBP_server(); -#endif + // WiFi Access if (stored_preferences.nmeaTcpServer) stop_NMEA_server(); @@ -957,6 +937,8 @@ void wifi_OFF() Web Configuration portal * ******************************/ +// change from standard 1436 to a minimal 100 +// #define HTTP_UPLOAD_BUFLEN 100 #include WebServer webserver(80); @@ -974,28 +956,30 @@ const char json_error[] PROGMEM = "{'status':'error'}"; #include "bonogps_css_base.h" #endif const char WEBPORTAL_HEADER[] PROGMEM = "\n\n\t\n\t\tBono GPS\n\t\t\n\t\t\n\t\t\n\t\n\n\n
"; -#ifdef GIT_REPO -// TODO fix the macro definition to avoid preprocessor warning. GIT_REPO should only contain the url path, not the address part, to comply with macros being alphanumeric only -const char WEBPORTAL_FOOTER[] PROGMEM = "\n\n\n"; +const char WEBPORTAL_FOOTER[] PROGMEM = "\n\n\n"; +#ifdef TASK_SCHEDULER +const char WEBPORTAL_ROOT_OPTIONS[] PROGMEM = "\n\n
Device\n\n\n\n\n\n\n
Turn device and GPS OFF
\n
"; #else -const char WEBPORTAL_FOOTER[] PROGMEM = "\n
Version: " BONO_GPS_VERSION "
\n\n"; +const char WEBPORTAL_ROOT_OPTIONS[] PROGMEM = "\n\n
Device\n\n\n\n\n\n
"; #endif -const char WEBPORTAL_ROOT_OPTIONS[] PROGMEM = "\n\n
Device\n\n\n\n\n\n\n
"; const char WEBPORTAL_OPTION_CHECKED[] PROGMEM = "' checked>"; const char WEBPORTAL_OPTION_LABELCLASSBTN[] PROGMEM = "\n\t