diff --git a/.github/workflows/build-iotnode-lorawan-develop.yml b/.github/workflows/build-iotnode-lorawan-develop.yml
deleted file mode 100644
index c20935e..0000000
--- a/.github/workflows/build-iotnode-lorawan-develop.yml
+++ /dev/null
@@ -1,93 +0,0 @@
-name: IoT Node - LoRaWAN - Firmware build Action
-on:
- push:
- branches:
- - develop
-
- workflow_dispatch:
- branches:
-
-env:
- ARDUINO_RP2040_DIR: .arduino15/packages/rp2040/hardware/rp2040/4.3.1
- IOT_NODE_LORAWAN_APP_KEY: ${{ secrets.IOT_NODE_LORAWAN_APP_KEY }}
- FLX_SPARKFUN_LORAWAN_APP_EUI: ${{ secrets.FLX_SPARKFUN_LORAWAN_APP_EUI }}
-
-jobs:
- build:
- name: Build IoT Node - LoRaWAN Firmware
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repo and submodules
- uses: actions/checkout@v3
- with:
- ref: develop
-
- # checkout flux-sdk
- - name: Checkout the flux-sdk
- run: |
- git clone --branch release/iot-node-lorawan-release https://github.com/sparkfun/flux-sdk.git
- echo "FLUX_SDK_PATH=`pwd`/flux-sdk" >> $GITHUB_ENV
-
- # Run cmake - this will build a custom SparkFun_Flux library we can use with
- # the Arduino CLI
- - name: Run CMake
- run: |
- echo $FLUX_SDK_PATH
- mkdir -p build
- cd build
- cmake ..
- cd ..
-
- # Setup Arduino command line - install esp32 and all the libs flux needs
- - name: Arduino - Install and setup the Arduino CLI
- uses: arduino/setup-arduino-cli@v1
-
- - name: Arduino - Start config file
- run: arduino-cli config init --additional-urls "https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json"
-
- - name: Arduino - Update index
- run: arduino-cli core update-index
-
- # Install RP2040 - 4.0.3 (Nov, 2024)
- - name: Arduino - Install rp2040 platform
- run: arduino-cli core install rp2040:rp2040@4.3.1
-
- - name: Patch in our IOT Node boards
- run: |
- cd patch
- cp boards.txt $HOME/$ARDUINO_RP2040_DIR/boards.txt
- cp -R sparkfun_iotnode_lorawanrp2350 $HOME/$ARDUINO_RP2040_DIR/variants/
- cp sparkfun_iotnode_lorawan_rp2350.h $HOME/$ARDUINO_RP2040_DIR/pico-sdk/src/boards/include/boards/
- cd ..
-
- # install the libraries Flux uses
- - name: Install Flux dependant libraries
- run: ./flux-sdk/install-libs.sh
-
- # currently using a local copy of the library that removed some warning messages - source is here:
- # arduino-cli lib install --git-url "https://github.com/felixgalindo/XBeeArduino.git"
- - name: Install The XBee LoRaWAN library
- run: |
- arduino-cli config set library.enable_unsafe_install true
- arduino-cli lib install --git-url "https://github.com/sparkfun/XBeeArduino.git"
- arduino-cli lib install FastLED
-
- # Compile time - build the Firmware for the data logger.
- # Note:
- # - The use of a full path to flux - this is needed or the build fails (relative paths get merged).
- # - ** Nov 25 - for build testing, using the pro micro board definition until new board added
-
- - name: Compile DataLogger firmware binary
- run:
- arduino-cli compile --fqbn rp2040:rp2040:sparkfun_iotnode_lorawanrp2350 ./sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWAN.ino
- --build-property "compiler.cpp.extra_flags=\"-DIOT_NODE_LORAWAN_APP_KEY=$IOT_NODE_LORAWAN_APP_KEY\" \"-DFLX_SPARKFUN_LORAWAN_APP_EUI=$FLX_SPARKFUN_LORAWAN_APP_EUI\" \"-DBUILD_NUMBER=$GITHUB_RUN_NUMBER\""
- --export-binaries --clean --library `pwd`/SparkFun_IoTNodeLoRaWAN
-
- # Upload the build files - bootloader, paritions, firmware
- - uses: actions/upload-artifact@v3
- with:
- name: Upload Build
- path: sfeIoTNodeLoRaWAN/build/rp2040.rp2040.sparkfun_iotnode_lorawanrp2350/sfeIoTNodeLoRaWAN.ino.uf2
-
-
diff --git a/.github/workflows/build-iotnode-lorawan-release1.0.0.yml b/.github/workflows/build-iotnode-lorawan-release1.0.0.yml
deleted file mode 100644
index d6e8742..0000000
--- a/.github/workflows/build-iotnode-lorawan-release1.0.0.yml
+++ /dev/null
@@ -1,93 +0,0 @@
-name: IoT Node - LoRaWAN - Firmware build Action
-on:
- push:
- branches:
- - release/v01.00.00
-
- workflow_dispatch:
- branches:
-
-env:
- ARDUINO_RP2040_DIR: .arduino15/packages/rp2040/hardware/rp2040/4.3.1
- IOT_NODE_LORAWAN_APP_KEY: ${{ secrets.IOT_NODE_LORAWAN_APP_KEY }}
- FLX_SPARKFUN_LORAWAN_APP_EUI: ${{ secrets.FLX_SPARKFUN_LORAWAN_APP_EUI }}
-
-jobs:
- build:
- name: Build IoT Node - LoRaWAN Firmware
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repo and submodules
- uses: actions/checkout@v3
- with:
- ref: release/v01.00.00
-
- # checkout flux-sdk
- - name: Checkout the flux-sdk
- run: |
- git clone --branch release/iot-node-lorawan-release https://github.com/sparkfun/flux-sdk.git
- echo "FLUX_SDK_PATH=`pwd`/flux-sdk" >> $GITHUB_ENV
-
- # Run cmake - this will build a custom SparkFun_Flux library we can use with
- # the Arduino CLI
- - name: Run CMake
- run: |
- echo $FLUX_SDK_PATH
- mkdir -p build
- cd build
- cmake ..
- cd ..
-
- # Setup Arduino command line - install esp32 and all the libs flux needs
- - name: Arduino - Install and setup the Arduino CLI
- uses: arduino/setup-arduino-cli@v1
-
- - name: Arduino - Start config file
- run: arduino-cli config init --additional-urls "https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json"
-
- - name: Arduino - Update index
- run: arduino-cli core update-index
-
- # Install RP2040 - 4.0.3 (Nov, 2024)
- - name: Arduino - Install rp2040 platform
- run: arduino-cli core install rp2040:rp2040@4.3.1
-
- - name: Patch in our IOT Node boards
- run: |
- cd patch
- cp boards.txt $HOME/$ARDUINO_RP2040_DIR/boards.txt
- cp -R sparkfun_iotnode_lorawanrp2350 $HOME/$ARDUINO_RP2040_DIR/variants/
- cp sparkfun_iotnode_lorawan_rp2350.h $HOME/$ARDUINO_RP2040_DIR//pico-sdk/src/boards/include/boards/
- cd ..
-
- # install the libraries Flux uses
- - name: Install Flux dependant libraries
- run: ./flux-sdk/install-libs.sh
-
- # currently using a local copy of the library that removed some warning messages - source is here:
- # arduino-cli lib install --git-url "https://github.com/felixgalindo/XBeeArduino.git"
- - name: Install The XBee LoRaWAN library
- run: |
- arduino-cli config set library.enable_unsafe_install true
- arduino-cli lib install --git-url "https://github.com/sparkfun/XBeeArduino.git"
- arduino-cli lib install FastLED
-
- # Compile time - build the Firmware for the data logger.
- # Note:
- # - The use of a full path to flux - this is needed or the build fails (relative paths get merged).
- # - ** Nov 25 - for build testing, using the pro micro board definition until new board added
-
- - name: Compile DataLogger firmware binary
- run:
- arduino-cli compile --fqbn rp2040:rp2040:sparkfun_iotnode_lorawanrp2350 ./sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWAN.ino
- --build-property "compiler.cpp.extra_flags=\"-DIOT_NODE_LORAWAN_APP_KEY=$IOT_NODE_LORAWAN_APP_KEY\" \"-DFLX_SPARKFUN_LORAWAN_APP_EUI=$FLX_SPARKFUN_LORAWAN_APP_EUI\" \"-DBUILD_NUMBER=$GITHUB_RUN_NUMBER\""
- --export-binaries --clean --library `pwd`/SparkFun_IoTNodeLoRaWAN
-
- # Upload the build files - bootloader, paritions, firmware
- - uses: actions/upload-artifact@v3
- with:
- name: Upload Build
- path: sfeIoTNodeLoRaWAN/build/rp2040.rp2040.sparkfun_iotnode_lorawanrp2350/sfeIoTNodeLoRaWAN.ino.uf2
-
-
diff --git a/.github/workflows/build-iotnode-lorawan.yml b/.github/workflows/build-iotnode-lorawan.yml
index 252df3e..86fbfad 100644
--- a/.github/workflows/build-iotnode-lorawan.yml
+++ b/.github/workflows/build-iotnode-lorawan.yml
@@ -2,11 +2,11 @@ name: IoT Node - LoRaWAN - Firmware build Action
on:
push:
branches:
- - main
+ - main
workflow_dispatch:
- branches:
-
+
+
env:
ARDUINO_RP2040_DIR: .arduino15/packages/rp2040/hardware/rp2040/4.3.1
IOT_NODE_LORAWAN_APP_KEY: ${{ secrets.IOT_NODE_LORAWAN_APP_KEY }}
@@ -20,13 +20,11 @@ jobs:
steps:
- name: Checkout Repo and submodules
uses: actions/checkout@v3
- with:
- ref: main
# checkout flux-sdk
- name: Checkout the flux-sdk
run: |
- git clone --branch release/iot-node-lorawan-release https://github.com/sparkfun/flux-sdk.git
+ git clone --branch release/iot-node-lorawan-v1.0.1 https://github.com/sparkfun/flux-sdk.git
echo "FLUX_SDK_PATH=`pwd`/flux-sdk" >> $GITHUB_ENV
# Run cmake - this will build a custom SparkFun_Flux library we can use with
@@ -51,15 +49,15 @@ jobs:
# Install RP2040 - 4.0.3 (Nov, 2024)
- name: Arduino - Install rp2040 platform
- run: arduino-cli core install rp2040:rp2040@4.3.1
+ run: arduino-cli core install rp2040:rp2040@4.4.4
- - name: Patch in our IOT Node boards
- run: |
- cd patch
- cp boards.txt $HOME/$ARDUINO_RP2040_DIR/boards.txt
- cp -R sparkfun_iotnode_lorawanrp2350 $HOME/$ARDUINO_RP2040_DIR/variants/
- cp sparkfun_iotnode_lorawan_rp2350.h $HOME/$ARDUINO_RP2040_DIR//pico-sdk/src/boards/include/boards/
- cd ..
+ # - name: Patch in our IOT Node boards
+ # run: |
+ # cd patch
+ # cp boards.txt $HOME/$ARDUINO_RP2040_DIR/boards.txt
+ # cp -R sparkfun_iotnode_lorawanrp2350 $HOME/$ARDUINO_RP2040_DIR/variants/
+ # cp sparkfun_iotnode_lorawan_rp2350.h $HOME/$ARDUINO_RP2040_DIR//pico-sdk/src/boards/include/boards/
+ # cd ..
# install the libraries Flux uses
- name: Install Flux dependant libraries
@@ -67,27 +65,33 @@ jobs:
# currently using a local copy of the library that removed some warning messages - source is here:
# arduino-cli lib install --git-url "https://github.com/felixgalindo/XBeeArduino.git"
+ # arduino-cli lib install --git-url "https://github.com/sparkfun/XBeeArduino.git"
- name: Install The XBee LoRaWAN library
run: |
arduino-cli config set library.enable_unsafe_install true
- arduino-cli lib install --git-url "https://github.com/sparkfun/XBeeArduino.git"
+ arduino-cli lib install --git-url "https://github.com/felixgalindo/XBeeArduino.git"
arduino-cli lib install FastLED
# Compile time - build the Firmware for the data logger.
# Note:
# - The use of a full path to flux - this is needed or the build fails (relative paths get merged).
# - ** Nov 25 - for build testing, using the pro micro board definition until new board added
+ #
+ # May 2025 -
+ # Add filesystem params for the flash layout - 1MB+ for prefs, 4MB for filesystem, the rest (11MB) for firmware
- name: Compile DataLogger firmware binary
run:
arduino-cli compile --fqbn rp2040:rp2040:sparkfun_iotnode_lorawanrp2350 ./sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWAN.ino
--build-property "compiler.cpp.extra_flags=\"-DIOT_NODE_LORAWAN_APP_KEY=$IOT_NODE_LORAWAN_APP_KEY\" \"-DFLX_SPARKFUN_LORAWAN_APP_EUI=$FLX_SPARKFUN_LORAWAN_APP_EUI\" \"-DBUILD_NUMBER=$GITHUB_RUN_NUMBER\""
+ --build-property build.flash_length=11526144 --build-property upload.maximum_size=11526144 --build-property build.eeprom_start=284155904 --build-property build.fs_end=284155904 --build-property build.fs_start=279961600 --build-property build.flash_total=16777216
--export-binaries --clean --library `pwd`/SparkFun_IoTNodeLoRaWAN
- # Upload the build files - bootloader, paritions, firmware
- - uses: actions/upload-artifact@v3
+ # Upload the build files - bootloader, partitions, firmware
+ - name: Upload Build Artifacts
+ uses: actions/upload-artifact@v4
with:
- name: Upload Build
- path: sfeIoTNodeLoRaWAN/build/rp2040.rp2040.sparkfun_iotnode_lorawanrp2350/sfeIoTNodeLoRaWAN.ino.uf2
+ name: Upload Builds
+ path: sfeIoTNodeLoRaWAN/build/rp2040.rp2040.sparkfun_iotnode_lorawanrp2350/
diff --git a/.github/workflows/mkdocs.yml b/.github/workflows/mkdocs.yml
new file mode 100644
index 0000000..095efaa
--- /dev/null
+++ b/.github/workflows/mkdocs.yml
@@ -0,0 +1,37 @@
+name: Run mkdocs
+on:
+ push:
+ branches:
+ - main
+
+ workflow_dispatch:
+ branches:
+
+permissions:
+ contents: write
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Set up Python runtime
+ uses: actions/setup-python@v4
+ with:
+ python-version: 3.x
+
+ - name: Install Python dependencies
+ run: pip install mkdocs-monorepo-plugin mkdocs-redirects mkdocs-with-pdf weasyprint mkdocs-git-authors-plugin mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2
+
+ - name: Set up build cache
+ uses: actions/cache@v3
+ with:
+ key: ${{ github.ref }}
+ path: .cache
+
+ - name: Install Insiders build
+ env:
+ GH_TOKEN: ${{ secrets.GH_TOKEN }}
+ run: pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git
+ - run: mkdocs gh-deploy --force
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2ab53cb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+
+build/
+
+SparkFun_IoTNodeLoRaWAN/
+.idea/
+
+cmake-build-debug/
+
+.vscode/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 37d83d1..17afe91 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -28,8 +28,12 @@ flux_sdk_add_module(
flux_logging
flux_system
flux_prefs
+ flux_prefs_json
flux_prefs_serial
flux_network
+ flux_sdcard
+ flux_file
+ flux_firmware
device_bme280
device_bme68x
device_bmp384
@@ -57,7 +61,8 @@ flux_sdk_add_module(
device_vcnl4040
device_veml6075
device_veml7700
- device_vl53l1x)
+ device_vl53l1x
+ device_soilmoisture)
# now call the init function/macro - this will build the Arduino Library SparkFun_Flux under this
# main directory
diff --git a/README.md b/README.md
index f925b59..53aff02 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,44 @@
-# sfe-iot-node-lorawan
-IoT Node Firmware for a Dig LoRaWAN deployment
-### Compile command
+
-```
-arduino-cli compile --fqbn rp2040:rp2040:sparkfun_promicrorp2350 --export-binaries ./sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWAN.ino --library `pwd`/SparkFun_Flux
-```
+# SparkFun IoT Node - LoRaWAN
+
+Firmware and associated Documentation and Firmware for the SparkFun IoT Node - LoRaWAN product
+
+
+
+
+[](https://github.com/sparkfun/sfe-iot-node-lorawan/actions/workflows/build-iotnode-lorawan.yml)
+
+
+This repository contains the latest firmware for the SparkFun IoT Node - LoRaWAN development board. While the IoT Node - LoRaWAN development board is programmable using Arduino, the IoT Node - LoRa board ships with a firmware application that enables rapid sensor definition and deployment on a Digi LoRaWAN XON network. This repository contains the source for this LoRaWAN application and well as firmware releases.
+
+The IoT Node - LoRaWAN firmware is pre-programmed to automatically log data from 25+ SparkFun [Qwiic](https://www.sparkfun.com/qwiic) sensors, all without requiring any hardware setup or code development. Just plug in a qwiic board, and log data to the LoRaWAN network. The IoT Node - LoRaWAN board automatically detects the connected sensor, configures the device and enables logging to the serial console and, if connected, to the Digi LoRaWAN network.
+
+The SparkFun IoT Node - LoRaWAN board and firmware are designed to enable posting data to the LoRaWAN network within minutes, requiring no development or configuration. The SparkFun IoT Node - LoRaWAN board is configured to work with the Dig LoRaWAN network. Once the board is registered with your Digi XON account (via the on-board digital data tag - which is similar to a QR code), the board with this firmware should automatically connect to your Digi LoRaWAN account. Connect a supported qwiic sensor and data is automatically posted to the LoRaWAN network.
+
+The IoT Node - LoRaWAN firmware is highly configurable via an easily to use serial interface. Simply plug in a USB C cable and open a terminal at 115200 Kbps. By default the logging output is automatically streamed to the serial terminal - pressing any key will bring up the menu system.
+
+Details are outlined in [IoT Node - LoRaWAN Documentation](https://docs.sparkfun.com/sfe-iot-node-lorawan).
+
+
+## Latest Firmware
+
+* Version 01.01.00 - [Release](https://github.com/sparkfun/sfe-iot-node-lorawan/releases/tag/v01.01.00)
+
+> [!NOTE]
+> With firmware version v1.1.0 and above, the XBee LR module on the IoT Node - LoRaWAN board must be running firmware version A5013 - (May 1, 2025) or later. Details on the firmware and how to update are located [here](https://hub.digi.com/support/products/xbee-studio/?_gl=1*1dnbbi0*_gcl_au*MTY5MDM3NjY5LjE3NDYwNDk1Nzg.*_ga*MjY3MjAwOTM1LjE3NDYwNDk1Nzg.*_ga_RZXDK3PM3B*MTc0NjIyNTE0NC42LjAuMTc0NjIyNTE0NC42MC4wLjE4MzUzMzYzNjg.)
+
+## Documentation
+
+* **[Hardware Hookup Guide](https://docs.sparkfun.com/SparkFun_IoT_Node_LoRaWAN/quick_start/)** - Basic hookup guide for the SparkFun IoT Node - LoRaWAN board
+* **GitHub Hardware Repo**
+ * **[SparkFun IoT Node - LoRaWAN](https://github.com/sparkfun/SparkFun_IoT_Node_LoRaWAN)**
+
+## Supported Products
+
+* **[DEV-26060](https://www.sparkfun.com/products/26060)** - SparkFun IoT Node - LoRaWAN
+
+### Latest Release
+
+Details on the latest Firmware release are listed on the [Release Page](https://github.com/sparkfun/sfe-iot-node-lorawan/releases)
diff --git a/docs/assets/img/IoT-Node-LoRaWAN-Banner.jpg b/docs/assets/img/IoT-Node-LoRaWAN-Banner.jpg
new file mode 100644
index 0000000..bd10ba8
Binary files /dev/null and b/docs/assets/img/IoT-Node-LoRaWAN-Banner.jpg differ
diff --git a/docs/assets/img/advanced-data-encoding-output.png b/docs/assets/img/advanced-data-encoding-output.png
new file mode 100644
index 0000000..52a8983
Binary files /dev/null and b/docs/assets/img/advanced-data-encoding-output.png differ
diff --git a/docs/assets/img/digi-device-list.png b/docs/assets/img/digi-device-list.png
new file mode 100644
index 0000000..c965330
Binary files /dev/null and b/docs/assets/img/digi-device-list.png differ
diff --git a/docs/assets/img/digi-device-messages.png b/docs/assets/img/digi-device-messages.png
new file mode 100644
index 0000000..ce480b1
Binary files /dev/null and b/docs/assets/img/digi-device-messages.png differ
diff --git a/docs/assets/img/digi-lora-provision-end.png b/docs/assets/img/digi-lora-provision-end.png
new file mode 100644
index 0000000..8ff2f77
Binary files /dev/null and b/docs/assets/img/digi-lora-provision-end.png differ
diff --git a/docs/assets/img/digi-lora-scan-begin.png b/docs/assets/img/digi-lora-scan-begin.png
new file mode 100644
index 0000000..758dcc3
Binary files /dev/null and b/docs/assets/img/digi-lora-scan-begin.png differ
diff --git a/docs/assets/img/digi-xon-a-device.png b/docs/assets/img/digi-xon-a-device.png
new file mode 100644
index 0000000..0cd2cca
Binary files /dev/null and b/docs/assets/img/digi-xon-a-device.png differ
diff --git a/docs/assets/img/digi-xon-devices.png b/docs/assets/img/digi-xon-devices.png
new file mode 100644
index 0000000..906b538
Binary files /dev/null and b/docs/assets/img/digi-xon-devices.png differ
diff --git a/docs/assets/img/node-sent-messages.png b/docs/assets/img/node-sent-messages.png
new file mode 100644
index 0000000..d6f11e6
Binary files /dev/null and b/docs/assets/img/node-sent-messages.png differ
diff --git a/docs/assets/img/opreation-led-cmd.png b/docs/assets/img/opreation-led-cmd.png
new file mode 100644
index 0000000..ed92da3
Binary files /dev/null and b/docs/assets/img/opreation-led-cmd.png differ
diff --git a/docs/assets/img/settings-device-page.png b/docs/assets/img/settings-device-page.png
new file mode 100644
index 0000000..812344c
Binary files /dev/null and b/docs/assets/img/settings-device-page.png differ
diff --git a/docs/assets/img/settings_all_settings.png b/docs/assets/img/settings_all_settings.png
new file mode 100644
index 0000000..0c6116e
Binary files /dev/null and b/docs/assets/img/settings_all_settings.png differ
diff --git a/docs/assets/img/settings_application.png b/docs/assets/img/settings_application.png
new file mode 100644
index 0000000..e49f5f7
Binary files /dev/null and b/docs/assets/img/settings_application.png differ
diff --git a/docs/assets/img/settings_device_ens160.png b/docs/assets/img/settings_device_ens160.png
new file mode 100644
index 0000000..a18b73c
Binary files /dev/null and b/docs/assets/img/settings_device_ens160.png differ
diff --git a/docs/assets/img/settings_device_list.png b/docs/assets/img/settings_device_list.png
new file mode 100644
index 0000000..2a96f46
Binary files /dev/null and b/docs/assets/img/settings_device_list.png differ
diff --git a/docs/assets/img/settings_entry_range.png b/docs/assets/img/settings_entry_range.png
new file mode 100644
index 0000000..d20257f
Binary files /dev/null and b/docs/assets/img/settings_entry_range.png differ
diff --git a/docs/assets/img/settings_entry_select.png b/docs/assets/img/settings_entry_select.png
new file mode 100644
index 0000000..dcaa4d3
Binary files /dev/null and b/docs/assets/img/settings_entry_select.png differ
diff --git a/docs/assets/img/settings_function.png b/docs/assets/img/settings_function.png
new file mode 100644
index 0000000..7eae7ea
Binary files /dev/null and b/docs/assets/img/settings_function.png differ
diff --git a/docs/assets/img/settings_function_prompt.png b/docs/assets/img/settings_function_prompt.png
new file mode 100644
index 0000000..afc497d
Binary files /dev/null and b/docs/assets/img/settings_function_prompt.png differ
diff --git a/docs/assets/img/settings_logger.png b/docs/assets/img/settings_logger.png
new file mode 100644
index 0000000..ac1198f
Binary files /dev/null and b/docs/assets/img/settings_logger.png differ
diff --git a/docs/assets/img/settings_lorawan.png b/docs/assets/img/settings_lorawan.png
new file mode 100644
index 0000000..76c1062
Binary files /dev/null and b/docs/assets/img/settings_lorawan.png differ
diff --git a/docs/assets/img/settings_prompt_simple.png b/docs/assets/img/settings_prompt_simple.png
new file mode 100644
index 0000000..8ccccd1
Binary files /dev/null and b/docs/assets/img/settings_prompt_simple.png differ
diff --git a/docs/assets/img/settings_save_settings.png b/docs/assets/img/settings_save_settings.png
new file mode 100644
index 0000000..db63c95
Binary files /dev/null and b/docs/assets/img/settings_save_settings.png differ
diff --git a/docs/assets/img/settings_startupmenu.png b/docs/assets/img/settings_startupmenu.png
new file mode 100644
index 0000000..679ae36
Binary files /dev/null and b/docs/assets/img/settings_startupmenu.png differ
diff --git a/docs/assets/img/settings_system.png b/docs/assets/img/settings_system.png
new file mode 100644
index 0000000..3b33ffb
Binary files /dev/null and b/docs/assets/img/settings_system.png differ
diff --git a/docs/assets/img/settings_time.png b/docs/assets/img/settings_time.png
new file mode 100644
index 0000000..f17c436
Binary files /dev/null and b/docs/assets/img/settings_time.png differ
diff --git a/docs/assets/img/settings_timer.png b/docs/assets/img/settings_timer.png
new file mode 100644
index 0000000..4dd1f23
Binary files /dev/null and b/docs/assets/img/settings_timer.png differ
diff --git a/docs/assets/img/settings_top_menu.png b/docs/assets/img/settings_top_menu.png
new file mode 100644
index 0000000..e9ac8f4
Binary files /dev/null and b/docs/assets/img/settings_top_menu.png differ
diff --git a/docs/assets/img/verbose-lora-message.png b/docs/assets/img/verbose-lora-message.png
new file mode 100644
index 0000000..948f01b
Binary files /dev/null and b/docs/assets/img/verbose-lora-message.png differ
diff --git a/docs/assets/img/verbose-startup.png b/docs/assets/img/verbose-startup.png
new file mode 100644
index 0000000..5b0bad9
Binary files /dev/null and b/docs/assets/img/verbose-startup.png differ
diff --git a/docs/assets/img/verbose-value-type.png b/docs/assets/img/verbose-value-type.png
new file mode 100644
index 0000000..8e874a5
Binary files /dev/null and b/docs/assets/img/verbose-value-type.png differ
diff --git a/docs/console_commands.md b/docs/console_commands.md
new file mode 100644
index 0000000..0f3de93
--- /dev/null
+++ b/docs/console_commands.md
@@ -0,0 +1,35 @@
+# IOT Node - LoRaWAN - Console Commands
+
+The serial console interactive menu system of the IoT Node - LoRaWAN an intuitive, dynamic and flexible methodology to interact with the system configuration.While extremely capable, when performing common admin or debugging tasks the menu system is an impediment to the desired operation. A fast, interactive solution is needed.
+
+To provide rapid access to common administration and debugging commands, the IoT Node - LoRaWAN firmware provides a set of commands that are entered directly into the console. Starting with a "!" (bang), these commands are referred to as ***Console Commands*** or ***Bang Commands***.
+
+## Available Commands
+
+The following commands are available:
+
+|Command | Description|
+|:---|:----|
+|!reset-device-forced|Resets the device (clears settings and restarts the device) without a prompt|
+|!reset-device| Resets the device (clears settings and restarts the device) with a [Yes/No] prompt|
+|!clear-settings|Clears the on-device saved settings with a [Yes/No] prompt|
+|!clear-settings-forced|Clears the on-device saved settings without a prompt|
+|!restart|Restarts the device with a [Yes/No] prompt|
+|!restart-forced|Restarts the device without a prompt|
+|!log-rate|Outputs the current log-rate of the device (milliseconds between logging transactions)|
+|!log-rate-toggle|Toggle the on/off state of the log rate data recording by the system. This value is not persisted to on-board settings unless the settings are saved.|
+|!devices|Lists the currently connected devices|
+|!save-settings|Saves the current system settings to the preference system|
+|!verbose|Toggles Verbose output/message mode. This value is not persistent|
+|!heap|Outputs the current statistics of the system heap memory|
+|!log-now|Trigger a data logging event|
+|!lora-status|Display the status and settings of the LoRaWAN|
+|!about|Outputs the full *About* page of the Node Board|
+|!version|Outputs the firmware version|
+|!help|Outputs the available *!* commands|
+
+### Command Usage
+
+To use a *Bang Command*, connect to the target IoT Node - LoRaWAN device via a serial console. and enter the command, starting with a `!` symbol Entering any other character will launch the standard DataLogger IoT menu system. When the `!` symbol is pressed, a prompt **>** should appear.
+
+> Note: Since most *Bang Commands* are not interactive, they also enable commanding by another device, such as a computer attached to the IoT Node board.
diff --git a/docs/data_encoding.md b/docs/data_encoding.md
new file mode 100644
index 0000000..bcdbe8f
--- /dev/null
+++ b/docs/data_encoding.md
@@ -0,0 +1,174 @@
+
+# LoRaWAN Data Encoding
+
+To achieve incredible low-power and long-range performance, a LoRaWAN end node minimizes the size of data packets sent across the LoRa network. While the size of a data packet is adjustable based on specific performance needs and network deployment topology, for maximum flexibility, the SparkFun IoT Node - LoRaWAN firmware uses a packet payload size of 11 bytes. This relativity small payload length is a challenge for a general data-logging application and requires that the firmware develop a unique data packing methodology to meet the general data logging goals of the implementation.
+
+## Value Packing Structure
+
+The IoT Node - LoRaWAN firmware employs a simple tagged format to pack and send sensor data across the LoRaWAN network. The key element to this methodology is the ***tag***, which is defined a "Value Type" for the implementation used for sending data. The Value Type tag is followed by the data value, which is formatted for network transport.
+
+The general structure of a packed value is:
+
+ \[ **Value Type** *{1 byte}* ][**Data Value** *{n bytes - network byte order }*]
+
+### Value Type
+
+Key attributes of a "Value Type" tag/code:
+
+* There is a common set of "Value Type" code IDs - each code identifies a value, which is defined as a specific measured value/phenomenology and its associated units.
+* The "Value Type" codes are known by both sender and receiver of a data value
+* The length of a data value is defined by it's Value Type.
+ * Data types supported: *unit8, uint16, unit32, int8, int16, int32, float and double*
+
+### Data Formatting
+
+When a data value is "packed", for multi-byte values, the data is encoded for network endianness (big-endian format).
+
+The following table outlines how a data value is packed, based on it's data type size:
+
+| Data Type | Length (bytes) | Format Used |
+|--|--|--|
+| int8 | 1 | No format applied |
+| int16 | 2 | Network Byte Order (2 bytes) |
+| int32 | 4 | Network Byte Order (4 bytes) |
+| uint8 | 1 | No format applied |
+| uint16 | 2 | Network Byte Order (2 bytes) |
+| uint32 | 4 | Network Byte Order (4 bytes) |
+| float | 4 | Network Byte Order (4 bytes) |
+| double | 8 | \[ Network Byte Order (4 bytes) ][ Network Byte Order (4 bytes) ] |
+
+## Packet Encoding
+
+When packing a data value in the LoRaWAN packet payload, which has a total of 11 bytes available, data values are formatted as described in the previous section and added to the payload until no further space is available. When the payload is *full* (no free space available for the next data value), it is sent to the LoRaWAN network.
+
+So for a 11 byte LoRaWAN Payload buffer, the contents could be (note a Value Type is 1 byte):
+
+* \[ **Value Type**][**Data Value** *{4 bytes}*]\[ **Value Type**][**Data Value** *{4 bytes}*]\[**empty** {1 byte}] = **10 bytes used**
+* \[ **Value Type**][**Data Value** *{2 bytes}*]\[ **Value Type**][**Data Value** *{4 bytes}*]\[**empty** {3 byte}] = **8 bytes used***
+* \[ **Value Type**][**Data Value** *{2 bytes}*]\[ **Value Type**][**Data Value** *{4 bytes}*]\[ **Value Type**][**Data Value** *{2 bytes}*] = **11 bytes used**
+
+The following example uses *verbose* output from a data collection and send event to show how the data is packed:
+
+
+
+In this image, the Value Type IDs and encoded for each value is highlighted individually and as part of the packed data payload.
+
+The general payload packing is as follows:
+
+### *Initial Condition*
+
+* Set the current position in the payload to position 0
+
+### *Operation*
+
+1) Data Packet is formatted
+1) If no room is available in the payload
+ * The data payload is sent to the LoRaWAN
+ * The payload buffer set to position 0
+1) The data packet is added to the payload buffer
+1) The current position in in the payload is incremented by the size of the data packet
+1) Repeat step 1) until all data is sent
+
+### *End Condition*
+
+* Flush the payload buffer - send any pending data to the LoRaWAN
+
+## Sensor and Data Value Encodings
+
+The following table outlines the sensors and data encoding used by the IoT Node - LoRaWAN firmware:
+
+| Sensor | Parameter | Value Type | Value Type Code | Data Type |
+| -- | -- | -- | -- | -- |
+| BME688 | | | ||
+| | Humidity | Humidity_F | 8 | float|
+| | Temperature C | TempC |10 | float|
+| | Pressure | Pressure_F |9 | float|
+| BME280 | ||||
+|| Humidity |Humidity_F |8 | float|
+|| Temperature F | TempF |11| float|
+|| Temperature C | TempC |10| float|
+|BMP384|||||
+|| Temperature C | TempC_D |50|double|
+|| Presure (Pa)| Pressure_D |51| double|
+|BMP581|||||
+|| Pressure (Pa) | Pressure_F |9| float|
+|| Temperature C | TempC |10| float|
+|CCS811|||||
+|| CO2 | CO2_F |13| float|
+|| VOC| TVOC |12| float|
+|ENS160|||||
+|| Equivalent CO2 | CO2 |6| uint16|
+|| TVOC| VOC |4| unit16|
+||Ethanol Concentration | ETOH || uint16 |
+|| Air Quality Index | AQI |5| uint8 |
+|FS3000|||||
+|| Flow (MPS) | MPS |14| float|
+|| FLow (MPH) | MPH |15| float|
+|GNSS|||||
+|| Latitude in Degrees | Latitude |16| double|
+|| Longitude in Degrees| Longitude |17| double|
+|| Altitude (meters) | Altitude |18| double|
+|ISM330|||||
+|| Accelerometer X (milli-g)| AccelX |19| float|
+|| Accelerometer Y (milli-g)| AccelY |20| float|
+|| Accelerometer Z (milli-g)| AccelZ |21| float|
+|| Gyro X (milli-dps)| GyroX |22| float|
+|| Gyro Y (milli-dps)| GyroY |23| float|
+|| Gyro Z (milli-dps)| GyroZ |24| float|
+|LPS25HB|||||
+|| Pressure (hPa) | Pressure_F |9| float|
+|| Temperature C | TempC |10| float|
+|MAX17048|||||
+|| Voltage (V)| BatteryVoltage |48| float|
+|| State Of Charge (%) | BatteryCharge |47| float|
+|| Change Rate (%/hr) | BatteryChargeRate |49| float|
+|Micro Pressure|||||
+|| Pressure (Pa)| Pressure_F |9| float|
+|MS5637|||||
+|| Pressure (mBar) | Pressure_mBar |25| float|
+|| Temperature C | TempC |10| float|
+|NAU7802|||||
+|| Weight| WeightUserUnits|26| float|
+|OPT4048|||||
+|| CIEx| CIE_X |27| double|
+|| CIEy | CIE_Y |28| double|
+|| CIET | CCT |29| double|
+|RV8803 RTC|||||
+|| Epoch| Epoch|31| uint32|
+|SCD40 CO2 Sensor|||||
+|| CO2 (PPM)| CO2_U32 |32| uint32|
+|| Temperature (C) | TempC |10| float|
+|| Humidity (%RH) | Humidity_F |8| float|
+|SGP30 Air Quality Sensor|||||
+|| CO2 (PPM)| CO2_U32 |32| uint32|
+|| TVOC (PPB) | TVOC_U32 |33| uint32|
+|| H2 (PPM)| H2 |34| uint32|
+|| Ethanol (PPM)| ETOH_U32 |35| uint32|
+|SGP40 Air Quality Sensor|||||
+|| TVOC (PPB) | TVOC_U32 |33| uint32|
+|SHTC3 Humidity and Temperature Sensor|||||
+|| Temperature (F) | TempF |11| float|
+|| Temperature (C) | TempC |10| float|
+|| Humidity (%RH) | Humidity_F |8| float|
+|STC31 CO2 Sensor|||||
+|| CO2 (%) | CO2_F |13| float|
+|| Temperature (C) | TempC |10| float|
+|Human Presence Sensor|||||
+||Presence (cm^-1) | Presence |36| int16|
+|| Motion (LSB) | Motion |37| int16|
+|TMP117 Precision Temperature Sensor|||||
+||Temperature (C)| TempC |10| float|
+|VCNL4040 Proximity Sensor|||||
+|| Proximity | Proximity |38| uint16|
+|| Lux | LUX_U16 |39| uint16|
+|VEML6075 UV Sensor|||||
+|| UVA Level | UVAIndex |40| float|
+|| UVB Level | UVBIndex |41| float|
+|| UV Index | UVIndex |42| float|
+|VEML7700 Ambient Light Sensor|||||
+|| Ambient Light Level | AmbientLight |44| uint32|
+|| White Level | WhiteLight |45| uint32|
+||Lux| LUX_F |43| float|
+|VL53L1X Distance Sensor|||||
+||Distance (mm)| Distance |46| unit32|
+
diff --git a/docs/getting_started.md b/docs/getting_started.md
new file mode 100644
index 0000000..aaa0aaa
--- /dev/null
+++ b/docs/getting_started.md
@@ -0,0 +1,62 @@
+# Getting Started
+
+The SparkFun IoT Node - LoRaWAN firmware is designed to enable rapid setup and connection to the Digi LoRaWAN network or the Digi X-ON system. The SparkFun IoT Node - LoRaWAN board is pre-provisioned with the necessary keys to connect to Digi X-ON, and the default XON Application ID for the demo application is set as default within the IOT Node - LoRaWAN firmware. From the board standpoint, once the Digi module is registered with a XON account, all that is required is to connect the antenna, a supported qwiic sensor and apply power to the board.
+
+## Setting up your Digi X-ON account and Gateway
+
+To get started, you'll need to have access to an HX15 Gateway (NA or EU version) and a Digi Account. If you've purchased the kit, a Gateway will be included. Digi has a great ["Getting Started" video here](https://youtu.be/nrmTp8ZYa6c?si=9FnklldcUvFMTXLr). The kit also has a welcome card included that contains a QR Code. Scanning this code will take you to a URL where you can register for an account.
+
+## Registering the IoT Node - LoRaWAN
+
+### Provisioning
+
+To provision a IoT Node - LoRaWAN device, go to the following link, log in if necessary, and scan the Data Matrix on the XBee Module using the [Digi Scan page](https://scan-us1.haxiot.com/).
+
+Note - if the DataMatrix scan is out-of-focus and unable to resolve, wait a few seconds and a manual entry prompt will appear on Digi Scan. From here you manually enter the modules serial number.
+
+Using the mobile interface, the module registration scan has the following appearance, with a provisioning screen shown once the data module is detected:
+
+
+
+Once scanned, attributes are entered and the Application for the board selected - in this case the application is ***Sparkfun IoT Node***:
+
+
+And once the *PROVISION* button is pressed, the following status/steps are show in the application as the module is provisioned...
+
+
+
+
+After you device is registered with your account, it will be listed in the device section of you XON account.
+
+
+
+Device listing
+
+
+
+From the specific device page, the messages sent by the device are listed. The ***Data*** column contains the message data.
+
+
+
+With the highlighted corresponding sent messages reported on the output of the IoT Node board:
+
+
+
+## Troubleshooting and Notes
+
+### If the Node Board Fails to Connect
+
+* Make sure your Digi XON gateway is powered on, connected and connected to a network
+* Verify that the LoRa Antenna is property connected to the IOT Node - LoRaWAN board
+
+### Application ID or Key Error message printed at startup
+
+While not often, this has been seen with some new boards. Restarting the board a couple of times often resoles this issue.
+
+If it persists, verify the values being used via the settings menu. If need be, reset the board via the menu system to clear out any invalid value.
+
+Note: The Application and Network Key values are ***secret***, and as such stored securely on the device and not visible once entered.
+
+### Notes
+
+* Sometimes the first data message fails to send on setup. This is only after initial setup, with following messages successfully sent.
\ No newline at end of file
diff --git a/docs/github/file_issue.md b/docs/github/file_issue.md
index 6d39f15..53c27bb 100644
--- a/docs/github/file_issue.md
+++ b/docs/github/file_issue.md
@@ -2,13 +2,10 @@
Spot something wrong? Please let us know.
-!!! attention
- This is not where customers should seek assistance on a product. If you require technical assistance or have questions about a product that is not working as expected, please head over to the [SparkFun Technical Assistance](https://www.sparkfun.com/technical_assistance) page for some initial troubleshooting.
-
- [SparkFun Technical Assistance Page](https://www.sparkfun.com/technical_assistance){ .md-button .md-button--primary }
-
- If you can't find what you need there, you'll need a [Forum Account](https://forum.sparkfun.com/ucp.php?mode=register) to search product forums and post questions.
+This is not where customers should seek assistance on a product. If you require technical assistance or have questions about a product that is not working as expected, please head over to the [SparkFun Technical Assistance](https://www.sparkfun.com/technical_assistance) page for some initial troubleshooting.
+
+If you can't find what you need there, you'll need a [Forum Account](https://forum.sparkfun.com/ucp.php?mode=register) to search product forums and post questions.
## Discrepancies in the Documentation
diff --git a/docs/introduction.md b/docs/introduction.md
index e69de29..a7853b1 100644
--- a/docs/introduction.md
+++ b/docs/introduction.md
@@ -0,0 +1,34 @@
+
+
+
+# SparkFun IoT Node - LoRaWAN
+
+Firmware and associated Documentation and Firmware for the SparkFun IoT Node - LoRaWAN product
+
+This repository contains the latest firmware for the SparkFun IoT Node - LoRaWAN development board. While the IoT Node - LoRaWAN development board is programmable using Arduino, the IoT Node - LoRa board ships with a firmware application that enables rapid sensor definition and deployment on a Digi LoRaWAN XON network. This repository contains the source for this LoRaWAN application and well as firmware releases.
+
+The IoT Node - LoRaWAN firmware is pre-programmed to automatically log data from 25+ SparkFun [Qwiic](https://www.sparkfun.com/qwiic) sensors, all without requiring any hardware setup or code development. Just plug in a qwiic board, and log data to the LoRaWAN network. The IoT Node - LoRaWAN board automatically detects the connected sensor, configures the device and enables logging to the serial console and, if connected, to the Digi LoRaWAN network.
+
+The SparkFun IoT Node - LoRaWAN board and firmware are designed to enable posting data to the LoRaWAN network within minutes, requiring no development or configuration. The SparkFun IoT Node - LoRaWAN board is configured to work with the Dig LoRaWAN network. Once the board is registered with your Digi XON account (via the on-board digital data tag - which is similar to a QR code), the board with this firmware should automatically connect to your Digi LoRaWAN account. Connect a supported qwiic sensor and data is automatically posted to the LoRaWAN network.
+
+The IoT Node - LoRaWAN firmware is highly configurable via an easily to use serial interface. Simply plug in a USB C cable and open a terminal at 115200 Kbps. By default the logging output is automatically streamed to the serial terminal - pressing any key will bring up the menu system.
+
+## Latest Firmware
+
+* Version 01.01.00 - [Release](https://github.com/sparkfun/sfe-iot-node-lorawan/releases/tag/v01.01.00)
+
+> NOTE
+> With firmware version v1.1.0 and above, the XBee LR module on the IoT Node - LoRaWAN board must be running firmware version A5013 - (May 1, 2025) or later. Details on the firmware and how to update are located [here](https://hub.digi.com/support/products/xbee-studio/?_gl=1*1dnbbi0*_gcl_au*MTY5MDM3NjY5LjE3NDYwNDk1Nzg.*_ga*MjY3MjAwOTM1LjE3NDYwNDk1Nzg.*_ga_RZXDK3PM3B*MTc0NjIyNTE0NC42LjAuMTc0NjIyNTE0NC42MC4wLjE4MzUzMzYzNjg.)
+
+## Documentation
+
+* **[Hardware Hookup Guide](https://docs.sparkfun.com/SparkFun_IoT_Node_LoRaWAN/quick_start/)** - Basic hookup guide for the SparkFun IoT Node - LoRaWAN board
+* **[SparkFun IoT Node - LoRaWAN](https://github.com/sparkfun/SparkFun_IoT_Node_LoRaWAN)** - Hardware Repo for the IoT Node board
+
+## Supported Products
+
+* **[DEV-26060](https://www.sparkfun.com/products/26060)** - SparkFun IoT Node - LoRaWAN
+
+### Latest Release
+
+Details on the latest Firmware release are listed on the [Release Page](https://github.com/sparkfun/sfe-iot-node-lorawan/releases)
\ No newline at end of file
diff --git a/docs/other_features.md b/docs/other_features.md
new file mode 100644
index 0000000..7bd3193
--- /dev/null
+++ b/docs/other_features.md
@@ -0,0 +1,51 @@
+# Additional Functionality
+
+## Sending Data to the IOT Node - LoRaWAN board
+
+To demonstrate the ability to send commands to the IoT Node - LoRaWAN board, the firmware implements some simple commands to change the on-board RGB LED of the device. While simple, the commands demonstrate the flexibility of this functionality.
+
+### General Command Structure
+
+The LED command structure consist of a set of Hex (number) codes sent to the target SparkFun IoT Node - LoRaWAN board via port 2 of the LoRaWAN connection.
+
+And example of this in the Digi XON control panel for a IoT Node - LoRaWAN device is shown in the following image:
+
+
+
+This sends the command code **0x01FF0000**, which turns on the on-board LED and sets the color red. Note - the port value is set to 2.
+
+Command codes have the following general structure:
+
+**[Command Code - 1 byte][RGB Color - 3 bytes]**
+
+The available command codes:
+
+|Code| Payload | Description |
+|--|--|--|
+|01|RGB value | Turn on the LED, set to the provided RGB value|
+|02| | Turn off the LED|
+|03|RGB Value | Blink the LED using the provided RGB value|
+|04|RGB Value | Fast blink the LED using the provided RGB value|
+|05| Brightness | Set the brightness of the LED - a 1 byte value: 0 - 255|
+
+## Button Events
+
+The SparkFun IoT Node - LoRaWAN board has a "user button". When pressed, the button will perform the following actions:
+
+|Type| Description|
+|--|--|
+|Momentary Press|When the button is momentary pressed, a log-event is triggered.|
+|Pressed and Held| When the on-board is pressed and held down for 30 seconds, the IoT Node - LoRaWAN board is reset: settings are erased and the board restarted.|
+
+## LED Flashes
+
+During the normal course of operation, the IoT Node - LoRaWAN board firmware will enable and flash the on-board LED as an operational indicator. The following table outlines what each LED value indicates:
+
+|Color|Flash|Description
+|--|--|--|
+|Green| No | System Startup|
+|White | No | Settings Menu is use|
+|Blue | Blink | Logging event triggered|
+|Green | Blink | Data sent to the LoRaWAN|
+|Yellow | Flashing | User button held down - faster blink over time|
+|Red | Flashing | User button held down - about to reset the board|
\ No newline at end of file
diff --git a/docs/settings_devices.md b/docs/settings_devices.md
new file mode 100644
index 0000000..c9fb2e9
--- /dev/null
+++ b/docs/settings_devices.md
@@ -0,0 +1,38 @@
+# IoT Node - LoRaWAN - Device Settings
+
+The device settings menu of the system presents the property pages for each device connected to the IoT Node - LoRaWAN board.
+
+The contents of the Device Settings page is dynamic and changes based on the devices connected to the board. The following is an example of a device settings listing page:
+
+
+
+In this page, the devices ***MAX17948*** and ***BME280*** are listed. Selected an individual device entry will bring up the property page for that device.
+
+Below is the property page for the ***BME280** device:
+
+
+
+While the contents of a specific device settings page is dependent on the particular device, each page as a common set of operations.
+
+## Parameters
+
+All devices have a set of parameters, as shown in the above device page for the BME280 device.
+
+Parameters can be enabled/disabled, controlling which values are output - logged to the Serial Console and sent to the LoRaWAN.
+
+Each device allows the enabling/disabling of individual parameters, but functions are also provided to enable or disable all parameters with one operation.
+
+When a parameter is disabled, it is highlighted on the devices settings page.
+
+### LoRaWAN Sent Values
+
+Not all parameters are sent via the LoRaWAN - only those that *make sense* for the limitations of the LoRaWAN system. To determine which values are sent, consult the Advanced section of this documentation, or enable verbose messaging and display a devices settings page. The format of this is shown in the settings page of the ENS160 device later on this page.
+
+## Properties
+
+If a device as available properties, these are listed on the devices settings page. The following page shows properties and parameter settings for the ***ENS160*** device.
+
+
+
+The properties/settings behave just like any other setting within the system. Once set, if a device with the same name/type is loaded, the saved settings are applied at startup.
+
diff --git a/docs/settings_overview.md b/docs/settings_overview.md
new file mode 100644
index 0000000..3ce49e1
--- /dev/null
+++ b/docs/settings_overview.md
@@ -0,0 +1,66 @@
+# Settings Overview
+
+One of the unique features of the SparkFun IoT Node - LoRaWAN firmware is the interactive serial console menu system it provides. This dynamic system allows end user access to the operational settings of the system, without the requirement of additional software development or configuration files. Each subsystem and device within the framework has a set of operational properties and functions that are user accessible via the serial menu.
+
+## Operation
+
+The operation menu is access from a serial console - connected to the IoT Node - LoRaWAN board via a USB-C connection. A *modern/interactive* console is required for this operation - which most modern implementations are. Examples include the **scree** and **minicom** commands on a Linux or macOS system, or **TerraTerm** on a Windows platform.
+
+### Navigation
+
+During normal operation, the IoT Node - LoRaWAN firmware will output startup information to the Serial console, followed by data log information every time a log event occurs. Once startup is completed, the serial menu can be entered by pressing any key except `!` (which allows entry of a console command) at the serial console. When pressed the top level of the menu system is present and will look similar to the following image.
+
+
+
+The top menu outputs general information about the board and presents two options:
+
+ - 1\) Settings - System settings and operations
+ - 2\) Device Settings - Settings for connected devices
+
+ To select a entry in a menu, press (or letter) the number corresponding to the menu entry. So in the above examples, pressing `1` will select the Settings menu, and pressing `2` selects the Device settings menu option.
+
+ To exit a menu, press `x` (exit) at the top menu or `b` (back) at any level of the menu system. Additionally pressing the `escape` key will leave the current menu page, and if pressed on the top menu, any modified property values are not saved to on-board persistent storage.
+
+ Note - if a menu is left in an idle state, the system will exit the current page after a timeout period.
+
+In the system there are to types of actionable entries - **Properties** or attributes of the system, and **Functions**, which execute a specific operation within the system.
+
+## Properties - Entry and Editing
+
+Properties represent a particular setting or attribute of the system. They have default values as defined by the firmware application, but are user settable. Properties values are saved to the onboard flash storage of the IoT Node - LoRaWAN board, and as such persistent across device restarts.
+
+When a value is edited in the menu, any changes are saved when the menu system is normally exited - exiting with the **escape** key will not save any changes.
+
+ When an individual entry is selected, a prompt which is based on the entry type, restrictions and value.
+
+#### Simple Prompt
+
+ When entering a simple value, a basic prompt is presented, as shown in the following image, where the Name of the board is entered:
+
+ 
+
+#### Data Range
+
+Some values have a range limit - requiring the value being entered be within a specified set of limits. The following image shows a valid range of 1200 to 500000 for the Baud Rate property of the device.
+
+
+
+#### Valid Value Limits
+
+Properties can also have a specific set of valid values available. The following image show the valid values for logging output to the Serial Console. The selected value is limited to one of three values: 1 - Disabled, 2 - CSV Format and 3 - JSON Format. No other valid value is accepted by the system.
+
+
+
+## Functions
+
+Functions represent an action that is performed when selected and executed. When a function is selected, the user is always presented with a prompt. The prompt can be a simple "Yes/No" confirmation or or a specific value to pass to the function.
+
+The following image shows a set of Functions that either restart or reset the IoT Node - LoRaWAN device.
+
+
+
+When a specific function is selected, as with the selection of "Restart" in the above list, the system prompts the user before executing the function.
+
+
+
+Pressing 'Y' will execute the Restart Function in the above example - selecting 'n' or pressing the 'escape' key aborts the function call and returns to the menu system.
\ No newline at end of file
diff --git a/docs/settings_settings.md b/docs/settings_settings.md
new file mode 100644
index 0000000..8d006a5
--- /dev/null
+++ b/docs/settings_settings.md
@@ -0,0 +1,244 @@
+# IoT Node - LoRaWAN - Settings
+
+The following sections provide an overview of the available settings and functions within the settings menu of the IoT Node - LoRaWAN firmware.
+
+The settings system is divided into two sections - ***Settings*** and ***Device Settings*** as shown in the following image:
+
+
+
+## Settings - System Settings and Operations
+
+When this entry is selected, the following entries are presented:
+
+
+
+### Application Settings
+
+The ***Application Settings*** menu has the following entries:
+
+
+
+#### Color Output
+
+When enabled (the default), output to the console will use colors to highlight values and functionality. When disabled, all output is plain text. When using a limited serial console application, set this value to false.
+
+#### Board Name
+
+Set this value any name desired for the particular board. By default this value is ***empty***.
+
+#### Serial Console Format
+
+This property sets the output format for sensor/log data for the serial console. Available values include CSV, JSON and Disabled. The default value is ***CSV***.
+
+#### JSON Buffer Size
+
+This is the size - in bytes - the application should use when building JSON formatted output. The default value is ***1600*** bytes. This value should only be adjusted if logging a large number of values to the serial console.
+
+The maximum bytes used by the JSON system is displayed on the ***About*** page of the application (try using `!about` console command to see this value).
+
+#### Terminal Baud Rate
+
+Use this value to change the baud rate settings for the serial console. Once changed this value might require a system restart to take effect. The default value is ***115200***.
+
+#### Device Names
+
+When enabled (default is ***disabled***), attached devices have their address appended to the name. This is helpful to identify a particular board when two or more of the same board type are attached to the IoT Node board.
+
+#### Startup Delay
+
+When the IoT Node board starts up, an startup menu is displayed. This settings determines how long to display this menu. Setting this value disables the menu.
+
+The startup menu has the following options:
+
+
+
+Pressing the indicted menu key selects that option. If the startup delay expires, a *normal* startup sequence occurs.
+
+##### Startup Menu Entries
+
+* 'n' = Normal startup sequence
+* 'v' = Verbose output messaging is enabled at startup
+* 'a' = Disable qwiic device autoload
+* 'l' = List the available qwiic/i2c drivers at startup (this list is deleted after startup)
+* 's' = Disable settings restore on startup
+
+#### Verbose Messages
+
+When enabled, verbose output is enabled. This value is ***disabled*** by default.
+
+#### About...
+
+When selected, the system displays the ***About*** page for the application. This reflects the current status of system. This page is also displayed using the `!about` console command.
+
+### LoRaWAN Network
+
+The LoRaWAN Network page has the following settings:
+
+
+
+#### Enabled
+
+Used to enable/disable the LoRaWAN network functionality. This value is *enabled* by default.
+
+#### Application EUI
+
+The Application EUI for the LoRaWAN connection
+
+#### Application Key
+
+The Application Key for the LoRaWAN connection. This value is *secret*, and while editable, it is not visible when editing.
+
+#### Network Key
+
+The Network Key for the LoRaWAN connection. This value is *secret*, and while editable, it is not visible when editing.
+
+#### LoRaWAN Class
+
+The operating class for the LoRaWAN module. By default this value is set to ***C***.
+
+#### LoRaWAN Region
+
+The operating region for the LoRaWAN module. By default this value is ***US915***.
+
+#### Reset
+
+Calls the *reset* function on the module.
+
+### LoRaWAN Logger
+
+This pages has no entires currently.
+
+### Logger
+
+The logger system is used to output values to the Serial Console.
+
+The logger has the following settings:
+
+
+
+
+#### Timestamp Mode
+
+Enables output of a timestamp to the logged information and sets the format of the timestamp. By default this is ***disabled***.
+
+#### Sample Numbering
+
+If enabled, a sample number is included in the console output of logged data. This value is ***disabled*** by default.
+
+#### Numbering Increment
+
+The amount to increment each sample number when sample numbering is enabled. The default value is ***1***.
+
+#### Output ID
+
+When enabled, the board ID is included in the logged output. This value is ***disabled*** by default.
+
+#### Output Name
+
+When enabled, the board Name is included in the logged output. This value is ***disabled*** by default.
+
+#### Rate Metic
+
+When enabled, metrics are recorded for the logging system. This value is ***disabled*** by default.
+
+#### Reset Sample Counter
+
+Resets the data sample number to a user provided value.
+
+### Logging Timer
+
+The timer has the following properties:
+
+
+
+#### Interval
+
+The interval for the logging timer. For every *interval* period, a logging event occurs - sending data to the LoRaWAN and serial console (if enabled). The default value is ***90000 ms***.
+
+### System Control
+
+The System Control page includes the following entries:
+
+
+
+#### Device Restart
+
+When selected, the user is prompted to restart the device/system. This is also available using the `!restart` console command.
+
+#### Device Reset
+
+When selected, the user is prompted to reset the device/system. A device reset erases the current saved settings values and restarts the board/system. This is also available using the `!reset-device` console command.
+
+### Time Setup
+
+By default the IOT Node - LoRaWAN is not connected to a timekeeping source and defaults to a start time value of January 1, 1970 (epoch value of 0). But if a time keeping device is added (GNSS or Real Time Clock), this page is used to set time parameters for the board.
+
+The Time Setup property page has the following entries:
+
+
+
+#### Time Zone
+
+The timezone specification string to use for the system clock. By default, the Mountain Time zone (the zone of SparkFun) is used.
+
+#### Reference Clock
+
+If a reference clock device is connected to the IoT Node board, use this option to select this clock.
+
+#### Update Interval
+
+Specify how often the system clock is updated using the reference clock in minutes.
+
+
+#### Enable Clock Fallback
+
+Adds a secondary reference clock to use if the primary clock becomes unavailable.
+
+#### Dependant Interval
+
+If a *dependant* clock is connected (a clock being set by the system clock), this value sets how often the dependant clock device is updated.
+
+#### Update Connected
+
+If enabled, any connected clocks have their time updated when the system clock is updated.
+
+### Save Settings
+
+The Save Settings system is designed to include a "fallback" settings system if available. Normally this might be a JSON file on a SDCard or similar device. At launch, this functionality is not available for the IoT Node - LoRaWAN board.
+
+
+The Save Settings property page has the following elements:
+
+
+
+#### Fallback Restore
+
+If enabled, restore settings from the fallback system if the primary storage system is unavailable or empty.
+
+#### Fallback Save
+
+If enabled and a fallback device is available, saving settings to primary storage also saves them to the secondary device.
+
+#### Buffer Size
+
+The buffer size used for internal I/O operations. This is not used for the IoT Node Board.
+
+#### Save Settings
+
+When called, the current value of the systems settings is saved to the primary persistent storage system.
+
+#### Restore Settings
+
+When called, systems settings are restore from the primary storage system.
+
+#### Clear Settings
+
+When called, the primary (on board) settings storage is erased/reset.
+
+#### Save to Fallback
+
+If a fallback device is available, when this function is called, system settings are saved to the fallback device.
+
+#### Restore from Fallback
+
+If a fallback device is available, when this function is called, system settings are restored from the fallback device.
\ No newline at end of file
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
index 7dd8d78..1241c80 100644
--- a/docs/troubleshooting.md
+++ b/docs/troubleshooting.md
@@ -1,13 +1,9 @@
-### General Troubleshooting Help
+## General Troubleshooting Help
-!!! note
-
- Not working as expected and need help?
- If you need technical assistance and more information on a product that is not working as you expected, we recommend heading on over to the SparkFun Technical Assistance page for some initial troubleshooting.
+
+ ### Not working as expected and need help?
-
+If you need technical assistance and more information on a product that is not working as you expected, we recommend heading on over to the [SparkFun Technical Assistance](https://www.sparkfun.com/technical_assistance) page for some initial troubleshooting.
- If you don't find what you need there, the SparkFun Forums are a great place to find and ask for help. If this is your first visit, you'll need to create a forum account to search product forums and post questions.
-
-
+If you don't find what you need there, the [SparkFun Forums](https://community.sparkfun.com/) are a great place to find and ask for help. If this is your first visit, you'll need to create a forum account to search product forums and post questions.
\ No newline at end of file
diff --git a/docs/verbose_output.md b/docs/verbose_output.md
new file mode 100644
index 0000000..69ee800
--- /dev/null
+++ b/docs/verbose_output.md
@@ -0,0 +1,57 @@
+# Verbose Output
+
+For advanced work with the firmware, enabling **Verbose Mode** is incredibly helpful. This is especially true for data encoding and transmission.
+
+When verbose messaging is enabled, verbose messages are prefixed with a **[V]** and Debug messages are prefixed with a **[D]**.
+
+## Enabling verbose Mode
+
+There are three main methods to enable verbose mode:
+
+| Location | Details |
+|--|--|
+|Settings Menu | Settings>Application Settings > Verbose Messages. Enabled/Disable Verbose Messaging. This setting will persist across restarts.|
+!!verbose Console Command| This toggles verbose messages and is not persistent|
+|Start Menu - Select option 'v' | Enables verbose messages before system startup. This value is not persistent|
+
+## Output LoRaWAN Encoding
+
+When verbose messaging is enabled, when a loRaWAN message is packed, the packed values and the overall payload is output.
+
+The following is an example of output for two data values:
+
+
+
+In this example, verbose output is enabled using the console command **!verbose**, and a logging event triggered using **!log-now**.
+
+Two sensor values are packed for transmission - **Humidity** and **TemperatureF**. The verbose message output includes the Value Type/ID for each data value, as well as the encoded value in hexadecimal.
+
+And once a LoRaWAN data payload is sent, the entire 11 byte payload is output, along with it's send status and associated frame ID.
+
+## Device Value Type IDs
+
+For each supported device, a subset of parameters are enabled for LoRaWAN transmission. With verbose output enabled, these parameters are indicated by having a Value Type ID when viewed in on a device settings page.
+
+The following is an example of the Value Type codes for the BME280 device:
+
+
+
+On this page, the parameters that have **Value Types** codes are enabled for LoRaWAN transmission.
+
+### Disabled Parameters
+
+Note - Parameters that are disabled are not sent to the LoRaWAN.
+
+## Startup Messages
+
+If Verbose Output is enabled and save in the system settings, or if the ***[v]erbose*** startup mode was selected, some addition messages are output during the startup sequence.
+
+And example of startup messages:
+
+
+
+In this example, "Verbose Output" was enabled in the system settings, and is noted on startup.
+
+Several **Debug** messages related to some settings not saved/restore - but these can easily be ignored.
+
+Additional information is output when connected to the LoRaWAN network, including the device EUID, and what operating class the LoRaWAN module is set to.
diff --git a/mkdocs.yml b/mkdocs.yml
index e8afa28..682b9a3 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -8,7 +8,7 @@ repo_url: https://github.com/sparkfun/sfe-iot-node-lorawan
repo_name: sparkfun/sfe-iot-node-lorawan
copyright:
- Copyright 2023 - SparkFun Electronics®
+ Copyright 2025 - SparkFun Electronics®
6333 Dry Creek Parkway, Niwot, Colorado 80503
# Default edit/view actions to "main" branch, instead of "master"
@@ -247,8 +247,19 @@ extra_javascript:
# Configures webpage navigation
nav:
- - Getting Started:
+ - Home:
- Introduction: introduction.md
+ - Getting Started:
+ - Getting Started: getting_started.md
+ - Other Features: other_features.md
+ - Settings:
+ - Overview: settings_overview.md
+ - Settings: settings_settings.md
+ - Device Settings: settings_devices.md
+ - Advanced:
+ - Data Encoding: data_encoding.md
+ - Console Commands: console_commands.md
+ - Verbose Output: verbose_output.md
- Support:
- Troubleshooting: troubleshooting.md
- Submit Issues: github/file_issue.md
diff --git a/overrides/partials/nav.html b/overrides/partials/nav.html
index 7478d0f..b819dce 100644
--- a/overrides/partials/nav.html
+++ b/overrides/partials/nav.html
@@ -69,7 +69,7 @@
-
+
Hard Copies {% include ".icons/material/book-open-variant.svg" %}
diff --git a/overrides/partials/tabs.html b/overrides/partials/tabs.html
index 7190191..ea324e7 100644
--- a/overrides/partials/tabs.html
+++ b/overrides/partials/tabs.html
@@ -34,7 +34,7 @@
{% if "hard_copy.md" %}
-
-
+
Hard Copies 🖨️
diff --git a/overrides/partials/toc-backup.html b/overrides/partials/toc-backup.html
index a5328f3..9f059df 100644
--- a/overrides/partials/toc-backup.html
+++ b/overrides/partials/toc-backup.html
@@ -55,7 +55,7 @@
-
-
+
View Guide as Single-Page {% include ".icons/fontawesome/solid/scroll.svg" %}
diff --git a/sfeIoTNodeLoRaWAN/flxLoRaWANDigi.cpp b/sfeIoTNodeLoRaWAN/flxLoRaWANDigi.cpp
index 4d26be5..6c33153 100644
--- a/sfeIoTNodeLoRaWAN/flxLoRaWANDigi.cpp
+++ b/sfeIoTNodeLoRaWAN/flxLoRaWANDigi.cpp
@@ -391,7 +391,7 @@ bool flxLoRaWANDigi::setupModule(void)
for (int i = 0; i < 3; i++)
{
flxLog_N_(F("."));
- if (_pXBeeLR->getLoRaWANDevEUI((uint8_t *)_devEUI, sizeof(_devEUI)))
+ if (_pXBeeLR->getLoRaWANDevEUI(_devEUI, sizeof(_devEUI)))
{
status = true;
break;
@@ -408,13 +408,13 @@ bool flxLoRaWANDigi::setupModule(void)
// note:
// TODO: this wasn't working in 12/2024 -- need to revisit in the future as the XBee LR library is updated
- // // Set the region
- // if (!_pXBeeLR->setLoRaWANRegion(_lora_region))
- // flxLog_W(F("%s: Error setting the LoRaWAN Region to `%s`"), name(), getRegionName());
- // else
- // flxLog_V(F("%s: Set the LoRaWAN Region to `%s`"), name(), getRegionName());
+ // Set the region
+ if (!_pXBeeLR->setLoRaWANRegion(_lora_region))
+ flxLog_W(F("%s: Error setting the LoRaWAN Region to `%s`"), name(), getRegionName());
+ else
+ flxLog_V_(F("%s: Set the LoRaWAN Region to `%s`"), name(), getRegionName());
- // flxLog_N_(F("."));
+ flxLog_N_(F("."));
// Do we need to configure the module?
if (_moduleConfigured() == false)
diff --git a/sfeIoTNodeLoRaWAN/flxLoRaWANLogger.cpp b/sfeIoTNodeLoRaWAN/flxLoRaWANLogger.cpp
index 59c7a7d..1c47006 100644
--- a/sfeIoTNodeLoRaWAN/flxLoRaWANLogger.cpp
+++ b/sfeIoTNodeLoRaWAN/flxLoRaWANLogger.cpp
@@ -9,6 +9,7 @@
*/
#include "flxLoRaWANLogger.h"
+#include
//---------------------------------------------------------------------------
// flxLoRaWANLogger Class - outputs data to the lorawan during a log event
@@ -52,7 +53,46 @@ void flxLoRaWANLogger::logObservation(void)
// we don't process arrays. We only process scalar values
if ((param->flags() & kParameterOutFlagArray) == kParameterOutFlagArray)
{
- flxLog_V("Array parameters not supported by LoRaWAN driver. Parameter: %s", param->name());
+ flxParameterOutArray *pArray = (flxParameterOutArray *)param->accessor();
+ // look for known values - if not, skip
+ switch (pArray->valueType())
+ {
+ case kParamValueLocation: {
+
+ flxDataArrayFloat *parrData = (flxDataArrayFloat *)pArray->get();
+
+ // is the data array sane?
+ if (parrData->size() != 2)
+ {
+ flxLog_W("Location array size is not 2. Size: %d", parrData->size());
+ continue;
+ }
+
+ // location is a two element float array, that we want to send in the same packet.
+ // So first, flush the buffer, then send the data
+ _pLoRaWAN->flushBuffer();
+
+ // trick the system into thinking we have a float array, which the LoRaWAN driver
+ // can handle. We need to do this because the LoRaWAN driver is expecting a float array[2]
+ float *pfData = parrData->get();
+ float tmparr[2] = {pfData[0], pfData[1]};
+
+ if (flxIsLoggingVerbose())
+ {
+ // dump out details for the parameter. Note - for packed value, this depends on
+ // verbose output from the packer.
+ flxLog_V_("LoRa Packing [%s::%s] Type: Location Value ID: 0x%02X Value: (%f,%f)",
+ pDevice->name(), param->name(), pArray->valueType(), tmparr[0], tmparr[1]);
+ }
+
+ // send the data
+ status = _pLoRaWAN->sendData(pArray->valueType(), tmparr);
+ break;
+ }
+ default:
+ flxLog_V("Array parameters not supported by LoRaWAN driver. Parameter: %s", param->name());
+ break;
+ }
continue;
}
flxParameterOutScalar *pScalar = (flxParameterOutScalar *)param->accessor();
diff --git a/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWAN.cpp b/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWAN.cpp
index 9027a89..1b902e4 100644
--- a/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWAN.cpp
+++ b/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWAN.cpp
@@ -9,6 +9,7 @@
*---------------------------------------------------------------------------------
*/
#include "sfeIoTNodeLoRaWAN.h"
+#include "sfeNLBoard.h"
#include "sfeNLCommands.h"
#include "sfeNLLed.h"
#include "sfeNLVersion.h"
@@ -48,6 +49,14 @@ const uint8_t kLoRaWANMsgLEDFlash = 0x05;
// Set the brightness for the on-board LED
const uint8_t kLoRaWANMsgLEDBrightness = 0x06;
+
+// For finding the firmware files on SD card
+#define kLoRaWANFirmwareFilePrefix "sfeIoTNodeLoRaWAN_"
+//---------------------------------------------------------------------------
+
+// The default Soil Sensor pins
+const uint8_t kSoilSensorVCCPin = 28;
+const uint8_t kSoilSensorSensorPin = 29;
//---------------------------------------------------------------------------
// Application keys - used to encrypt runtime secrets for the app.
@@ -69,7 +78,8 @@ static const uint8_t _app_jump[] = {104, 72, 67, 51, 74, 67, 108, 99, 104, 11
#define kAppClassPrefix "INLW"
//---------------------------------------------------------------------------
//
-sfeIoTNodeLoRaWAN::sfeIoTNodeLoRaWAN() : _opFlags{0}
+sfeIoTNodeLoRaWAN::sfeIoTNodeLoRaWAN()
+ : _logTypeSD{kAppLogTypeNone}, _logTypeSer{kAppLogTypeNone}, _opFlags{0}, _hasOnBoardFlashFS{false}
{
// Constructor
}
@@ -209,14 +219,18 @@ void sfeIoTNodeLoRaWAN::onInit()
// flxLog_I("in onInit()");
_logTypeSer = kAppLogTypeNone;
+ _logTypeSD = kAppLogTypeNone;
serialLogType.setTitle("Output");
flxRegister(serialLogType, "Serial Console Format", "Enable and set the output format");
+ flxRegister(sdCardLogType, "SD Card Format", "Enable and set the output format");
flxRegister(jsonBufferSize, "JSON Buffer Size", "Output buffer size in bytes");
// Terminal Serial Baud Rate
flxRegister(serialBaudRate, "Terminal Baud Rate", "Update terminal baud rate. Changes take effect on restart");
_terminalBaudRate = kDefaultTerminalBaudRate;
+ enableSoilSensor.setTitle("Devices");
+ flxRegister(enableSoilSensor, "Soil Moisture Sensor", "Enable GPIO attached Soil Moisture Sensor");
// Advanced settings
verboseDevNames.setTitle("Advanced");
flxRegister(verboseDevNames, "Device Names", "Name always includes the device address");
@@ -234,6 +248,12 @@ void sfeIoTNodeLoRaWAN::onInit()
_sysStorageDevice.initialize(preStart, kSegmentSize, 10);
_sysStorage.setStorageDevice(&_sysStorageDevice);
flxSettings.setStorage(&_sysStorage);
+ flxSettings.setFallback(&_jsonStorage);
+
+ _jsonStorage.setFileSystem(&_theSDCard);
+ _jsonStorage.setFilename("iot-node-lorawan.json");
+
+ _theSDCard.setCSPin(kNLBoardSDCardCSPin);
// Did the user set a serial value?
uint32_t theRate;
@@ -316,6 +336,25 @@ bool sfeIoTNodeLoRaWAN::onSetup()
// was list device divers set by startup commands?
if (inOpMode(kAppOpStartListDevices))
flux.dumpDeviceAutoLoadTable();
+ // setup SD card. Do this before calling start - so prefs can be read off SD if needed
+ if (!setupSDCard())
+ {
+ flxLog_W(F("Unable to initialize the SD Card. Is an SD card installed on the board?"));
+ }
+
+ // Filesystem to read firmware from
+ _sysUpdate.setFileSystem(&_theSDCard);
+
+ // Serial UX - used to list files to select off the filesystem
+ _sysUpdate.setSerialSettings(_serialSettings);
+
+ _sysUpdate.setFirmwareFilePrefix(kLoRaWANFirmwareFilePrefix);
+
+ flxRegisterEventCB(flxEvent::kOnFirmwareLoad, this, &sfeIoTNodeLoRaWAN::onFirmwareLoad);
+ flux_add(&_sysUpdate);
+
+ // check our on-board flash file system
+ _hasOnBoardFlashFS = checkOnBoardFS();
// Button events we're listening on
_boardButton.on_momentaryPress.call(this, &sfeIoTNodeLoRaWAN::onLogEvent);
@@ -354,6 +393,10 @@ void sfeIoTNodeLoRaWAN::onDeviceLoad()
for (auto b : *buttons)
b->on_clicked.call(this, &sfeIoTNodeLoRaWAN::onQwiicButtonEvent);
+
+ // setup our soil sensor device
+ _soilSensor.vccPin = kSoilSensorVCCPin;
+ _soilSensor.sensorPin = kSoilSensorSensorPin;
}
//---------------------------------------------------------------------------
//
@@ -396,8 +439,10 @@ bool sfeIoTNodeLoRaWAN::onStart()
flxLog_N_(F(" %-20s - %-40s {"), device->name(), device->description());
if (device->getKind() == flxDeviceKindI2C)
flxLog_N("%s x%x}", "qwiic", device->address());
- else
+ else if (device->getKind() == flxDeviceKindSPI)
flxLog_N("%s p%u}", "SPI", device->address());
+ else if (device->getKind() == flxDeviceKindGPIO)
+ flxLog_N("%s p%u}", "GPIO", device->address());
if (device->nOutputParameters() > 0)
{
@@ -495,12 +540,39 @@ void sfeIoTNodeLoRaWAN::set_jsonBufferSize(uint32_t new_size)
_fmtJSON.setBufferSize(new_size);
}
+uint8_t sfeIoTNodeLoRaWAN::get_logTypeSD(void)
+{
+ return _logTypeSD;
+}
+//---------------------------------------------------------------------------
+void sfeIoTNodeLoRaWAN::set_logTypeSD(uint8_t logType)
+{
+ if (logType == _logTypeSD)
+ return;
+
+ if (_logTypeSD == kAppLogTypeCSV)
+ _fmtCSV.remove(&_theOutputFile);
+ else if (_logTypeSD == kAppLogTypeJSON)
+ _fmtJSON.remove(&_theOutputFile);
+
+ _logTypeSD = logType;
+
+ if (_logTypeSD == kAppLogTypeCSV)
+ _fmtCSV.add(&_theOutputFile);
+ else if (_logTypeSD == kAppLogTypeJSON)
+ _fmtJSON.add(&_theOutputFile);
+}
+
//---------------------------------------------------------------------------
uint8_t sfeIoTNodeLoRaWAN::get_logTypeSer(void)
{
return _logTypeSer;
}
-//---------------------------------------------------------------------------
+/**
+ * @brief Sets the log type for serial output
+ *
+ * @param[in] logType The log type
+ */
void sfeIoTNodeLoRaWAN::set_logTypeSer(uint8_t logType)
{
if (logType == _logTypeSer)
@@ -521,17 +593,67 @@ void sfeIoTNodeLoRaWAN::set_logTypeSer(uint8_t logType)
//---------------------------------------------------------------------------
// local/board name things
+/**
+ * @brief Getter for the the local name property
+ *
+ * @return The local name.
+ */
+
std::string sfeIoTNodeLoRaWAN::get_local_name(void)
{
return flux.localName();
}
//---------------------------------------------------------------------------
+/**
+ * @brief Setter for the local name property
+ *
+ * @param[in] name The name
+ */
void sfeIoTNodeLoRaWAN::set_local_name(std::string name)
{
flux.setLocalName(name);
}
+//---------------------------------------------------------------------------
+// soil sensor enabled/disable
+//---------------------------------------------------------------------------
+void sfeIoTNodeLoRaWAN::set_soil_enabled(bool enable)
+{
+ // Is the soil sensor in the system?
+
+ bool active = flux.contains(_soilSensor);
+ if (active == enable)
+ return; // same
+
+ if (enable)
+ {
+ // is the sensor initialized?
+ if (!_soilSensor.isInitialized())
+ {
+ // init the sensor - this adds to the device list
+ if (_soilSensor.initialize() == false)
+ flxLog_W(F("%s: failed to initialize."), _soilSensor.name());
+ }
+ else
+ flux.add(_soilSensor);
+ _loraWANLogger.add(_soilSensor);
+ _logger.add(_soilSensor);
+ }
+ else
+ {
+ flux.remove(_soilSensor);
+ _loraWANLogger.remove(_soilSensor);
+ _logger.remove(_soilSensor);
+ }
+
+ _soilSensor.isEnabled(enable);
+}
+
+bool sfeIoTNodeLoRaWAN::get_soil_enabled(void)
+{
+ return flux.contains(_soilSensor);
+}
//---------------------------------------------------------------------------
// Display things during settings edits
//---------------------------------------------------------------------------
@@ -663,6 +785,15 @@ void sfeIoTNodeLoRaWAN::onSystemResetEvent(void)
// The system is being reset - reset our settings
flxSettings.reset();
}
+//---------------------------------------------------------------------------
+void sfeIoTNodeLoRaWAN::onFirmwareLoad(bool bLoading)
+{
+ if (bLoading)
+ sfeLED.on(sfeLED.Yellow);
+ else
+ sfeLED.off();
+}
+
//---------------------------------------------------------------------------
// Callback for LoRaWAN receive events
void sfeIoTNodeLoRaWAN::onLoRaWANReceiveEvent(uint32_t data)
@@ -730,7 +861,7 @@ void sfeIoTNodeLoRaWAN::checkBatteryLevels(void)
}
//---------------------------------------------------------------------------
-// Terminal Baudrate things
+// Terminal Baud-rate things
//---------------------------------------------------------------------------
uint32_t sfeIoTNodeLoRaWAN::get_termBaudRate(void)
{
diff --git a/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWAN.h b/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWAN.h
index f34a8c0..ca57bb3 100644
--- a/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWAN.h
+++ b/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWAN.h
@@ -17,17 +17,21 @@
#include
#include
+#include "flxLoRaWANDigi.h"
+#include "flxLoRaWANLogger.h"
+#include "sfeNLButton.h"
#include
+#include
+#include
+#include
#include
#include
#include
+#include
#include
+#include
#include
-#include "flxLoRaWANDigi.h"
-#include "flxLoRaWANLogger.h"
-#include "sfeNLButton.h"
-
// Buffer size of our JSON document output
const uint16_t kAppJSONDocSize = 1600;
// Default log interval in milli secs
@@ -77,6 +81,13 @@ class sfeIoTNodeLoRaWAN : public flxApplication
static constexpr uint8_t kAppLogTypeJSON = 0x2;
static constexpr const char *kLogFormatNames[] = {"Disabled", "CSV Format", "JSON Format"};
+
+ //---------------------------------------------------------------------------
+ uint8_t get_logTypeSD(void);
+
+ //---------------------------------------------------------------------------
+ void set_logTypeSD(uint8_t logType);
+ uint8_t _logTypeSD;
uint8_t _logTypeSer; // type of serial log output format
//---------------------------------------------------------------------------
uint8_t get_logTypeSer(void);
@@ -110,6 +121,9 @@ class sfeIoTNodeLoRaWAN : public flxApplication
bool get_verbose(void);
void set_verbose(bool enable);
+ bool get_soil_enabled(void);
+ void set_soil_enabled(bool enable);
+
void onSettingsEdit(bool bLoading);
void onSystemActivity(void);
void onSystemActivityLow(void);
@@ -120,6 +134,7 @@ class sfeIoTNodeLoRaWAN : public flxApplication
void onErrorMessage(uint8_t);
void onLogEvent(void);
void onQwiicButtonEvent(bool);
+ void onFirmwareLoad(bool bLoading);
void onLoRaWANSendEvent(bool);
void onLoRaWANReceiveEvent(uint32_t);
@@ -153,6 +168,12 @@ class sfeIoTNodeLoRaWAN : public flxApplication
&sfeIoTNodeLoRaWAN::set_verbose_dev_name>
verboseDevNames;
+ flxPropertyRWUInt8
+ sdCardLogType = {kAppLogTypeCSV,
+ {{kLogFormatNames[kAppLogTypeNone], kAppLogTypeNone},
+ {kLogFormatNames[kAppLogTypeCSV], kAppLogTypeCSV},
+ {kLogFormatNames[kAppLogTypeJSON], kAppLogTypeJSON}}};
+
flxPropertyRWUInt8
serialLogType = {kAppLogTypeCSV,
{{kLogFormatNames[kAppLogTypeNone], kAppLogTypeNone},
@@ -176,6 +197,9 @@ class sfeIoTNodeLoRaWAN : public flxApplication
flxPropertyRWBool
verboseEnabled = {false};
+ flxPropertyRWBool
+ enableSoilSensor = {false};
+
private:
friend class sfeNLCommands;
void _displayAboutObjHelper(char, const char *, bool);
@@ -197,6 +221,8 @@ class sfeIoTNodeLoRaWAN : public flxApplication
// setup routines
bool setupTime();
void setupENS160(void);
+ bool setupSDCard(void);
+ bool checkOnBoardFS(void);
// Our LoRaWAN network/connection object
flxLoRaWANDigi _loraWANConnection;
@@ -213,6 +239,10 @@ class sfeIoTNodeLoRaWAN : public flxApplication
flxFormatJSON _fmtJSON;
flxFormatCSV _fmtCSV;
+ flxFSSDCard _theSDCard;
+ flxFileRotate _theOutputFile;
+ flxStorageJSONPrefFile _jsonStorage;
+
// Serial Settings editor
flxSettingsSerial _serialSettings;
@@ -226,6 +256,12 @@ class sfeIoTNodeLoRaWAN : public flxApplication
// Fuel gauge
flxDevMAX17048 *_fuelGauge;
+ // The soil moisture device object -- if a user connects it to the GPIO of the device.
+ flxDevSoilMoisture _soilSensor;
+
+ // The system firmware object
+ flxSysFirmware _sysUpdate;
+
// for our button events of the board
sfeNLButton _boardButton;
@@ -233,4 +269,7 @@ class sfeIoTNodeLoRaWAN : public flxApplication
std::unique_ptr _batteryJob;
uint32_t _opFlags;
+
+ // flag for the on-board flash file system (RP2350)
+ bool _hasOnBoardFlashFS = false;
};
\ No newline at end of file
diff --git a/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWANAbout.cpp b/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWANAbout.cpp
index 0665534..3dd448e 100644
--- a/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWANAbout.cpp
+++ b/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWANAbout.cpp
@@ -17,6 +17,8 @@
#include
#include
+#include
+
void sfeIoTNodeLoRaWAN::_displayAboutObjHelper(char pre_ch, const char *szName, bool enabled)
{
flxLog_N_("%c %-20s : ", pre_ch, szName);
@@ -115,24 +117,60 @@ void sfeIoTNodeLoRaWAN::displayAppStatus(bool useInfo)
flxSerial.textToWhite();
flxLog_N(" System:");
flxSerial.textToNormal();
+ flxSerial.flush();
}
- // if (_theSDCard.enabled())
- // {
+ if (_theSDCard.enabled())
+ {
+
+ char szSize[32];
+ char szCap[32];
+
+ uint64_t sd_size = _theSDCard.size();
+ uint64_t sd_total = _theSDCard.total();
- // char szSize[32];
- // char szCap[32];
- // char szAvail[32];
+ flx_utils::formatByteString(sd_size, 2, szSize, sizeof(szSize));
+ flx_utils::formatByteString(sd_total, 2, szCap, sizeof(szCap));
+
+ flxLog___(logLevel, "%cSD Card - Type: %s Size: %s Capacity: %s ", pre_ch, _theSDCard.type(), szSize, szCap);
+
+ // Getting about used can take time -- so only do if about is called (use info is false)
+ if (!useInfo)
+ {
+ flxLog_N_("...");
+ flxSerial.flush();
+ char szAvail[32];
+ // This call can take some time .. .so
+ uint64_t sd_used = _theSDCard.used();
+ flx_utils::formatByteString(sd_total - sd_used, 2, szAvail, sizeof(szAvail));
+ flxLog_N("Free: %s (%.1f%%)", szAvail, 100. - (sd_used / (float)sd_total * 100.));
+ }
+ else
+ flxLog_N("");
+ }
+ else
+ flxLog__(logLevel, "%cSD card not available", pre_ch);
- // flx_utils::formatByteString(_theSDCard.size(), 2, szSize, sizeof(szSize));
- // flx_utils::formatByteString(_theSDCard.total(), 2, szCap, sizeof(szCap));
- // flx_utils::formatByteString(_theSDCard.total() - _theSDCard.used(), 2, szAvail, sizeof(szAvail));
+ flxLog___(logLevel, "%cSystem File System - ", pre_ch);
- // flxLog__(logLevel, "%cSD Card - Type: %s Size: %s Capacity: %s Free: %s (%.1f%%)", pre_ch,
- // _theSDCard.type(),
- // szSize, szCap, szAvail, 100. - (_theSDCard.used() / (float)_theSDCard.total() * 100.));
- // }
- // else
- // flxLog__(logLevel, "%cSD card not available", pre_ch);
+ if (_hasOnBoardFlashFS)
+ {
+ FSInfo fs_info;
+ if (LittleFS.info(fs_info))
+ {
+ char szSize[32];
+ char szUsed[32];
+ char szAvail[32];
+ flx_utils::formatByteString(fs_info.totalBytes, 2, szSize, sizeof(szSize));
+ flx_utils::formatByteString(fs_info.usedBytes, 2, szUsed, sizeof(szUsed));
+ flx_utils::formatByteString(fs_info.totalBytes - fs_info.usedBytes, 2, szAvail, sizeof(szAvail));
+
+ flxLog_N("size: %s, used: %s, free: %s", szSize, szUsed, szAvail);
+ }
+ else
+ flxLog_N(F("unable to access info"));
+ }
+ else
+ flxLog_N(F("not available"));
// show heap level
flxLog__(logLevel, "%cSystem Heap - Total: %dB Free: %dB (%.1f%%)", pre_ch, flxPlatform::heap_size(),
@@ -167,15 +205,15 @@ void sfeIoTNodeLoRaWAN::displayAppStatus(bool useInfo)
flxLog__(logLevel, "%cJSON Buffer - Size: %dB Max Used: %dB", pre_ch, jsonBufferSize(), _fmtJSON.getMaxSizeUsed());
flxLog__(logLevel, "%cSerial Output: %s", pre_ch, kLogFormatNames[serialLogType()]);
flxLog_N("%c Baud Rate: %d", pre_ch, serialBaudRate());
+ flxLog__(logLevel, "%cSD Card Output: %s", pre_ch, kLogFormatNames[sdCardLogType()]);
// flxLog__(logLevel, "%cSD Card Output: %s", pre_ch, kLogFormatNames[sdCardLogType()]);
// at startup, useInfo == true, the file isn't known, so skip output
- // if (!useInfo)
- // flxLog_N("%c Current Filename: \t%s", pre_ch,
- // _theOutputFile.currentFilename().length() == 0 ? "" :
- // _theOutputFile.currentFilename().c_str());
- // flxLog_N("%c Rotate Period: %d Hours", pre_ch, _theOutputFile.rotatePeriod());
+ if (!useInfo)
+ flxLog_N("%c Current Filename: \t%s", pre_ch,
+ _theOutputFile.currentFilename().length() == 0 ? "" : _theOutputFile.currentFilename().c_str());
+ flxLog_N("%c Rotate Period: %d Hours", pre_ch, _theOutputFile.rotatePeriod());
flxLog_N("");
@@ -196,8 +234,11 @@ void sfeIoTNodeLoRaWAN::displayAppStatus(bool useInfo)
flxLog_N_(F("%c %-20s - %-40s {"), pre_ch, device->name(), device->description());
if (device->getKind() == flxDeviceKindI2C)
flxLog_N("%s x%x}", "qwiic", device->address());
- else
+
+ else if (device->getKind() == flxDeviceKindSPI)
flxLog_N("%s p%u}", "SPI", device->address());
+ else if (device->getKind() == flxDeviceKindGPIO)
+ flxLog_N("%s p%u}", "GPIO", device->address());
}
flxLog_N("");
diff --git a/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWANSetup.cpp b/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWANSetup.cpp
index c4023cf..65a66ae 100644
--- a/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWANSetup.cpp
+++ b/sfeIoTNodeLoRaWAN/sfeIoTNodeLoRaWANSetup.cpp
@@ -21,6 +21,13 @@
#include
#include
+#include
+
+// on board flash file system bounds
+
+extern uint8_t _FS_start;
+extern uint8_t _FS_end;
+
//---------------------------------------------------------------------------
// setupTime()
//
@@ -88,4 +95,60 @@ void sfeIoTNodeLoRaWAN::setupENS160(void)
flxLog_I(F("%s: compensation values applied from %s"), pENS160->name(), pSHTC3->name());
return;
}
+}
+
+//---------------------------------------------------------------------------
+// setupSDCard()
+//
+// Set's up the SD card subsystem and the objects/systems that use it.
+bool sfeIoTNodeLoRaWAN::setupSDCard(void)
+{
+
+ // setup output to the SD card
+ if (_theSDCard.initialize())
+ {
+
+ _theOutputFile.setName("Data File", "Output file rotation manager");
+
+ // SD card is available - lets setup output for it
+ // Add the filesystem to the file output/rotation object
+ _theOutputFile.setFileSystem(_theSDCard);
+
+ // setup our file rotation parameters
+ _theOutputFile.filePrefix = "sfe";
+ _theOutputFile.startNumber = 1;
+ _theOutputFile.rotatePeriod(24); // one day
+
+ // add the file output to the CSV output.
+ //_fmtCSV.add(_theOutputFile);
+
+ // have the CSV format driver listen to the new file event. This
+ // will cause a header to be written next cycle.
+ flxRegisterEventCB(flxEvent::kOnNewFile, &_fmtCSV, &flxFormatCSV::output_header);
+
+ return true;
+ }
+ return false;
+}
+//---------------------------------------------------------------------------
+// checkOnBoardFS()
+//
+// Do we have an onboard FS?
+
+bool sfeIoTNodeLoRaWAN::checkOnBoardFS(void)
+{
+
+ // Was a filesystem set for the on-board flash?
+ if (&_FS_end - &_FS_start <= 0)
+ {
+ flxLog_W(F("No onboard flash file system detected"));
+ return false;
+ }
+ // Startup little fs
+ if (LittleFS.begin() == false)
+ {
+ flxLog_W(F("Unable to mount flash file system"));
+ return false;
+ }
+ return true;
}
\ No newline at end of file
diff --git a/sfeIoTNodeLoRaWAN/sfeNLBoard.h b/sfeIoTNodeLoRaWAN/sfeNLBoard.h
index 6de910c..8396c52 100644
--- a/sfeIoTNodeLoRaWAN/sfeNLBoard.h
+++ b/sfeIoTNodeLoRaWAN/sfeNLBoard.h
@@ -19,6 +19,9 @@ const uint8_t kNLBoardUserButton = 24;
// 3v3 pin
// const uint8_t kNLBoardEn3v3_SW = 32;
+// SD Card CS Ping
+const uint8_t kNLBoardSDCardCSPin = 13;
+
// LED Built in
const uint8_t kNLBoardLEDBuiltin = 25;
diff --git a/sfeIoTNodeLoRaWAN/sfeNLCommands.h b/sfeIoTNodeLoRaWAN/sfeNLCommands.h
index 90c5634..bd9de78 100644
--- a/sfeIoTNodeLoRaWAN/sfeNLCommands.h
+++ b/sfeIoTNodeLoRaWAN/sfeNLCommands.h
@@ -120,32 +120,29 @@ class sfeNLCommands
/// @param theApp Pointer to the DataLogger App
/// @retval bool indicates success (true) or failure (!true)
///
- // bool loadJSONSettings(sfeIoTNodeLoRaWAN *theApp)
- // {
- // if (!theApp)
- // return false;
-
- // flxLog_I(F("Load JSON Settings - Not Implemented"));
+ bool loadJSONSettings(sfeIoTNodeLoRaWAN *theApp)
+ {
+ if (!theApp)
+ return false;
- // // // Create a JSON prefs serial object and read in the settings
- // // flxStorageJSONPrefSerial prefsSerial(flxSettings.fallbackBuffer() > 0 ? flxSettings.fallbackBuffer() :
- // 2000);
+ // Create a JSON prefs serial object and read in the settings
+ flxStorageJSONPrefSerial prefsSerial(flxSettings.fallbackBuffer() > 0 ? flxSettings.fallbackBuffer() : 2000);
- // // // restore the settings from serial
- // // bool status = flxSettings.restoreObjectFromStorage(&flux, &prefsSerial);
- // // if (!status)
- // // return false;
+ // restore the settings from serial
+ bool status = flxSettings.restoreObjectFromStorage(&flux, &prefsSerial);
+ if (!status)
+ return false;
- // // flxLog_I_(F("Settings restored from serial..."));
+ flxLog_I_(F("Settings restored from serial..."));
- // // // now save the new settings in primary storage
- // // status = flxSettings.save(&flux, true);
- // // if (status)
- // // flxLog_N(F("saved locally"));
+ // now save the new settings in primary storage
+ status = flxSettings.save(&flux, true);
+ if (status)
+ flxLog_N(F("saved locally"));
- // // return status;
- // return true;
- // }
+ // return status;
+ return true;
+ }
//---------------------------------------------------------------------
///
/// @brief Saves the current system to preferences/Settings
@@ -232,35 +229,37 @@ class sfeNLCommands
/// @param theApp Pointer to the DataLogger App
/// @retval bool indicates success (true) or failure (!true)
///
- // bool sdCardStats(sfeIoTNodeLoRaWAN *theApp)
- // {
- // if (!theApp)
- // return false;
+ bool sdCardStats(sfeIoTNodeLoRaWAN *theApp)
+ {
+ if (!theApp)
+ return false;
- // flxLog_I(F("SD Stats - Not Implemented"));
+ if (theApp->_theSDCard.enabled())
+ {
+ char szSize[32];
+ char szCap[32];
+ char szAvail[32];
- // // if (theApp->_theSDCard.enabled())
- // // {
+ uint64_t sd_size = theApp->_theSDCard.size();
+ uint64_t sd_total = theApp->_theSDCard.total();
- // // char szSize[32];
- // // char szCap[32];
- // // char szAvail[32];
+ flx_utils::formatByteString(sd_size, 2, szSize, sizeof(szSize));
+ flx_utils::formatByteString(sd_total, 2, szCap, sizeof(szCap));
- // // flx_utils::formatByteString(theApp->_theSDCard.size(), 2, szSize, sizeof(szSize));
- // // flx_utils::formatByteString(theApp->_theSDCard.total(), 2, szCap, sizeof(szCap));
- // // flx_utils::formatByteString(theApp->_theSDCard.total() - theApp->_theSDCard.used(), 2, szAvail,
- // // sizeof(szAvail));
+ flxLog_I_("SD Card - Type: %s Size: %s Capacity: %s ", theApp->_theSDCard.type(), szSize, szCap);
- // // flxLog_I(F("SD Card - Type: %s Size: %s Capacity: %s Free: %s (%.1f%%)"), theApp->_theSDCard.type(),
- // // szSize,
- // // szCap, szAvail, 100. - (theApp->_theSDCard.used() / (float)theApp->_theSDCard.total() *
- // 100.));
- // // }
- // // else
- // // flxLog_I(F("SD card not available"));
+ flxLog_N_("...");
+ flxSerial.flush();
+ // This call can take some time .. .so
+ uint64_t sd_used = theApp->_theSDCard.used();
+ flx_utils::formatByteString(sd_total - sd_used, 2, szAvail, sizeof(szAvail));
+ flxLog_N("Free: %s (%.1f%%)", szAvail, 100. - (sd_used / (float)sd_total * 100.));
+ }
+ else
+ flxLog_I(F("SD card not available"));
- // return true;
- // }
+ return true;
+ }
//---------------------------------------------------------------------
///
@@ -429,11 +428,11 @@ class sfeNLCommands
{"clear-settings-forced", &sfeNLCommands::clearDeviceSettingsForced},
{"restart", &sfeNLCommands::restartDevice},
{"restart-forced", &sfeNLCommands::restartDeviceForced},
- // {"json-settings", &sfeNLCommands::loadJSONSettings},
+ {"json-settings", &sfeNLCommands::loadJSONSettings},
{"log-rate", &sfeNLCommands::logRateStats},
{"log-rate-toggle", &sfeNLCommands::logRateToggle},
{"log-now", &sfeNLCommands::logObservationNow},
- // {"sdcard", &sfeNLCommands::sdCardStats},
+ {"sdcard", &sfeNLCommands::sdCardStats},
{"devices", &sfeNLCommands::listLoadedDevices},
{"save-settings", &sfeNLCommands::saveSettings},
{"heap", &sfeNLCommands::heapStatus},
@@ -472,6 +471,7 @@ class sfeNLCommands
flxLog_N(F("Unknown Command: `%s`"), sBuffer.c_str());
status = false;
}
+ flxLog_N("");
return status;
}
};
diff --git a/sfeIoTNodeLoRaWAN/sfeNLVersion.h b/sfeIoTNodeLoRaWAN/sfeNLVersion.h
index 35f66d5..c49cc05 100644
--- a/sfeIoTNodeLoRaWAN/sfeNLVersion.h
+++ b/sfeIoTNodeLoRaWAN/sfeNLVersion.h
@@ -16,13 +16,13 @@
#define kDLVersionNumberMajor 1
// Minor version number
-#define kDLVersionNumberMinor 0
+#define kDLVersionNumberMinor 1
// Point version number
#define kDLVersionNumberPoint 0
// Version string description
-#define kDLVersionDescriptor "Version 1.0.0"
+#define kDLVersionDescriptor ""
// app name/class ID string
#define kDLAppClassNameID "SFE-IOT-NODE_LORAWAN"