diff --git a/.github/workflows/build-clang-doxy.yml b/.github/workflows/build-clang-doxy.yml index 7a7987c2b..e26361c18 100644 --- a/.github/workflows/build-clang-doxy.yml +++ b/.github/workflows/build-clang-doxy.yml @@ -20,9 +20,23 @@ 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: - uses: actions/setup-python@v5 with: @@ -48,6 +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 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 @@ -106,6 +121,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 +137,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 +198,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 +236,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 diff --git a/.github/workflows/release-offline.yml b/.github/workflows/release-offline.yml index 8e3c8808d..e83f1400f 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 @@ -112,6 +114,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: offline-mode - name: Install CI-Arduino run: bash ci/actions_install.sh - name: Install extra Arduino libraries @@ -161,23 +169,153 @@ 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, using KEEP for all settings." + fi + 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) + 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 || '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 + 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 || fromJson(steps.get_board_json.outputs.boardJson).mcuName}} 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 diff --git a/.gitignore b/.gitignore index c8c95f2de..986b733b3 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,8 @@ html/* 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/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/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 @@ + diff --git a/library.properties b/library.properties index 810670201..216e3eafb 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 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 c3c5fd565..918513681 100644 --- a/platformio.ini +++ b/platformio.ini @@ -20,15 +20,15 @@ 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 ; 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 @@ -39,11 +39,12 @@ 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 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 +69,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 +82,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 @@ -341,26 +346,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..21e5a675e 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,8 +259,34 @@ #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 +// expansion board breakout (OLED/SD/RTC-PCF8563) +#define SD_CS_PIN 21 #else #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/Wippersnapper_V2.cpp b/src/Wippersnapper_V2.cpp index 9bf541f58..06e565538 100644 --- a/src/Wippersnapper_V2.cpp +++ b/src/Wippersnapper_V2.cpp @@ -845,7 +845,8 @@ void Wippersnapper_V2::runNetFSMV2() { #ifdef USE_DISPLAY WsV2._ui_helperV2->show_scr_error( "CONNECTION ERROR", - "Unable to connect to WiFi Network. Please check that you entered " + "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...", @@ -882,8 +883,8 @@ void Wippersnapper_V2::runNetFSMV2() { 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..."); + WS_DEBUG_PRINTLN("Unable to connect to Adafruit IO MQTT, retrying in 3 " + "seconds..."); delay(3000); maxAttempts--; } @@ -892,7 +893,8 @@ void Wippersnapper_V2::runNetFSMV2() { 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 " + "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 @@ -957,7 +959,6 @@ void Wippersnapper_V2::haltErrorV2(const char *error, False otherwise. */ bool Wippersnapper_V2::PublishSignal(pb_size_t which_payload, void *payload) { - #ifdef DEBUG_PROFILE unsigned long total_start_time = micros(); #endif @@ -1295,7 +1296,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 diff --git a/src/Wippersnapper_V2.h b/src/Wippersnapper_V2.h index 97187cb0b..9d3246c97 100644 --- a/src/Wippersnapper_V2.h +++ b/src/Wippersnapper_V2.h @@ -73,19 +73,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" @@ -220,6 +222,8 @@ 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 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/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 538a8c8c6..4463f8174 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 * { @@ -113,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 * { @@ -128,6 +138,26 @@ 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 * { + 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 * { @@ -346,6 +376,7 @@ static const std::map I2cFactorySensor = { static const std::unordered_map> map_address_to_drivers = { + {0x0A, {"d6t1a"}}, {0x0B, {"lc709203f"}}, {0x12, {"pmsa003i"}}, {0x13, {"vncl4020"}}, @@ -366,11 +397,12 @@ 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", "ina228", "ina237", "ina238", "ina260", + "ms8607", "si7021", "stemma_soil"}}, + {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"}}, @@ -1048,8 +1080,12 @@ 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 || + 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!"); diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 6390365ed..77fe318fb 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -26,12 +26,18 @@ #include "drivers/drvBme680.h" #include "drivers/drvBmp280.h" #include "drivers/drvBmp3xx.h" +#include "drivers/drvD6t1a.h" #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" +#include "drivers/drvIna228.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..bcde94908 100644 --- a/src/components/i2c/drivers/drvBase.h +++ b/src/components/i2c/drivers/drvBase.h @@ -15,8 +15,12 @@ #ifndef DRV_BASE_H #define DRV_BASE_H +#include "helpers/ws_helper_macros.h" #include #include +#include +#include +#include #include #define NO_MUX_CH 0xFFFF; ///< No MUX channel specified diff --git a/src/components/i2c/drivers/drvD6t1a.h b/src/components/i2c/drivers/drvD6t1a.h new file mode 100644 index 000000000..71d8b12d6 --- /dev/null +++ b/src/components/i2c/drivers/drvD6t1a.h @@ -0,0 +1,130 @@ +/*! + * @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 + +#include "drvBase.h" + +/*! + @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) { + _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); + return _d6t1a->begin(_address); + } + + /*! + @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 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.cpp b/src/components/i2c/drivers/drvIna228.cpp new file mode 100644 index 000000000..4ecb26b0b --- /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..d6f7cc8c5 --- /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 = nullptr; ///< 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 new file mode 100644 index 000000000..49f04f061 --- /dev/null +++ b/src/components/i2c/drivers/drvIna237.cpp @@ -0,0 +1,92 @@ +/*! + * @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; + } + + _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; +} + +/*******************************************************************************/ +/*! + @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..45e06e023 --- /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 = nullptr; ///< 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..71ceff4cd --- /dev/null +++ b/src/components/i2c/drivers/drvIna238.cpp @@ -0,0 +1,92 @@ +/*! + * @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; + } + + _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; +} + +/*******************************************************************************/ +/*! + @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..a99d62c14 --- /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 = nullptr; ///< 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..c8bd39949 --- /dev/null +++ b/src/components/i2c/drivers/drvIna260.cpp @@ -0,0 +1,85 @@ +/*! + * @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; + } + + _ina260->setAveragingCount(INA260_COUNT_16); + _ina260->setVoltageConversionTime(INA260_TIME_140_us); + _ina260->setCurrentConversionTime(INA260_TIME_140_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 drvIna260::getEventVoltage(sensors_event_t *voltageEvent) { + voltageEvent->voltage = _ina260->readBusVoltage() / 1000.0f; + 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..c128f2c3b 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,21 +78,12 @@ 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 + Adafruit_INA260 *_ina260 = nullptr; ///< Pointer to INA260 sensor object }; #endif // DRV_INA260_H \ No newline at end of file diff --git a/src/provisioning/sdcard/ws_sdcard.cpp b/src/provisioning/sdcard/ws_sdcard.cpp index 090fb8008..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); @@ -179,7 +184,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 +257,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(); } @@ -829,6 +861,10 @@ bool ws_sdcard::ParseExportedFromDevice(JsonDocument &doc) { return false; } + bool global_auto_config = true; + global_auto_config = exportedFromDevice["autoConfig"].as(); + WsV2._global_auto_config = global_auto_config; + return true; } @@ -889,6 +925,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 " @@ -1014,6 +1056,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 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) || \ diff --git a/src/ws_adapters.h b/src/ws_adapters.h index d2bcf87bb..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; /** @@ -56,11 +51,15 @@ typedef ws_wifi_ninafw ws_adapter_wifi; defined(ARDUINO_RASPBERRY_PI_PICO) || \ defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER) || \ defined(ARDUINO_ADAFRUIT_METRO_RP2350) -#define SD_CS_PIN 23 +#define WS_OFFLINE_ADAPTER #include "adapters/offline/ws_offline_pico.h" typedef ws_offline_pico ws_adapter_offline; #else #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