From f4c149baa3b35d637717cbc40f30296bcd2e0751 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Fri, 8 Aug 2025 16:51:10 +0100 Subject: [PATCH 01/32] Library updates --- library.properties | 3 +-- platformio.ini | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/library.properties b/library.properties index 810670201..77289ed90 100644 --- a/library.properties +++ b/library.properties @@ -7,5 +7,4 @@ paragraph=Arduino application for Adafruit.io WipperSnapper category=Communication url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino architectures=* -depends=SdFat - Adafruit Fork, Adafruit SPIFlash, Adafruit NeoPixel, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox, Adafruit LED Backpack Library, Adafruit LiquidCrystal - +depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox diff --git a/platformio.ini b/platformio.ini index c3c5fd565..66e230845 100644 --- a/platformio.ini +++ b/platformio.ini @@ -25,10 +25,10 @@ lib_deps = ; https://github.com/adafruit/Adafruit_TouchScreen.git ; https://github.com/brentru/lvgl.git#wippersnapper ; https://github.com/brentru/Adafruit_LvGL_Glue.git#development - adafruit/Adafruit TinyUSB Library + ;;;;;;;;;;; All Boards need these libraries included ;;;;;;;;;;;;;; adafruit/Adafruit Zero DMA Library - adafruit/Adafruit SPIFlash adafruit/Adafruit NeoPixel + adafruit/Adafruit SPIFlash adafruit/Adafruit DotStar adafruit/ENS160 - Adafruit Fork adafruit/Adafruit SleepyDog Library @@ -40,10 +40,10 @@ lib_deps = adafruit/Adafruit DS248x adafruit/Adafruit INA219 adafruit/Adafruit INA260 Library + adafruit/Adafruit HDC302x adafruit/Adafruit HTS221 adafruit/Adafruit HTU21DF Library adafruit/Adafruit HTU31D Library - adafruit/Adafruit HDC302x adafruit/Adafruit LTR390 Library adafruit/Adafruit LTR329 and LTR303 adafruit/Adafruit PCT2075 @@ -68,7 +68,6 @@ lib_deps = stm32duino/STM32duino VL53L4CD stm32duino/STM32duino VL53L4CX adafruit/Adafruit_VL6180X - adafruit/Adafruit PM25 AQI Sensor adafruit/Adafruit VEML7700 Library adafruit/Adafruit LC709203F adafruit/Adafruit LPS2X @@ -82,21 +81,26 @@ lib_deps = adafruit/Adafruit STMPE610 adafruit/Adafruit TouchScreen adafruit/Adafruit MQTT Library - adafruit/Adafruit LED Backpack Library + bblanchon/ArduinoJson adafruit/Adafruit LiquidCrystal + adafruit/Adafruit LED Backpack Library + adafruit/Adafruit PM25 AQI Sensor + adafruit/Adafruit SH110X adafruit/Adafruit SSD1306 - https://github.com/adafruit/Adafruit_SHT4X.git - bblanchon/ArduinoJson - https://github.com/adafruit/SdFat.git + https://github.com/tyeth/omron-devhub_d6t-arduino.git https://github.com/pstolarz/OneWireNg.git + https://github.com/pstolarz/Arduino-Temperature-Control-Library.git https://github.com/Sensirion/arduino-sht.git + https://github.com/adafruit/Adafruit_SHT4X.git + https://github.com/Sensirion/arduino-i2c-scd4x.git https://github.com/Sensirion/arduino-i2c-sen5x.git https://github.com/Sensirion/arduino-i2c-sen66.git https://github.com/adafruit/WiFiNINA.git https://github.com/Starmbi/hp_BH1750.git + https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git https://github.com/adafruit/RTClib.git + https://github.com/adafruit/SdFat.git https://github.com/bblanchon/ArduinoStreamUtils.git - https://github.com/Sensirion/arduino-i2c-scd4x.git adafruit/Adafruit GPS Library adafruit/Adafruit uBlox From 28661b602aa9eca97dd6bb808a83a3d5d147626d Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Fri, 8 Aug 2025 16:51:39 +0100 Subject: [PATCH 02/32] Online build changes - esptool/web-native-usb targets --- .github/workflows/build-clang-doxy.yml | 105 +++++++++++++++++++------ 1 file changed, 80 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build-clang-doxy.yml b/.github/workflows/build-clang-doxy.yml index 7a7987c2b..a055ace9d 100644 --- a/.github/workflows/build-clang-doxy.yml +++ b/.github/workflows/build-clang-doxy.yml @@ -20,10 +20,32 @@ jobs: strategy: fail-fast: false matrix: - arduino-platform: ["funhouse_noota"] - include: - - offset: "0x1000" + arduino-platform: + [ + "feather_esp32s2", + "feather_esp32s2_reverse_tft", + "feather_esp32s2_tft", + "funhouse_noota", + "magtag", + "metroesp32s2", + "qtpy_esp32s2", + "esp32s3_devkitc_1_n8", + "feather_esp32s3_4mbflash_2mbpsram", + "feather_esp32s3_reverse_tft", + "feather_esp32s3_tft", + "qtpy_esp32s3_n4r2", + "xiao_esp32s3", + ] + steps: + - name: "skip if unwanted" + continue-on-error: true + if: | + github.event_name == 'workflow_dispatch' && + github.event.inputs.board != '' && + matrix.arduino-platform != github.event.inputs.board + run: | + echo "don't build this one!"; exit 1 - uses: actions/setup-python@v5 with: python-version: "3.x" @@ -48,6 +70,8 @@ jobs: - name: Install extra Arduino libraries run: | git clone --quiet https://github.com/pstolarz/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library + git clone --quiet --branch 2.2.54 https://github.com/adafruit/SdFat.git /home/runner/Arduino/libraries/SdFat + # git clone --quiet --branch v4.0.3 https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg git clone --quiet https://github.com/adafruit/Adafruit_HX8357_Library.git /home/runner/Arduino/libraries/Adafruit_HX8357_Library git clone --quiet https://github.com/adafruit/Adafruit_ILI9341.git /home/runner/Arduino/libraries/Adafruit_ILI9341 @@ -106,6 +130,7 @@ jobs: mv examples/Wippersnapper_demo/build/*/Wippersnapper_demo.ino.elf wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.elf mv examples/Wippersnapper_demo/build/*/Wippersnapper_demo.ino.map wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.map mv examples/Wippersnapper_demo/build/*/Wippersnapper_demo.ino.bootloader.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.bootloader.bin + mv examples/Wippersnapper_demo/build/*/Wippersnapper_demo.ino.merged.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.merged_auto.bin mv examples/Wippersnapper_demo/build/*/Wippersnapper_demo.ino.partitions.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.partitions.bin - name: Get Board Flash Parameters id: get_board_json @@ -121,6 +146,52 @@ jobs: echo $content echo EOF } >> "$GITHUB_OUTPUT" + - name: fetch tinyuf2 combined.bin + run: | + BOARD_NAME="${{fromJson(steps.get_board_json.outputs.boardJson).bootloaderBoardName}}" + for attempt in 1 2; do + echo "Attempt $attempt: Fetching tinyuf2 release info for board $BOARD_NAME" + API_RESPONSE=$(curl --silent --fail https://api.github.com/repos/adafruit/tinyuf2/releases/latest) + if [ $? -ne 0 ]; then + echo "Attempt $attempt: curl failed to fetch release info." + if [ "$attempt" -eq 2 ]; then exit 1; else sleep 2; continue; fi + fi + DOWNLOAD_URL=$(echo "$API_RESPONSE" | jq -r '.assets[] | select(.browser_download_url | contains("tinyuf2-'$BOARD_NAME'-") and endswith(".zip")) | .browser_download_url // empty') + if [ -z "$DOWNLOAD_URL" ]; then + echo "Attempt $attempt: No matching tinyuf2 zip found for board $BOARD_NAME." + if [ "$attempt" -eq 2 ]; then exit 1; else sleep 2; continue; fi + fi + echo "Attempt $attempt: Downloading $DOWNLOAD_URL" + wget "$DOWNLOAD_URL" -O tinyuf2.zip + if [ $? -eq 0 ]; then + unzip -o tinyuf2.zip -d . + break + else + echo "Attempt $attempt: wget failed to download $DOWNLOAD_URL" + if [ "$attempt" -eq 2 ]; then exit 1; else sleep 2; fi + fi + done + - name: move partition and bootloader files for tinyuf2 (to match flash_args) + run: | + # Copy files where they're expected to make flash_args happy + mkdir bootloader + cp bootloader.bin bootloader/bootloader.bin + mkdir partition_table + cp partition-table.bin partition_table/partition-table.bin + + - name: Create new_flash_args file from flash_args with added app bin + output file + run: | + # Create new_flash_args with esptool parameters first and output file + echo "--flash-mode ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}}" > new_flash_args + echo "--flash-freq ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashFreq}}" >> new_flash_args + echo "--flash-size ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashSize}}" >> new_flash_args + echo "-o wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.combined.bin" >> new_flash_args + + # Append flash_args content to new_flash_args, skipping the first line + tail -n +2 flash_args >> new_flash_args + + # Append main app to flash_args file + echo "0x10000 wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.bin" >> new_flash_args - name: Check boot_app0 file existence (esp32sx built from core, not-source) id: check_files uses: andstor/file-existence-action@v3 @@ -136,23 +207,17 @@ jobs: ls /home/runner/Arduino/hardware/espressif/esp32/tools/partitions - name: boot_app0 file from arduino-cli core if: steps.check_files.outputs.files_exists == 'true' - run: mv /home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions/boot_app0.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.boot_app0.bin + run: cp /home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions/boot_app0.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.boot_app0.bin - name: boot_app0 file from esp32 source bsp if: steps.check_files.outputs.files_exists == 'false' - run: mv /home/runner/Arduino/hardware/espressif/esp32/tools/partitions/boot_app0.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.boot_app0.bin - - name: Create combined binary using Esptool merge_bin + run: cp /home/runner/Arduino/hardware/espressif/esp32/tools/partitions/boot_app0.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.boot_app0.bin + - name: Copy boot_app0 file to ota_data_initial.bin (overwrite tinyuf2 boot preference) + run: cp wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.boot_app0.bin ota_data_initial.bin + - name: Create combined binary using Esptool merge-bin run: | echo ${{ steps.get_board_json.outputs.boardJson }} echo ${{ fromJson(steps.get_board_json.outputs.boardJson) }} - python3 -m esptool --chip ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.chip}} merge_bin \ - --flash_mode ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}} \ - --flash_freq ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashFreq}} \ - --flash_size ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashSize}} \ - -o wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.combined.bin \ - ${{ matrix.offset }} wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.bootloader.bin \ - 0x8000 wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.partitions.bin \ - 0xe000 wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.boot_app0.bin \ - 0x10000 wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.bin + python3 -m esptool --chip ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.chip}} merge-bin @new_flash_args - name: Zip build artifacts run: | zip -r wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.zip wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.* @@ -180,19 +245,9 @@ jobs: matrix: arduino-platform: [ - "magtag", - "metroesp32s2", "metro_esp32s3", - "feather_esp32s2", - "feather_esp32s2_tft", - "feather_esp32s2_reverse_tft", "feather_esp32s3", - "feather_esp32s3_4mbflash_2mbpsram", - "feather_esp32s3_tft", "qtpy_esp32s3", - "qtpy_esp32s2", - "feather_esp32s3_reverse_tft", - "qtpy_esp32s3_n4r2", ] steps: - uses: actions/setup-python@v5 From 0e7a9dbbe2194004e6840f0d5898f7a73b76311d Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Fri, 8 Aug 2025 16:52:42 +0100 Subject: [PATCH 03/32] Offline build task - web-native-usb + boards ref --- .github/workflows/release-offline.yml | 141 +++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-offline.yml b/.github/workflows/release-offline.yml index 8e3c8808d..e1e73ea95 100644 --- a/.github/workflows/release-offline.yml +++ b/.github/workflows/release-offline.yml @@ -112,6 +112,12 @@ jobs: repository: adafruit/ci-arduino ref: ci-wippersnapper path: ci + - name: Checkout Board Definitions + uses: actions/checkout@v4 + with: + repository: adafruit/Wippersnapper_Boards + path: ws-boards + ref: rebased-rp2040_datalogger_feather - name: Install CI-Arduino run: bash ci/actions_install.sh - name: Install extra Arduino libraries @@ -161,23 +167,154 @@ jobs: - name: Copy lv_conf.h file in Adafruit_LittlevGL_Glue_Library to the arduino library folder run: | cp /home/runner/Arduino/libraries/Adafruit_LittlevGL_Glue_Library/lv_conf.h /home/runner/Arduino/libraries + - name: Install Dependencies (esptool) + run: | + pip3 install esptool - name: Build for ESP32-SX run: | python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 - name: list files (tree) run: | - tree + tree -L 7 -h - name: Rename build artifacts to reflect the platform name run: | mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.uf2 wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.bin + mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.elf wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.elf + mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.map wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.map + mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.bootloader.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.bootloader.bin + mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.merged.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.merged_auto.bin + mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.partitions.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.partitions.bin + - name: Get Board Flash Parameters + id: get_board_json + run: | + board_name=${{ matrix.arduino-platform }} + # Remove '_noota' suffix if present + board_name=${board_name%_noota} + # Remove 'wippersnapper_' prefix if present + board_name=${board_name#wippersnapper_} + # check folder name exists, otherwise do replace of underscore with dash, or blank + if [ ! -d "ws-boards/boards/${board_name}" ]; then + echo "Board definition folder ws-boards/boards/${board_name} does not exist, checking for alternative names." + if [ -d "ws-boards/boards/${board_name//_/-}" ]; then + board_name=${board_name//_/-} + echo "Found alternative board definition folder ws-boards/boards/${board_name//_/-}." + # Remove all underscores if still not found + elif [ -d "ws-boards/boards/${board_name//_}" ]; then + board_name=${board_name//_} + echo "Found alternative board definition folder ws-boards/boards/${board_name//_}." + else + echo "Error: Board definition folder ws-boards/boards/${board_name} does not exist." + exit 1 + fi + fi + content=$(cat ws-boards/boards/${board_name}/definition.json) + { + echo 'boardJson<> "$GITHUB_OUTPUT" + - name: fetch tinyuf2 combined.bin + id: get_tinyuf2 + continue-on-error: true + run: | + # check ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}} is not empty + if [ -z "${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}}" ]; then + echo "Error: esptool.flashMode is not set in board definition." + exit 1 + fi + BOARD_NAME="${{fromJson(steps.get_board_json.outputs.boardJson).bootloaderBoardName}}" + for attempt in 1 2; do + echo "Attempt $attempt: Fetching tinyuf2 release info for board $BOARD_NAME" + API_RESPONSE=$(curl --silent --fail https://api.github.com/repos/adafruit/tinyuf2/releases/latest) + if [ $? -ne 0 ]; then + echo "Attempt $attempt: curl failed to fetch release info." + if [ "$attempt" -eq 2 ]; then exit 1; else sleep 2; continue; fi + fi + DOWNLOAD_URL=$(echo "$API_RESPONSE" | jq -r '.assets[] | select(.browser_download_url | contains("tinyuf2-'$BOARD_NAME'-") and endswith(".zip")) | .browser_download_url // empty') + if [ -z "$DOWNLOAD_URL" ]; then + echo "Attempt $attempt: No matching tinyuf2 zip found for board $BOARD_NAME." + if [ "$attempt" -eq 2 ]; then exit 1; else sleep 2; continue; fi + fi + echo "Attempt $attempt: Downloading $DOWNLOAD_URL" + wget "$DOWNLOAD_URL" -O tinyuf2.zip + if [ $? -eq 0 ]; then + unzip -o tinyuf2.zip -d . + break + else + echo "Attempt $attempt: wget failed to download $DOWNLOAD_URL" + if [ "$attempt" -eq 2 ]; then exit 1; else sleep 2; fi + fi + done + - if: ${{ steps.get_tinyuf2.outcome == 'success' }} + name: move partition and bootloader files for tinyuf2 (to match flash_args) + run: | + # Copy files where they're expected to make flash_args happy + mkdir bootloader + cp bootloader.bin bootloader/bootloader.bin + mkdir partition_table + cp partition-table.bin partition_table/partition-table.bin + + - if: ${{ steps.get_tinyuf2.outcome == 'success' }} + name: Create new_flash_args file from flash_args with added app bin + output file + run: | + # Create new_flash_args with esptool parameters first and output file + echo "--flash-mode ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}}" > new_flash_args + echo "--flash-freq ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashFreq}}" >> new_flash_args + echo "--flash-size ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashSize}}" >> new_flash_args + echo "-o wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.combined.bin" >> new_flash_args + + # Append flash_args content to new_flash_args, skipping the first line + tail -n +2 flash_args >> new_flash_args + + # Append main app to flash_args file + echo "0x10000 wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.bin" >> new_flash_args + - if: ${{ steps.get_tinyuf2.outcome == 'success' }} + name: Check boot_app0 file existence (esp32sx built from core, not-source) + id: check_files + uses: andstor/file-existence-action@v3 + with: + files: "/home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions/boot_app0.bin" + - if: ${{ steps.get_tinyuf2.outcome == 'success' && steps.check_files.outputs.files_exists == 'true' }} + name: list arduino esp32 core files + run: | + ls /home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions + - if: ${{ steps.get_tinyuf2.outcome == 'success' && steps.check_files.outputs.files_exists == 'false' }} + name: list arduino esp32 bsp core files + run: | + ls /home/runner/Arduino/hardware/espressif/esp32/tools/partitions + - if: ${{ steps.get_tinyuf2.outcome == 'success' && steps.check_files.outputs.files_exists == 'true' }} + name: boot_app0 file from arduino-cli core + run: cp /home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions/boot_app0.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.boot_app0.bin + - if: ${{ steps.get_tinyuf2.outcome == 'success' && steps.check_files.outputs.files_exists == 'false' }} + name: boot_app0 file from esp32 source bsp + run: cp /home/runner/Arduino/hardware/espressif/esp32/tools/partitions/boot_app0.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.boot_app0.bin + - if: ${{ steps.get_tinyuf2.outcome == 'success' }} + name: Copy boot_app0 file to ota_data_initial.bin (overwrite tinyuf2 boot preference) + run: cp wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.boot_app0.bin ota_data_initial.bin + - if: ${{ steps.get_tinyuf2.outcome == 'success' }} + name: Create combined binary using Esptool merge-bin + run: | + echo ${{ steps.get_board_json.outputs.boardJson }} + echo ${{ fromJson(steps.get_board_json.outputs.boardJson) }} + python3 -m esptool --chip ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.chip}} merge-bin @new_flash_args + - if: ${{ steps.get_tinyuf2.outcome == 'success' }} + name: Zip build artifacts + run: | + zip -r wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.zip wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.* + - if: ${{ steps.get_tinyuf2.outcome == 'success' }} + name: Upload build artifacts zip + uses: actions/upload-artifact@v4 + with: + name: build-files-${{ matrix.arduino-platform }}-zip + path: | + wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.zip - name: upload build artifacts uses: actions/upload-artifact@v4 with: name: build-files-${{ matrix.arduino-platform }}.${{ env.WS_VERSION }} path: | wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 - wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.bin build-rp2040: name: 🏗️ RP2040, RP2350 From 68c597ad23667f2c2e67b43d6ef91c9d90da5620 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Fri, 8 Aug 2025 16:53:30 +0100 Subject: [PATCH 04/32] New board targets (S3 XIAO/Espressif DevkitC) --- platformio.ini | 35 +++++++++++++++---- src/Wippersnapper_Boards.h | 21 +++++++++++ src/provisioning/tinyusb/Wippersnapper_FS.cpp | 4 +-- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/platformio.ini b/platformio.ini index 66e230845..88aba16cd 100644 --- a/platformio.ini +++ b/platformio.ini @@ -20,7 +20,7 @@ lib_deps = ;;;;;;;;;;; FunHouse / LVGL Boards uncomment these ;;;;;;;;;;;;;; ; https://github.com/adafruit/Adafruit_HX8357_Library.git ; https://github.com/adafruit/Adafruit_ILI9341.git - ; https://github.com/adafruit/Adafruit_STMPE610.git + ; https://github.com/adafruit/Adafruit_STMPE610.git ; https://github.com/adafruit/Adafruit-ST7735-Library.git ; https://github.com/adafruit/Adafruit_TouchScreen.git ; https://github.com/brentru/lvgl.git#wippersnapper @@ -345,26 +345,47 @@ board = adafruit_qtpy_esp32s3_nopsram build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM extra_scripts = pre:rename_usb_config.py + ; Espressif ESP32-S3 NO PSRAM espressif_esp32s3_devkitc_1_n8 [env:espressif_esp32s3_devkitc_1_n8] extends = common:esp32 board = esp32-s3-devkitc-1 +build_flags = -DARDUINO_ESPRESSIF_ESP32S3_DEVKITC_1_N8 -DUSE_TINYUSB=1 -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=1 +board_build.partitions = noota_ffat.csv +; board_build.partitions = tinyuf2-partitions-8MB.csv +; extra_scripts = pre:rename_usb_config.py + +; Espressif ESP32-S3 NO PSRAM espressif_esp32s3_devkitc_1_n8 (DEBUG) +[env:espressif_esp32s3_devkitc_1_n8_debug] +extends = common:esp32 +board = esp32-s3-devkitc-1 build_type = debug -build_flags = +build_flags = -DUSE_TINYUSB=1 + -DARDUINO_USB_MODE=0 + -DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_ESPRESSIF_ESP32S3_DEVKITC_1_N8 -DDEBUG=1 -DESP_LOG_LEVEL=5 - -DARDUINO_CORE_DEBUG_LEVEL=5 - -DARDUINO_DEBUG_LEVEL=5 - ; -DARDUINO_DEBUG_OUTPUT=Serial - ; -DARDUINO_DEBUG_BAUD=115200 + -DARDUINO_CORE_LOG_LEVEL=5 -DARDUINO_LOG_LEVEL=5 - -DCORE_DEBUG_LEVEL=5 -DARDUHAL_LOG_LEVEL=5 +; board_build.partitions = tinyuf2-partitions-8MB.csv +board_build.partitions = noota_ffat.csv +; extra_scripts = pre:rename_usb_config.py + +; Seeed Studio ESP32 boards: + +; Xiao ESP32S3 N8R8 (SENSE) +[env:seeed-xiao_esp32s3_n8r8] +extends = common:esp32 +board = seeed_xiao_esp32s3 +build_flags = -DARDUINO_XIAO_ESP32S3 -DUSE_TINYUSB -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_USB_MODE=0 board_build.partitions = tinyuf2-partitions-8MB.csv extra_scripts = pre:rename_usb_config.py + + ; ESP8266 Boards ; Adafruit Feather HUZZAH ESP8266 diff --git a/src/Wippersnapper_Boards.h b/src/Wippersnapper_Boards.h index 0797d37e8..531e4ac9a 100644 --- a/src/Wippersnapper_Boards.h +++ b/src/Wippersnapper_Boards.h @@ -218,11 +218,13 @@ #define USE_TINYUSB #define USE_STATUS_LED #define STATUS_LED_PIN 64 +#define SD_CS_PIN 17 #elif defined(ARDUINO_RASPBERRY_PI_PICO_2W) #define BOARD_ID "rpi-pico-2w" #define USE_TINYUSB #define USE_STATUS_LED #define STATUS_LED_PIN 64 +#define SD_CS_PIN 17 #elif defined(ARDUINO_RASPBERRY_PI_PICO) #define BOARD_ID "rpi-pico" #define USE_TINYUSB @@ -257,6 +259,25 @@ #define USE_STATUS_NEOPIXEL #define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL #define STATUS_NEOPIXEL_NUM 1 +#elif defined(ARDUINO_ESP32S3_DEV) +#define BOARD_ID "esp32s3-devkitc-1-n8" +#define USE_TINYUSB +#define USE_STATUS_NEOPIXEL +#define STATUS_NEOPIXEL_PIN 48 +#define STATUS_NEOPIXEL_NUM 1 +#ifdef BOARD_HAS_PSRAM +#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation +// Update board ID if PSRAM is present, needs new board definition +#endif +#elif defined(ARDUINO_XIAO_ESP32S3) +#define BOARD_ID "xiao-esp32s3" +#define BOARD_HAS_PSRAM +#define USE_PSRAM +#define USE_TINYUSB +#define USE_STATUS_LED +#define STATUS_LED_PIN LED_BUILTIN +// XIAO S3 Sense Camera addon SD card CS pin GPIO21, or D2/GPIO3 on grove breakout +#define SD_CS_PIN 21 #else #warning "Board type not identified within Wippersnapper_Boards.h!" #endif diff --git a/src/provisioning/tinyusb/Wippersnapper_FS.cpp b/src/provisioning/tinyusb/Wippersnapper_FS.cpp index 5d20aa906..d62e3f302 100644 --- a/src/provisioning/tinyusb/Wippersnapper_FS.cpp +++ b/src/provisioning/tinyusb/Wippersnapper_FS.cpp @@ -14,10 +14,10 @@ */ #if defined(ARDUINO_MAGTAG29_ESP32S2) || defined(ARDUINO_METRO_ESP32S2) || \ defined(ARDUINO_METRO_ESP32S3) || defined(ARDUINO_FUNHOUSE_ESP32S2) || \ - defined(ADAFRUIT_PYPORTAL_M4_TITANO) || \ + defined(ADAFRUIT_PYPORTAL_M4_TITANO) || defined(ARDUINO_ESP32S3_DEV) || \ defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE) || defined(ADAFRUIT_PYPORTAL) || \ defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2) || \ - defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) || \ + defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) || defined(ARDUINO_XIAO_ESP32S3) || \ defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2_TFT) || \ defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_NOPSRAM) || \ defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) || \ From d6d0f7f0e35c101ea84732f7d749085e499efbd3 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Fri, 8 Aug 2025 16:54:12 +0100 Subject: [PATCH 05/32] Wokwi build defines for platformIO sketch --- src/Wippersnapper_demo.ino | 8 ++++++++ src/ws_adapters.h | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/src/Wippersnapper_demo.ino b/src/Wippersnapper_demo.ino index 2f4af4902..817f5b53c 100644 --- a/src/Wippersnapper_demo.ino +++ b/src/Wippersnapper_demo.ino @@ -10,7 +10,15 @@ // All text above must be included in any redistribution. #include "ws_adapters.h" +#if defined(OFFLINE_MODE_WOKWI) +ws_adapter_wifi wipper; // Wokwi offline mode uses a wifi adapter +#elif defined(WS_WIFI_ADAPTER) ws_adapter_wifi wipper; +#elif defined(WS_OFFLINE_ADAPTER) +ws_adapter_offline wipper; +#else +#error "No valid ws_adapter_wifi or ws_adapter_offline defined! Please check your board configuration." +#endif #define WS_DEBUG // Enable debug output! void setup() { diff --git a/src/ws_adapters.h b/src/ws_adapters.h index d2bcf87bb..0faf4951a 100644 --- a/src/ws_adapters.h +++ b/src/ws_adapters.h @@ -56,6 +56,7 @@ typedef ws_wifi_ninafw ws_adapter_wifi; defined(ARDUINO_RASPBERRY_PI_PICO) || \ defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER) || \ defined(ARDUINO_ADAFRUIT_METRO_RP2350) +#define WS_OFFLINE_ADAPTER #define SD_CS_PIN 23 #include "adapters/offline/ws_offline_pico.h" typedef ws_offline_pico ws_adapter_offline; @@ -63,4 +64,8 @@ typedef ws_offline_pico ws_adapter_offline; #warning "Transport adapter not defined within ws_adapters.h!" #endif +#ifndef WS_OFFLINE_ADAPTER +#define WS_WIFI_ADAPTER +#endif + #endif // WS_ADAPTERS_H \ No newline at end of file From 5546bd0100aebcdd438723ff508c131d9f9b421b Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Fri, 8 Aug 2025 16:54:26 +0100 Subject: [PATCH 06/32] Add .clang-format file --- .github/workflows/.clang-format | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/.clang-format diff --git a/.github/workflows/.clang-format b/.github/workflows/.clang-format new file mode 100644 index 000000000..ed70f56ff --- /dev/null +++ b/.github/workflows/.clang-format @@ -0,0 +1,13 @@ +Language: Cpp +BasedOnStyle: Google +IndentWidth: 2 +ColumnLimit: 80 +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +BinPackArguments: true +BinPackParameters: true +BreakBeforeBraces: Attach +DerivePointerAlignment: false +PointerAlignment: Left +SpacesBeforeTrailingComments: 1 \ No newline at end of file From 33b202e35eadb4e075da91e53bc1edfdd3964f58 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Mon, 11 Aug 2025 12:27:02 +0100 Subject: [PATCH 07/32] Add OMRON D6T-1A --- src/components/i2c/controller.cpp | 6 ++ src/components/i2c/controller.h | 1 + src/components/i2c/drivers/drvD6t1a.h | 134 ++++++++++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 src/components/i2c/drivers/drvD6t1a.h diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 538a8c8c6..e0e61a5e6 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -103,6 +103,11 @@ static const std::map I2cFactorySensor = { const char *driver_name) -> drvBase * { return new drvDps310(i2c, addr, mux_channel, driver_name); }}, + {"d6t1a", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvD6t1a(i2c, addr, mux_channel, driver_name); + }}, {"ds2484", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { @@ -346,6 +351,7 @@ static const std::map I2cFactorySensor = { static const std::unordered_map> map_address_to_drivers = { + {0x0A, {"d6t1a"}}, {0x0B, {"lc709203f"}}, {0x12, {"pmsa003i"}}, {0x13, {"vncl4020"}}, diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 6390365ed..3ea390507 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -27,6 +27,7 @@ #include "drivers/drvBmp280.h" #include "drivers/drvBmp3xx.h" #include "drivers/drvDps310.h" +#include "drivers/drvD6t1a.h" #include "drivers/drvDs2484.h" #include "drivers/drvEns160.h" #include "drivers/drvHts221.h" diff --git a/src/components/i2c/drivers/drvD6t1a.h b/src/components/i2c/drivers/drvD6t1a.h new file mode 100644 index 000000000..ab4ff10e2 --- /dev/null +++ b/src/components/i2c/drivers/drvD6t1a.h @@ -0,0 +1,134 @@ +/*! + * @file drvD6t1a.h + * + * Device driver for the OMRON D6T-1A Non-contact Thermal sensor. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Tyeth Gundry 2025 for Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + * + */ + +#ifndef DRV_D6T1A_H +#define DRV_D6T1A_H +#include "drvBase.h" +#include + +/*! + @brief Class that provides a sensor driver for the D6T1A temperature sensor. +*/ +class drvD6t1a : public drvBase { + +public: + /*! + @brief Constructor for a D6T1A sensor. + @param i2c + The I2C interface. + @param sensorAddress + 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. + */ + drvD6t1a(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) { + _i2c = i2c; + _address = sensorAddress; + _i2c_mux_channel = mux_channel; + strncpy(_name, driver_name, sizeof(_name) - 1); + _name[sizeof(_name) - 1] = '\0'; + _deviceTemp = NAN; + _objectTemp = NAN; + _lastRead = 0; + _d6t1a = nullptr; + } + + /*! + @brief Destructor for a D6T1A sensor. + */ + ~drvD6t1a() { delete _d6t1a; } + + /*! + @brief Initializes the D6T1A sensor and begins I2C. + @returns True if initialized successfully, False otherwise. + */ + bool begin() override { + _d6t1a = new OmronD6T(OmronD6T::D6T_1A, _i2c); + if (!_d6t1a->begin(_address)) + return false; + return true; + } + + /*! + @brief Checks if sensor was read within last 200ms. + @returns True if the sensor was recently read, False otherwise. + */ + bool HasBeenReadInLast200ms() { + return _lastRead != 0 && (millis() - _lastRead < 200); + } + + /*! + @brief Reads the sensor. + @returns True if the sensor was read successfully, False otherwise. + */ + bool ReadSensorData() { + if (HasBeenReadInLast200ms()) + return true; + + _d6t1a->read(); + _deviceTemp = (float)_d6t1a->ambientTempC(); + _objectTemp = (float)_d6t1a->objectTempC(0, 0); + _lastRead = millis(); + return true; + } + + /*! + @brief Gets the D6T1A's current ambient temperature. + @param tempEvent + Pointer to an Adafruit_Sensor event. + @returns True if the temperature was obtained successfully, False otherwise. + */ + bool getEventAmbientTemp(sensors_event_t *tempEvent) { + if (ReadSensorData() && !isnan(_deviceTemp)) { + tempEvent->temperature = _deviceTemp; + return true; + } + return false; + } + + /*! + @brief Gets the D6T1A's object temperature. + @param tempEvent + Pointer to an Adafruit_Sensor event. + @returns True if the temperature was obtained successfully, False otherwise. + */ + bool getEventObjectTemp(sensors_event_t *tempEvent) { + if (ReadSensorData() && !isnan(_objectTemp)) { + tempEvent->temperature = _objectTemp; + return true; + } + return false; + } + + void ConfigureDefaultSensorTypes() override { + _default_sensor_types_count = 2; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE; + _default_sensor_types[1] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE; + } + +protected: + float _deviceTemp; ///< Device temperature in Celsius + float _objectTemp; ///< Object temperature in Celsius + uint32_t _lastRead; ///< Last time the sensor was read in milliseconds + OmronD6T *_d6t1a; ///< D6T1A object +}; + +#endif // DRV_D6T1A_H \ No newline at end of file From 393e70ad83eb408a46de7422d18fea582af40e7c Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Mon, 11 Aug 2025 12:31:43 +0100 Subject: [PATCH 08/32] remove commented out milesburton library for v2 --- .github/workflows/build-clang-doxy.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build-clang-doxy.yml b/.github/workflows/build-clang-doxy.yml index a055ace9d..5258c1f91 100644 --- a/.github/workflows/build-clang-doxy.yml +++ b/.github/workflows/build-clang-doxy.yml @@ -71,7 +71,6 @@ jobs: run: | git clone --quiet https://github.com/pstolarz/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library git clone --quiet --branch 2.2.54 https://github.com/adafruit/SdFat.git /home/runner/Arduino/libraries/SdFat - # git clone --quiet --branch v4.0.3 https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg git clone --quiet https://github.com/adafruit/Adafruit_HX8357_Library.git /home/runner/Arduino/libraries/Adafruit_HX8357_Library git clone --quiet https://github.com/adafruit/Adafruit_ILI9341.git /home/runner/Arduino/libraries/Adafruit_ILI9341 From a9ae906878717e35369d37396fea39e46a556c0f Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 12 Aug 2025 12:36:22 +0100 Subject: [PATCH 09/32] Add global skip option for auto config [exportedFromDevice.autoConfig] --- src/Wippersnapper_V2.h | 1 + src/Wippersnapper_demo.ino.cpp | 28 +++++++++++++++++++++++++++ src/provisioning/sdcard/ws_sdcard.cpp | 10 ++++++++++ 3 files changed, 39 insertions(+) create mode 100644 src/Wippersnapper_demo.ino.cpp diff --git a/src/Wippersnapper_V2.h b/src/Wippersnapper_V2.h index 97187cb0b..aaacca39e 100644 --- a/src/Wippersnapper_V2.h +++ b/src/Wippersnapper_V2.h @@ -220,6 +220,7 @@ class Wippersnapper_V2 { void errorWriteHangV2(const char *error); bool _is_offline_mode; ///< Global flag for if the device is in offline mode + bool _global_auto_config = true; ///< Support no auto config for exportedDevice // TODO: Do we need this? ws_board_status_t _boardStatusV2 = diff --git a/src/Wippersnapper_demo.ino.cpp b/src/Wippersnapper_demo.ino.cpp new file mode 100644 index 000000000..283fc09a5 --- /dev/null +++ b/src/Wippersnapper_demo.ino.cpp @@ -0,0 +1,28 @@ +# 1 "C:\\Users\\tyeth\\AppData\\Local\\Temp\\tmp97kub74s" +#include +# 1 "C:/dev/arduino/Adafruit_Wippersnapper_Arduino/src/Wippersnapper_demo.ino" +# 12 "C:/dev/arduino/Adafruit_Wippersnapper_Arduino/src/Wippersnapper_demo.ino" +#include "ws_adapters.h" +#if defined(OFFLINE_MODE_WOKWI) +ws_adapter_wifi wipper; +#elif defined(WS_WIFI_ADAPTER) +ws_adapter_wifi wipper; +#elif defined(WS_OFFLINE_ADAPTER) +ws_adapter_offline wipper; +#else +#error "No valid ws_adapter_wifi or ws_adapter_offline defined! Please check your board configuration." +#endif +#define WS_DEBUG +void setup(); +void loop(); +#line 24 "C:/dev/arduino/Adafruit_Wippersnapper_Arduino/src/Wippersnapper_demo.ino" +void setup() { + Serial.begin(115200); + while(!Serial); + wipper.provision(); + wipper.connect(); +} + +void loop() { + wipper.run(); +} \ No newline at end of file diff --git a/src/provisioning/sdcard/ws_sdcard.cpp b/src/provisioning/sdcard/ws_sdcard.cpp index 090fb8008..c160e2187 100644 --- a/src/provisioning/sdcard/ws_sdcard.cpp +++ b/src/provisioning/sdcard/ws_sdcard.cpp @@ -829,6 +829,10 @@ bool ws_sdcard::ParseExportedFromDevice(JsonDocument &doc) { return false; } + if (exportedFromDevice["autoConfig"].as() == false) { + WsV2._global_auto_config = false; + } + return true; } @@ -889,6 +893,12 @@ bool ws_sdcard::ParseFileConfig() { return false; } + // If global skip (exportedFromDevice.autoConfig == false) then just continue + if (!WsV2._global_auto_config) { + WS_DEBUG_PRINTLN("[SD] Auto config is disabled, skipping I2C scan."); + return true; + } + // Add the results of I2C scan to the shared buffer if (!AddI2cScanResultsToBuffer()) { WS_DEBUG_PRINTLN("[SD] Error: Unable to add I2C scan results to " From bf1498fcc9c5c87524ff1e4dbfa79278ee6a3eab Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 12 Aug 2025 13:48:38 +0100 Subject: [PATCH 10/32] Add PCF8563 RTC for XIAO expansion board --- src/provisioning/sdcard/ws_sdcard.cpp | 31 ++++++++++++++++++++++++++- src/provisioning/sdcard/ws_sdcard.h | 2 ++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/provisioning/sdcard/ws_sdcard.cpp b/src/provisioning/sdcard/ws_sdcard.cpp index c160e2187..bd53e7f1d 100644 --- a/src/provisioning/sdcard/ws_sdcard.cpp +++ b/src/provisioning/sdcard/ws_sdcard.cpp @@ -179,7 +179,32 @@ bool ws_sdcard::InitPCF8523() { _rtc_pcf8523->adjust(DateTime(F(__DATE__), F(__TIME__))); } _rtc_pcf8523->start(); - _cfg_i2c_addresses.push_back(0x68); // Disable auto-config for DS3231 + _cfg_i2c_addresses.push_back(0x68); // Disable auto-config for PCF8523 + return true; +} + +/**************************************************************************/ +/*! + @brief Initializes a PCF8563 RTC. + @returns True if the RTC was successfully initialized, False + otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::InitPCF8563() { + _rtc_pcf8563 = new RTC_PCF8563(); + if (!_rtc_pcf8563->begin(WsV2._i2c_controller->GetI2cBus())) { + WS_DEBUG_PRINTLN("[SD] Error: Failed to initialize PCF8563 RTC on WIRE"); + if (!_rtc_pcf8563->begin(WsV2._i2c_controller->GetI2cBus(true))) { + WS_DEBUG_PRINTLN("[SD] Error: Failed to initialize PCF8563 RTC on WIRE1"); + delete _rtc_pcf8563; + return false; + } + } + if (!_rtc_pcf8563->isrunning() || _rtc_pcf8563->lostPower()) { + _rtc_pcf8563->adjust(DateTime(F(__DATE__), F(__TIME__))); + } + _rtc_pcf8563->start(); + _cfg_i2c_addresses.push_back(0x51); // Disable auto-config for PCF8563 return true; } @@ -227,6 +252,8 @@ bool ws_sdcard::ConfigureRTC(const char *rtc_type) { return InitDS3231(); } else if (strcmp(rtc_type, "PCF8523") == 0) { return InitPCF8523(); + } else if (strcmp(rtc_type, "PCF8563") == 0) { + return InitPCF8563(); } else if (strcmp(rtc_type, "SOFT") == 0) { return InitSoftRTC(); } @@ -1024,6 +1051,8 @@ uint32_t ws_sdcard::GetTimestamp() { now = _rtc_ds1307->now(); else if (_rtc_pcf8523 != nullptr) now = _rtc_pcf8523->now(); + else if (_rtc_pcf8563 != nullptr) + now = _rtc_pcf8563->now(); else if (_is_soft_rtc) { uint32_t cur_time = GetSoftRTCTime(); TickSoftRTC(); diff --git a/src/provisioning/sdcard/ws_sdcard.h b/src/provisioning/sdcard/ws_sdcard.h index e66c19cc8..32169b060 100644 --- a/src/provisioning/sdcard/ws_sdcard.h +++ b/src/provisioning/sdcard/ws_sdcard.h @@ -83,6 +83,7 @@ class ws_sdcard { bool InitDS1307(); bool InitDS3231(); bool InitPCF8523(); + bool InitPCF8563(); bool InitSoftRTC(); void TickSoftRTC(); uint32_t GetSoftRTCTime(); @@ -134,6 +135,7 @@ class ws_sdcard { RTC_DS3231 *_rtc_ds3231 = nullptr; ///< DS3231 RTC object RTC_DS1307 *_rtc_ds1307 = nullptr; ///< DS1307 RTC object RTC_PCF8523 *_rtc_pcf8523 = nullptr; ///< PCF8523 RTC object + RTC_PCF8563 *_rtc_pcf8563 = nullptr; ///< PCF8563 RTC object bool _is_soft_rtc; ///< True if a "soft rtc" is being used, False otherwise uint32_t _soft_rtc_counter; ///< Holds the counter for a "soft rtc" bool _use_test_data; ///< True if sample data is being used for testing From 544b78c512ae010f117cce0370b4083dd9bcb71a Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 12 Aug 2025 13:49:03 +0100 Subject: [PATCH 11/32] WIP: autoConfig getting written as null to config.json --- src/components/i2c/controller.cpp | 3 +++ src/provisioning/sdcard/ws_sdcard.cpp | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index e0e61a5e6..a623d4768 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -1054,6 +1054,9 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) { GPSController *drv_uart_gps = nullptr; if (strcmp(device_name, "UNKNOWN_SCAN") == 0) { + if (!WsV2._global_auto_config) { + return true; + } WS_DEBUG_PRINTLN("Attempting to autoconfig device found in scan..."); if (device_descriptor.i2c_device_address == 0x68 || device_descriptor.i2c_device_address == 0x70) { diff --git a/src/provisioning/sdcard/ws_sdcard.cpp b/src/provisioning/sdcard/ws_sdcard.cpp index bd53e7f1d..6cb61e9b9 100644 --- a/src/provisioning/sdcard/ws_sdcard.cpp +++ b/src/provisioning/sdcard/ws_sdcard.cpp @@ -856,9 +856,9 @@ bool ws_sdcard::ParseExportedFromDevice(JsonDocument &doc) { return false; } - if (exportedFromDevice["autoConfig"].as() == false) { - WsV2._global_auto_config = false; - } + bool global_auto_config = true; + global_auto_config = exportedFromDevice["autoConfig"].as(); + WsV2._global_auto_config = global_auto_config; return true; } From fe43d5acb2ee7c4595418766ded1f8228893b8b7 Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 12 Aug 2025 15:15:20 +0100 Subject: [PATCH 12/32] fix(autoconfig): stop writing config if global auto off. --- src/Wippersnapper_V2.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Wippersnapper_V2.cpp b/src/Wippersnapper_V2.cpp index 9bf541f58..09fca1767 100644 --- a/src/Wippersnapper_V2.cpp +++ b/src/Wippersnapper_V2.cpp @@ -1295,7 +1295,10 @@ void Wippersnapper_V2::connect() { // Call the TL signal decoder to parse the incoming JSON data callDecodeB2D(); #ifndef OFFLINE_MODE_WOKWI - WsV2._fileSystemV2->WriteFileConfig(); + //TODO: Don't write the config file if unchanged versus current config + if (WsV2._global_auto_config) { + WsV2._fileSystemV2->WriteFileConfig(); + } #endif // OFFLINE_MODE_WOKWI used for CI test simulations, lacks TinyUSB WS_DEBUG_PRINTLN("[APP] Hardware configured!"); // Blink status LED to green to indicate successful configuration From 871ce8ed425c0c5eaff27e0680b19531d38947af Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 12 Aug 2025 15:44:39 +0100 Subject: [PATCH 13/32] fix(autoconfig): don't run against 0x51 (PCF8563) --- src/components/i2c/controller.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index a623d4768..9ffe410c2 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -1058,7 +1058,8 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) { return true; } WS_DEBUG_PRINTLN("Attempting to autoconfig device found in scan..."); - if (device_descriptor.i2c_device_address == 0x68 || + if (device_descriptor.i2c_device_address == 0x51 || + device_descriptor.i2c_device_address == 0x68 || device_descriptor.i2c_device_address == 0x70) { WS_DEBUG_PRINTLN("[i2c] Device address is shared with RTC/MUX, can not " "auto-init, skipping!"); From cae51576e6dbbfac28070d39725276aef47f2f17 Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 12 Aug 2025 15:46:26 +0100 Subject: [PATCH 14/32] chore(gitignore): cleanup cpp sketch asset --- .gitignore | 1 + src/Wippersnapper_demo.ino.cpp | 28 ---------------------------- 2 files changed, 1 insertion(+), 28 deletions(-) delete mode 100644 src/Wippersnapper_demo.ino.cpp diff --git a/.gitignore b/.gitignore index c8c95f2de..7cd678d8a 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ html/* src/.vscode/settings.json .DS_STORE examples/Wippersnapper_demo/build/ +src/Wippersnapper_demo.ino.cpp # Virtual environment directories .venv/ diff --git a/src/Wippersnapper_demo.ino.cpp b/src/Wippersnapper_demo.ino.cpp deleted file mode 100644 index 283fc09a5..000000000 --- a/src/Wippersnapper_demo.ino.cpp +++ /dev/null @@ -1,28 +0,0 @@ -# 1 "C:\\Users\\tyeth\\AppData\\Local\\Temp\\tmp97kub74s" -#include -# 1 "C:/dev/arduino/Adafruit_Wippersnapper_Arduino/src/Wippersnapper_demo.ino" -# 12 "C:/dev/arduino/Adafruit_Wippersnapper_Arduino/src/Wippersnapper_demo.ino" -#include "ws_adapters.h" -#if defined(OFFLINE_MODE_WOKWI) -ws_adapter_wifi wipper; -#elif defined(WS_WIFI_ADAPTER) -ws_adapter_wifi wipper; -#elif defined(WS_OFFLINE_ADAPTER) -ws_adapter_offline wipper; -#else -#error "No valid ws_adapter_wifi or ws_adapter_offline defined! Please check your board configuration." -#endif -#define WS_DEBUG -void setup(); -void loop(); -#line 24 "C:/dev/arduino/Adafruit_Wippersnapper_Arduino/src/Wippersnapper_demo.ino" -void setup() { - Serial.begin(115200); - while(!Serial); - wipper.provision(); - wipper.connect(); -} - -void loop() { - wipper.run(); -} \ No newline at end of file From 4b70a62d3056bdc1820fd06aedf3754a9fbfd15d Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 12 Aug 2025 16:12:49 +0100 Subject: [PATCH 15/32] fix(clang): add clang format file to root, and run against PR --- .../workflows/.clang-format => .clang-format | 0 src/Wippersnapper_Boards.h | 5 +- src/Wippersnapper_V2.cpp | 738 +++++++++--------- src/Wippersnapper_V2.h | 141 ++-- src/components/i2c/controller.h | 34 +- src/components/i2c/drivers/drvD6t1a.h | 37 +- 6 files changed, 488 insertions(+), 467 deletions(-) rename .github/workflows/.clang-format => .clang-format (100%) diff --git a/.github/workflows/.clang-format b/.clang-format similarity index 100% rename from .github/workflows/.clang-format rename to .clang-format diff --git a/src/Wippersnapper_Boards.h b/src/Wippersnapper_Boards.h index 531e4ac9a..b9eff6217 100644 --- a/src/Wippersnapper_Boards.h +++ b/src/Wippersnapper_Boards.h @@ -276,8 +276,9 @@ #define USE_TINYUSB #define USE_STATUS_LED #define STATUS_LED_PIN LED_BUILTIN -// XIAO S3 Sense Camera addon SD card CS pin GPIO21, or D2/GPIO3 on grove breakout -#define SD_CS_PIN 21 +// XIAO S3 Sense Camera addon SD card CS pin GPIO21, or D2/GPIO3 on grove +// expansion board breakout (OLED/SD/RTC-PCF8563) +#define SD_CS_PIN 21 #else #warning "Board type not identified within Wippersnapper_Boards.h!" #endif diff --git a/src/Wippersnapper_V2.cpp b/src/Wippersnapper_V2.cpp index 09fca1767..b45b53667 100644 --- a/src/Wippersnapper_V2.cpp +++ b/src/Wippersnapper_V2.cpp @@ -112,8 +112,9 @@ void Wippersnapper_V2::provision() { // Begin display if (!WsV2._displayV2->begin()) { WS_DEBUG_PRINTLN("Unable to enable display driver and LVGL"); - haltErrorV2("Unable to enable display driver, please check the json " - "configuration!"); + haltErrorV2( + "Unable to enable display driver, please check the json " + "configuration!"); } WsV2._displayV2->enableLogging(); @@ -147,7 +148,9 @@ void Wippersnapper_V2::provision() { /*! @brief Disconnects from Adafruit IO+ Wippersnapper_V2. */ -void Wippersnapper_V2::disconnect() { _disconnect(); } +void Wippersnapper_V2::disconnect() { + _disconnect(); +} // Concrete class definition for abstract classes @@ -191,7 +194,7 @@ int32_t Wippersnapper_V2::getRSSI() { @param clientID A unique client identifier string. */ -void Wippersnapper_V2::setupMQTTClient(const char * /*clientID*/) { +void Wippersnapper_V2::setupMQTTClient(const char* /*clientID*/) { WS_DEBUG_PRINTLN("Wippersnapper_V2::setupMQTTClient"); WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); } @@ -213,8 +216,8 @@ ws_status_t Wippersnapper_V2::networkStatus() { @param ssidPassword Your wireless network's password. */ -void Wippersnapper_V2::set_ssid_pass(const char * /*ssid*/, - const char * /*ssidPassword*/) { +void Wippersnapper_V2::set_ssid_pass(const char* /*ssid*/, + const char* /*ssidPassword*/) { WS_DEBUG_PRINTLN("Wippersnapper_V2::set_ssid_pass"); WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); } @@ -256,7 +259,7 @@ void Wippersnapper_V2::set_user_key() { @returns True if Checkin Response decoded and parsed successfully, False otherwise. */ -bool handleCheckinResponse(pb_istream_t *stream) { +bool handleCheckinResponse(pb_istream_t* stream) { // Decode the Checkin Response message if (!WsV2.CheckInModel->DecodeCheckinResponse(stream)) { WS_DEBUG_PRINTLN("ERROR: Unable to decode Checkin Response message"); @@ -300,166 +303,166 @@ bool handleCheckinResponse(pb_istream_t *stream) { Optional arguments from decoder calling function. @returns True if decoded and executed successfully, False otherwise. */ -bool cbDecodeBrokerToDevice(pb_istream_t *stream, const pb_field_t *field, - void **arg) { +bool cbDecodeBrokerToDevice(pb_istream_t* stream, const pb_field_t* field, + void** arg) { (void)arg; // marking unused parameters to avoid compiler warning switch (field->tag) { - case wippersnapper_signal_BrokerToDevice_checkin_response_tag: - WS_DEBUG_PRINTLN("-> Checkin Response Message Type"); - WS_DEBUG_PRINT("Handling Checkin Response..."); - if (!handleCheckinResponse(stream)) { - return false; - } - WS_DEBUG_PRINTLN("Handled!"); - break; - case wippersnapper_signal_BrokerToDevice_digitalio_add_tag: - WS_DEBUG_PRINTLN("-> DigitalIO Add Message Type"); - if (!WsV2.digital_io_controller->Handle_DigitalIO_Add(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_digitalio_remove_tag: - WS_DEBUG_PRINTLN("-> DigitalIO Remove Message Type"); - if (!WsV2.digital_io_controller->Handle_DigitalIO_Remove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_digitalio_write_tag: - WS_DEBUG_PRINTLN("-> DigitalIO Write Message Type"); - if (!WsV2.digital_io_controller->Handle_DigitalIO_Write(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_analogio_add_tag: - WS_DEBUG_PRINTLN("-> AnalogIO Add Message Type"); - if (!WsV2.analogio_controller->Handle_AnalogIOAdd(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_analogio_remove_tag: - WS_DEBUG_PRINTLN("-> AnalogIO Remove Message Type"); - if (!WsV2.analogio_controller->Handle_AnalogIORemove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_ds18x20_add_tag: - WS_DEBUG_PRINTLN("-> DS18X20 Add Message Type"); - if (!WsV2._ds18x20_controller->Handle_Ds18x20Add(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_ds18x20_remove_tag: - WS_DEBUG_PRINTLN("-> DS18X20 Remove Message Type"); - if (!WsV2._ds18x20_controller->Handle_Ds18x20Remove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_i2c_device_add_replace_tag: - WS_DEBUG_PRINTLN("-> I2C Device Add/Replace Message Type"); - if (!WsV2._i2c_controller->Handle_I2cDeviceAddOrReplace(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_i2c_bus_scan_tag: - WS_DEBUG_PRINTLN("-> I2C Bus Scan Message Type"); - if (!WsV2._i2c_controller->Handle_I2cBusScan(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_i2c_device_remove_tag: - WS_DEBUG_PRINTLN("-> I2C Device Remove Message Type"); - if (!WsV2._i2c_controller->Handle_I2cDeviceRemove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_i2c_device_output_write_tag: - WS_DEBUG_PRINTLN("-> I2C Device Output Write Message Type"); - if (!WsV2._i2c_controller->Handle_I2cDeviceOutputWrite(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pixels_add_tag: - WS_DEBUG_PRINTLN("-> Pixels Add Message Type"); - if (!WsV2._pixels_controller->Handle_Pixels_Add(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pixels_remove_tag: - WS_DEBUG_PRINTLN("-> Pixels Remove Message Type"); - if (!WsV2._pixels_controller->Handle_Pixels_Remove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pixels_write_tag: - WS_DEBUG_PRINTLN("-> Pixels Write Message Type"); - if (!WsV2._pixels_controller->Handle_Pixels_Write(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pwm_add_tag: - WS_DEBUG_PRINTLN("-> PWM Add Message Type"); - if (!WsV2._pwm_controller->Handle_PWM_Add(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pwm_write_duty_tag: - WS_DEBUG_PRINTLN("-> PWM Write Duty Cycle Message Type"); - if (!WsV2._pwm_controller->Handle_PWM_Write_DutyCycle(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pwm_write_freq_tag: - WS_DEBUG_PRINTLN("-> PWM Write Frequency Message Type"); - if (!WsV2._pwm_controller->Handle_PWM_Write_Frequency(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pwm_remove_tag: - WS_DEBUG_PRINTLN("-> PWM Remove Message Type"); - if (!WsV2._pwm_controller->Handle_PWM_Remove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_servo_add_tag: - WS_DEBUG_PRINTLN("-> Servo Add Message Type"); - if (!WsV2._servo_controller->Handle_Servo_Add(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_servo_write_tag: - WS_DEBUG_PRINTLN("-> Servo Write Message Type"); - if (!WsV2._servo_controller->Handle_Servo_Write(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_servo_remove_tag: - WS_DEBUG_PRINTLN("-> Servo Remove Message Type"); - if (!WsV2._servo_controller->Handle_Servo_Remove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_uart_add_tag: - WS_DEBUG_PRINTLN("-> UART Add Message Type"); - if (!WsV2._uart_controller->Handle_UartAdd(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_uart_remove_tag: - WS_DEBUG_PRINTLN("-> UART Remove Message Type"); - if (!WsV2._uart_controller->Handle_UartRemove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_uart_write_tag: - WS_DEBUG_PRINTLN("-> UART Write Message Type"); - if (!WsV2._uart_controller->Handle_UartWrite(stream)) { + case wippersnapper_signal_BrokerToDevice_checkin_response_tag: + WS_DEBUG_PRINTLN("-> Checkin Response Message Type"); + WS_DEBUG_PRINT("Handling Checkin Response..."); + if (!handleCheckinResponse(stream)) { + return false; + } + WS_DEBUG_PRINTLN("Handled!"); + break; + case wippersnapper_signal_BrokerToDevice_digitalio_add_tag: + WS_DEBUG_PRINTLN("-> DigitalIO Add Message Type"); + if (!WsV2.digital_io_controller->Handle_DigitalIO_Add(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_digitalio_remove_tag: + WS_DEBUG_PRINTLN("-> DigitalIO Remove Message Type"); + if (!WsV2.digital_io_controller->Handle_DigitalIO_Remove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_digitalio_write_tag: + WS_DEBUG_PRINTLN("-> DigitalIO Write Message Type"); + if (!WsV2.digital_io_controller->Handle_DigitalIO_Write(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_analogio_add_tag: + WS_DEBUG_PRINTLN("-> AnalogIO Add Message Type"); + if (!WsV2.analogio_controller->Handle_AnalogIOAdd(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_analogio_remove_tag: + WS_DEBUG_PRINTLN("-> AnalogIO Remove Message Type"); + if (!WsV2.analogio_controller->Handle_AnalogIORemove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_ds18x20_add_tag: + WS_DEBUG_PRINTLN("-> DS18X20 Add Message Type"); + if (!WsV2._ds18x20_controller->Handle_Ds18x20Add(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_ds18x20_remove_tag: + WS_DEBUG_PRINTLN("-> DS18X20 Remove Message Type"); + if (!WsV2._ds18x20_controller->Handle_Ds18x20Remove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_i2c_device_add_replace_tag: + WS_DEBUG_PRINTLN("-> I2C Device Add/Replace Message Type"); + if (!WsV2._i2c_controller->Handle_I2cDeviceAddOrReplace(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_i2c_bus_scan_tag: + WS_DEBUG_PRINTLN("-> I2C Bus Scan Message Type"); + if (!WsV2._i2c_controller->Handle_I2cBusScan(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_i2c_device_remove_tag: + WS_DEBUG_PRINTLN("-> I2C Device Remove Message Type"); + if (!WsV2._i2c_controller->Handle_I2cDeviceRemove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_i2c_device_output_write_tag: + WS_DEBUG_PRINTLN("-> I2C Device Output Write Message Type"); + if (!WsV2._i2c_controller->Handle_I2cDeviceOutputWrite(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pixels_add_tag: + WS_DEBUG_PRINTLN("-> Pixels Add Message Type"); + if (!WsV2._pixels_controller->Handle_Pixels_Add(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pixels_remove_tag: + WS_DEBUG_PRINTLN("-> Pixels Remove Message Type"); + if (!WsV2._pixels_controller->Handle_Pixels_Remove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pixels_write_tag: + WS_DEBUG_PRINTLN("-> Pixels Write Message Type"); + if (!WsV2._pixels_controller->Handle_Pixels_Write(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pwm_add_tag: + WS_DEBUG_PRINTLN("-> PWM Add Message Type"); + if (!WsV2._pwm_controller->Handle_PWM_Add(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pwm_write_duty_tag: + WS_DEBUG_PRINTLN("-> PWM Write Duty Cycle Message Type"); + if (!WsV2._pwm_controller->Handle_PWM_Write_DutyCycle(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pwm_write_freq_tag: + WS_DEBUG_PRINTLN("-> PWM Write Frequency Message Type"); + if (!WsV2._pwm_controller->Handle_PWM_Write_Frequency(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pwm_remove_tag: + WS_DEBUG_PRINTLN("-> PWM Remove Message Type"); + if (!WsV2._pwm_controller->Handle_PWM_Remove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_servo_add_tag: + WS_DEBUG_PRINTLN("-> Servo Add Message Type"); + if (!WsV2._servo_controller->Handle_Servo_Add(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_servo_write_tag: + WS_DEBUG_PRINTLN("-> Servo Write Message Type"); + if (!WsV2._servo_controller->Handle_Servo_Write(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_servo_remove_tag: + WS_DEBUG_PRINTLN("-> Servo Remove Message Type"); + if (!WsV2._servo_controller->Handle_Servo_Remove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_uart_add_tag: + WS_DEBUG_PRINTLN("-> UART Add Message Type"); + if (!WsV2._uart_controller->Handle_UartAdd(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_uart_remove_tag: + WS_DEBUG_PRINTLN("-> UART Remove Message Type"); + if (!WsV2._uart_controller->Handle_UartRemove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_uart_write_tag: + WS_DEBUG_PRINTLN("-> UART Write Message Type"); + if (!WsV2._uart_controller->Handle_UartWrite(stream)) { + return false; + } + break; + default: + WS_DEBUG_PRINTLN("ERROR: BrokerToDevice message type not found!"); return false; - } - break; - default: - WS_DEBUG_PRINTLN("ERROR: BrokerToDevice message type not found!"); - return false; } // once this is returned, pb_dec_submessage() // decodes the submessage contents. @@ -474,7 +477,7 @@ bool cbDecodeBrokerToDevice(pb_istream_t *stream, const pb_field_t *field, @param len Length of data received from MQTT broker. */ -void cbBrokerToDevice(char *data, uint16_t len) { +void cbBrokerToDevice(char* data, uint16_t len) { WS_DEBUG_PRINTLN("=> New B2D message!"); wippersnapper_signal_BrokerToDevice msg_signal = wippersnapper_signal_BrokerToDevice_init_default; @@ -484,7 +487,7 @@ void cbBrokerToDevice(char *data, uint16_t len) { // Decode msg_signal WS_DEBUG_PRINTLN("Creating input stream..."); - pb_istream_t istream = pb_istream_from_buffer((uint8_t *)data, len); + pb_istream_t istream = pb_istream_from_buffer((uint8_t*)data, len); WS_DEBUG_PRINTLN("Decoding BrokerToDevice message..."); if (!pb_decode(&istream, wippersnapper_signal_BrokerToDevice_fields, &msg_signal)) { @@ -504,7 +507,7 @@ void callDecodeB2D() { wippersnapper_signal_BrokerToDevice_init_default; // Configure the payload callback msg_signal.cb_payload.funcs.decode = cbDecodeBrokerToDevice; - const std::vector &buffer = WsV2._sharedConfigBuffers[i]; + const std::vector& buffer = WsV2._sharedConfigBuffers[i]; pb_istream_t istream = pb_istream_from_buffer(buffer.data(), buffer.size()); // Decode the message if (!pb_decode(&istream, wippersnapper_signal_BrokerToDevice_fields, @@ -523,7 +526,7 @@ void callDecodeB2D() { @param len Length of data received from MQTT broker. */ -void cbErrorTopicV2(char *errorData, uint16_t len) { +void cbErrorTopicV2(char* errorData, uint16_t len) { (void)len; // marking unused parameter to avoid compiler warning WS_DEBUG_PRINT("IO Ban Error: "); WS_DEBUG_PRINTLN(errorData); @@ -550,11 +553,11 @@ void cbErrorTopicV2(char *errorData, uint16_t len) { @param len Length of data received from MQTT broker. */ -void cbThrottleTopicV2(char *throttleData, uint16_t len) { +void cbThrottleTopicV2(char* throttleData, uint16_t len) { (void)len; // marking unused parameter to avoid compiler warning WS_DEBUG_PRINT("IO Throttle Error: "); WS_DEBUG_PRINTLN(throttleData); - char *throttleMessage; + char* throttleMessage; // Parse out # of seconds from message buffer throttleMessage = strtok(throttleData, ","); throttleMessage = strtok(NULL, " "); @@ -624,9 +627,9 @@ bool Wippersnapper_V2::generateDeviceUID() { // Attempt to allocate memory for the _device_uid WS_DEBUG_PRINTLN("Allocating memory for device UID"); #ifdef USE_PSRAM - _device_uidV2 = (char *)ps_malloc(sizeof(char) * lenDeviceUID); + _device_uidV2 = (char*)ps_malloc(sizeof(char) * lenDeviceUID); #else - _device_uidV2 = (char *)malloc(sizeof(char) * lenDeviceUID); + _device_uidV2 = (char*)malloc(sizeof(char) * lenDeviceUID); #endif // Check if memory allocation was successful @@ -669,9 +672,9 @@ bool Wippersnapper_V2::generateWSTopics() { // Attempt to allocate memory for the broker-to-device topic #ifdef USE_PSRAM - WsV2._topicB2d = (char *)ps_malloc(sizeof(char) * lenTopicB2d); + WsV2._topicB2d = (char*)ps_malloc(sizeof(char) * lenTopicB2d); #else - WsV2._topicB2d = (char *)malloc(sizeof(char) * lenTopicB2d); + WsV2._topicB2d = (char*)malloc(sizeof(char) * lenTopicB2d); #endif // Check if memory allocation was successful if (WsV2._topicB2d == NULL) @@ -689,9 +692,9 @@ bool Wippersnapper_V2::generateWSTopics() { // Create global device to broker topic // Attempt to allocate memory for the broker-to-device topic #ifdef USE_PSRAM - WsV2._topicD2b = (char *)ps_malloc(sizeof(char) * lenTopicD2b); + WsV2._topicD2b = (char*)ps_malloc(sizeof(char) * lenTopicD2b); #else - WsV2._topicD2b = (char *)malloc(sizeof(char) * lenTopicD2b); + WsV2._topicD2b = (char*)malloc(sizeof(char) * lenTopicD2b); #endif // Check if memory allocation was successful if (WsV2._topicD2b == NULL) @@ -704,9 +707,9 @@ bool Wippersnapper_V2::generateWSTopics() { // Attempt to allocate memory for the error topic #ifdef USE_PSRAM - WsV2._topicError = (char *)ps_malloc(sizeof(char) * lenTopicError); + WsV2._topicError = (char*)ps_malloc(sizeof(char) * lenTopicError); #else - WsV2._topicError = (char *)malloc(sizeof(char) * lenTopicError); + WsV2._topicError = (char*)malloc(sizeof(char) * lenTopicError); #endif // Check if memory allocation was successful if (WsV2._topicError == NULL) @@ -724,9 +727,9 @@ bool Wippersnapper_V2::generateWSTopics() { // Attempt to allocate memory for the error topic #ifdef USE_PSRAM - WsV2._topicThrottle = (char *)ps_malloc(sizeof(char) * lenTopicThrottle); + WsV2._topicThrottle = (char*)ps_malloc(sizeof(char) * lenTopicThrottle); #else - WsV2._topicThrottle = (char *)malloc(sizeof(char) * lenTopicThrottle); + WsV2._topicThrottle = (char*)malloc(sizeof(char) * lenTopicThrottle); #endif // Check if memory allocation was successful if (WsV2._topicThrottle == NULL) @@ -751,7 +754,7 @@ bool Wippersnapper_V2::generateWSTopics() { @param error The error message to write to the serial and filesystem. */ -void Wippersnapper_V2::errorWriteHangV2(const char *error) { +void Wippersnapper_V2::errorWriteHangV2(const char* error) { // Print error WS_DEBUG_PRINTLN(error); #ifdef USE_TINYUSB @@ -781,128 +784,132 @@ void Wippersnapper_V2::runNetFSMV2() { int maxAttempts; while (fsmNetwork != FSM_NET_CONNECTED) { switch (fsmNetwork) { - case FSM_NET_CHECK_MQTT: - if (WsV2._mqttV2->connected()) { - // WS_DEBUG_PRINTLN("Connected to Adafruit IO!"); - fsmNetwork = FSM_NET_CONNECTED; - return; - } - fsmNetwork = FSM_NET_CHECK_NETWORK; - break; - case FSM_NET_CHECK_NETWORK: - if (networkStatus() == WS_NET_CONNECTED) { - WS_DEBUG_PRINTLN("Connected to WiFi!"); + case FSM_NET_CHECK_MQTT: + if (WsV2._mqttV2->connected()) { + // WS_DEBUG_PRINTLN("Connected to Adafruit IO!"); + fsmNetwork = FSM_NET_CONNECTED; + return; + } + fsmNetwork = FSM_NET_CHECK_NETWORK; + break; + case FSM_NET_CHECK_NETWORK: + if (networkStatus() == WS_NET_CONNECTED) { + WS_DEBUG_PRINTLN("Connected to WiFi!"); #ifdef USE_DISPLAY - if (WsV2._ui_helperV2->getLoadingState()) - WsV2._ui_helperV2->set_load_bar_icon_complete(loadBarIconWifi); + if (WsV2._ui_helperV2->getLoadingState()) + WsV2._ui_helperV2->set_load_bar_icon_complete(loadBarIconWifi); #endif - fsmNetwork = FSM_NET_ESTABLISH_MQTT; + fsmNetwork = FSM_NET_ESTABLISH_MQTT; + break; + } + fsmNetwork = FSM_NET_ESTABLISH_NETWORK; break; - } - fsmNetwork = FSM_NET_ESTABLISH_NETWORK; - break; - case FSM_NET_ESTABLISH_NETWORK: - WS_DEBUG_PRINTLN("Establishing network connection..."); - WS_PRINTER.flush(); + case FSM_NET_ESTABLISH_NETWORK: + WS_DEBUG_PRINTLN("Establishing network connection..."); + WS_PRINTER.flush(); #ifdef USE_DISPLAY - if (WsV2._ui_helperV2->getLoadingState()) - WsV2._ui_helperV2->set_label_status("Connecting to WiFi..."); + if (WsV2._ui_helperV2->getLoadingState()) + WsV2._ui_helperV2->set_label_status("Connecting to WiFi..."); #endif - // Perform a WiFi scan and check if SSID within - // secrets.json is within the scanned SSIDs - WS_DEBUG_PRINT("Performing a WiFi scan for SSID..."); - if (!check_valid_ssid()) { + // Perform a WiFi scan and check if SSID within + // secrets.json is within the scanned SSIDs + WS_DEBUG_PRINT("Performing a WiFi scan for SSID..."); + if (!check_valid_ssid()) { #ifdef USE_DISPLAY - WsV2._ui_helperV2->show_scr_error( - "ERROR", "Unable to find WiFi network listed in " - "the secrets file. Rebooting soon..."); + WsV2._ui_helperV2->show_scr_error( + "ERROR", + "Unable to find WiFi network listed in " + "the secrets file. Rebooting soon..."); #endif - haltErrorV2("ERROR: Unable to find WiFi network, rebooting soon...", - WS_LED_STATUS_WIFI_CONNECTING); - } - // Attempt to connect to wireless network - maxAttempts = 5; - while (maxAttempts > 0) { - // blink before we connect - statusLEDBlink(WS_LED_STATUS_WIFI_CONNECTING); - feedWDTV2(); - // attempt to connect - WS_DEBUG_PRINT("Connecting to WiFi (attempt #"); - WS_DEBUG_PRINT(5 - maxAttempts); - WS_DEBUG_PRINTLN(")"); - WS_PRINTER.flush(); - feedWDTV2(); - _connect(); - feedWDTV2(); - // did we connect? - if (networkStatus() == WS_NET_CONNECTED) - break; - maxAttempts--; - } - // Validate connection - if (networkStatus() != WS_NET_CONNECTED) { - WS_DEBUG_PRINTLN("ERROR: Unable to connect to WiFi!"); + haltErrorV2("ERROR: Unable to find WiFi network, rebooting soon...", + WS_LED_STATUS_WIFI_CONNECTING); + } + // Attempt to connect to wireless network + maxAttempts = 5; + while (maxAttempts > 0) { + // blink before we connect + statusLEDBlink(WS_LED_STATUS_WIFI_CONNECTING); + feedWDTV2(); + // attempt to connect + WS_DEBUG_PRINT("Connecting to WiFi (attempt #"); + WS_DEBUG_PRINT(5 - maxAttempts); + WS_DEBUG_PRINTLN(")"); + WS_PRINTER.flush(); + feedWDTV2(); + _connect(); + feedWDTV2(); + // did we connect? + if (networkStatus() == WS_NET_CONNECTED) + break; + maxAttempts--; + } + // Validate connection + if (networkStatus() != WS_NET_CONNECTED) { + WS_DEBUG_PRINTLN("ERROR: Unable to connect to WiFi!"); #ifdef USE_DISPLAY - WsV2._ui_helperV2->show_scr_error( - "CONNECTION ERROR", - "Unable to connect to WiFi Network. Please check that you entered " - "the WiFi credentials correctly. Rebooting in 5 seconds..."); + WsV2._ui_helperV2->show_scr_error( + "CONNECTION ERROR", + "Unable to connect to WiFi Network. Please check that you " + "entered " + "the WiFi credentials correctly. Rebooting in 5 seconds..."); #endif - haltErrorV2("ERROR: Unable to connect to WiFi, rebooting soon...", - WS_LED_STATUS_WIFI_CONNECTING); - } + haltErrorV2("ERROR: Unable to connect to WiFi, rebooting soon...", + WS_LED_STATUS_WIFI_CONNECTING); + } - fsmNetwork = FSM_NET_CHECK_NETWORK; - break; - case FSM_NET_ESTABLISH_MQTT: + fsmNetwork = FSM_NET_CHECK_NETWORK; + break; + case FSM_NET_ESTABLISH_MQTT: #ifdef USE_DISPLAY - if (WsV2._ui_helperV2->getLoadingState()) - WsV2._ui_helperV2->set_label_status("Connecting to IO..."); + if (WsV2._ui_helperV2->getLoadingState()) + WsV2._ui_helperV2->set_label_status("Connecting to IO..."); #endif - WsV2._mqttV2->setKeepAliveInterval(WS_KEEPALIVE_INTERVAL_MS / 1000); - // Attempt to connect - maxAttempts = 5; - while (maxAttempts > 0) { - WS_DEBUG_PRINT("Connecting to AIO MQTT (attempt #"); - WS_DEBUG_PRINT(5 - maxAttempts); - WS_DEBUG_PRINTLN(")"); - WS_PRINTER.flush(); - WS_DEBUG_PRINT("WiFi Status: "); - WS_DEBUG_PRINTLN(networkStatus()); - WS_PRINTER.flush(); - feedWDTV2(); - statusLEDBlink(WS_LED_STATUS_MQTT_CONNECTING); - feedWDTV2(); - int8_t mqttRC = WsV2._mqttV2->connect(); - feedWDTV2(); - if (mqttRC == WS_MQTT_CONNECTED) { - fsmNetwork = FSM_NET_CHECK_MQTT; - break; + WsV2._mqttV2->setKeepAliveInterval(WS_KEEPALIVE_INTERVAL_MS / 1000); + // Attempt to connect + maxAttempts = 5; + while (maxAttempts > 0) { + WS_DEBUG_PRINT("Connecting to AIO MQTT (attempt #"); + WS_DEBUG_PRINT(5 - maxAttempts); + WS_DEBUG_PRINTLN(")"); + WS_PRINTER.flush(); + WS_DEBUG_PRINT("WiFi Status: "); + WS_DEBUG_PRINTLN(networkStatus()); + WS_PRINTER.flush(); + feedWDTV2(); + statusLEDBlink(WS_LED_STATUS_MQTT_CONNECTING); + feedWDTV2(); + int8_t mqttRC = WsV2._mqttV2->connect(); + feedWDTV2(); + if (mqttRC == WS_MQTT_CONNECTED) { + fsmNetwork = FSM_NET_CHECK_MQTT; + break; + } + WS_DEBUG_PRINT("MQTT Connection Error: "); + WS_DEBUG_PRINTLN(mqttRC); + WS_DEBUG_PRINTLN(WsV2._mqttV2->connectErrorString(mqttRC)); + WS_DEBUG_PRINTLN( + "Unable to connect to Adafruit IO MQTT, retrying in 3 " + "seconds..."); + delay(3000); + maxAttempts--; } - WS_DEBUG_PRINT("MQTT Connection Error: "); - WS_DEBUG_PRINTLN(mqttRC); - WS_DEBUG_PRINTLN(WsV2._mqttV2->connectErrorString(mqttRC)); - WS_DEBUG_PRINTLN( - "Unable to connect to Adafruit IO MQTT, retrying in 3 seconds..."); - delay(3000); - maxAttempts--; - } - if (fsmNetwork != FSM_NET_CHECK_MQTT) { + if (fsmNetwork != FSM_NET_CHECK_MQTT) { #ifdef USE_DISPLAY - WsV2._ui_helperV2->show_scr_error( - "CONNECTION ERROR", - "Unable to connect to Adafruit.io. If you are repeatedly having " - "this issue, please check that your IO Username and IO Key are set " - "correctly in the secrets file. This device will reboot in 5 " - "seconds..."); + WsV2._ui_helperV2->show_scr_error( + "CONNECTION ERROR", + "Unable to connect to Adafruit.io. If you are repeatedly having " + "this issue, please check that your IO Username and IO Key are " + "set " + "correctly in the secrets file. This device will reboot in 5 " + "seconds..."); #endif - haltErrorV2( - "ERROR: Unable to connect to Adafruit.IO MQTT, rebooting soon...", - WS_LED_STATUS_MQTT_CONNECTING); - } - break; - default: - break; + haltErrorV2( + "ERROR: Unable to connect to Adafruit.IO MQTT, rebooting soon...", + WS_LED_STATUS_MQTT_CONNECTING); + } + break; + default: + break; } } } @@ -919,7 +926,7 @@ void Wippersnapper_V2::runNetFSMV2() { If false, the device will not allow the WDT to bite and instead hang indefinitely, holding the WIPPER drive open */ -void Wippersnapper_V2::haltErrorV2(const char *error, +void Wippersnapper_V2::haltErrorV2(const char* error, ws_led_status_t ledStatusColor, bool reboot) { WS_DEBUG_PRINT("ERROR "); @@ -956,8 +963,7 @@ void Wippersnapper_V2::haltErrorV2(const char *error, @returns True if the signal message published successfully, False otherwise. */ -bool Wippersnapper_V2::PublishSignal(pb_size_t which_payload, void *payload) { - +bool Wippersnapper_V2::PublishSignal(pb_size_t which_payload, void* payload) { #ifdef DEBUG_PROFILE unsigned long total_start_time = micros(); #endif @@ -969,80 +975,82 @@ bool Wippersnapper_V2::PublishSignal(pb_size_t which_payload, void *payload) { // Fill generic signal payload with the payload from the args. WS_DEBUG_PRINT("Signal Payload Type: "); switch (which_payload) { - case wippersnapper_signal_DeviceToBroker_checkin_request_tag: - WS_DEBUG_PRINTLN("CheckinRequest"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_checkin_request_tag; - MsgSignal.payload.checkin_request = - *(wippersnapper_checkin_CheckinRequest *)payload; - break; - case wippersnapper_signal_DeviceToBroker_digitalio_event_tag: - WS_DEBUG_PRINTLN("DigitalIOEvent"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_digitalio_event_tag; - MsgSignal.payload.digitalio_event = - *(wippersnapper_digitalio_DigitalIOEvent *)payload; - break; - case wippersnapper_signal_DeviceToBroker_analogio_event_tag: - WS_DEBUG_PRINTLN("AnalogIOEvent"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_analogio_event_tag; - MsgSignal.payload.analogio_event = - *(wippersnapper_analogio_AnalogIOEvent *)payload; - break; - case wippersnapper_signal_DeviceToBroker_ds18x20_added_tag: - WS_DEBUG_PRINTLN("DS18X20Added"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_ds18x20_added_tag; - MsgSignal.payload.ds18x20_added = - *(wippersnapper_ds18x20_Ds18x20Added *)payload; - break; - case wippersnapper_signal_DeviceToBroker_ds18x20_event_tag: - WS_DEBUG_PRINTLN("DS18X20Event"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_ds18x20_event_tag; - MsgSignal.payload.ds18x20_event = - *(wippersnapper_ds18x20_Ds18x20Event *)payload; - break; - case wippersnapper_signal_DeviceToBroker_pixels_added_tag: - WS_DEBUG_PRINTLN("PixelsAdded"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_pixels_added_tag; - MsgSignal.payload.pixels_added = - *(wippersnapper_pixels_PixelsAdded *)payload; - break; - case wippersnapper_signal_DeviceToBroker_pwm_added_tag: - WS_DEBUG_PRINTLN("PWMAdded"); - MsgSignal.which_payload = wippersnapper_signal_DeviceToBroker_pwm_added_tag; - MsgSignal.payload.pwm_added = *(wippersnapper_pwm_PWMAdded *)payload; - break; - case wippersnapper_signal_DeviceToBroker_servo_added_tag: - WS_DEBUG_PRINTLN("ServoAdded"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_servo_added_tag; - MsgSignal.payload.servo_added = *(wippersnapper_servo_ServoAdded *)payload; - break; - case wippersnapper_signal_DeviceToBroker_uart_added_tag: - WS_DEBUG_PRINTLN("UARTAdded"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_uart_added_tag; - MsgSignal.payload.uart_added = *(wippersnapper_uart_UartAdded *)payload; - break; - case wippersnapper_signal_DeviceToBroker_uart_input_event_tag: - WS_DEBUG_PRINTLN("UARTInputEvent"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_uart_input_event_tag; - MsgSignal.payload.uart_input_event = - *(wippersnapper_uart_UartInputEvent *)payload; - break; - case wippersnapper_signal_DeviceToBroker_gps_event_tag: - WS_DEBUG_PRINTLN("GPSEvent"); - MsgSignal.which_payload = wippersnapper_signal_DeviceToBroker_gps_event_tag; - MsgSignal.payload.gps_event = *(wippersnapper_gps_GPSEvent *)payload; - break; - default: - WS_DEBUG_PRINTLN("ERROR: Invalid signal payload type, bailing out!"); - return false; + case wippersnapper_signal_DeviceToBroker_checkin_request_tag: + WS_DEBUG_PRINTLN("CheckinRequest"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_checkin_request_tag; + MsgSignal.payload.checkin_request = + *(wippersnapper_checkin_CheckinRequest*)payload; + break; + case wippersnapper_signal_DeviceToBroker_digitalio_event_tag: + WS_DEBUG_PRINTLN("DigitalIOEvent"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_digitalio_event_tag; + MsgSignal.payload.digitalio_event = + *(wippersnapper_digitalio_DigitalIOEvent*)payload; + break; + case wippersnapper_signal_DeviceToBroker_analogio_event_tag: + WS_DEBUG_PRINTLN("AnalogIOEvent"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_analogio_event_tag; + MsgSignal.payload.analogio_event = + *(wippersnapper_analogio_AnalogIOEvent*)payload; + break; + case wippersnapper_signal_DeviceToBroker_ds18x20_added_tag: + WS_DEBUG_PRINTLN("DS18X20Added"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_ds18x20_added_tag; + MsgSignal.payload.ds18x20_added = + *(wippersnapper_ds18x20_Ds18x20Added*)payload; + break; + case wippersnapper_signal_DeviceToBroker_ds18x20_event_tag: + WS_DEBUG_PRINTLN("DS18X20Event"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_ds18x20_event_tag; + MsgSignal.payload.ds18x20_event = + *(wippersnapper_ds18x20_Ds18x20Event*)payload; + break; + case wippersnapper_signal_DeviceToBroker_pixels_added_tag: + WS_DEBUG_PRINTLN("PixelsAdded"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_pixels_added_tag; + MsgSignal.payload.pixels_added = + *(wippersnapper_pixels_PixelsAdded*)payload; + break; + case wippersnapper_signal_DeviceToBroker_pwm_added_tag: + WS_DEBUG_PRINTLN("PWMAdded"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_pwm_added_tag; + MsgSignal.payload.pwm_added = *(wippersnapper_pwm_PWMAdded*)payload; + break; + case wippersnapper_signal_DeviceToBroker_servo_added_tag: + WS_DEBUG_PRINTLN("ServoAdded"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_servo_added_tag; + MsgSignal.payload.servo_added = *(wippersnapper_servo_ServoAdded*)payload; + break; + case wippersnapper_signal_DeviceToBroker_uart_added_tag: + WS_DEBUG_PRINTLN("UARTAdded"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_uart_added_tag; + MsgSignal.payload.uart_added = *(wippersnapper_uart_UartAdded*)payload; + break; + case wippersnapper_signal_DeviceToBroker_uart_input_event_tag: + WS_DEBUG_PRINTLN("UARTInputEvent"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_uart_input_event_tag; + MsgSignal.payload.uart_input_event = + *(wippersnapper_uart_UartInputEvent*)payload; + break; + case wippersnapper_signal_DeviceToBroker_gps_event_tag: + WS_DEBUG_PRINTLN("GPSEvent"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_gps_event_tag; + MsgSignal.payload.gps_event = *(wippersnapper_gps_GPSEvent*)payload; + break; + default: + WS_DEBUG_PRINTLN("ERROR: Invalid signal payload type, bailing out!"); + return false; } // Get the encoded size of the signal message @@ -1295,7 +1303,7 @@ void Wippersnapper_V2::connect() { // Call the TL signal decoder to parse the incoming JSON data callDecodeB2D(); #ifndef OFFLINE_MODE_WOKWI - //TODO: Don't write the config file if unchanged versus current config + // TODO: Don't write the config file if unchanged versus current config if (WsV2._global_auto_config) { WsV2._fileSystemV2->WriteFileConfig(); } diff --git a/src/Wippersnapper_V2.h b/src/Wippersnapper_V2.h index aaacca39e..57b37883f 100644 --- a/src/Wippersnapper_V2.h +++ b/src/Wippersnapper_V2.h @@ -29,22 +29,26 @@ defined */ #ifdef WS_DEBUG -#define WS_DEBUG_PRINT(...) \ - { WS_PRINTER.print(__VA_ARGS__); } /**< Print debug message to serial */ -#define WS_DEBUG_PRINTLN(...) \ - { \ - WS_PRINTER.println(__VA_ARGS__); \ - } /**< Print debug message with newline \ +#define WS_DEBUG_PRINT(...) \ + { \ + WS_PRINTER.print(__VA_ARGS__); \ + } /**< Print debug message to serial */ +#define WS_DEBUG_PRINTLN(...) \ + { \ + WS_PRINTER.println(__VA_ARGS__); \ + } /**< Print debug message with newline \ */ -#define WS_DEBUG_PRINTHEX(...) \ - { \ - WS_PRINTER.print(__VA_ARGS__, HEX); \ +#define WS_DEBUG_PRINTHEX(...) \ + { \ + WS_PRINTER.print(__VA_ARGS__, HEX); \ } /**< Print debug message in hexadecimal */ #else -#define WS_DEBUG_PRINT(...) \ - {} /**< Debug print */ -#define WS_DEBUG_PRINTLN(...) \ - {} /**< Debug println */ +#define WS_DEBUG_PRINT(...) \ + { \ + } /**< Debug print */ +#define WS_DEBUG_PRINTLN(...) \ + { \ + } /**< Debug println */ #endif /*! @@ -52,17 +56,17 @@ @param timeout Delay duration in milliseconds */ -#define WS_DELAY_WITH_WDT(timeout) \ - { \ - unsigned long start = millis(); \ - while (millis() - start < timeout) { \ - delay(10); \ - yield(); \ - WsV2.feedWDTV2(); \ - if (millis() < start) { \ - start = millis(); \ - } \ - } \ +#define WS_DELAY_WITH_WDT(timeout) \ + { \ + unsigned long start = millis(); \ + while (millis() - start < timeout) { \ + delay(10); \ + yield(); \ + WsV2.feedWDTV2(); \ + if (millis() < start) { \ + start = millis(); \ + } \ + } \ } // Cpp STD @@ -73,19 +77,21 @@ #include // Nanopb messages and dependencies -#include "protos/signal.pb.h" #include #include #include #include +#include "protos/signal.pb.h" + // External libraries +#include // SPI +#include // I2C + #include "Adafruit_MQTT.h" // MQTT Client #include "Adafruit_SleepyDog.h" // Watchdog #include "Arduino.h" // Wiring #include "RTClib.h" // RTC -#include // SPI -#include // I2C // Wippersnapper API Helpers #include "Wippersnapper_Boards.h" @@ -123,14 +129,14 @@ #include "provisioning/littlefs/WipperSnapper_LittleFS.h" #endif -#define WS_VERSION \ +#define WS_VERSION \ "1.0.0-offline-beta.4" ///< WipperSnapper app. version ///< (semver-formatted) #define WS_WDT_TIMEOUT 60000 ///< WDT timeout #define WS_MAX_ALT_WIFI_NETWORKS 3 ///< Maximum number of alternative networks /* MQTT Configuration */ -#define WS_KEEPALIVE_INTERVAL_MS \ +#define WS_KEEPALIVE_INTERVAL_MS \ 5000 ///< Session keepalive interval time, in milliseconds // Forward declarations @@ -158,7 +164,7 @@ class UARTController; Wippersnapper interface. */ class Wippersnapper_V2 { -public: + public: Wippersnapper_V2(); virtual ~Wippersnapper_V2(); @@ -174,7 +180,7 @@ class Wippersnapper_V2 { ///< (from 0.0 to 1.0) virtual void set_user_key(); - virtual void set_ssid_pass(const char *ssid, const char *ssidPassword); + virtual void set_ssid_pass(const char* ssid, const char* ssidPassword); virtual void set_ssid_pass(); virtual bool check_valid_ssid(); @@ -185,7 +191,7 @@ class Wippersnapper_V2 { virtual void getMacAddr(); virtual int32_t getRSSI(); - virtual void setupMQTTClient(const char *clientID); + virtual void setupMQTTClient(const char* clientID); virtual ws_status_t networkStatus(); @@ -194,7 +200,7 @@ class Wippersnapper_V2 { bool generateWSTopics(); // High-level MQTT Publish - bool PublishSignal(pb_size_t which_payload, void *payload); + bool PublishSignal(pb_size_t which_payload, void* payload); // Checkin API bool CreateCheckinRequest(); @@ -214,13 +220,14 @@ class Wippersnapper_V2 { void BlinkKATStatus(); // Error handling helpers - void haltErrorV2(const char *error, + void haltErrorV2(const char* error, ws_led_status_t ledStatusColor = WS_LED_STATUS_ERROR_RUNTIME, bool reboot = true); - void errorWriteHangV2(const char *error); + void errorWriteHangV2(const char* error); bool _is_offline_mode; ///< Global flag for if the device is in offline mode - bool _global_auto_config = true; ///< Support no auto config for exportedDevice + bool _global_auto_config = + true; ///< Support no auto config for exportedDevice // TODO: Do we need this? ws_board_status_t _boardStatusV2 = @@ -228,39 +235,39 @@ class Wippersnapper_V2 { // TODO: We really should look at making these static definitions, not dynamic // to free up space on the heap - Wippersnapper_FS *_fileSystemV2; ///< Instance of Filesystem (native USB) - WipperSnapper_LittleFS - *_littleFSV2; ///< Instance of LittleFS Filesystem (non-native USB) - ws_sdcard *_sdCardV2; ///< Instance of SD card class + Wippersnapper_FS* _fileSystemV2; ///< Instance of Filesystem (native USB) + WipperSnapper_LittleFS* + _littleFSV2; ///< Instance of LittleFS Filesystem (non-native USB) + ws_sdcard* _sdCardV2; ///< Instance of SD card class #ifdef USE_DISPLAY - ws_display_driver *_displayV2 = nullptr; ///< Instance of display driver class - ws_display_ui_helper *_ui_helperV2 = + ws_display_driver* _displayV2 = nullptr; ///< Instance of display driver class + ws_display_ui_helper* _ui_helperV2 = nullptr; ///< Instance of display UI helper class #endif // API v2 Components - CheckinModel *CheckInModel = nullptr; ///< Instance of CheckinModel class - SensorModel *sensorModel = nullptr; ///< Instance of SensorModel class - DigitalIOController *digital_io_controller = + CheckinModel* CheckInModel = nullptr; ///< Instance of CheckinModel class + SensorModel* sensorModel = nullptr; ///< Instance of SensorModel class + DigitalIOController* digital_io_controller = nullptr; ///< Instance of DigitalIO controller class - AnalogIOController *analogio_controller = + AnalogIOController* analogio_controller = nullptr; ///< Instance of AnalogIO controller - DS18X20Controller *_ds18x20_controller = + DS18X20Controller* _ds18x20_controller = nullptr; ///< Instance of DS18X20 controller - GPSController *_gps_controller = nullptr; ///< Instance of GPS controller - I2cController *_i2c_controller = nullptr; ///< Instance of I2C controller - PixelsController *_pixels_controller = + GPSController* _gps_controller = nullptr; ///< Instance of GPS controller + I2cController* _i2c_controller = nullptr; ///< Instance of I2C controller + PixelsController* _pixels_controller = nullptr; ///< Instance of Pixels controller - PWMController *_pwm_controller = nullptr; ///< Instance of PWM controller - ServoController *_servo_controller = + PWMController* _pwm_controller = nullptr; ///< Instance of PWM controller + ServoController* _servo_controller = nullptr; ///< Instance of Servo controller - UARTController *_uart_controller = nullptr; ///< Instance of UART controller + UARTController* _uart_controller = nullptr; ///< Instance of UART controller // TODO: does this really need to be global? uint8_t _macAddrV2[6]; /*!< Unique network iface identifier */ char sUIDV2[13]; /*!< Unique hardware identifier */ - const char *_boardIdV2; /*!< Adafruit IO+ board string */ - Adafruit_MQTT *_mqttV2; /*!< Reference to Adafruit_MQTT, _mqtt. */ + const char* _boardIdV2; /*!< Adafruit IO+ board string */ + Adafruit_MQTT* _mqttV2; /*!< Reference to Adafruit_MQTT, _mqtt. */ // TODO: Audit this, does it need to be here? secretsConfig _configV2; /*!< Wippersnapper secrets.json as a struct. */ @@ -271,7 +278,7 @@ class Wippersnapper_V2 { int32_t totalDigitalPinsV2; /*!< Total number of digital-input capable pins */ // TODO: Do these need to be here or can they sit within their function? - char *throttleMessageV2; /*!< Pointer to throttle message data. */ + char* throttleMessageV2; /*!< Pointer to throttle message data. */ int throttleTimeV2; /*!< Total amount of time to throttle the device, in milliseconds. */ @@ -285,21 +292,21 @@ class Wippersnapper_V2 { _sharedConfigBuffers; ///< Shared JSON config buffers for offline mode JsonDocument _config_doc; ///< Storage for the config.json file uint8_t pin_sd_cs; ///< SD card chip select pin -private: + private: void _initV2(); // MQTT topics - char *_topicB2d; - char *_topicD2b; - char *_topicError; - char *_topicThrottle; + char* _topicB2d; + char* _topicD2b; + char* _topicError; + char* _topicThrottle; // Adafruit_MQTT Subscription objects - Adafruit_MQTT_Subscribe *_subscribeB2d; - Adafruit_MQTT_Subscribe *_subscribeError; - Adafruit_MQTT_Subscribe *_subscribeThrottle; + Adafruit_MQTT_Subscribe* _subscribeB2d; + Adafruit_MQTT_Subscribe* _subscribeError; + Adafruit_MQTT_Subscribe* _subscribeThrottle; -protected: + protected: ws_status_t _statusV2 = WS_IDLE; ///< Wippersnapper status uint32_t _last_mqtt_connectV2 = 0; /*!< Previous time when client connected to @@ -310,8 +317,8 @@ class Wippersnapper_V2 { IO's MQTT broker, in milliseconds. */ // Device information - const char *_deviceIdV2; /*!< Adafruit IO+ device identifier string */ - char *_device_uidV2; /*!< Unique device identifier */ + const char* _deviceIdV2; /*!< Adafruit IO+ device identifier string */ + char* _device_uidV2; /*!< Unique device identifier */ }; extern Wippersnapper_V2 WsV2; ///< Global member variable for callbacks diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 3ea390507..becf083a4 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -26,8 +26,8 @@ #include "drivers/drvBme680.h" #include "drivers/drvBmp280.h" #include "drivers/drvBmp3xx.h" -#include "drivers/drvDps310.h" #include "drivers/drvD6t1a.h" +#include "drivers/drvDps310.h" #include "drivers/drvDs2484.h" #include "drivers/drvEns160.h" #include "drivers/drvHts221.h" @@ -83,38 +83,38 @@ class I2cHardware; ///< Forward declaration appropriate hardware, model, and device driver classes. */ class I2cController { -public: + public: I2cController(); ~I2cController(); void update(); // Routing // - bool Handle_I2cDeviceAddOrReplace(pb_istream_t *stream); - bool Handle_I2cBusScan(pb_istream_t *stream); - bool Handle_I2cDeviceRemove(pb_istream_t *stream); - bool Handle_I2cDeviceOutputWrite(pb_istream_t *stream); + bool Handle_I2cDeviceAddOrReplace(pb_istream_t* stream); + bool Handle_I2cBusScan(pb_istream_t* stream); + bool Handle_I2cDeviceRemove(pb_istream_t* stream); + bool Handle_I2cDeviceOutputWrite(pb_istream_t* stream); // Publishing // bool PublishI2cDeviceAddedorReplaced( - const wippersnapper_i2c_I2cDeviceDescriptor &device_descriptor, - const wippersnapper_i2c_I2cDeviceStatus &device_status); + const wippersnapper_i2c_I2cDeviceDescriptor& device_descriptor, + const wippersnapper_i2c_I2cDeviceStatus& device_status); // Helpers // bool IsBusStatusOK(bool is_alt_bus = false); - bool InitMux(const char *name, uint32_t address, bool is_alt_bus); + bool InitMux(const char* name, uint32_t address, bool is_alt_bus); void ConfigureMuxChannel(uint32_t mux_channel, bool is_alt_bus); bool RemoveDriver(uint32_t address, bool is_output_device); bool ScanI2cBus(bool default_bus); - TwoWire *GetI2cBus(bool is_alt_bus = false); + TwoWire* GetI2cBus(bool is_alt_bus = false); uint32_t GetScanDeviceAddress(int index); size_t GetScanDeviceCount(); void PrintAllDrivers(); -private: - I2cModel *_i2c_model = nullptr; ///< Pointer to an I2C model object - I2cOutputModel *_i2c_output_model = + private: + I2cModel* _i2c_model = nullptr; ///< Pointer to an I2C model object + I2cOutputModel* _i2c_output_model = nullptr; ///< Pointer to an I2C output model object - I2cHardware *_i2c_bus_default = nullptr; ///< Pointer to the default I2C bus - I2cHardware *_i2c_bus_alt = nullptr; ///< Pointer to an alternative I2C bus - std::vector _i2c_drivers; ///< Vector of ptrs to I2C input drivers - std::vector + I2cHardware* _i2c_bus_default = nullptr; ///< Pointer to the default I2C bus + I2cHardware* _i2c_bus_alt = nullptr; ///< Pointer to an alternative I2C bus + std::vector _i2c_drivers; ///< Vector of ptrs to I2C input drivers + std::vector _i2c_drivers_output; ///< Vector of ptrs to I2C output drivers wippersnapper_i2c_I2cBusScanned _scan_results; ///< Stores results of I2C bus scan diff --git a/src/components/i2c/drivers/drvD6t1a.h b/src/components/i2c/drivers/drvD6t1a.h index ab4ff10e2..a6e14371d 100644 --- a/src/components/i2c/drivers/drvD6t1a.h +++ b/src/components/i2c/drivers/drvD6t1a.h @@ -15,15 +15,16 @@ #ifndef DRV_D6T1A_H #define DRV_D6T1A_H -#include "drvBase.h" #include +#include "drvBase.h" + /*! - @brief Class that provides a sensor driver for the D6T1A temperature sensor. + @brief Class that provides a sensor driver for the D6T1A temperature + sensor. */ class drvD6t1a : public drvBase { - -public: + public: /*! @brief Constructor for a D6T1A sensor. @param i2c @@ -35,8 +36,8 @@ class drvD6t1a : public drvBase { @param driver_name The name of the driver. */ - drvD6t1a(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, - const char *driver_name) + drvD6t1a(TwoWire* i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char* driver_name) : drvBase(i2c, sensorAddress, mux_channel, driver_name) { _i2c = i2c; _address = sensorAddress; @@ -52,7 +53,9 @@ class drvD6t1a : public drvBase { /*! @brief Destructor for a D6T1A sensor. */ - ~drvD6t1a() { delete _d6t1a; } + ~drvD6t1a() { + delete _d6t1a; + } /*! @brief Initializes the D6T1A sensor and begins I2C. @@ -92,9 +95,10 @@ class drvD6t1a : public drvBase { @brief Gets the D6T1A's current ambient temperature. @param tempEvent Pointer to an Adafruit_Sensor event. - @returns True if the temperature was obtained successfully, False otherwise. + @returns True if the temperature was obtained successfully, False + otherwise. */ - bool getEventAmbientTemp(sensors_event_t *tempEvent) { + bool getEventAmbientTemp(sensors_event_t* tempEvent) { if (ReadSensorData() && !isnan(_deviceTemp)) { tempEvent->temperature = _deviceTemp; return true; @@ -106,9 +110,10 @@ class drvD6t1a : public drvBase { @brief Gets the D6T1A's object temperature. @param tempEvent Pointer to an Adafruit_Sensor event. - @returns True if the temperature was obtained successfully, False otherwise. + @returns True if the temperature was obtained successfully, False + otherwise. */ - bool getEventObjectTemp(sensors_event_t *tempEvent) { + bool getEventObjectTemp(sensors_event_t* tempEvent) { if (ReadSensorData() && !isnan(_objectTemp)) { tempEvent->temperature = _objectTemp; return true; @@ -124,11 +129,11 @@ class drvD6t1a : public drvBase { wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE; } -protected: - float _deviceTemp; ///< Device temperature in Celsius - float _objectTemp; ///< Object temperature in Celsius - uint32_t _lastRead; ///< Last time the sensor was read in milliseconds - OmronD6T *_d6t1a; ///< D6T1A object + protected: + float _deviceTemp; ///< Device temperature in Celsius + float _objectTemp; ///< Object temperature in Celsius + uint32_t _lastRead; ///< Last time the sensor was read in milliseconds + OmronD6T* _d6t1a; ///< D6T1A object }; #endif // DRV_D6T1A_H \ No newline at end of file From 00adc7741dfc7ff629c66d4d5eb000eed238035d Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 12 Aug 2025 16:37:01 +0100 Subject: [PATCH 16/32] clang format --- .clang-format | 13 - src/Wippersnapper_V2.cpp | 737 +++++++++++++------------- src/Wippersnapper_V2.h | 128 ++--- src/components/i2c/controller.h | 32 +- src/components/i2c/drivers/drvD6t1a.h | 18 +- 5 files changed, 453 insertions(+), 475 deletions(-) delete mode 100644 .clang-format diff --git a/.clang-format b/.clang-format deleted file mode 100644 index ed70f56ff..000000000 --- a/.clang-format +++ /dev/null @@ -1,13 +0,0 @@ -Language: Cpp -BasedOnStyle: Google -IndentWidth: 2 -ColumnLimit: 80 -AllowShortFunctionsOnASingleLine: Empty -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -BinPackArguments: true -BinPackParameters: true -BreakBeforeBraces: Attach -DerivePointerAlignment: false -PointerAlignment: Left -SpacesBeforeTrailingComments: 1 \ No newline at end of file diff --git a/src/Wippersnapper_V2.cpp b/src/Wippersnapper_V2.cpp index b45b53667..06e565538 100644 --- a/src/Wippersnapper_V2.cpp +++ b/src/Wippersnapper_V2.cpp @@ -112,9 +112,8 @@ void Wippersnapper_V2::provision() { // Begin display if (!WsV2._displayV2->begin()) { WS_DEBUG_PRINTLN("Unable to enable display driver and LVGL"); - haltErrorV2( - "Unable to enable display driver, please check the json " - "configuration!"); + haltErrorV2("Unable to enable display driver, please check the json " + "configuration!"); } WsV2._displayV2->enableLogging(); @@ -148,9 +147,7 @@ void Wippersnapper_V2::provision() { /*! @brief Disconnects from Adafruit IO+ Wippersnapper_V2. */ -void Wippersnapper_V2::disconnect() { - _disconnect(); -} +void Wippersnapper_V2::disconnect() { _disconnect(); } // Concrete class definition for abstract classes @@ -194,7 +191,7 @@ int32_t Wippersnapper_V2::getRSSI() { @param clientID A unique client identifier string. */ -void Wippersnapper_V2::setupMQTTClient(const char* /*clientID*/) { +void Wippersnapper_V2::setupMQTTClient(const char * /*clientID*/) { WS_DEBUG_PRINTLN("Wippersnapper_V2::setupMQTTClient"); WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); } @@ -216,8 +213,8 @@ ws_status_t Wippersnapper_V2::networkStatus() { @param ssidPassword Your wireless network's password. */ -void Wippersnapper_V2::set_ssid_pass(const char* /*ssid*/, - const char* /*ssidPassword*/) { +void Wippersnapper_V2::set_ssid_pass(const char * /*ssid*/, + const char * /*ssidPassword*/) { WS_DEBUG_PRINTLN("Wippersnapper_V2::set_ssid_pass"); WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); } @@ -259,7 +256,7 @@ void Wippersnapper_V2::set_user_key() { @returns True if Checkin Response decoded and parsed successfully, False otherwise. */ -bool handleCheckinResponse(pb_istream_t* stream) { +bool handleCheckinResponse(pb_istream_t *stream) { // Decode the Checkin Response message if (!WsV2.CheckInModel->DecodeCheckinResponse(stream)) { WS_DEBUG_PRINTLN("ERROR: Unable to decode Checkin Response message"); @@ -303,166 +300,166 @@ bool handleCheckinResponse(pb_istream_t* stream) { Optional arguments from decoder calling function. @returns True if decoded and executed successfully, False otherwise. */ -bool cbDecodeBrokerToDevice(pb_istream_t* stream, const pb_field_t* field, - void** arg) { +bool cbDecodeBrokerToDevice(pb_istream_t *stream, const pb_field_t *field, + void **arg) { (void)arg; // marking unused parameters to avoid compiler warning switch (field->tag) { - case wippersnapper_signal_BrokerToDevice_checkin_response_tag: - WS_DEBUG_PRINTLN("-> Checkin Response Message Type"); - WS_DEBUG_PRINT("Handling Checkin Response..."); - if (!handleCheckinResponse(stream)) { - return false; - } - WS_DEBUG_PRINTLN("Handled!"); - break; - case wippersnapper_signal_BrokerToDevice_digitalio_add_tag: - WS_DEBUG_PRINTLN("-> DigitalIO Add Message Type"); - if (!WsV2.digital_io_controller->Handle_DigitalIO_Add(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_digitalio_remove_tag: - WS_DEBUG_PRINTLN("-> DigitalIO Remove Message Type"); - if (!WsV2.digital_io_controller->Handle_DigitalIO_Remove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_digitalio_write_tag: - WS_DEBUG_PRINTLN("-> DigitalIO Write Message Type"); - if (!WsV2.digital_io_controller->Handle_DigitalIO_Write(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_analogio_add_tag: - WS_DEBUG_PRINTLN("-> AnalogIO Add Message Type"); - if (!WsV2.analogio_controller->Handle_AnalogIOAdd(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_analogio_remove_tag: - WS_DEBUG_PRINTLN("-> AnalogIO Remove Message Type"); - if (!WsV2.analogio_controller->Handle_AnalogIORemove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_ds18x20_add_tag: - WS_DEBUG_PRINTLN("-> DS18X20 Add Message Type"); - if (!WsV2._ds18x20_controller->Handle_Ds18x20Add(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_ds18x20_remove_tag: - WS_DEBUG_PRINTLN("-> DS18X20 Remove Message Type"); - if (!WsV2._ds18x20_controller->Handle_Ds18x20Remove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_i2c_device_add_replace_tag: - WS_DEBUG_PRINTLN("-> I2C Device Add/Replace Message Type"); - if (!WsV2._i2c_controller->Handle_I2cDeviceAddOrReplace(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_i2c_bus_scan_tag: - WS_DEBUG_PRINTLN("-> I2C Bus Scan Message Type"); - if (!WsV2._i2c_controller->Handle_I2cBusScan(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_i2c_device_remove_tag: - WS_DEBUG_PRINTLN("-> I2C Device Remove Message Type"); - if (!WsV2._i2c_controller->Handle_I2cDeviceRemove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_i2c_device_output_write_tag: - WS_DEBUG_PRINTLN("-> I2C Device Output Write Message Type"); - if (!WsV2._i2c_controller->Handle_I2cDeviceOutputWrite(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pixels_add_tag: - WS_DEBUG_PRINTLN("-> Pixels Add Message Type"); - if (!WsV2._pixels_controller->Handle_Pixels_Add(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pixels_remove_tag: - WS_DEBUG_PRINTLN("-> Pixels Remove Message Type"); - if (!WsV2._pixels_controller->Handle_Pixels_Remove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pixels_write_tag: - WS_DEBUG_PRINTLN("-> Pixels Write Message Type"); - if (!WsV2._pixels_controller->Handle_Pixels_Write(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pwm_add_tag: - WS_DEBUG_PRINTLN("-> PWM Add Message Type"); - if (!WsV2._pwm_controller->Handle_PWM_Add(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pwm_write_duty_tag: - WS_DEBUG_PRINTLN("-> PWM Write Duty Cycle Message Type"); - if (!WsV2._pwm_controller->Handle_PWM_Write_DutyCycle(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pwm_write_freq_tag: - WS_DEBUG_PRINTLN("-> PWM Write Frequency Message Type"); - if (!WsV2._pwm_controller->Handle_PWM_Write_Frequency(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_pwm_remove_tag: - WS_DEBUG_PRINTLN("-> PWM Remove Message Type"); - if (!WsV2._pwm_controller->Handle_PWM_Remove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_servo_add_tag: - WS_DEBUG_PRINTLN("-> Servo Add Message Type"); - if (!WsV2._servo_controller->Handle_Servo_Add(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_servo_write_tag: - WS_DEBUG_PRINTLN("-> Servo Write Message Type"); - if (!WsV2._servo_controller->Handle_Servo_Write(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_servo_remove_tag: - WS_DEBUG_PRINTLN("-> Servo Remove Message Type"); - if (!WsV2._servo_controller->Handle_Servo_Remove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_uart_add_tag: - WS_DEBUG_PRINTLN("-> UART Add Message Type"); - if (!WsV2._uart_controller->Handle_UartAdd(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_uart_remove_tag: - WS_DEBUG_PRINTLN("-> UART Remove Message Type"); - if (!WsV2._uart_controller->Handle_UartRemove(stream)) { - return false; - } - break; - case wippersnapper_signal_BrokerToDevice_uart_write_tag: - WS_DEBUG_PRINTLN("-> UART Write Message Type"); - if (!WsV2._uart_controller->Handle_UartWrite(stream)) { - return false; - } - break; - default: - WS_DEBUG_PRINTLN("ERROR: BrokerToDevice message type not found!"); + case wippersnapper_signal_BrokerToDevice_checkin_response_tag: + WS_DEBUG_PRINTLN("-> Checkin Response Message Type"); + WS_DEBUG_PRINT("Handling Checkin Response..."); + if (!handleCheckinResponse(stream)) { return false; + } + WS_DEBUG_PRINTLN("Handled!"); + break; + case wippersnapper_signal_BrokerToDevice_digitalio_add_tag: + WS_DEBUG_PRINTLN("-> DigitalIO Add Message Type"); + if (!WsV2.digital_io_controller->Handle_DigitalIO_Add(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_digitalio_remove_tag: + WS_DEBUG_PRINTLN("-> DigitalIO Remove Message Type"); + if (!WsV2.digital_io_controller->Handle_DigitalIO_Remove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_digitalio_write_tag: + WS_DEBUG_PRINTLN("-> DigitalIO Write Message Type"); + if (!WsV2.digital_io_controller->Handle_DigitalIO_Write(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_analogio_add_tag: + WS_DEBUG_PRINTLN("-> AnalogIO Add Message Type"); + if (!WsV2.analogio_controller->Handle_AnalogIOAdd(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_analogio_remove_tag: + WS_DEBUG_PRINTLN("-> AnalogIO Remove Message Type"); + if (!WsV2.analogio_controller->Handle_AnalogIORemove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_ds18x20_add_tag: + WS_DEBUG_PRINTLN("-> DS18X20 Add Message Type"); + if (!WsV2._ds18x20_controller->Handle_Ds18x20Add(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_ds18x20_remove_tag: + WS_DEBUG_PRINTLN("-> DS18X20 Remove Message Type"); + if (!WsV2._ds18x20_controller->Handle_Ds18x20Remove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_i2c_device_add_replace_tag: + WS_DEBUG_PRINTLN("-> I2C Device Add/Replace Message Type"); + if (!WsV2._i2c_controller->Handle_I2cDeviceAddOrReplace(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_i2c_bus_scan_tag: + WS_DEBUG_PRINTLN("-> I2C Bus Scan Message Type"); + if (!WsV2._i2c_controller->Handle_I2cBusScan(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_i2c_device_remove_tag: + WS_DEBUG_PRINTLN("-> I2C Device Remove Message Type"); + if (!WsV2._i2c_controller->Handle_I2cDeviceRemove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_i2c_device_output_write_tag: + WS_DEBUG_PRINTLN("-> I2C Device Output Write Message Type"); + if (!WsV2._i2c_controller->Handle_I2cDeviceOutputWrite(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pixels_add_tag: + WS_DEBUG_PRINTLN("-> Pixels Add Message Type"); + if (!WsV2._pixels_controller->Handle_Pixels_Add(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pixels_remove_tag: + WS_DEBUG_PRINTLN("-> Pixels Remove Message Type"); + if (!WsV2._pixels_controller->Handle_Pixels_Remove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pixels_write_tag: + WS_DEBUG_PRINTLN("-> Pixels Write Message Type"); + if (!WsV2._pixels_controller->Handle_Pixels_Write(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pwm_add_tag: + WS_DEBUG_PRINTLN("-> PWM Add Message Type"); + if (!WsV2._pwm_controller->Handle_PWM_Add(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pwm_write_duty_tag: + WS_DEBUG_PRINTLN("-> PWM Write Duty Cycle Message Type"); + if (!WsV2._pwm_controller->Handle_PWM_Write_DutyCycle(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pwm_write_freq_tag: + WS_DEBUG_PRINTLN("-> PWM Write Frequency Message Type"); + if (!WsV2._pwm_controller->Handle_PWM_Write_Frequency(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_pwm_remove_tag: + WS_DEBUG_PRINTLN("-> PWM Remove Message Type"); + if (!WsV2._pwm_controller->Handle_PWM_Remove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_servo_add_tag: + WS_DEBUG_PRINTLN("-> Servo Add Message Type"); + if (!WsV2._servo_controller->Handle_Servo_Add(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_servo_write_tag: + WS_DEBUG_PRINTLN("-> Servo Write Message Type"); + if (!WsV2._servo_controller->Handle_Servo_Write(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_servo_remove_tag: + WS_DEBUG_PRINTLN("-> Servo Remove Message Type"); + if (!WsV2._servo_controller->Handle_Servo_Remove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_uart_add_tag: + WS_DEBUG_PRINTLN("-> UART Add Message Type"); + if (!WsV2._uart_controller->Handle_UartAdd(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_uart_remove_tag: + WS_DEBUG_PRINTLN("-> UART Remove Message Type"); + if (!WsV2._uart_controller->Handle_UartRemove(stream)) { + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_uart_write_tag: + WS_DEBUG_PRINTLN("-> UART Write Message Type"); + if (!WsV2._uart_controller->Handle_UartWrite(stream)) { + return false; + } + break; + default: + WS_DEBUG_PRINTLN("ERROR: BrokerToDevice message type not found!"); + return false; } // once this is returned, pb_dec_submessage() // decodes the submessage contents. @@ -477,7 +474,7 @@ bool cbDecodeBrokerToDevice(pb_istream_t* stream, const pb_field_t* field, @param len Length of data received from MQTT broker. */ -void cbBrokerToDevice(char* data, uint16_t len) { +void cbBrokerToDevice(char *data, uint16_t len) { WS_DEBUG_PRINTLN("=> New B2D message!"); wippersnapper_signal_BrokerToDevice msg_signal = wippersnapper_signal_BrokerToDevice_init_default; @@ -487,7 +484,7 @@ void cbBrokerToDevice(char* data, uint16_t len) { // Decode msg_signal WS_DEBUG_PRINTLN("Creating input stream..."); - pb_istream_t istream = pb_istream_from_buffer((uint8_t*)data, len); + pb_istream_t istream = pb_istream_from_buffer((uint8_t *)data, len); WS_DEBUG_PRINTLN("Decoding BrokerToDevice message..."); if (!pb_decode(&istream, wippersnapper_signal_BrokerToDevice_fields, &msg_signal)) { @@ -507,7 +504,7 @@ void callDecodeB2D() { wippersnapper_signal_BrokerToDevice_init_default; // Configure the payload callback msg_signal.cb_payload.funcs.decode = cbDecodeBrokerToDevice; - const std::vector& buffer = WsV2._sharedConfigBuffers[i]; + const std::vector &buffer = WsV2._sharedConfigBuffers[i]; pb_istream_t istream = pb_istream_from_buffer(buffer.data(), buffer.size()); // Decode the message if (!pb_decode(&istream, wippersnapper_signal_BrokerToDevice_fields, @@ -526,7 +523,7 @@ void callDecodeB2D() { @param len Length of data received from MQTT broker. */ -void cbErrorTopicV2(char* errorData, uint16_t len) { +void cbErrorTopicV2(char *errorData, uint16_t len) { (void)len; // marking unused parameter to avoid compiler warning WS_DEBUG_PRINT("IO Ban Error: "); WS_DEBUG_PRINTLN(errorData); @@ -553,11 +550,11 @@ void cbErrorTopicV2(char* errorData, uint16_t len) { @param len Length of data received from MQTT broker. */ -void cbThrottleTopicV2(char* throttleData, uint16_t len) { +void cbThrottleTopicV2(char *throttleData, uint16_t len) { (void)len; // marking unused parameter to avoid compiler warning WS_DEBUG_PRINT("IO Throttle Error: "); WS_DEBUG_PRINTLN(throttleData); - char* throttleMessage; + char *throttleMessage; // Parse out # of seconds from message buffer throttleMessage = strtok(throttleData, ","); throttleMessage = strtok(NULL, " "); @@ -627,9 +624,9 @@ bool Wippersnapper_V2::generateDeviceUID() { // Attempt to allocate memory for the _device_uid WS_DEBUG_PRINTLN("Allocating memory for device UID"); #ifdef USE_PSRAM - _device_uidV2 = (char*)ps_malloc(sizeof(char) * lenDeviceUID); + _device_uidV2 = (char *)ps_malloc(sizeof(char) * lenDeviceUID); #else - _device_uidV2 = (char*)malloc(sizeof(char) * lenDeviceUID); + _device_uidV2 = (char *)malloc(sizeof(char) * lenDeviceUID); #endif // Check if memory allocation was successful @@ -672,9 +669,9 @@ bool Wippersnapper_V2::generateWSTopics() { // Attempt to allocate memory for the broker-to-device topic #ifdef USE_PSRAM - WsV2._topicB2d = (char*)ps_malloc(sizeof(char) * lenTopicB2d); + WsV2._topicB2d = (char *)ps_malloc(sizeof(char) * lenTopicB2d); #else - WsV2._topicB2d = (char*)malloc(sizeof(char) * lenTopicB2d); + WsV2._topicB2d = (char *)malloc(sizeof(char) * lenTopicB2d); #endif // Check if memory allocation was successful if (WsV2._topicB2d == NULL) @@ -692,9 +689,9 @@ bool Wippersnapper_V2::generateWSTopics() { // Create global device to broker topic // Attempt to allocate memory for the broker-to-device topic #ifdef USE_PSRAM - WsV2._topicD2b = (char*)ps_malloc(sizeof(char) * lenTopicD2b); + WsV2._topicD2b = (char *)ps_malloc(sizeof(char) * lenTopicD2b); #else - WsV2._topicD2b = (char*)malloc(sizeof(char) * lenTopicD2b); + WsV2._topicD2b = (char *)malloc(sizeof(char) * lenTopicD2b); #endif // Check if memory allocation was successful if (WsV2._topicD2b == NULL) @@ -707,9 +704,9 @@ bool Wippersnapper_V2::generateWSTopics() { // Attempt to allocate memory for the error topic #ifdef USE_PSRAM - WsV2._topicError = (char*)ps_malloc(sizeof(char) * lenTopicError); + WsV2._topicError = (char *)ps_malloc(sizeof(char) * lenTopicError); #else - WsV2._topicError = (char*)malloc(sizeof(char) * lenTopicError); + WsV2._topicError = (char *)malloc(sizeof(char) * lenTopicError); #endif // Check if memory allocation was successful if (WsV2._topicError == NULL) @@ -727,9 +724,9 @@ bool Wippersnapper_V2::generateWSTopics() { // Attempt to allocate memory for the error topic #ifdef USE_PSRAM - WsV2._topicThrottle = (char*)ps_malloc(sizeof(char) * lenTopicThrottle); + WsV2._topicThrottle = (char *)ps_malloc(sizeof(char) * lenTopicThrottle); #else - WsV2._topicThrottle = (char*)malloc(sizeof(char) * lenTopicThrottle); + WsV2._topicThrottle = (char *)malloc(sizeof(char) * lenTopicThrottle); #endif // Check if memory allocation was successful if (WsV2._topicThrottle == NULL) @@ -754,7 +751,7 @@ bool Wippersnapper_V2::generateWSTopics() { @param error The error message to write to the serial and filesystem. */ -void Wippersnapper_V2::errorWriteHangV2(const char* error) { +void Wippersnapper_V2::errorWriteHangV2(const char *error) { // Print error WS_DEBUG_PRINTLN(error); #ifdef USE_TINYUSB @@ -784,132 +781,130 @@ void Wippersnapper_V2::runNetFSMV2() { int maxAttempts; while (fsmNetwork != FSM_NET_CONNECTED) { switch (fsmNetwork) { - case FSM_NET_CHECK_MQTT: - if (WsV2._mqttV2->connected()) { - // WS_DEBUG_PRINTLN("Connected to Adafruit IO!"); - fsmNetwork = FSM_NET_CONNECTED; - return; - } - fsmNetwork = FSM_NET_CHECK_NETWORK; - break; - case FSM_NET_CHECK_NETWORK: - if (networkStatus() == WS_NET_CONNECTED) { - WS_DEBUG_PRINTLN("Connected to WiFi!"); + case FSM_NET_CHECK_MQTT: + if (WsV2._mqttV2->connected()) { + // WS_DEBUG_PRINTLN("Connected to Adafruit IO!"); + fsmNetwork = FSM_NET_CONNECTED; + return; + } + fsmNetwork = FSM_NET_CHECK_NETWORK; + break; + case FSM_NET_CHECK_NETWORK: + if (networkStatus() == WS_NET_CONNECTED) { + WS_DEBUG_PRINTLN("Connected to WiFi!"); #ifdef USE_DISPLAY - if (WsV2._ui_helperV2->getLoadingState()) - WsV2._ui_helperV2->set_load_bar_icon_complete(loadBarIconWifi); + if (WsV2._ui_helperV2->getLoadingState()) + WsV2._ui_helperV2->set_load_bar_icon_complete(loadBarIconWifi); #endif - fsmNetwork = FSM_NET_ESTABLISH_MQTT; - break; - } - fsmNetwork = FSM_NET_ESTABLISH_NETWORK; + fsmNetwork = FSM_NET_ESTABLISH_MQTT; break; - case FSM_NET_ESTABLISH_NETWORK: - WS_DEBUG_PRINTLN("Establishing network connection..."); - WS_PRINTER.flush(); + } + fsmNetwork = FSM_NET_ESTABLISH_NETWORK; + break; + case FSM_NET_ESTABLISH_NETWORK: + WS_DEBUG_PRINTLN("Establishing network connection..."); + WS_PRINTER.flush(); #ifdef USE_DISPLAY - if (WsV2._ui_helperV2->getLoadingState()) - WsV2._ui_helperV2->set_label_status("Connecting to WiFi..."); + if (WsV2._ui_helperV2->getLoadingState()) + WsV2._ui_helperV2->set_label_status("Connecting to WiFi..."); #endif - // Perform a WiFi scan and check if SSID within - // secrets.json is within the scanned SSIDs - WS_DEBUG_PRINT("Performing a WiFi scan for SSID..."); - if (!check_valid_ssid()) { + // Perform a WiFi scan and check if SSID within + // secrets.json is within the scanned SSIDs + WS_DEBUG_PRINT("Performing a WiFi scan for SSID..."); + if (!check_valid_ssid()) { #ifdef USE_DISPLAY - WsV2._ui_helperV2->show_scr_error( - "ERROR", - "Unable to find WiFi network listed in " - "the secrets file. Rebooting soon..."); + WsV2._ui_helperV2->show_scr_error( + "ERROR", "Unable to find WiFi network listed in " + "the secrets file. Rebooting soon..."); #endif - haltErrorV2("ERROR: Unable to find WiFi network, rebooting soon...", - WS_LED_STATUS_WIFI_CONNECTING); - } - // Attempt to connect to wireless network - maxAttempts = 5; - while (maxAttempts > 0) { - // blink before we connect - statusLEDBlink(WS_LED_STATUS_WIFI_CONNECTING); - feedWDTV2(); - // attempt to connect - WS_DEBUG_PRINT("Connecting to WiFi (attempt #"); - WS_DEBUG_PRINT(5 - maxAttempts); - WS_DEBUG_PRINTLN(")"); - WS_PRINTER.flush(); - feedWDTV2(); - _connect(); - feedWDTV2(); - // did we connect? - if (networkStatus() == WS_NET_CONNECTED) - break; - maxAttempts--; - } - // Validate connection - if (networkStatus() != WS_NET_CONNECTED) { - WS_DEBUG_PRINTLN("ERROR: Unable to connect to WiFi!"); + haltErrorV2("ERROR: Unable to find WiFi network, rebooting soon...", + WS_LED_STATUS_WIFI_CONNECTING); + } + // Attempt to connect to wireless network + maxAttempts = 5; + while (maxAttempts > 0) { + // blink before we connect + statusLEDBlink(WS_LED_STATUS_WIFI_CONNECTING); + feedWDTV2(); + // attempt to connect + WS_DEBUG_PRINT("Connecting to WiFi (attempt #"); + WS_DEBUG_PRINT(5 - maxAttempts); + WS_DEBUG_PRINTLN(")"); + WS_PRINTER.flush(); + feedWDTV2(); + _connect(); + feedWDTV2(); + // did we connect? + if (networkStatus() == WS_NET_CONNECTED) + break; + maxAttempts--; + } + // Validate connection + if (networkStatus() != WS_NET_CONNECTED) { + WS_DEBUG_PRINTLN("ERROR: Unable to connect to WiFi!"); #ifdef USE_DISPLAY - WsV2._ui_helperV2->show_scr_error( - "CONNECTION ERROR", - "Unable to connect to WiFi Network. Please check that you " - "entered " - "the WiFi credentials correctly. Rebooting in 5 seconds..."); + WsV2._ui_helperV2->show_scr_error( + "CONNECTION ERROR", + "Unable to connect to WiFi Network. Please check that you " + "entered " + "the WiFi credentials correctly. Rebooting in 5 seconds..."); #endif - haltErrorV2("ERROR: Unable to connect to WiFi, rebooting soon...", - WS_LED_STATUS_WIFI_CONNECTING); - } + haltErrorV2("ERROR: Unable to connect to WiFi, rebooting soon...", + WS_LED_STATUS_WIFI_CONNECTING); + } - fsmNetwork = FSM_NET_CHECK_NETWORK; - break; - case FSM_NET_ESTABLISH_MQTT: + fsmNetwork = FSM_NET_CHECK_NETWORK; + break; + case FSM_NET_ESTABLISH_MQTT: #ifdef USE_DISPLAY - if (WsV2._ui_helperV2->getLoadingState()) - WsV2._ui_helperV2->set_label_status("Connecting to IO..."); + if (WsV2._ui_helperV2->getLoadingState()) + WsV2._ui_helperV2->set_label_status("Connecting to IO..."); #endif - WsV2._mqttV2->setKeepAliveInterval(WS_KEEPALIVE_INTERVAL_MS / 1000); - // Attempt to connect - maxAttempts = 5; - while (maxAttempts > 0) { - WS_DEBUG_PRINT("Connecting to AIO MQTT (attempt #"); - WS_DEBUG_PRINT(5 - maxAttempts); - WS_DEBUG_PRINTLN(")"); - WS_PRINTER.flush(); - WS_DEBUG_PRINT("WiFi Status: "); - WS_DEBUG_PRINTLN(networkStatus()); - WS_PRINTER.flush(); - feedWDTV2(); - statusLEDBlink(WS_LED_STATUS_MQTT_CONNECTING); - feedWDTV2(); - int8_t mqttRC = WsV2._mqttV2->connect(); - feedWDTV2(); - if (mqttRC == WS_MQTT_CONNECTED) { - fsmNetwork = FSM_NET_CHECK_MQTT; - break; - } - WS_DEBUG_PRINT("MQTT Connection Error: "); - WS_DEBUG_PRINTLN(mqttRC); - WS_DEBUG_PRINTLN(WsV2._mqttV2->connectErrorString(mqttRC)); - WS_DEBUG_PRINTLN( - "Unable to connect to Adafruit IO MQTT, retrying in 3 " - "seconds..."); - delay(3000); - maxAttempts--; + WsV2._mqttV2->setKeepAliveInterval(WS_KEEPALIVE_INTERVAL_MS / 1000); + // Attempt to connect + maxAttempts = 5; + while (maxAttempts > 0) { + WS_DEBUG_PRINT("Connecting to AIO MQTT (attempt #"); + WS_DEBUG_PRINT(5 - maxAttempts); + WS_DEBUG_PRINTLN(")"); + WS_PRINTER.flush(); + WS_DEBUG_PRINT("WiFi Status: "); + WS_DEBUG_PRINTLN(networkStatus()); + WS_PRINTER.flush(); + feedWDTV2(); + statusLEDBlink(WS_LED_STATUS_MQTT_CONNECTING); + feedWDTV2(); + int8_t mqttRC = WsV2._mqttV2->connect(); + feedWDTV2(); + if (mqttRC == WS_MQTT_CONNECTED) { + fsmNetwork = FSM_NET_CHECK_MQTT; + break; } - if (fsmNetwork != FSM_NET_CHECK_MQTT) { + WS_DEBUG_PRINT("MQTT Connection Error: "); + WS_DEBUG_PRINTLN(mqttRC); + WS_DEBUG_PRINTLN(WsV2._mqttV2->connectErrorString(mqttRC)); + WS_DEBUG_PRINTLN("Unable to connect to Adafruit IO MQTT, retrying in 3 " + "seconds..."); + delay(3000); + maxAttempts--; + } + if (fsmNetwork != FSM_NET_CHECK_MQTT) { #ifdef USE_DISPLAY - WsV2._ui_helperV2->show_scr_error( - "CONNECTION ERROR", - "Unable to connect to Adafruit.io. If you are repeatedly having " - "this issue, please check that your IO Username and IO Key are " - "set " - "correctly in the secrets file. This device will reboot in 5 " - "seconds..."); + WsV2._ui_helperV2->show_scr_error( + "CONNECTION ERROR", + "Unable to connect to Adafruit.io. If you are repeatedly having " + "this issue, please check that your IO Username and IO Key are " + "set " + "correctly in the secrets file. This device will reboot in 5 " + "seconds..."); #endif - haltErrorV2( - "ERROR: Unable to connect to Adafruit.IO MQTT, rebooting soon...", - WS_LED_STATUS_MQTT_CONNECTING); - } - break; - default: - break; + haltErrorV2( + "ERROR: Unable to connect to Adafruit.IO MQTT, rebooting soon...", + WS_LED_STATUS_MQTT_CONNECTING); + } + break; + default: + break; } } } @@ -926,7 +921,7 @@ void Wippersnapper_V2::runNetFSMV2() { If false, the device will not allow the WDT to bite and instead hang indefinitely, holding the WIPPER drive open */ -void Wippersnapper_V2::haltErrorV2(const char* error, +void Wippersnapper_V2::haltErrorV2(const char *error, ws_led_status_t ledStatusColor, bool reboot) { WS_DEBUG_PRINT("ERROR "); @@ -963,7 +958,7 @@ void Wippersnapper_V2::haltErrorV2(const char* error, @returns True if the signal message published successfully, False otherwise. */ -bool Wippersnapper_V2::PublishSignal(pb_size_t which_payload, void* payload) { +bool Wippersnapper_V2::PublishSignal(pb_size_t which_payload, void *payload) { #ifdef DEBUG_PROFILE unsigned long total_start_time = micros(); #endif @@ -975,82 +970,80 @@ bool Wippersnapper_V2::PublishSignal(pb_size_t which_payload, void* payload) { // Fill generic signal payload with the payload from the args. WS_DEBUG_PRINT("Signal Payload Type: "); switch (which_payload) { - case wippersnapper_signal_DeviceToBroker_checkin_request_tag: - WS_DEBUG_PRINTLN("CheckinRequest"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_checkin_request_tag; - MsgSignal.payload.checkin_request = - *(wippersnapper_checkin_CheckinRequest*)payload; - break; - case wippersnapper_signal_DeviceToBroker_digitalio_event_tag: - WS_DEBUG_PRINTLN("DigitalIOEvent"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_digitalio_event_tag; - MsgSignal.payload.digitalio_event = - *(wippersnapper_digitalio_DigitalIOEvent*)payload; - break; - case wippersnapper_signal_DeviceToBroker_analogio_event_tag: - WS_DEBUG_PRINTLN("AnalogIOEvent"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_analogio_event_tag; - MsgSignal.payload.analogio_event = - *(wippersnapper_analogio_AnalogIOEvent*)payload; - break; - case wippersnapper_signal_DeviceToBroker_ds18x20_added_tag: - WS_DEBUG_PRINTLN("DS18X20Added"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_ds18x20_added_tag; - MsgSignal.payload.ds18x20_added = - *(wippersnapper_ds18x20_Ds18x20Added*)payload; - break; - case wippersnapper_signal_DeviceToBroker_ds18x20_event_tag: - WS_DEBUG_PRINTLN("DS18X20Event"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_ds18x20_event_tag; - MsgSignal.payload.ds18x20_event = - *(wippersnapper_ds18x20_Ds18x20Event*)payload; - break; - case wippersnapper_signal_DeviceToBroker_pixels_added_tag: - WS_DEBUG_PRINTLN("PixelsAdded"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_pixels_added_tag; - MsgSignal.payload.pixels_added = - *(wippersnapper_pixels_PixelsAdded*)payload; - break; - case wippersnapper_signal_DeviceToBroker_pwm_added_tag: - WS_DEBUG_PRINTLN("PWMAdded"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_pwm_added_tag; - MsgSignal.payload.pwm_added = *(wippersnapper_pwm_PWMAdded*)payload; - break; - case wippersnapper_signal_DeviceToBroker_servo_added_tag: - WS_DEBUG_PRINTLN("ServoAdded"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_servo_added_tag; - MsgSignal.payload.servo_added = *(wippersnapper_servo_ServoAdded*)payload; - break; - case wippersnapper_signal_DeviceToBroker_uart_added_tag: - WS_DEBUG_PRINTLN("UARTAdded"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_uart_added_tag; - MsgSignal.payload.uart_added = *(wippersnapper_uart_UartAdded*)payload; - break; - case wippersnapper_signal_DeviceToBroker_uart_input_event_tag: - WS_DEBUG_PRINTLN("UARTInputEvent"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_uart_input_event_tag; - MsgSignal.payload.uart_input_event = - *(wippersnapper_uart_UartInputEvent*)payload; - break; - case wippersnapper_signal_DeviceToBroker_gps_event_tag: - WS_DEBUG_PRINTLN("GPSEvent"); - MsgSignal.which_payload = - wippersnapper_signal_DeviceToBroker_gps_event_tag; - MsgSignal.payload.gps_event = *(wippersnapper_gps_GPSEvent*)payload; - break; - default: - WS_DEBUG_PRINTLN("ERROR: Invalid signal payload type, bailing out!"); - return false; + case wippersnapper_signal_DeviceToBroker_checkin_request_tag: + WS_DEBUG_PRINTLN("CheckinRequest"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_checkin_request_tag; + MsgSignal.payload.checkin_request = + *(wippersnapper_checkin_CheckinRequest *)payload; + break; + case wippersnapper_signal_DeviceToBroker_digitalio_event_tag: + WS_DEBUG_PRINTLN("DigitalIOEvent"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_digitalio_event_tag; + MsgSignal.payload.digitalio_event = + *(wippersnapper_digitalio_DigitalIOEvent *)payload; + break; + case wippersnapper_signal_DeviceToBroker_analogio_event_tag: + WS_DEBUG_PRINTLN("AnalogIOEvent"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_analogio_event_tag; + MsgSignal.payload.analogio_event = + *(wippersnapper_analogio_AnalogIOEvent *)payload; + break; + case wippersnapper_signal_DeviceToBroker_ds18x20_added_tag: + WS_DEBUG_PRINTLN("DS18X20Added"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_ds18x20_added_tag; + MsgSignal.payload.ds18x20_added = + *(wippersnapper_ds18x20_Ds18x20Added *)payload; + break; + case wippersnapper_signal_DeviceToBroker_ds18x20_event_tag: + WS_DEBUG_PRINTLN("DS18X20Event"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_ds18x20_event_tag; + MsgSignal.payload.ds18x20_event = + *(wippersnapper_ds18x20_Ds18x20Event *)payload; + break; + case wippersnapper_signal_DeviceToBroker_pixels_added_tag: + WS_DEBUG_PRINTLN("PixelsAdded"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_pixels_added_tag; + MsgSignal.payload.pixels_added = + *(wippersnapper_pixels_PixelsAdded *)payload; + break; + case wippersnapper_signal_DeviceToBroker_pwm_added_tag: + WS_DEBUG_PRINTLN("PWMAdded"); + MsgSignal.which_payload = wippersnapper_signal_DeviceToBroker_pwm_added_tag; + MsgSignal.payload.pwm_added = *(wippersnapper_pwm_PWMAdded *)payload; + break; + case wippersnapper_signal_DeviceToBroker_servo_added_tag: + WS_DEBUG_PRINTLN("ServoAdded"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_servo_added_tag; + MsgSignal.payload.servo_added = *(wippersnapper_servo_ServoAdded *)payload; + break; + case wippersnapper_signal_DeviceToBroker_uart_added_tag: + WS_DEBUG_PRINTLN("UARTAdded"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_uart_added_tag; + MsgSignal.payload.uart_added = *(wippersnapper_uart_UartAdded *)payload; + break; + case wippersnapper_signal_DeviceToBroker_uart_input_event_tag: + WS_DEBUG_PRINTLN("UARTInputEvent"); + MsgSignal.which_payload = + wippersnapper_signal_DeviceToBroker_uart_input_event_tag; + MsgSignal.payload.uart_input_event = + *(wippersnapper_uart_UartInputEvent *)payload; + break; + case wippersnapper_signal_DeviceToBroker_gps_event_tag: + WS_DEBUG_PRINTLN("GPSEvent"); + MsgSignal.which_payload = wippersnapper_signal_DeviceToBroker_gps_event_tag; + MsgSignal.payload.gps_event = *(wippersnapper_gps_GPSEvent *)payload; + break; + default: + WS_DEBUG_PRINTLN("ERROR: Invalid signal payload type, bailing out!"); + return false; } // Get the encoded size of the signal message diff --git a/src/Wippersnapper_V2.h b/src/Wippersnapper_V2.h index 57b37883f..d601c2997 100644 --- a/src/Wippersnapper_V2.h +++ b/src/Wippersnapper_V2.h @@ -29,25 +29,25 @@ defined */ #ifdef WS_DEBUG -#define WS_DEBUG_PRINT(...) \ - { \ - WS_PRINTER.print(__VA_ARGS__); \ +#define WS_DEBUG_PRINT(...) \ + { \ + WS_PRINTER.print(__VA_ARGS__); \ } /**< Print debug message to serial */ -#define WS_DEBUG_PRINTLN(...) \ - { \ - WS_PRINTER.println(__VA_ARGS__); \ - } /**< Print debug message with newline \ +#define WS_DEBUG_PRINTLN(...) \ + { \ + WS_PRINTER.println(__VA_ARGS__); \ + } /**< Print debug message with newline \ */ -#define WS_DEBUG_PRINTHEX(...) \ - { \ - WS_PRINTER.print(__VA_ARGS__, HEX); \ +#define WS_DEBUG_PRINTHEX(...) \ + { \ + WS_PRINTER.print(__VA_ARGS__, HEX); \ } /**< Print debug message in hexadecimal */ #else -#define WS_DEBUG_PRINT(...) \ - { \ +#define WS_DEBUG_PRINT(...) \ + { \ } /**< Debug print */ -#define WS_DEBUG_PRINTLN(...) \ - { \ +#define WS_DEBUG_PRINTLN(...) \ + { \ } /**< Debug println */ #endif @@ -56,17 +56,17 @@ @param timeout Delay duration in milliseconds */ -#define WS_DELAY_WITH_WDT(timeout) \ - { \ - unsigned long start = millis(); \ - while (millis() - start < timeout) { \ - delay(10); \ - yield(); \ - WsV2.feedWDTV2(); \ - if (millis() < start) { \ - start = millis(); \ - } \ - } \ +#define WS_DELAY_WITH_WDT(timeout) \ + { \ + unsigned long start = millis(); \ + while (millis() - start < timeout) { \ + delay(10); \ + yield(); \ + WsV2.feedWDTV2(); \ + if (millis() < start) { \ + start = millis(); \ + } \ + } \ } // Cpp STD @@ -129,14 +129,14 @@ #include "provisioning/littlefs/WipperSnapper_LittleFS.h" #endif -#define WS_VERSION \ +#define WS_VERSION \ "1.0.0-offline-beta.4" ///< WipperSnapper app. version ///< (semver-formatted) #define WS_WDT_TIMEOUT 60000 ///< WDT timeout #define WS_MAX_ALT_WIFI_NETWORKS 3 ///< Maximum number of alternative networks /* MQTT Configuration */ -#define WS_KEEPALIVE_INTERVAL_MS \ +#define WS_KEEPALIVE_INTERVAL_MS \ 5000 ///< Session keepalive interval time, in milliseconds // Forward declarations @@ -164,7 +164,7 @@ class UARTController; Wippersnapper interface. */ class Wippersnapper_V2 { - public: +public: Wippersnapper_V2(); virtual ~Wippersnapper_V2(); @@ -180,7 +180,7 @@ class Wippersnapper_V2 { ///< (from 0.0 to 1.0) virtual void set_user_key(); - virtual void set_ssid_pass(const char* ssid, const char* ssidPassword); + virtual void set_ssid_pass(const char *ssid, const char *ssidPassword); virtual void set_ssid_pass(); virtual bool check_valid_ssid(); @@ -191,7 +191,7 @@ class Wippersnapper_V2 { virtual void getMacAddr(); virtual int32_t getRSSI(); - virtual void setupMQTTClient(const char* clientID); + virtual void setupMQTTClient(const char *clientID); virtual ws_status_t networkStatus(); @@ -200,7 +200,7 @@ class Wippersnapper_V2 { bool generateWSTopics(); // High-level MQTT Publish - bool PublishSignal(pb_size_t which_payload, void* payload); + bool PublishSignal(pb_size_t which_payload, void *payload); // Checkin API bool CreateCheckinRequest(); @@ -220,10 +220,10 @@ class Wippersnapper_V2 { void BlinkKATStatus(); // Error handling helpers - void haltErrorV2(const char* error, + void haltErrorV2(const char *error, ws_led_status_t ledStatusColor = WS_LED_STATUS_ERROR_RUNTIME, bool reboot = true); - void errorWriteHangV2(const char* error); + void errorWriteHangV2(const char *error); bool _is_offline_mode; ///< Global flag for if the device is in offline mode bool _global_auto_config = @@ -235,39 +235,39 @@ class Wippersnapper_V2 { // TODO: We really should look at making these static definitions, not dynamic // to free up space on the heap - Wippersnapper_FS* _fileSystemV2; ///< Instance of Filesystem (native USB) - WipperSnapper_LittleFS* - _littleFSV2; ///< Instance of LittleFS Filesystem (non-native USB) - ws_sdcard* _sdCardV2; ///< Instance of SD card class + Wippersnapper_FS *_fileSystemV2; ///< Instance of Filesystem (native USB) + WipperSnapper_LittleFS + *_littleFSV2; ///< Instance of LittleFS Filesystem (non-native USB) + ws_sdcard *_sdCardV2; ///< Instance of SD card class #ifdef USE_DISPLAY - ws_display_driver* _displayV2 = nullptr; ///< Instance of display driver class - ws_display_ui_helper* _ui_helperV2 = + ws_display_driver *_displayV2 = nullptr; ///< Instance of display driver class + ws_display_ui_helper *_ui_helperV2 = nullptr; ///< Instance of display UI helper class #endif // API v2 Components - CheckinModel* CheckInModel = nullptr; ///< Instance of CheckinModel class - SensorModel* sensorModel = nullptr; ///< Instance of SensorModel class - DigitalIOController* digital_io_controller = + CheckinModel *CheckInModel = nullptr; ///< Instance of CheckinModel class + SensorModel *sensorModel = nullptr; ///< Instance of SensorModel class + DigitalIOController *digital_io_controller = nullptr; ///< Instance of DigitalIO controller class - AnalogIOController* analogio_controller = + AnalogIOController *analogio_controller = nullptr; ///< Instance of AnalogIO controller - DS18X20Controller* _ds18x20_controller = + DS18X20Controller *_ds18x20_controller = nullptr; ///< Instance of DS18X20 controller - GPSController* _gps_controller = nullptr; ///< Instance of GPS controller - I2cController* _i2c_controller = nullptr; ///< Instance of I2C controller - PixelsController* _pixels_controller = + GPSController *_gps_controller = nullptr; ///< Instance of GPS controller + I2cController *_i2c_controller = nullptr; ///< Instance of I2C controller + PixelsController *_pixels_controller = nullptr; ///< Instance of Pixels controller - PWMController* _pwm_controller = nullptr; ///< Instance of PWM controller - ServoController* _servo_controller = + PWMController *_pwm_controller = nullptr; ///< Instance of PWM controller + ServoController *_servo_controller = nullptr; ///< Instance of Servo controller - UARTController* _uart_controller = nullptr; ///< Instance of UART controller + UARTController *_uart_controller = nullptr; ///< Instance of UART controller // TODO: does this really need to be global? uint8_t _macAddrV2[6]; /*!< Unique network iface identifier */ char sUIDV2[13]; /*!< Unique hardware identifier */ - const char* _boardIdV2; /*!< Adafruit IO+ board string */ - Adafruit_MQTT* _mqttV2; /*!< Reference to Adafruit_MQTT, _mqtt. */ + const char *_boardIdV2; /*!< Adafruit IO+ board string */ + Adafruit_MQTT *_mqttV2; /*!< Reference to Adafruit_MQTT, _mqtt. */ // TODO: Audit this, does it need to be here? secretsConfig _configV2; /*!< Wippersnapper secrets.json as a struct. */ @@ -278,7 +278,7 @@ class Wippersnapper_V2 { int32_t totalDigitalPinsV2; /*!< Total number of digital-input capable pins */ // TODO: Do these need to be here or can they sit within their function? - char* throttleMessageV2; /*!< Pointer to throttle message data. */ + char *throttleMessageV2; /*!< Pointer to throttle message data. */ int throttleTimeV2; /*!< Total amount of time to throttle the device, in milliseconds. */ @@ -292,21 +292,21 @@ class Wippersnapper_V2 { _sharedConfigBuffers; ///< Shared JSON config buffers for offline mode JsonDocument _config_doc; ///< Storage for the config.json file uint8_t pin_sd_cs; ///< SD card chip select pin - private: +private: void _initV2(); // MQTT topics - char* _topicB2d; - char* _topicD2b; - char* _topicError; - char* _topicThrottle; + char *_topicB2d; + char *_topicD2b; + char *_topicError; + char *_topicThrottle; // Adafruit_MQTT Subscription objects - Adafruit_MQTT_Subscribe* _subscribeB2d; - Adafruit_MQTT_Subscribe* _subscribeError; - Adafruit_MQTT_Subscribe* _subscribeThrottle; + Adafruit_MQTT_Subscribe *_subscribeB2d; + Adafruit_MQTT_Subscribe *_subscribeError; + Adafruit_MQTT_Subscribe *_subscribeThrottle; - protected: +protected: ws_status_t _statusV2 = WS_IDLE; ///< Wippersnapper status uint32_t _last_mqtt_connectV2 = 0; /*!< Previous time when client connected to @@ -317,8 +317,8 @@ class Wippersnapper_V2 { IO's MQTT broker, in milliseconds. */ // Device information - const char* _deviceIdV2; /*!< Adafruit IO+ device identifier string */ - char* _device_uidV2; /*!< Unique device identifier */ + const char *_deviceIdV2; /*!< Adafruit IO+ device identifier string */ + char *_device_uidV2; /*!< Unique device identifier */ }; extern Wippersnapper_V2 WsV2; ///< Global member variable for callbacks diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index becf083a4..35c8f6bee 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -83,38 +83,38 @@ class I2cHardware; ///< Forward declaration appropriate hardware, model, and device driver classes. */ class I2cController { - public: +public: I2cController(); ~I2cController(); void update(); // Routing // - bool Handle_I2cDeviceAddOrReplace(pb_istream_t* stream); - bool Handle_I2cBusScan(pb_istream_t* stream); - bool Handle_I2cDeviceRemove(pb_istream_t* stream); - bool Handle_I2cDeviceOutputWrite(pb_istream_t* stream); + bool Handle_I2cDeviceAddOrReplace(pb_istream_t *stream); + bool Handle_I2cBusScan(pb_istream_t *stream); + bool Handle_I2cDeviceRemove(pb_istream_t *stream); + bool Handle_I2cDeviceOutputWrite(pb_istream_t *stream); // Publishing // bool PublishI2cDeviceAddedorReplaced( - const wippersnapper_i2c_I2cDeviceDescriptor& device_descriptor, - const wippersnapper_i2c_I2cDeviceStatus& device_status); + const wippersnapper_i2c_I2cDeviceDescriptor &device_descriptor, + const wippersnapper_i2c_I2cDeviceStatus &device_status); // Helpers // bool IsBusStatusOK(bool is_alt_bus = false); - bool InitMux(const char* name, uint32_t address, bool is_alt_bus); + bool InitMux(const char *name, uint32_t address, bool is_alt_bus); void ConfigureMuxChannel(uint32_t mux_channel, bool is_alt_bus); bool RemoveDriver(uint32_t address, bool is_output_device); bool ScanI2cBus(bool default_bus); - TwoWire* GetI2cBus(bool is_alt_bus = false); + TwoWire *GetI2cBus(bool is_alt_bus = false); uint32_t GetScanDeviceAddress(int index); size_t GetScanDeviceCount(); void PrintAllDrivers(); - private: - I2cModel* _i2c_model = nullptr; ///< Pointer to an I2C model object - I2cOutputModel* _i2c_output_model = +private: + I2cModel *_i2c_model = nullptr; ///< Pointer to an I2C model object + I2cOutputModel *_i2c_output_model = nullptr; ///< Pointer to an I2C output model object - I2cHardware* _i2c_bus_default = nullptr; ///< Pointer to the default I2C bus - I2cHardware* _i2c_bus_alt = nullptr; ///< Pointer to an alternative I2C bus - std::vector _i2c_drivers; ///< Vector of ptrs to I2C input drivers - std::vector + I2cHardware *_i2c_bus_default = nullptr; ///< Pointer to the default I2C bus + I2cHardware *_i2c_bus_alt = nullptr; ///< Pointer to an alternative I2C bus + std::vector _i2c_drivers; ///< Vector of ptrs to I2C input drivers + std::vector _i2c_drivers_output; ///< Vector of ptrs to I2C output drivers wippersnapper_i2c_I2cBusScanned _scan_results; ///< Stores results of I2C bus scan diff --git a/src/components/i2c/drivers/drvD6t1a.h b/src/components/i2c/drivers/drvD6t1a.h index a6e14371d..aaf788dbe 100644 --- a/src/components/i2c/drivers/drvD6t1a.h +++ b/src/components/i2c/drivers/drvD6t1a.h @@ -24,7 +24,7 @@ sensor. */ class drvD6t1a : public drvBase { - public: +public: /*! @brief Constructor for a D6T1A sensor. @param i2c @@ -36,8 +36,8 @@ class drvD6t1a : public drvBase { @param driver_name The name of the driver. */ - drvD6t1a(TwoWire* i2c, uint16_t sensorAddress, uint32_t mux_channel, - const char* driver_name) + drvD6t1a(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) : drvBase(i2c, sensorAddress, mux_channel, driver_name) { _i2c = i2c; _address = sensorAddress; @@ -53,9 +53,7 @@ class drvD6t1a : public drvBase { /*! @brief Destructor for a D6T1A sensor. */ - ~drvD6t1a() { - delete _d6t1a; - } + ~drvD6t1a() { delete _d6t1a; } /*! @brief Initializes the D6T1A sensor and begins I2C. @@ -98,7 +96,7 @@ class drvD6t1a : public drvBase { @returns True if the temperature was obtained successfully, False otherwise. */ - bool getEventAmbientTemp(sensors_event_t* tempEvent) { + bool getEventAmbientTemp(sensors_event_t *tempEvent) { if (ReadSensorData() && !isnan(_deviceTemp)) { tempEvent->temperature = _deviceTemp; return true; @@ -113,7 +111,7 @@ class drvD6t1a : public drvBase { @returns True if the temperature was obtained successfully, False otherwise. */ - bool getEventObjectTemp(sensors_event_t* tempEvent) { + bool getEventObjectTemp(sensors_event_t *tempEvent) { if (ReadSensorData() && !isnan(_objectTemp)) { tempEvent->temperature = _objectTemp; return true; @@ -129,11 +127,11 @@ class drvD6t1a : public drvBase { wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE; } - protected: +protected: float _deviceTemp; ///< Device temperature in Celsius float _objectTemp; ///< Object temperature in Celsius uint32_t _lastRead; ///< Last time the sensor was read in milliseconds - OmronD6T* _d6t1a; ///< D6T1A object + OmronD6T *_d6t1a; ///< D6T1A object }; #endif // DRV_D6T1A_H \ No newline at end of file From 0c34fe51705f974b6fbe2b2b618cba472627084f Mon Sep 17 00:00:00 2001 From: tyeth Date: Wed, 13 Aug 2025 13:34:18 +0100 Subject: [PATCH 17/32] Refactor INA260 and add INA237/238 --- .gitignore | 1 + library.properties | 2 +- platformio.ini | 1 + src/components/i2c/controller.cpp | 25 +++++-- src/components/i2c/controller.h | 3 + src/components/i2c/drivers/drvBase.h | 3 + src/components/i2c/drivers/drvIna237.cpp | 82 ++++++++++++++++++++++ src/components/i2c/drivers/drvIna237.h | 89 ++++++++++++++++++++++++ src/components/i2c/drivers/drvIna238.cpp | 82 ++++++++++++++++++++++ src/components/i2c/drivers/drvIna238.h | 89 ++++++++++++++++++++++++ src/components/i2c/drivers/drvIna260.cpp | 82 ++++++++++++++++++++++ src/components/i2c/drivers/drvIna260.h | 38 +++------- 12 files changed, 461 insertions(+), 36 deletions(-) create mode 100644 src/components/i2c/drivers/drvIna237.cpp create mode 100644 src/components/i2c/drivers/drvIna237.h create mode 100644 src/components/i2c/drivers/drvIna238.cpp create mode 100644 src/components/i2c/drivers/drvIna238.h create mode 100644 src/components/i2c/drivers/drvIna260.cpp diff --git a/.gitignore b/.gitignore index 7cd678d8a..986b733b3 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ src/.vscode/settings.json .DS_STORE examples/Wippersnapper_demo/build/ src/Wippersnapper_demo.ino.cpp +build_output_*.txt # Virtual environment directories .venv/ diff --git a/library.properties b/library.properties index 77289ed90..216e3eafb 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,4 @@ paragraph=Arduino application for Adafruit.io WipperSnapper category=Communication url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino architectures=* -depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox +depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA237 and INA238 Library, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox diff --git a/platformio.ini b/platformio.ini index 88aba16cd..918513681 100644 --- a/platformio.ini +++ b/platformio.ini @@ -39,6 +39,7 @@ lib_deps = adafruit/Adafruit DPS310 adafruit/Adafruit DS248x adafruit/Adafruit INA219 + adafruit/Adafruit INA237 and INA238 Library adafruit/Adafruit INA260 Library adafruit/Adafruit HDC302x adafruit/Adafruit HTS221 diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 9ffe410c2..9f24bcbcc 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -133,6 +133,21 @@ static const std::map I2cFactorySensor = { const char *driver_name) -> drvBase * { return new drvIna219(i2c, addr, mux_channel, driver_name); }}, + {"ina237", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvIna237(i2c, addr, mux_channel, driver_name); + }}, + {"ina238", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvIna238(i2c, addr, mux_channel, driver_name); + }}, + {"ina260", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvIna260(i2c, addr, mux_channel, driver_name); + }}, {"lc709203f", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { @@ -372,11 +387,11 @@ static const std::unordered_map> {0x38, {"aht20", "max17048"}}, {0x39, {"tsl2591"}}, {0x40, - {"htu21d", "htu31d", "ina219", "ina260", "ms8607", "si7021", - "stemma_soil"}}, - {0x41, {"htu31d", "ina219", "ina260"}}, - {0x44, {"hdc302x", "ina260", "sht3x", "sht4x"}}, - {0x45, {"hdc302x", "ina260", "sht3x"}}, + {"htu21d", "htu31d", "ina219", "ina237", "ina238", "ina260", + "ms8607", "si7021", "stemma_soil"}}, + {0x41, {"htu31d", "ina219", "ina237", "ina238", "ina260"}}, + {0x44, {"hdc302x", "ina237", "ina238", "ina260", "sht3x", "sht4x"}}, + {0x45, {"hdc302x", "ina237", "ina238", "ina260", "sht3x"}}, {0x46, {"hdc302x"}}, {0x47, {"hdc302x"}}, {0x48, {"adt7410", "pct2075", "tmp117"}}, diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 35c8f6bee..e35334f6f 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -33,6 +33,9 @@ #include "drivers/drvHts221.h" #include "drivers/drvHtu21d.h" #include "drivers/drvIna219.h" +#include "drivers/drvIna237.h" +#include "drivers/drvIna238.h" +#include "drivers/drvIna260.h" #include "drivers/drvLc709203f.h" #include "drivers/drvLps22hb.h" #include "drivers/drvLps25hb.h" diff --git a/src/components/i2c/drivers/drvBase.h b/src/components/i2c/drivers/drvBase.h index 70ee12352..cabb581ad 100644 --- a/src/components/i2c/drivers/drvBase.h +++ b/src/components/i2c/drivers/drvBase.h @@ -17,7 +17,10 @@ #define DRV_BASE_H #include #include +#include +#include #include +#include "helpers/ws_helper_macros.h" #define NO_MUX_CH 0xFFFF; ///< No MUX channel specified #define DEFAULT_SENSOR_PERIOD 15.0f ///< Default sensor period, in seconds diff --git a/src/components/i2c/drivers/drvIna237.cpp b/src/components/i2c/drivers/drvIna237.cpp new file mode 100644 index 000000000..9bd70e9a1 --- /dev/null +++ b/src/components/i2c/drivers/drvIna237.cpp @@ -0,0 +1,82 @@ +/*! + * @file drvIna237.cpp + * + * Device driver for the INA237 High Precision DC Current and Voltage Monitor + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Tyeth Gundry 2025 for Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + * + */ + +#include "drvIna237.h" +#include + +/*******************************************************************************/ +/*! + @brief Destructor for an INA237 sensor. +*/ +/*******************************************************************************/ +drvIna237::~drvIna237() { + if (_ina237) { + delete _ina237; + _ina237 = nullptr; + } +} + +/*******************************************************************************/ +/*! + @brief Initializes the INA237 sensor and begins I2C. + @returns True if initialized successfully, False otherwise. +*/ +/*******************************************************************************/ +bool drvIna237::begin() { + _ina237 = new Adafruit_INA237(); + if (!_ina237->begin(_address, _i2c)) { + WS_DEBUG_PRINTLN("INA237 failed to initialise!"); + return false; + } + // TODO: use setCalibration() + + return true; +} + +/*******************************************************************************/ +/*! + @brief Reads a voltage sensor and converts the + reading into the expected SI unit. + @param voltageEvent + voltage sensor reading, in volts. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/*******************************************************************************/ +bool drvIna237::getEventVoltage(sensors_event_t *voltageEvent) { + voltageEvent->voltage = _ina237->getBusVoltage_V(); + return true; +} + +/** + * @brief Get the current sensor event. + * + * @param currentEvent Pointer to the current sensor event. + * + * @returns True if the sensor event was obtained successfully, False + * otherwise. + */ +bool drvIna237::getEventCurrent(sensors_event_t *currentEvent) { + currentEvent->current = _ina237->getCurrent_mA(); + return true; +} + +void drvIna237::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 2; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE; + _default_sensor_types[1] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_CURRENT; +} \ No newline at end of file diff --git a/src/components/i2c/drivers/drvIna237.h b/src/components/i2c/drivers/drvIna237.h new file mode 100644 index 000000000..15a522e05 --- /dev/null +++ b/src/components/i2c/drivers/drvIna237.h @@ -0,0 +1,89 @@ +/*! + * @file drvIna237.h + * + * Device driver for the INA237 High Precision DC Current and Voltage Monitor + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Tyeth Gundry 2025 for Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + * + */ +#ifndef DRV_INA237_H +#define DRV_INA237_H + +#include "drvBase.h" + +class Adafruit_INA237; + +/**************************************************************************/ +/*! + @brief Class that provides a driver interface for a INA237 sensor. +*/ +/**************************************************************************/ +class drvIna237 : public drvBase { +public: + /*******************************************************************************/ + /*! + @brief Constructor for a INA237 sensor. + @param i2c + The I2C interface. + @param sensorAddress + 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. + */ + /*******************************************************************************/ + drvIna237(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + + /*******************************************************************************/ + /*! + @brief Destructor for an INA237 sensor. + */ + /*******************************************************************************/ + ~drvIna237(); + + /*******************************************************************************/ + /*! + @brief Initializes the INA237 sensor and begins I2C. + @returns True if initialized successfully, False otherwise. + */ + /*******************************************************************************/ + bool begin(); + + /*******************************************************************************/ + /*! + @brief Reads a voltage sensor and converts the + reading into the expected SI unit. + @param voltageEvent + voltage sensor reading, in volts. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + bool getEventVoltage(sensors_event_t *voltageEvent); + + /** + * @brief Get the current sensor event. + * + * @param currentEvent Pointer to the current sensor event. + * + * @returns True if the sensor event was obtained successfully, False + * otherwise. + */ + bool getEventCurrent(sensors_event_t *currentEvent); + + void ConfigureDefaultSensorTypes() override; + +protected: + Adafruit_INA237 *_ina237; ///< Pointer to INA237 sensor object +}; + +#endif // DRV_INA237_H \ No newline at end of file diff --git a/src/components/i2c/drivers/drvIna238.cpp b/src/components/i2c/drivers/drvIna238.cpp new file mode 100644 index 000000000..456447484 --- /dev/null +++ b/src/components/i2c/drivers/drvIna238.cpp @@ -0,0 +1,82 @@ +/*! + * @file drvIna238.cpp + * + * Device driver for the INA238 High Precision DC Current and Voltage Monitor + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Tyeth Gundry 2025 for Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + * + */ + +#include "drvIna238.h" +#include + +/*******************************************************************************/ +/*! + @brief Destructor for an INA238 sensor. +*/ +/*******************************************************************************/ +drvIna238::~drvIna238() { + if (_ina238) { + delete _ina238; + _ina238 = nullptr; + } +} + +/*******************************************************************************/ +/*! + @brief Initializes the INA238 sensor and begins I2C. + @returns True if initialized successfully, False otherwise. +*/ +/*******************************************************************************/ +bool drvIna238::begin() { + _ina238 = new Adafruit_INA238(); + if (!_ina238->begin(_address, _i2c)) { + WS_DEBUG_PRINTLN("INA238 failed to initialise!"); + return false; + } + // TODO: use setCalibration() + + return true; +} + +/*******************************************************************************/ +/*! + @brief Reads a voltage sensor and converts the + reading into the expected SI unit. + @param voltageEvent + voltage sensor reading, in volts. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/*******************************************************************************/ +bool drvIna238::getEventVoltage(sensors_event_t *voltageEvent) { + voltageEvent->voltage = _ina238->getBusVoltage_V(); + return true; +} + +/** + * @brief Get the current sensor event. + * + * @param currentEvent Pointer to the current sensor event. + * + * @returns True if the sensor event was obtained successfully, False + * otherwise. + */ +bool drvIna238::getEventCurrent(sensors_event_t *currentEvent) { + currentEvent->current = _ina238->getCurrent_mA(); + return true; +} + +void drvIna238::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 2; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE; + _default_sensor_types[1] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_CURRENT; +} \ No newline at end of file diff --git a/src/components/i2c/drivers/drvIna238.h b/src/components/i2c/drivers/drvIna238.h new file mode 100644 index 000000000..f3d171997 --- /dev/null +++ b/src/components/i2c/drivers/drvIna238.h @@ -0,0 +1,89 @@ +/*! + * @file drvIna238.h + * + * Device driver for the INA238 High Precision DC Current and Voltage Monitor + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Tyeth Gundry 2025 for Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + * + */ +#ifndef DRV_INA238_H +#define DRV_INA238_H + +#include "drvBase.h" + +class Adafruit_INA238; + +/**************************************************************************/ +/*! + @brief Class that provides a driver interface for a INA238 sensor. +*/ +/**************************************************************************/ +class drvIna238 : public drvBase { +public: + /*******************************************************************************/ + /*! + @brief Constructor for a INA238 sensor. + @param i2c + The I2C interface. + @param sensorAddress + 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. + */ + /*******************************************************************************/ + drvIna238(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + + /*******************************************************************************/ + /*! + @brief Destructor for an INA238 sensor. + */ + /*******************************************************************************/ + ~drvIna238(); + + /*******************************************************************************/ + /*! + @brief Initializes the INA238 sensor and begins I2C. + @returns True if initialized successfully, False otherwise. + */ + /*******************************************************************************/ + bool begin(); + + /*******************************************************************************/ + /*! + @brief Reads a voltage sensor and converts the + reading into the expected SI unit. + @param voltageEvent + voltage sensor reading, in volts. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + bool getEventVoltage(sensors_event_t *voltageEvent); + + /** + * @brief Get the current sensor event. + * + * @param currentEvent Pointer to the current sensor event. + * + * @returns True if the sensor event was obtained successfully, False + * otherwise. + */ + bool getEventCurrent(sensors_event_t *currentEvent); + + void ConfigureDefaultSensorTypes() override; + +protected: + Adafruit_INA238 *_ina238; ///< Pointer to INA238 sensor object +}; + +#endif // DRV_INA238_H \ No newline at end of file diff --git a/src/components/i2c/drivers/drvIna260.cpp b/src/components/i2c/drivers/drvIna260.cpp new file mode 100644 index 000000000..a722434fb --- /dev/null +++ b/src/components/i2c/drivers/drvIna260.cpp @@ -0,0 +1,82 @@ +/*! + * @file drvIna260.cpp + * + * Device driver for the INA260 DC Current and Voltage Monitor + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Tyeth Gundry 2025 for Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + * + */ + +#include "drvIna260.h" +#include + +/*******************************************************************************/ +/*! + @brief Destructor for an INA260 sensor. +*/ +/*******************************************************************************/ +drvIna260::~drvIna260() { + if (_ina260) { + delete _ina260; + _ina260 = nullptr; + } +} + +/*******************************************************************************/ +/*! + @brief Initializes the INA260 sensor and begins I2C. + @returns True if initialized successfully, False otherwise. +*/ +/*******************************************************************************/ +bool drvIna260::begin() { + _ina260 = new Adafruit_INA260(); + if (!_ina260->begin(_address, _i2c)) { + WS_DEBUG_PRINTLN("INA260 failed to initialise!"); + return false; + } + // TODO: use setCalibration() + + return true; +} + +/*******************************************************************************/ +/*! + @brief Reads a voltage sensor and converts the + reading into the expected SI unit. + @param voltageEvent + voltage sensor reading, in volts. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/*******************************************************************************/ +bool drvIna260::getEventVoltage(sensors_event_t *voltageEvent) { + voltageEvent->voltage = _ina260->readBusVoltage(); + return true; +} + +/** + * @brief Get the current sensor event. + * + * @param currentEvent Pointer to the current sensor event. + * + * @returns True if the sensor event was obtained successfully, False + * otherwise. + */ +bool drvIna260::getEventCurrent(sensors_event_t *currentEvent) { + currentEvent->current = _ina260->readCurrent(); + return true; +} + +void drvIna260::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 2; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE; + _default_sensor_types[1] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_CURRENT; +} \ No newline at end of file diff --git a/src/components/i2c/drivers/drvIna260.h b/src/components/i2c/drivers/drvIna260.h index 5b4586290..dd2aaa68f 100644 --- a/src/components/i2c/drivers/drvIna260.h +++ b/src/components/i2c/drivers/drvIna260.h @@ -16,7 +16,8 @@ #define DRV_INA260_H #include "drvBase.h" -#include + +class Adafruit_INA260; /**************************************************************************/ /*! @@ -40,16 +41,14 @@ class drvIna260 : public drvBase { /*******************************************************************************/ drvIna260(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, const char *driver_name) - : drvBase(i2c, sensorAddress, mux_channel, driver_name) { - // Initialization handled by drvBase constructor - } + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} /*******************************************************************************/ /*! @brief Destructor for an INA260 sensor. */ /*******************************************************************************/ - ~drvIna260() { delete _ina260; } + ~drvIna260(); /*******************************************************************************/ /*! @@ -57,16 +56,7 @@ class drvIna260 : public drvBase { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { - _ina260 = new Adafruit_INA260(); - if (!_ina260->begin(_address, _i2c)) { - WS_DEBUG_PRINTLN("INA260 failed to initialise!"); - return false; - } - // TODO: use setCalibration() - - return true; - } + bool begin(); /*******************************************************************************/ /*! @@ -78,10 +68,7 @@ class drvIna260 : public drvBase { otherwise. */ /*******************************************************************************/ - bool getEventVoltage(sensors_event_t *voltageEvent) { - voltageEvent->voltage = _ina260->readBusVoltage(); - return true; - } + bool getEventVoltage(sensors_event_t *voltageEvent); /** * @brief Get the current sensor event. @@ -91,18 +78,9 @@ class drvIna260 : public drvBase { * @returns True if the sensor event was obtained successfully, False * otherwise. */ - bool getEventCurrent(sensors_event_t *currentEvent) { - currentEvent->current = _ina260->readCurrent(); - return true; - } + bool getEventCurrent(sensors_event_t *currentEvent); - void ConfigureDefaultSensorTypes() override { - _default_sensor_types_count = 2; - _default_sensor_types[0] = - wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE; - _default_sensor_types[1] = - wippersnapper_sensor_SensorType_SENSOR_TYPE_CURRENT; - } + void ConfigureDefaultSensorTypes() override; protected: Adafruit_INA260 *_ina260; ///< Pointer to INA260 sensor object From 38af67b863a74b7271da500fcd93369fd4d0a9ce Mon Sep 17 00:00:00 2001 From: tyeth Date: Wed, 13 Aug 2025 13:56:05 +0100 Subject: [PATCH 18/32] Add INA228, set INA2xx shunt/avg/conv.times --- src/components/i2c/controller.cpp | 13 ++-- src/components/i2c/controller.h | 1 + src/components/i2c/drivers/drvIna228.cpp | 91 ++++++++++++++++++++++++ src/components/i2c/drivers/drvIna228.h | 89 +++++++++++++++++++++++ src/components/i2c/drivers/drvIna237.cpp | 12 +++- src/components/i2c/drivers/drvIna238.cpp | 12 +++- src/components/i2c/drivers/drvIna260.cpp | 5 +- 7 files changed, 216 insertions(+), 7 deletions(-) create mode 100644 src/components/i2c/drivers/drvIna228.cpp create mode 100644 src/components/i2c/drivers/drvIna228.h diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 9f24bcbcc..44a041ed6 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -133,6 +133,11 @@ static const std::map I2cFactorySensor = { const char *driver_name) -> drvBase * { return new drvIna219(i2c, addr, mux_channel, driver_name); }}, + {"ina228", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvIna228(i2c, addr, mux_channel, driver_name); + }}, {"ina237", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { @@ -387,11 +392,11 @@ static const std::unordered_map> {0x38, {"aht20", "max17048"}}, {0x39, {"tsl2591"}}, {0x40, - {"htu21d", "htu31d", "ina219", "ina237", "ina238", "ina260", + {"htu21d", "htu31d", "ina219", "ina228", "ina237", "ina238", "ina260", "ms8607", "si7021", "stemma_soil"}}, - {0x41, {"htu31d", "ina219", "ina237", "ina238", "ina260"}}, - {0x44, {"hdc302x", "ina237", "ina238", "ina260", "sht3x", "sht4x"}}, - {0x45, {"hdc302x", "ina237", "ina238", "ina260", "sht3x"}}, + {0x41, {"htu31d", "ina219", "ina228", "ina237", "ina238", "ina260"}}, + {0x44, {"hdc302x", "ina228", "ina237", "ina238", "ina260", "sht3x", "sht4x"}}, + {0x45, {"hdc302x", "ina228", "ina237", "ina238", "ina260", "sht3x"}}, {0x46, {"hdc302x"}}, {0x47, {"hdc302x"}}, {0x48, {"adt7410", "pct2075", "tmp117"}}, diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index e35334f6f..eb41c5c22 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -33,6 +33,7 @@ #include "drivers/drvHts221.h" #include "drivers/drvHtu21d.h" #include "drivers/drvIna219.h" +#include "drivers/drvIna228.h" #include "drivers/drvIna237.h" #include "drivers/drvIna238.h" #include "drivers/drvIna260.h" diff --git a/src/components/i2c/drivers/drvIna228.cpp b/src/components/i2c/drivers/drvIna228.cpp new file mode 100644 index 000000000..6d9f2889d --- /dev/null +++ b/src/components/i2c/drivers/drvIna228.cpp @@ -0,0 +1,91 @@ +/*! + * @file drvIna228.cpp + * + * Device driver for the INA228 High Precision DC Current and Voltage Monitor + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Tyeth Gundry 2025 for Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + * + */ + +#include "drvIna228.h" +#include + +/*******************************************************************************/ +/*! + @brief Destructor for an INA228 sensor. +*/ +/*******************************************************************************/ +drvIna228::~drvIna228() { + if (_ina228) { + delete _ina228; + _ina228 = nullptr; + } +} + +/*******************************************************************************/ +/*! + @brief Initializes the INA228 sensor and begins I2C. + @returns True if initialized successfully, False otherwise. +*/ +/*******************************************************************************/ +bool drvIna228::begin() { + _ina228 = new Adafruit_INA228(); + if (!_ina228->begin(_address, _i2c)) { + WS_DEBUG_PRINTLN("INA228 failed to initialise!"); + return false; + } + + _ina228->setShunt(0.015, 10.0); + if (_ina228->getCurrentConversionTime() != INA228_TIME_280_us) { + _ina228->setCurrentConversionTime(INA228_TIME_280_us); + } + if (_ina228->getAveragingCount() != INA228_COUNT_16) { + _ina228->setAveragingCount(INA228_COUNT_16); + } + if (_ina228->getVoltageConversionTime() != INA228_TIME_150_us) { + _ina228->setVoltageConversionTime(INA228_TIME_150_us); + } + return true; +} + +/*******************************************************************************/ +/*! + @brief Reads a voltage sensor and converts the + reading into the expected SI unit. + @param voltageEvent + voltage sensor reading, in volts. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/*******************************************************************************/ +bool drvIna228::getEventVoltage(sensors_event_t *voltageEvent) { + voltageEvent->voltage = _ina228->getBusVoltage_V(); + return true; +} + +/** + * @brief Get the current sensor event. + * + * @param currentEvent Pointer to the current sensor event. + * + * @returns True if the sensor event was obtained successfully, False + * otherwise. + */ +bool drvIna228::getEventCurrent(sensors_event_t *currentEvent) { + currentEvent->current = _ina228->getCurrent_mA(); + return true; +} + +void drvIna228::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 2; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE; + _default_sensor_types[1] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_CURRENT; +} \ No newline at end of file diff --git a/src/components/i2c/drivers/drvIna228.h b/src/components/i2c/drivers/drvIna228.h new file mode 100644 index 000000000..05bc6b211 --- /dev/null +++ b/src/components/i2c/drivers/drvIna228.h @@ -0,0 +1,89 @@ +/*! + * @file drvIna228.h + * + * Device driver for the INA228 High Precision DC Current and Voltage Monitor + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Tyeth Gundry 2025 for Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + * + */ +#ifndef DRV_INA228_H +#define DRV_INA228_H + +#include "drvBase.h" + +class Adafruit_INA228; + +/**************************************************************************/ +/*! + @brief Class that provides a driver interface for a INA228 sensor. +*/ +/**************************************************************************/ +class drvIna228 : public drvBase { +public: + /*******************************************************************************/ + /*! + @brief Constructor for a INA228 sensor. + @param i2c + The I2C interface. + @param sensorAddress + 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. + */ + /*******************************************************************************/ + drvIna228(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + + /*******************************************************************************/ + /*! + @brief Destructor for an INA228 sensor. + */ + /*******************************************************************************/ + ~drvIna228(); + + /*******************************************************************************/ + /*! + @brief Initializes the INA228 sensor and begins I2C. + @returns True if initialized successfully, False otherwise. + */ + /*******************************************************************************/ + bool begin(); + + /*******************************************************************************/ + /*! + @brief Reads a voltage sensor and converts the + reading into the expected SI unit. + @param voltageEvent + voltage sensor reading, in volts. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + bool getEventVoltage(sensors_event_t *voltageEvent); + + /** + * @brief Get the current sensor event. + * + * @param currentEvent Pointer to the current sensor event. + * + * @returns True if the sensor event was obtained successfully, False + * otherwise. + */ + bool getEventCurrent(sensors_event_t *currentEvent); + + void ConfigureDefaultSensorTypes() override; + +protected: + Adafruit_INA228 *_ina228; ///< Pointer to INA228 sensor object +}; + +#endif // DRV_INA228_H \ No newline at end of file diff --git a/src/components/i2c/drivers/drvIna237.cpp b/src/components/i2c/drivers/drvIna237.cpp index 9bd70e9a1..49f04f061 100644 --- a/src/components/i2c/drivers/drvIna237.cpp +++ b/src/components/i2c/drivers/drvIna237.cpp @@ -40,7 +40,17 @@ bool drvIna237::begin() { WS_DEBUG_PRINTLN("INA237 failed to initialise!"); return false; } - // TODO: use setCalibration() + + _ina237->setShunt(0.015, 10.0); + if (_ina237->getCurrentConversionTime() != INA2XX_TIME_280_us) { + _ina237->setCurrentConversionTime(INA2XX_TIME_280_us); + } + if (_ina237->getAveragingCount() != INA2XX_COUNT_16) { + _ina237->setAveragingCount(INA2XX_COUNT_16); + } + if (_ina237->getVoltageConversionTime() != INA2XX_TIME_150_us) { + _ina237->setVoltageConversionTime(INA2XX_TIME_150_us); + } return true; } diff --git a/src/components/i2c/drivers/drvIna238.cpp b/src/components/i2c/drivers/drvIna238.cpp index 456447484..71ceff4cd 100644 --- a/src/components/i2c/drivers/drvIna238.cpp +++ b/src/components/i2c/drivers/drvIna238.cpp @@ -40,7 +40,17 @@ bool drvIna238::begin() { WS_DEBUG_PRINTLN("INA238 failed to initialise!"); return false; } - // TODO: use setCalibration() + + _ina238->setShunt(0.015, 10.0); + if (_ina238->getCurrentConversionTime() != INA2XX_TIME_280_us) { + _ina238->setCurrentConversionTime(INA2XX_TIME_280_us); + } + if (_ina238->getAveragingCount() != INA2XX_COUNT_16) { + _ina238->setAveragingCount(INA2XX_COUNT_16); + } + if (_ina238->getVoltageConversionTime() != INA2XX_TIME_150_us) { + _ina238->setVoltageConversionTime(INA2XX_TIME_150_us); + } return true; } diff --git a/src/components/i2c/drivers/drvIna260.cpp b/src/components/i2c/drivers/drvIna260.cpp index a722434fb..b58095006 100644 --- a/src/components/i2c/drivers/drvIna260.cpp +++ b/src/components/i2c/drivers/drvIna260.cpp @@ -40,7 +40,10 @@ bool drvIna260::begin() { WS_DEBUG_PRINTLN("INA260 failed to initialise!"); return false; } - // TODO: use setCalibration() + + _ina260->setAveragingCount(INA260_COUNT_16); + _ina260->setVoltageConversionTime(INA260_TIME_140_us); + _ina260->setCurrentConversionTime(INA260_TIME_140_us); return true; } From 9615ffbd59b69c637a47eaf67018908610c926f3 Mon Sep 17 00:00:00 2001 From: tyeth Date: Wed, 13 Aug 2025 18:26:21 +0100 Subject: [PATCH 19/32] clang-format --- src/components/i2c/controller.cpp | 3 ++- src/components/i2c/drivers/drvBase.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 44a041ed6..c0afa1b9f 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -395,7 +395,8 @@ static const std::unordered_map> {"htu21d", "htu31d", "ina219", "ina228", "ina237", "ina238", "ina260", "ms8607", "si7021", "stemma_soil"}}, {0x41, {"htu31d", "ina219", "ina228", "ina237", "ina238", "ina260"}}, - {0x44, {"hdc302x", "ina228", "ina237", "ina238", "ina260", "sht3x", "sht4x"}}, + {0x44, + {"hdc302x", "ina228", "ina237", "ina238", "ina260", "sht3x", "sht4x"}}, {0x45, {"hdc302x", "ina228", "ina237", "ina238", "ina260", "sht3x"}}, {0x46, {"hdc302x"}}, {0x47, {"hdc302x"}}, diff --git a/src/components/i2c/drivers/drvBase.h b/src/components/i2c/drivers/drvBase.h index cabb581ad..61ea61389 100644 --- a/src/components/i2c/drivers/drvBase.h +++ b/src/components/i2c/drivers/drvBase.h @@ -15,12 +15,12 @@ #ifndef DRV_BASE_H #define DRV_BASE_H +#include "helpers/ws_helper_macros.h" #include #include #include #include #include -#include "helpers/ws_helper_macros.h" #define NO_MUX_CH 0xFFFF; ///< No MUX channel specified #define DEFAULT_SENSOR_PERIOD 15.0f ///< Default sensor period, in seconds From ed15084c945a1e3f171dfde151d1286ea2f92719 Mon Sep 17 00:00:00 2001 From: tyeth Date: Wed, 13 Aug 2025 18:30:16 +0100 Subject: [PATCH 20/32] clang-format --- src/Wippersnapper_V2.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Wippersnapper_V2.h b/src/Wippersnapper_V2.h index d601c2997..9d3246c97 100644 --- a/src/Wippersnapper_V2.h +++ b/src/Wippersnapper_V2.h @@ -30,9 +30,7 @@ */ #ifdef WS_DEBUG #define WS_DEBUG_PRINT(...) \ - { \ - WS_PRINTER.print(__VA_ARGS__); \ - } /**< Print debug message to serial */ + { WS_PRINTER.print(__VA_ARGS__); } /**< Print debug message to serial */ #define WS_DEBUG_PRINTLN(...) \ { \ WS_PRINTER.println(__VA_ARGS__); \ @@ -44,11 +42,9 @@ } /**< Print debug message in hexadecimal */ #else #define WS_DEBUG_PRINT(...) \ - { \ - } /**< Debug print */ + {} /**< Debug print */ #define WS_DEBUG_PRINTLN(...) \ - { \ - } /**< Debug println */ + {} /**< Debug println */ #endif /*! From 8fdba6938a9c9589a4b4bdffbba08023cf4cbe4b Mon Sep 17 00:00:00 2001 From: tyeth Date: Wed, 13 Aug 2025 19:21:33 +0100 Subject: [PATCH 21/32] fix(INA260): millivolts returned by readBusVoltage --- src/components/i2c/drivers/drvIna260.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/i2c/drivers/drvIna260.cpp b/src/components/i2c/drivers/drvIna260.cpp index b58095006..c8bd39949 100644 --- a/src/components/i2c/drivers/drvIna260.cpp +++ b/src/components/i2c/drivers/drvIna260.cpp @@ -59,7 +59,7 @@ bool drvIna260::begin() { */ /*******************************************************************************/ bool drvIna260::getEventVoltage(sensors_event_t *voltageEvent) { - voltageEvent->voltage = _ina260->readBusVoltage(); + voltageEvent->voltage = _ina260->readBusVoltage() / 1000.0f; return true; } From f735ef01df7b9efe4853c272eee103aa78c9df22 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Wed, 13 Aug 2025 19:25:09 +0100 Subject: [PATCH 22/32] clang format --- src/components/i2c/controller.cpp | 2 +- src/components/i2c/drivers/drvIna228.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index c0afa1b9f..c5c547fd4 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -395,7 +395,7 @@ static const std::unordered_map> {"htu21d", "htu31d", "ina219", "ina228", "ina237", "ina238", "ina260", "ms8607", "si7021", "stemma_soil"}}, {0x41, {"htu31d", "ina219", "ina228", "ina237", "ina238", "ina260"}}, - {0x44, + {0x44, {"hdc302x", "ina228", "ina237", "ina238", "ina260", "sht3x", "sht4x"}}, {0x45, {"hdc302x", "ina228", "ina237", "ina238", "ina260", "sht3x"}}, {0x46, {"hdc302x"}}, diff --git a/src/components/i2c/drivers/drvIna228.cpp b/src/components/i2c/drivers/drvIna228.cpp index 6d9f2889d..4ecb26b0b 100644 --- a/src/components/i2c/drivers/drvIna228.cpp +++ b/src/components/i2c/drivers/drvIna228.cpp @@ -40,7 +40,7 @@ bool drvIna228::begin() { WS_DEBUG_PRINTLN("INA228 failed to initialise!"); return false; } - + _ina228->setShunt(0.015, 10.0); if (_ina228->getCurrentConversionTime() != INA228_TIME_280_us) { _ina228->setCurrentConversionTime(INA228_TIME_280_us); From 940d6c61966b1c12168390b303f96993d306b54b Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Wed, 13 Aug 2025 19:45:52 +0100 Subject: [PATCH 23/32] fix(rp2): include in i2c drvBase.h --- src/components/i2c/drivers/drvBase.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/i2c/drivers/drvBase.h b/src/components/i2c/drivers/drvBase.h index 61ea61389..bcde94908 100644 --- a/src/components/i2c/drivers/drvBase.h +++ b/src/components/i2c/drivers/drvBase.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include From 5ddf1e22c7ca9efb22df5b5053f82fcea5380122 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Wed, 13 Aug 2025 20:27:15 +0100 Subject: [PATCH 24/32] Add esp32s3 devkitc-1 N8, and XIAO S3 sense to build targets --- .github/workflows/release-offline.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-offline.yml b/.github/workflows/release-offline.yml index e1e73ea95..29d4bfbfd 100644 --- a/.github/workflows/release-offline.yml +++ b/.github/workflows/release-offline.yml @@ -96,6 +96,8 @@ jobs: "qtpy_esp32s2", "feather_esp32s3_reverse_tft", "qtpy_esp32s3_n4r2", + "esp32s3_devkitc_1_n8", + "xiao_esp32s3", ] steps: - uses: actions/setup-python@v5 @@ -259,9 +261,9 @@ jobs: name: Create new_flash_args file from flash_args with added app bin + output file run: | # Create new_flash_args with esptool parameters first and output file - echo "--flash-mode ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}}" > new_flash_args - echo "--flash-freq ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashFreq}}" >> new_flash_args - echo "--flash-size ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashSize}}" >> new_flash_args + echo "--flash-mode ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode || 'keep'}}" > new_flash_args + echo "--flash-freq ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashFreq || 'keep'}}" >> new_flash_args + echo "--flash-size ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashSize || 'keep'}}" >> new_flash_args echo "-o wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.combined.bin" >> new_flash_args # Append flash_args content to new_flash_args, skipping the first line From 4e15adb6c270f7cdffeba4c445c2d063aaf03a81 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Wed, 13 Aug 2025 20:28:31 +0100 Subject: [PATCH 25/32] Stop failing if no esptool section for board --- .github/workflows/release-offline.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/release-offline.yml b/.github/workflows/release-offline.yml index 29d4bfbfd..c59dfb208 100644 --- a/.github/workflows/release-offline.yml +++ b/.github/workflows/release-offline.yml @@ -222,8 +222,7 @@ jobs: run: | # check ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}} is not empty if [ -z "${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}}" ]; then - echo "Error: esptool.flashMode is not set in board definition." - exit 1 + echo "Error: esptool.flashMode is not set in board definition, using KEEP for all settings." fi BOARD_NAME="${{fromJson(steps.get_board_json.outputs.boardJson).bootloaderBoardName}}" for attempt in 1 2; do From 626e6f9597ee0f6e41ee011feea74aa42d3e523c Mon Sep 17 00:00:00 2001 From: tyeth Date: Wed, 13 Aug 2025 21:23:13 +0100 Subject: [PATCH 26/32] Add defaults for remaining fromJson esptool bits --- .github/workflows/release-offline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-offline.yml b/.github/workflows/release-offline.yml index c59dfb208..c04aa78f0 100644 --- a/.github/workflows/release-offline.yml +++ b/.github/workflows/release-offline.yml @@ -224,7 +224,7 @@ jobs: if [ -z "${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}}" ]; then echo "Error: esptool.flashMode is not set in board definition, using KEEP for all settings." fi - BOARD_NAME="${{fromJson(steps.get_board_json.outputs.boardJson).bootloaderBoardName}}" + BOARD_NAME="${{fromJson(steps.get_board_json.outputs.boardJson).bootloaderBoardName || matrix.arduino-platform}}" for attempt in 1 2; do echo "Attempt $attempt: Fetching tinyuf2 release info for board $BOARD_NAME" API_RESPONSE=$(curl --silent --fail https://api.github.com/repos/adafruit/tinyuf2/releases/latest) @@ -298,7 +298,7 @@ jobs: run: | echo ${{ steps.get_board_json.outputs.boardJson }} echo ${{ fromJson(steps.get_board_json.outputs.boardJson) }} - python3 -m esptool --chip ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.chip}} merge-bin @new_flash_args + python3 -m esptool --chip ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.chip || fromJson(steps.get_board_json.outputs.boardJson).mcuName}} merge-bin @new_flash_args - if: ${{ steps.get_tinyuf2.outcome == 'success' }} name: Zip build artifacts run: | From 50e8153b3d0b3cd480c93f2e4656ae65c055b63e Mon Sep 17 00:00:00 2001 From: tyeth Date: Wed, 13 Aug 2025 22:32:46 +0100 Subject: [PATCH 27/32] Test Skip and Generate files for Xiao + Espressif Devkit S3 --- examples/Wippersnapper_demo/.esp32s3_devkitc_1_n8.generate | 1 + examples/Wippersnapper_demo/.xiao_esp32s3.generate | 1 + .../.esp32s3_devkitc_1_n8.generate | 1 + .../Wippersnapper_demo_offline_netiface/.xiao_esp32s3.generate | 1 + .../.esp32s3_devkitc_1_n8.test.skip | 1 + .../.xiao_esp32s3.test.skip | 1 + examples/wippersnapper_debug/.esp32s3_devkitc_1_n8.test.skip | 1 + examples/wippersnapper_debug/.xiao_esp32s3.test.skip | 1 + 8 files changed, 8 insertions(+) create mode 100644 examples/Wippersnapper_demo/.esp32s3_devkitc_1_n8.generate create mode 100644 examples/Wippersnapper_demo/.xiao_esp32s3.generate create mode 100644 examples/Wippersnapper_demo_offline_netiface/.esp32s3_devkitc_1_n8.generate create mode 100644 examples/Wippersnapper_demo_offline_netiface/.xiao_esp32s3.generate create mode 100644 examples/Wippersnapper_demo_offline_nonetiface/.esp32s3_devkitc_1_n8.test.skip create mode 100644 examples/Wippersnapper_demo_offline_nonetiface/.xiao_esp32s3.test.skip create mode 100644 examples/wippersnapper_debug/.esp32s3_devkitc_1_n8.test.skip create mode 100644 examples/wippersnapper_debug/.xiao_esp32s3.test.skip diff --git a/examples/Wippersnapper_demo/.esp32s3_devkitc_1_n8.generate b/examples/Wippersnapper_demo/.esp32s3_devkitc_1_n8.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.esp32s3_devkitc_1_n8.generate @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo/.xiao_esp32s3.generate b/examples/Wippersnapper_demo/.xiao_esp32s3.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.xiao_esp32s3.generate @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline_netiface/.esp32s3_devkitc_1_n8.generate b/examples/Wippersnapper_demo_offline_netiface/.esp32s3_devkitc_1_n8.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline_netiface/.esp32s3_devkitc_1_n8.generate @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline_netiface/.xiao_esp32s3.generate b/examples/Wippersnapper_demo_offline_netiface/.xiao_esp32s3.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline_netiface/.xiao_esp32s3.generate @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline_nonetiface/.esp32s3_devkitc_1_n8.test.skip b/examples/Wippersnapper_demo_offline_nonetiface/.esp32s3_devkitc_1_n8.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline_nonetiface/.esp32s3_devkitc_1_n8.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline_nonetiface/.xiao_esp32s3.test.skip b/examples/Wippersnapper_demo_offline_nonetiface/.xiao_esp32s3.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline_nonetiface/.xiao_esp32s3.test.skip @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/.esp32s3_devkitc_1_n8.test.skip b/examples/wippersnapper_debug/.esp32s3_devkitc_1_n8.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.esp32s3_devkitc_1_n8.test.skip @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/.xiao_esp32s3.test.skip b/examples/wippersnapper_debug/.xiao_esp32s3.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.xiao_esp32s3.test.skip @@ -0,0 +1 @@ + From 890a87beec6ce860f67a1f34076fdcb677533513 Mon Sep 17 00:00:00 2001 From: tyeth Date: Wed, 13 Aug 2025 23:57:00 +0100 Subject: [PATCH 28/32] Support no default CS pin for espressif S3 devkit --- src/Wippersnapper_Boards.h | 6 ++++++ src/provisioning/sdcard/ws_sdcard.cpp | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/Wippersnapper_Boards.h b/src/Wippersnapper_Boards.h index b9eff6217..21e5a675e 100644 --- a/src/Wippersnapper_Boards.h +++ b/src/Wippersnapper_Boards.h @@ -283,4 +283,10 @@ #warning "Board type not identified within Wippersnapper_Boards.h!" #endif +#ifndef SD_CS_PIN +#warning \ + "SD_CS_PIN not defined! Double check board definition in Wippersnapper_Boards.h as user will be forced to specify in config.json" +#define SD_CS_PIN SD_CS_CFG_NOT_FOUND // No default CS pin +#endif + #endif // ADAFRUIT_WIPPERSNAPPER_BOARDS_H diff --git a/src/provisioning/sdcard/ws_sdcard.cpp b/src/provisioning/sdcard/ws_sdcard.cpp index 6cb61e9b9..c167fffa1 100644 --- a/src/provisioning/sdcard/ws_sdcard.cpp +++ b/src/provisioning/sdcard/ws_sdcard.cpp @@ -22,6 +22,11 @@ otherwise. */ bool ws_sdcard::InitSdCard(uint8_t pin_cs) { + if (pin_cs == SD_CS_CFG_NOT_FOUND) { + WS_DEBUG_PRINT("[SD] Init Error: CS pin is undefined. Add \"sd_cs_pin\" to " + "exportedFromDevice section of config.json file."); + return false; + } WsV2.pin_sd_cs = pin_cs; #ifdef SD_USE_SPI_1 SdSpiConfig _sd_spi_cfg(pin_cs, DEDICATED_SPI, SPI_SD_CLOCK, &SPI1); From b04f17ceb9ffd370571fd2f9b4b126bd78c7f4a7 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Thu, 14 Aug 2025 15:21:48 +0100 Subject: [PATCH 29/32] fix(hdc302x): Add strcmp for hdc302x + header --- examples/Wippersnapper_NoFS/.esp32s3_devkitc_1_n8.test.skip | 1 + examples/Wippersnapper_NoFS/.xiao_esp32s3.test.skip | 1 + src/components/i2c/controller.cpp | 5 +++++ src/components/i2c/controller.h | 1 + 4 files changed, 8 insertions(+) create mode 100644 examples/Wippersnapper_NoFS/.esp32s3_devkitc_1_n8.test.skip create mode 100644 examples/Wippersnapper_NoFS/.xiao_esp32s3.test.skip diff --git a/examples/Wippersnapper_NoFS/.esp32s3_devkitc_1_n8.test.skip b/examples/Wippersnapper_NoFS/.esp32s3_devkitc_1_n8.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_NoFS/.esp32s3_devkitc_1_n8.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_NoFS/.xiao_esp32s3.test.skip b/examples/Wippersnapper_NoFS/.xiao_esp32s3.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_NoFS/.xiao_esp32s3.test.skip @@ -0,0 +1 @@ + diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index c5c547fd4..4463f8174 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -118,6 +118,11 @@ static const std::map I2cFactorySensor = { const char *driver_name) -> drvBase * { return new drvEns160(i2c, addr, mux_channel, driver_name); }}, + {"hdc302x", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvHdc302x(i2c, addr, mux_channel, driver_name); + }}, {"hts221", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index eb41c5c22..77fe318fb 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -30,6 +30,7 @@ #include "drivers/drvDps310.h" #include "drivers/drvDs2484.h" #include "drivers/drvEns160.h" +#include "drivers/drvHdc302x.h" #include "drivers/drvHts221.h" #include "drivers/drvHtu21d.h" #include "drivers/drvIna219.h" From 355a444e4b0f615263bfe3f19386730417f19958 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Thu, 14 Aug 2025 15:51:04 +0100 Subject: [PATCH 30/32] Swap boards to offline-mode branch --- .github/workflows/release-offline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-offline.yml b/.github/workflows/release-offline.yml index c04aa78f0..e83f1400f 100644 --- a/.github/workflows/release-offline.yml +++ b/.github/workflows/release-offline.yml @@ -119,7 +119,7 @@ jobs: with: repository: adafruit/Wippersnapper_Boards path: ws-boards - ref: rebased-rp2040_datalogger_feather + ref: offline-mode - name: Install CI-Arduino run: bash ci/actions_install.sh - name: Install extra Arduino libraries From 3090f58e33216339262779726d251c3c00cc94ca Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 14 Aug 2025 17:19:50 +0100 Subject: [PATCH 31/32] Drop arch specific SD CS pins --- src/ws_adapters.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/ws_adapters.h b/src/ws_adapters.h index 0faf4951a..7e240232b 100644 --- a/src/ws_adapters.h +++ b/src/ws_adapters.h @@ -22,21 +22,17 @@ #if defined(ADAFRUIT_METRO_M4_EXPRESS) || \ defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE) || defined(ADAFRUIT_PYPORTAL) || \ defined(ADAFRUIT_PYPORTAL_M4_TITANO) || defined(USE_AIRLIFT) -#define SD_CS_PIN 10 #include "adapters/wifi/ws_wifi_airlift.h" typedef ws_wifi_airlift ws_adapter_wifi; // ESP8266 networking adapter #elif defined(ARDUINO_ARCH_ESP8266) -#define SD_CS_PIN 15 #include "adapters/wifi/ws_wifi_esp8266.h" typedef ws_wifi_esp8266 ws_adapter_wifi; #elif defined(ARDUINO_ESP32_DEV) || defined(ESP32_DEV) -#define SD_CS_PIN 15 #include "adapters/wifi/ws_wifi_esp32.h" typedef ws_wifi_esp32 ws_adapter_wifi; // ESP32 networking adapter #elif defined(ARDUINO_ARCH_ESP32) -#define SD_CS_PIN 33 #include "adapters/wifi/ws_wifi_esp32.h" typedef ws_wifi_esp32 ws_adapter_wifi; // Networking adapters for Raspberry Pi Pico W-series @@ -46,7 +42,6 @@ typedef ws_wifi_esp32 ws_adapter_wifi; typedef ws_wifi_pico ws_adapter_wifi; // Networking adapter for Arduino Nano 33 IoT and MKR WiFi 1010 #elif defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRWIFI1010) -#define SD_CS_PIN 33 #include "adapters/wifi/ws_wifi_ninafw.h" typedef ws_wifi_ninafw ws_adapter_wifi; /** @@ -57,7 +52,6 @@ typedef ws_wifi_ninafw ws_adapter_wifi; defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER) || \ defined(ARDUINO_ADAFRUIT_METRO_RP2350) #define WS_OFFLINE_ADAPTER -#define SD_CS_PIN 23 #include "adapters/offline/ws_offline_pico.h" typedef ws_offline_pico ws_adapter_offline; #else From 346c4c033a672ae7666191e76190537ae8a1b171 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Thu, 14 Aug 2025 19:52:54 +0100 Subject: [PATCH 32/32] Address PR feedback from @brentru --- .github/workflows/build-clang-doxy.yml | 10 +--------- src/components/i2c/drivers/drvD6t1a.h | 9 +-------- src/components/i2c/drivers/drvIna219.h | 2 +- src/components/i2c/drivers/drvIna228.h | 2 +- src/components/i2c/drivers/drvIna237.h | 2 +- src/components/i2c/drivers/drvIna238.h | 2 +- src/components/i2c/drivers/drvIna260.h | 2 +- 7 files changed, 7 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build-clang-doxy.yml b/.github/workflows/build-clang-doxy.yml index 5258c1f91..e26361c18 100644 --- a/.github/workflows/build-clang-doxy.yml +++ b/.github/workflows/build-clang-doxy.yml @@ -38,14 +38,6 @@ jobs: ] steps: - - name: "skip if unwanted" - continue-on-error: true - if: | - github.event_name == 'workflow_dispatch' && - github.event.inputs.board != '' && - matrix.arduino-platform != github.event.inputs.board - run: | - echo "don't build this one!"; exit 1 - uses: actions/setup-python@v5 with: python-version: "3.x" @@ -70,7 +62,7 @@ jobs: - name: Install extra Arduino libraries run: | git clone --quiet https://github.com/pstolarz/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library - git clone --quiet --branch 2.2.54 https://github.com/adafruit/SdFat.git /home/runner/Arduino/libraries/SdFat + git clone --quiet https://github.com/adafruit/SdFat.git /home/runner/Arduino/libraries/SdFat git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg git clone --quiet https://github.com/adafruit/Adafruit_HX8357_Library.git /home/runner/Arduino/libraries/Adafruit_HX8357_Library git clone --quiet https://github.com/adafruit/Adafruit_ILI9341.git /home/runner/Arduino/libraries/Adafruit_ILI9341 diff --git a/src/components/i2c/drivers/drvD6t1a.h b/src/components/i2c/drivers/drvD6t1a.h index aaf788dbe..71d8b12d6 100644 --- a/src/components/i2c/drivers/drvD6t1a.h +++ b/src/components/i2c/drivers/drvD6t1a.h @@ -39,11 +39,6 @@ class drvD6t1a : public drvBase { drvD6t1a(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, const char *driver_name) : drvBase(i2c, sensorAddress, mux_channel, driver_name) { - _i2c = i2c; - _address = sensorAddress; - _i2c_mux_channel = mux_channel; - strncpy(_name, driver_name, sizeof(_name) - 1); - _name[sizeof(_name) - 1] = '\0'; _deviceTemp = NAN; _objectTemp = NAN; _lastRead = 0; @@ -61,9 +56,7 @@ class drvD6t1a : public drvBase { */ bool begin() override { _d6t1a = new OmronD6T(OmronD6T::D6T_1A, _i2c); - if (!_d6t1a->begin(_address)) - return false; - return true; + return _d6t1a->begin(_address); } /*! diff --git a/src/components/i2c/drivers/drvIna219.h b/src/components/i2c/drivers/drvIna219.h index 5fd7851ba..11b13e7c0 100644 --- a/src/components/i2c/drivers/drvIna219.h +++ b/src/components/i2c/drivers/drvIna219.h @@ -100,7 +100,7 @@ class drvIna219 : public drvBase { } protected: - Adafruit_INA219 *_ina219; ///< Pointer to INA219 sensor object + Adafruit_INA219 *_ina219 = nullptr; ///< Pointer to INA219 sensor object }; #endif // drvIna219 \ No newline at end of file diff --git a/src/components/i2c/drivers/drvIna228.h b/src/components/i2c/drivers/drvIna228.h index 05bc6b211..d6f7cc8c5 100644 --- a/src/components/i2c/drivers/drvIna228.h +++ b/src/components/i2c/drivers/drvIna228.h @@ -83,7 +83,7 @@ class drvIna228 : public drvBase { void ConfigureDefaultSensorTypes() override; protected: - Adafruit_INA228 *_ina228; ///< Pointer to INA228 sensor object + Adafruit_INA228 *_ina228 = nullptr; ///< Pointer to INA228 sensor object }; #endif // DRV_INA228_H \ No newline at end of file diff --git a/src/components/i2c/drivers/drvIna237.h b/src/components/i2c/drivers/drvIna237.h index 15a522e05..45e06e023 100644 --- a/src/components/i2c/drivers/drvIna237.h +++ b/src/components/i2c/drivers/drvIna237.h @@ -83,7 +83,7 @@ class drvIna237 : public drvBase { void ConfigureDefaultSensorTypes() override; protected: - Adafruit_INA237 *_ina237; ///< Pointer to INA237 sensor object + Adafruit_INA237 *_ina237 = nullptr; ///< Pointer to INA237 sensor object }; #endif // DRV_INA237_H \ No newline at end of file diff --git a/src/components/i2c/drivers/drvIna238.h b/src/components/i2c/drivers/drvIna238.h index f3d171997..a99d62c14 100644 --- a/src/components/i2c/drivers/drvIna238.h +++ b/src/components/i2c/drivers/drvIna238.h @@ -83,7 +83,7 @@ class drvIna238 : public drvBase { void ConfigureDefaultSensorTypes() override; protected: - Adafruit_INA238 *_ina238; ///< Pointer to INA238 sensor object + Adafruit_INA238 *_ina238 = nullptr; ///< Pointer to INA238 sensor object }; #endif // DRV_INA238_H \ No newline at end of file diff --git a/src/components/i2c/drivers/drvIna260.h b/src/components/i2c/drivers/drvIna260.h index dd2aaa68f..c128f2c3b 100644 --- a/src/components/i2c/drivers/drvIna260.h +++ b/src/components/i2c/drivers/drvIna260.h @@ -83,7 +83,7 @@ class drvIna260 : public drvBase { void ConfigureDefaultSensorTypes() override; protected: - Adafruit_INA260 *_ina260; ///< Pointer to INA260 sensor object + Adafruit_INA260 *_ina260 = nullptr; ///< Pointer to INA260 sensor object }; #endif // DRV_INA260_H \ No newline at end of file