diff --git a/.github/workflows/build-clang-doxy.yml b/.github/workflows/build-clang-doxy.yml index 7c1c7c210..b746a8446 100644 --- a/.github/workflows/build-clang-doxy.yml +++ b/.github/workflows/build-clang-doxy.yml @@ -13,7 +13,7 @@ on: jobs: build-esp32sx-esptool: - name: Build WipperSnapper ESP32-Sx + name: 🏗️ESP32-Sx(lvgl) runs-on: ubuntu-latest strategy: fail-fast: false @@ -22,7 +22,7 @@ jobs: include: - offset: "0x1000" steps: - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: actions/checkout@v4 @@ -34,6 +34,7 @@ jobs: - uses: actions/checkout@v4 with: repository: adafruit/ci-arduino + ref: ci-wippersnapper path: ci - name: Checkout Board Definitions uses: actions/checkout@v4 @@ -51,12 +52,34 @@ jobs: git clone --quiet https://github.com/adafruit/Adafruit_STMPE610.git /home/runner/Arduino/libraries/Adafruit_STMPE610 git clone --quiet https://github.com/adafruit/Adafruit-ST7735-Library.git /home/runner/Arduino/libraries/Adafruit-ST7735-Library git clone --quiet https://github.com/adafruit/Adafruit_TouchScreen.git /home/runner/Arduino/libraries/Adafruit_TouchScreen + git clone --quiet https://github.com/adafruit/Adafruit_TinyUSB_Arduino /home/runner/Arduino/libraries/Adafruit_TinyUSB_Arduino git clone --depth 1 --branch wippersnapper https://github.com/brentru/lvgl.git /home/runner/Arduino/libraries/lvgl git clone --depth 1 --branch development https://github.com/brentru/Adafruit_LvGL_Glue.git /home/runner/Arduino/libraries/Adafruit_LittlevGL_Glue_Library - - name: Download and install stable Nanopb + - name: Download stable Nanopb + id: download-nanopb + continue-on-error: true run: | - # Download and extract nanopb wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8.tar.gz + - if: ${{ failure() || steps.download-nanopb.outcome != 'success' }} + name: Restore cached nanopb + id: cache-nanopb-restore + uses: actions/cache/restore@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - if: ${{ steps.download-nanopb.outcome == 'success' }} + name: Save nanopb to cache + id: cache-nanopb-save + uses: actions/cache/save@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - name: Install stable Nanopb + run: | tar -xf nanopb-0.4.8.tar.gz # Copy files to WipperSnapper's src/nanopb directory cp nanopb/pb_common.* nanopb/pb_encode.* nanopb/pb_decode.* src/nanopb @@ -70,7 +93,7 @@ jobs: - name: Install Dependencies (esptool) run: | pip3 install esptool - - name: Build for ESP32-SX + - name: Build for ESP32-SX (esptool) run: python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 - name: list files run: | @@ -96,14 +119,19 @@ jobs: echo $content echo EOF } >> "$GITHUB_OUTPUT" - - name: list arduino esp32 core files - run: | - ls /home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions - name: Check boot_app0 file existence (esp32sx built from core, not-source) id: check_files - uses: andstor/file-existence-action@v2 + uses: andstor/file-existence-action@v3 with: files: "/home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions/boot_app0.bin" + - name: list arduino esp32 core files + if: steps.check_files.outputs.files_exists == 'true' + run: | + ls /home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions + - name: list arduino esp32 bsp core files + if: steps.check_files.outputs.files_exists == 'false' + run: | + 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 @@ -126,24 +154,24 @@ jobs: - name: Zip build artifacts run: | zip -r wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.zip wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.* - - name: upload build artifacts zip - uses: actions/upload-artifact@v3 + - name: Upload build artifacts zip + uses: actions/upload-artifact@v4 with: - name: build-files + name: build-files-${{ matrix.arduino-platform }}-zip path: | wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.zip - name: Rename build artifacts to reflect the platform name run: | mv examples/*/build/*/Wippersnapper_demo.ino.uf2 wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 - - name: upload build artifacts - uses: actions/upload-artifact@v3 + - name: Upload build artifact UF2 file + uses: actions/upload-artifact@v4 with: - name: build-files + name: build-files-${{ matrix.arduino-platform }}-uf2 path: | wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 build-esp32sx: - name: Build WipperSnapper ESP32-Sx + name: 🏗️ESP32-Sx runs-on: ubuntu-latest strategy: fail-fast: false @@ -152,6 +180,7 @@ jobs: [ "magtag", "metroesp32s2", + "metro_esp32s3", "feather_esp32s2", "feather_esp32s2_tft", "feather_esp32s2_reverse_tft", @@ -164,7 +193,7 @@ jobs: "qtpy_esp32s3_n4r2", ] steps: - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: actions/checkout@v4 @@ -176,6 +205,7 @@ jobs: - uses: actions/checkout@v4 with: repository: adafruit/ci-arduino + ref: ci-wippersnapper path: ci - name: Install CI-Arduino run: bash ci/actions_install.sh @@ -188,12 +218,34 @@ jobs: git clone --quiet https://github.com/adafruit/Adafruit_STMPE610.git /home/runner/Arduino/libraries/Adafruit_STMPE610 git clone --quiet https://github.com/adafruit/Adafruit-ST7735-Library.git /home/runner/Arduino/libraries/Adafruit-ST7735-Library git clone --quiet https://github.com/adafruit/Adafruit_TouchScreen.git /home/runner/Arduino/libraries/Adafruit_TouchScreen + git clone --quiet https://github.com/adafruit/Adafruit_TinyUSB_Arduino /home/runner/Arduino/libraries/Adafruit_TinyUSB_Arduino git clone --depth 1 --branch wippersnapper https://github.com/brentru/lvgl.git /home/runner/Arduino/libraries/lvgl git clone --depth 1 --branch development https://github.com/brentru/Adafruit_LvGL_Glue.git /home/runner/Arduino/libraries/Adafruit_LittlevGL_Glue_Library - - name: Download and install stable Nanopb + - name: Download stable Nanopb + id: download-nanopb + continue-on-error: true run: | - # Download and extract nanopb wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8.tar.gz + - if: ${{ failure() || steps.download-nanopb.outcome != 'success' }} + name: Restore cached nanopb + id: cache-nanopb-restore + uses: actions/cache/restore@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - if: ${{ steps.download-nanopb.outcome == 'success' }} + name: Save nanopb to cache + id: cache-nanopb-save + uses: actions/cache/save@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - name: Install stable Nanopb + run: | tar -xf nanopb-0.4.8.tar.gz # Copy files to WipperSnapper's src/nanopb directory cp nanopb/pb_common.* nanopb/pb_encode.* nanopb/pb_decode.* src/nanopb @@ -205,25 +257,25 @@ jobs: run: | cp /home/runner/Arduino/libraries/Adafruit_LittlevGL_Glue_Library/lv_conf.h /home/runner/Arduino/libraries - name: Build for ESP32-SX - run: python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 - - name: list run: | - ls - ls examples/*/build/ + python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 + - name: list files (tree) + run: | + tree - name: Rename build artifacts to reflect the platform name run: | mv examples/*/build/*/Wippersnapper_demo.ino.uf2 wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 mv examples/*/build/*/Wippersnapper_demo.ino.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.bin - name: upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: build-files + 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-esp32: - name: Build WipperSnapper ESP32, ESP32-C3 + name: 🏗️ESP32/Cx runs-on: ubuntu-latest strategy: fail-fast: false @@ -235,13 +287,16 @@ jobs: "feather_esp32_v2", "itsybitsy_esp32", "wippersnapper_qtpy_esp32c3", + "wippersnapper_feather_esp32c6" ] include: - offset: "0x1000" - offset: "0x0" arduino-platform: "wippersnapper_qtpy_esp32c3" + - offset: "0x0" + arduino-platform: "wippersnapper_feather_esp32c6" steps: - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: actions/checkout@v4 @@ -253,6 +308,7 @@ jobs: - uses: actions/checkout@v4 with: repository: adafruit/ci-arduino + ref: ci-wippersnapper path: ci - name: Checkout Board Definitions uses: actions/checkout@v4 @@ -265,17 +321,38 @@ jobs: run: | git clone --quiet 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 - - name: Download and install stable Nanopb + - name: Download stable Nanopb + id: download-nanopb + continue-on-error: true run: | - # Download and extract nanopb wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8.tar.gz + - if: ${{ failure() || steps.download-nanopb.outcome != 'success' }} + name: Restore cached nanopb + id: cache-nanopb-restore + uses: actions/cache/restore@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - if: ${{ steps.download-nanopb.outcome == 'success' }} + name: Save nanopb to cache + id: cache-nanopb-save + uses: actions/cache/save@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - name: Install stable Nanopb + run: | tar -xf nanopb-0.4.8.tar.gz # Copy files to WipperSnapper's src/nanopb directory cp nanopb/pb_common.* nanopb/pb_encode.* nanopb/pb_decode.* src/nanopb mv nanopb/pb.h src/nanopb/nanopb.pb.h - name: Install Dependencies run: | - pip3 install esptool + pip install esptool==4.6 - name: build ESP32 platforms run: python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 - name: Check artifacts @@ -290,7 +367,7 @@ jobs: mv examples/Wippersnapper_demo/build/*/Wippersnapper_demo.ino.partitions.bin wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.partitions.bin - name: Check boot_app0 file existence (esp32 built from core, not-source) id: check_files - uses: andstor/file-existence-action@v2 + uses: andstor/file-existence-action@v3 with: files: "/home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions/boot_app0.bin" - name: boot_app0 file from arduino-cli core @@ -330,14 +407,14 @@ jobs: run: | zip -r wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.zip wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.* - name: upload build artifacts zip - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: build-files + name: build-files-${{ matrix.arduino-platform }}.${{ env.WS_VERSION }} path: | wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.zip build-samd: - name: Build WipperSnapper SAMD + name: 🏗️SAMD runs-on: ubuntu-latest strategy: fail-fast: false @@ -349,7 +426,7 @@ jobs: "metro_m4_airliftlite_tinyusb", ] steps: - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: actions/checkout@v4 @@ -361,6 +438,7 @@ jobs: - uses: actions/checkout@v4 with: repository: adafruit/ci-arduino + ref: ci-wippersnapper path: ci - name: Install CI-Arduino run: bash ci/actions_install.sh @@ -370,37 +448,59 @@ jobs: git clone --quiet https://github.com/adafruit/WiFiNINA.git /home/runner/Arduino/libraries/WiFiNINA git clone --quiet https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library git clone --quiet https://github.com/PaulStoffregen/OneWire.git /home/runner/Arduino/libraries/OneWire - - name: Download and install stable Nanopb + git clone --quiet https://github.com/adafruit/Adafruit_TinyUSB_Arduino /home/runner/Arduino/libraries/Adafruit_TinyUSB_Arduino + - name: Download stable Nanopb + id: download-nanopb + continue-on-error: true run: | - # Download and extract nanopb wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8.tar.gz + - if: ${{ failure() || steps.download-nanopb.outcome != 'success' }} + name: Restore cached nanopb + id: cache-nanopb-restore + uses: actions/cache/restore@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - if: ${{ steps.download-nanopb.outcome == 'success' }} + name: Save nanopb to cache + id: cache-nanopb-save + uses: actions/cache/save@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - name: Install stable Nanopb + run: | tar -xf nanopb-0.4.8.tar.gz # Copy files to WipperSnapper's src/nanopb directory cp nanopb/pb_common.* nanopb/pb_encode.* nanopb/pb_decode.* src/nanopb mv nanopb/pb.h src/nanopb/nanopb.pb.h - - name: build platforms + - name: build SAMD platforms run: python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 - name: Rename build artifacts to reflect the platform name run: | mv examples/*/build/*/Wippersnapper_demo.ino.uf2 wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 mv examples/*/build/*/Wippersnapper_demo.ino.hex wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.hex - name: upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: build-files + 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 }}.hex build-rp2040: - name: Build WipperSnapper RP2040 + name: 🏗️RP2040 runs-on: ubuntu-latest strategy: fail-fast: false matrix: - arduino-platform: ["picow_rp2040_tinyusb"] + arduino-platform: ["picow_rp2040_tinyusb", "picow_rp2350_tinyusb"] steps: - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: actions/checkout@v4 @@ -412,6 +512,7 @@ jobs: - uses: actions/checkout@v4 with: repository: adafruit/ci-arduino + ref: ci-wippersnapper path: ci - name: Install CI-Arduino run: bash ci/actions_install.sh @@ -420,36 +521,58 @@ jobs: run: | git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg git clone --quiet https://github.com/pstolarz/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library - - name: Download and install stable Nanopb + git clone --quiet https://github.com/adafruit/Adafruit_TinyUSB_Arduino /home/runner/Arduino/libraries/Adafruit_TinyUSB_Arduino + - name: Download stable Nanopb + id: download-nanopb + continue-on-error: true run: | - # Download and extract nanopb wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8.tar.gz + - if: ${{ failure() || steps.download-nanopb.outcome != 'success' }} + name: Restore cached nanopb + id: cache-nanopb-restore + uses: actions/cache/restore@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - if: ${{ steps.download-nanopb.outcome == 'success' }} + name: Save nanopb to cache + id: cache-nanopb-save + uses: actions/cache/save@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - name: Install stable Nanopb + run: | tar -xf nanopb-0.4.8.tar.gz # Copy files to WipperSnapper's src/nanopb directory cp nanopb/pb_common.* nanopb/pb_encode.* nanopb/pb_decode.* src/nanopb mv nanopb/pb.h src/nanopb/nanopb.pb.h - - name: build platforms + - name: build RP2040 platforms run: python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 - name: Rename build artifacts to reflect the platform name run: | mv examples/*/build/*/Wippersnapper_demo.ino.uf2 wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 - name: upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: build-files + name: build-files-${{ matrix.arduino-platform }}.${{ env.WS_VERSION }} path: | wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 # NOTE: This does NOT release artifacts, it only builds build-samd-non-fs: - name: Build WipperSnapper SAMD (NO-TINYUSB) + name: 🏗️SAMD🚫⧾🔱 runs-on: ubuntu-latest strategy: fail-fast: false matrix: arduino-platform: ["mkrwifi1010", "nano_33_iot"] steps: - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: actions/checkout@v4 @@ -461,6 +584,7 @@ jobs: - uses: actions/checkout@v4 with: repository: adafruit/ci-arduino + ref: ci-wippersnapper path: ci - name: Install CI-Arduino run: bash ci/actions_install.sh @@ -470,26 +594,47 @@ jobs: git clone --quiet https://github.com/arduino-libraries/Servo.git /home/runner/Arduino/libraries/Servo git clone --quiet https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library git clone --quiet https://github.com/PaulStoffregen/OneWire.git /home/runner/Arduino/libraries/OneWire - - name: Download and install stable Nanopb + - name: Download stable Nanopb + id: download-nanopb + continue-on-error: true run: | - # Download and extract nanopb wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8.tar.gz + - if: ${{ failure() || steps.download-nanopb.outcome != 'success' }} + name: Restore cached nanopb + id: cache-nanopb-restore + uses: actions/cache/restore@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - if: ${{ steps.download-nanopb.outcome == 'success' }} + name: Save nanopb to cache + id: cache-nanopb-save + uses: actions/cache/save@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - name: Install stable Nanopb + run: | tar -xf nanopb-0.4.8.tar.gz # Copy files to WipperSnapper's src/nanopb directory cp nanopb/pb_common.* nanopb/pb_encode.* nanopb/pb_decode.* src/nanopb mv nanopb/pb.h src/nanopb/nanopb.pb.h - - name: build platforms + - name: build SAMD (no-FS) platforms run: python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 build-esp8266: - name: Build WipperSnapper ESP8266 + name: 🏗️ESP8266 runs-on: ubuntu-latest strategy: fail-fast: false matrix: arduino-platform: ["feather_esp8266"] steps: - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: actions/checkout@v4 @@ -501,6 +646,7 @@ jobs: - uses: actions/checkout@v4 with: repository: adafruit/ci-arduino + ref: ci-wippersnapper path: ci - name: Install CI-Arduino run: bash ci/actions_install.sh @@ -508,15 +654,36 @@ jobs: run: | git clone --quiet https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library git clone --quiet https://github.com/PaulStoffregen/OneWire.git /home/runner/Arduino/libraries/OneWire - - name: Download and install stable Nanopb + - name: Download stable Nanopb + id: download-nanopb + continue-on-error: true run: | - # Download and extract nanopb wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8.tar.gz + - if: ${{ failure() || steps.download-nanopb.outcome != 'success' }} + name: Restore cached nanopb + id: cache-nanopb-restore + uses: actions/cache/restore@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - if: ${{ steps.download-nanopb.outcome == 'success' }} + name: Save nanopb to cache + id: cache-nanopb-save + uses: actions/cache/save@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - name: Install stable Nanopb + run: | tar -xf nanopb-0.4.8.tar.gz # Copy files to WipperSnapper's src/nanopb directory cp nanopb/pb_common.* nanopb/pb_encode.* nanopb/pb_decode.* src/nanopb mv nanopb/pb.h src/nanopb/nanopb.pb.h - - name: build platforms + - name: build ESP8266 platforms run: python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 - name: list build artifacts run: | @@ -531,14 +698,14 @@ jobs: run: | zip -r wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.zip wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.* - name: upload build artifacts zip - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: build-files + name: build-files-${{ matrix.arduino-platform }}.${{ env.WS_VERSION }} path: | wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.zip build-esp32sx-dev: - name: Build WipperSnapper ESP32-Sx DEV BUILDS + name: 🏗️ESP32-Sx(DEV) runs-on: ubuntu-latest strategy: fail-fast: false @@ -550,9 +717,12 @@ jobs: "feather_esp32s3_debug", "feather_esp32s3_4mbflash_2mbpsram_debug", "feather_esp32s3_tft_debug", + "wippersnapper_feather_esp32s3_reverse_tft_debug", + "metroesp32s2_debug", + "metro_esp32s3_debug", ] steps: - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: actions/checkout@v4 @@ -564,6 +734,7 @@ jobs: - uses: actions/checkout@v4 with: repository: adafruit/ci-arduino + ref: ci-wippersnapper path: ci - name: Install CI-Arduino run: bash ci/actions_install.sh @@ -576,12 +747,34 @@ jobs: git clone --quiet https://github.com/adafruit/Adafruit_STMPE610.git /home/runner/Arduino/libraries/Adafruit_STMPE610 git clone --quiet https://github.com/adafruit/Adafruit-ST7735-Library.git /home/runner/Arduino/libraries/Adafruit-ST7735-Library git clone --quiet https://github.com/adafruit/Adafruit_TouchScreen.git /home/runner/Arduino/libraries/Adafruit_TouchScreen + git clone --quiet https://github.com/adafruit/Adafruit_TinyUSB_Arduino /home/runner/Arduino/libraries/Adafruit_TinyUSB_Arduino git clone --depth 1 --branch wippersnapper https://github.com/brentru/lvgl.git /home/runner/Arduino/libraries/lvgl git clone --depth 1 --branch development https://github.com/brentru/Adafruit_LvGL_Glue.git /home/runner/Arduino/libraries/Adafruit_LittlevGL_Glue_Library - - name: Download and install stable Nanopb + - name: Download stable Nanopb + id: download-nanopb + continue-on-error: true run: | - # Download and extract nanopb wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8.tar.gz + - if: ${{ failure() || steps.download-nanopb.outcome != 'success' }} + name: Restore cached nanopb + id: cache-nanopb-restore + uses: actions/cache/restore@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - if: ${{ steps.download-nanopb.outcome == 'success' }} + name: Save nanopb to cache + id: cache-nanopb-save + uses: actions/cache/save@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - name: Install stable Nanopb + run: | tar -xf nanopb-0.4.8.tar.gz # Copy files to WipperSnapper's src/nanopb directory cp nanopb/pb_common.* nanopb/pb_encode.* nanopb/pb_decode.* src/nanopb @@ -597,20 +790,181 @@ jobs: - name: list run: | ls - ls examples/*/build/ + ls -R examples/*/build/ - name: Rename build artifacts to reflect the platform name run: | mv examples/*/build/*/wippersnapper_debug.ino.uf2 wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 mv examples/*/build/*/wippersnapper_debug.ino.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.bin - name: upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: build-files-dev + name: build-files-dev-${{ matrix.arduino-platform }}.${{ env.WS_VERSION }} path: | wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.bin + build-esp32-dev: + name: 🏗️ESP32/Cx(DEV) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + arduino-platform: + [ + "wippersnapper_feather_esp32c6_debug", + ] + include: + - offset: "0x1000" + - offset: "0x0" + arduino-platform: "wippersnapper_feather_esp32c6_debug" + steps: + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + - uses: actions/checkout@v4 + - name: Get WipperSnapper version + run: | + git fetch --prune --unshallow --tags + git describe --dirty --tags + echo >>$GITHUB_ENV WS_VERSION=$(git describe --dirty --tags) + - uses: actions/checkout@v4 + with: + 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 + - name: Install CI-Arduino + run: bash ci/actions_install.sh + - name: Install extra Arduino libraries + run: | + git clone --quiet 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 + - name: Download stable Nanopb + id: download-nanopb + continue-on-error: true + run: | + wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8.tar.gz + - if: ${{ failure() || steps.download-nanopb.outcome != 'success' }} + name: Restore cached nanopb + id: cache-nanopb-restore + uses: actions/cache/restore@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - if: ${{ steps.download-nanopb.outcome == 'success' }} + name: Save nanopb to cache + id: cache-nanopb-save + uses: actions/cache/save@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - name: Install stable Nanopb + run: | + tar -xf nanopb-0.4.8.tar.gz + # Copy files to WipperSnapper's src/nanopb directory + cp nanopb/pb_common.* nanopb/pb_encode.* nanopb/pb_decode.* src/nanopb + mv nanopb/pb.h src/nanopb/nanopb.pb.h + - name: Install Dependencies + run: | + pip3 install esptool + - name: build ESP32 platforms + run: python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 + - name: Check artifacts + run: | + ls examples/wippersnapper_debug/build/* + - name: Rename build artifacts to reflect the platform name + run: | + mv examples/wippersnapper_debug/build/*/wippersnapper_debug.ino.bin wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.bin + mv examples/wippersnapper_debug/build/*/wippersnapper_debug.ino.elf wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.elf + mv examples/wippersnapper_debug/build/*/wippersnapper_debug.ino.map wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.map + mv examples/wippersnapper_debug/build/*/wippersnapper_debug.ino.bootloader.bin wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.bootloader.bin + mv examples/wippersnapper_debug/build/*/wippersnapper_debug.ino.partitions.bin wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.partitions.bin + - name: Check boot_app0 file existence (esp32 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" + - 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 }}.littlefs.${{ 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 }}.littlefs.${{ env.WS_VERSION }}.boot_app0.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 '_debug' suffix if present + board_name=${board_name%_debug} + # Remove 'wippersnapper_' prefix if present + board_name=${board_name#wippersnapper_} + content=$(cat ws-boards/boards/${board_name//_/-}/definition.json) + { + echo 'boardJson<> "$GITHUB_OUTPUT" + - 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 }}.littlefs.${{ env.WS_VERSION }}.combined.bin \ + ${{ matrix.offset }} wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.bootloader.bin \ + 0x8000 wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.partitions.bin \ + 0xe000 wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.boot_app0.bin \ + 0x10000 wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.bin + - name: Zip build artifacts + run: | + zip -r wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.zip wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.* + - name: upload build artifacts zip + uses: actions/upload-artifact@v4 + with: + name: build-files-dev-${{ matrix.arduino-platform }}.${{ env.WS_VERSION }} + path: | + wippersnapper.${{ matrix.arduino-platform }}.littlefs.${{ env.WS_VERSION }}.zip + + merge-job-build-files: + name: Merge Artifacts for build-files + runs-on: ubuntu-latest + needs: [build-esp32sx-esptool, build-esp32sx, build-esp32, build-esp8266, build-samd, build-rp2040, build-samd-non-fs] + + steps: + - name: Merge Artifacts from Builds + uses: actions/upload-artifact/merge@v4 + with: + name: build-files + pattern: build-files-!(dev)-* + delete-merged: true + + merge-job2: + name: Merge Artifacts for build-files-dev + runs-on: ubuntu-latest + needs: [build-esp32sx-dev, build-esp32-dev] + + steps: + - name: Merge Artifacts from Dev Builds + uses: actions/upload-artifact/merge@v4 + with: + name: build-files-dev + pattern: build-files-dev-* + delete-merged: true + clang_and_doxy: + name: 🔎Clang & Doxygen runs-on: ubuntu-latest needs: [ @@ -622,7 +976,7 @@ jobs: build-rp2040, ] steps: - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: actions/checkout@v4 @@ -630,6 +984,7 @@ jobs: - uses: actions/checkout@v4 with: repository: adafruit/ci-arduino + ref: ci-wippersnapper path: ci - name: pre-install run: bash ci/actions_install.sh @@ -641,4 +996,4 @@ jobs: env: GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }} PRETTYNAME: "Adafruit.io WipperSnapper Library" - run: bash ci/doxy_gen_and_deploy.sh + run: bash ci/doxy_gen_and_deploy.sh \ No newline at end of file diff --git a/.github/workflows/release-callee.yml b/.github/workflows/release-callee.yml index a5b9956a2..7ca2d27b9 100644 --- a/.github/workflows/release-callee.yml +++ b/.github/workflows/release-callee.yml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Brent Rubell for Adafruit Industries, 2022 +# SPDX-FileCopyrightText: Brent Rubell for Adafruit Industries, 2022-2024 # # SPDX-License-Identifier: MIT name: WipperSnapper Release Callee diff --git a/.github/workflows/release-caller.yml b/.github/workflows/release-caller.yml index 91839b1e9..231ab93bf 100644 --- a/.github/workflows/release-caller.yml +++ b/.github/workflows/release-caller.yml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Brent Rubell for Adafruit Industries, 2022 +# SPDX-FileCopyrightText: Brent Rubell for Adafruit Industries, 2022 - 2024 # # SPDX-License-Identifier: MIT name: WipperSnapper Release Workflow diff --git a/.github/workflows/release-offline.yml b/.github/workflows/release-offline.yml new file mode 100644 index 000000000..6d8a7df0b --- /dev/null +++ b/.github/workflows/release-offline.yml @@ -0,0 +1,280 @@ +# SPDX-FileCopyrightText: Brent Rubell for Adafruit Industries, 2025 +# +# SPDX-License-Identifier: MIT +name: WipperSnapper Release Workflow for "Offline Mode" Alpha Feature +on: + push: + branches: + - migrate-api-v2 + secrets: + GH_REPO_TOKEN: + required: true + +jobs: + clang: + name: 🔎 Clang + runs-on: ubuntu-latest + steps: + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + - uses: actions/checkout@v4 + + - uses: actions/checkout@v4 + with: + repository: adafruit/ci-arduino + ref: ci-wippersnapper + path: ci + - name: pre-install + run: bash ci/actions_install.sh + - name: clang + run: python3 ci/run-clang-format.py -r -e "ci/*" -e "bin/*" -e src/nanopb -e src/protos -e src/pb.h -e src/provisioning/tinyusb src/ + + test-offline-mode: + name: 🧪 Test Offline Mode + runs-on: ubuntu-latest + needs: clang + steps: + - name: Check out repository code + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.13' + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install -r tests/requirements.txt + - name: Install Wokwi CI Server + uses: wokwi/wokwi-ci-server-action@v1 + - name: Install Wokwi CLI + run: curl -L https://wokwi.com/ci/install.sh | sh + - name: Install PIO Libraries for esp32dev target + run: pio pkg install --environment=esp32dev + - name: Build PlatformIO Project + run: platformio run --environment esp32dev + - name: Move new build file to test folder + run: cp .pio/build/esp32dev/firmware.elf tests/bin/offline/firmware.elf + - name: Run Wokwi Tests + run: pytest tests/test_offline.py --junitxml=report.xml -v + env: + WOKWI_CLI_TOKEN: ${{ secrets.WOKWI_CLI_TOKEN }} + - name: Publish Wokwi Test Results + uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + files: | + /home/runner/work/Adafruit_Wippersnapper_Arduino/Adafruit_Wippersnapper_Arduino/report.xml + + build-esp32sx: + name: 🏗️ ESP32-Sx + runs-on: ubuntu-latest + needs: [clang] + strategy: + fail-fast: false + matrix: + arduino-platform: + [ + "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 + with: + python-version: "3.x" + - uses: actions/checkout@v4 + - name: Get WipperSnapper version + run: | + git fetch --prune --unshallow --tags + git describe --dirty --tags + echo >>$GITHUB_ENV WS_VERSION=$(git describe --dirty --tags) + - uses: actions/checkout@v4 + with: + repository: adafruit/ci-arduino + ref: ci-wippersnapper + path: ci + - name: Install CI-Arduino + run: bash ci/actions_install.sh + - name: Install extra Arduino libraries + run: | + git clone --quiet 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 + git clone --quiet https://github.com/adafruit/Adafruit_STMPE610.git /home/runner/Arduino/libraries/Adafruit_STMPE610 + git clone --quiet https://github.com/adafruit/Adafruit-ST7735-Library.git /home/runner/Arduino/libraries/Adafruit-ST7735-Library + git clone --quiet https://github.com/adafruit/Adafruit_TouchScreen.git /home/runner/Arduino/libraries/Adafruit_TouchScreen + git clone --quiet https://github.com/adafruit/Adafruit_TinyUSB_Arduino /home/runner/Arduino/libraries/Adafruit_TinyUSB_Arduino + git clone --depth 1 --branch wippersnapper https://github.com/brentru/lvgl.git /home/runner/Arduino/libraries/lvgl + git clone --depth 1 --branch development https://github.com/brentru/Adafruit_LvGL_Glue.git /home/runner/Arduino/libraries/Adafruit_LittlevGL_Glue_Library + - name: Download stable Nanopb + id: download-nanopb + continue-on-error: true + run: | + wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8.tar.gz + - if: ${{ failure() || steps.download-nanopb.outcome != 'success' }} + name: Restore cached nanopb + id: cache-nanopb-restore + uses: actions/cache/restore@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - if: ${{ steps.download-nanopb.outcome == 'success' }} + name: Save nanopb to cache + id: cache-nanopb-save + uses: actions/cache/save@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - name: Install stable Nanopb + run: | + tar -xf nanopb-0.4.8.tar.gz + # Copy files to WipperSnapper's src/nanopb directory + cp nanopb/pb_common.* nanopb/pb_encode.* nanopb/pb_decode.* src/nanopb + mv nanopb/pb.h src/nanopb/nanopb.pb.h + - name: List all files in Adafruit_LittlevGL_Glue_Library folder + run: | + ls /home/runner/Arduino/libraries/Adafruit_LittlevGL_Glue_Library + - 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: Build for ESP32-SX + run: | + python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 + - name: list files (tree) + run: | + tree + - name: Rename build artifacts to reflect the platform name + run: | + mv examples/*/build/*/Wippersnapper_demo.ino.uf2 wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 + mv examples/*/build/*/Wippersnapper_demo.ino.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.bin + - 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 + runs-on: ubuntu-latest + needs: [clang] + strategy: + fail-fast: false + matrix: + arduino-platform: ["pico_rp2040_tinyusb", + "pico_rp2350_tinyusb", + "feather_rp2040_adalogger_tinyusb", + "metro_rp2350_tinyusb" + ] + steps: + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + - uses: actions/checkout@v4 + - name: Get WipperSnapper version + run: | + git fetch --prune --unshallow --tags + git describe --dirty --tags + echo >>$GITHUB_ENV WS_VERSION=$(git describe --dirty --tags) + - uses: actions/checkout@v4 + with: + repository: adafruit/ci-arduino + ref: ci-wippersnapper + path: ci + - name: Install CI-Arduino + run: bash ci/actions_install.sh + # manually install OneWireNG/TempControlLib for OneWireNg (RP2040 Supported OneWire w/backwards compat.) + - name: Install extra Arduino libraries + run: | + git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg + 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/Adafruit_TinyUSB_Arduino /home/runner/Arduino/libraries/Adafruit_TinyUSB_Arduino + - name: Download stable Nanopb + id: download-nanopb + continue-on-error: true + run: | + wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8.tar.gz + - if: ${{ failure() || steps.download-nanopb.outcome != 'success' }} + name: Restore cached nanopb + id: cache-nanopb-restore + uses: actions/cache/restore@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - if: ${{ steps.download-nanopb.outcome == 'success' }} + name: Save nanopb to cache + id: cache-nanopb-save + uses: actions/cache/save@v4 + env: + cache-name: cache-node-modules + with: + path: ./nanopb-0.4.8.tar.gz + key: nanopb-0.4.8.tar.gz + - name: Install stable Nanopb + run: | + tar -xf nanopb-0.4.8.tar.gz + # Copy files to WipperSnapper's src/nanopb directory + cp nanopb/pb_common.* nanopb/pb_encode.* nanopb/pb_decode.* src/nanopb + mv nanopb/pb.h src/nanopb/nanopb.pb.h + - name: build RP2040 platforms + run: python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 + - name: Rename build artifacts to reflect the platform name + run: | + mv examples/*/build/*/Wippersnapper_demo_offline.ino.uf2 wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 + - 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 + + merge-job-build-files: + name: Merge Artifacts for build-files + runs-on: ubuntu-latest + needs: [build-esp32sx, build-rp2040] + steps: + - name: Merge Artifacts from Builds + uses: actions/upload-artifact/merge@v4 + with: + name: build-files + pattern: build-files-!(dev)-* + delete-merged: true + + + release-wippersnapper: + name: 🚀 Upload Release Files + runs-on: ubuntu-latest + needs: merge-job-build-files + steps: + - name: Download build artifacts from build-platform steps + uses: actions/download-artifact@v4 + with: + name: build-files + - name: List Files + run: ls + - name: Upload Assets to the GitHub Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: | + wippersnapper.*.uf2 + wippersnapper.*.bin + wippersnapper.*.zip \ No newline at end of file diff --git a/.gitignore b/.gitignore index b22a8d404..b21993810 100644 --- a/.gitignore +++ b/.gitignore @@ -39,13 +39,28 @@ html/* # VSCode artifacts .vscode/* src/.vscode/settings.json - .DS_STORE - examples/Wippersnapper_demo/build/ +# Virtual environment directories +.venv/ +venv/ + +# Python artifacts +tests/__pycache__/ + # Platformio artifacts .pio/ -# Secrets -data/ \ No newline at end of file +# These sometimes contain credentials, don't commit them! +src/Wippersnapper_demo_wokwi.ino +data/ +examples/Wippersnapper_demo_offline/.theia/ +examples/Wippersnapper_demo_offline/.vscode/ +examples/Wippersnapper_demo_offline/build/ + +# Test results +report.xml + +# VSCode settings +.vscode/settings.json \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 65076780b..218d4eca1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,9 +1,23 @@ { "files.associations": { "limits": "c", - "type_traits": "c" + "type_traits": "c", + "vector": "cpp", + "array": "cpp", + "deque": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "string_view": "cpp", + "initializer_list": "cpp", + "span": "cpp", + "*.tcc": "cpp", + "list": "cpp", + "unordered_set": "cpp", + "format": "cpp", + "text_encoding": "cpp", + "regex": "cpp" }, - "C_Cpp.dimInactiveRegions": true, + "C_Cpp.dimInactiveRegions": false, "dotnet.defaultSolution": "disable", "cmake.configureOnOpen": false } \ No newline at end of file diff --git a/Doxyfile b/Doxyfile index c05228416..199b283ea 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.9.1 +# Doxyfile 1.9.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -12,6 +12,16 @@ # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options @@ -60,16 +70,28 @@ PROJECT_LOGO = OUTPUT_DIRECTORY = -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes -# performance problems for the file system. +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. # The default value is: NO. CREATE_SUBDIRS = NO +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode @@ -81,14 +103,14 @@ ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English @@ -189,6 +211,16 @@ SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus @@ -209,6 +241,14 @@ QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. @@ -232,16 +272,16 @@ TAB_SIZE = 4 # the documentation. An alias has the form: # name=value # For example adding -# "sideeffect=@par Side Effects:\n" +# "sideeffect=@par Side Effects:^^" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines (in the resulting output). You can put ^^ in the value part of an -# alias to insert a newline as if a physical newline was in the original file. -# When you need a literal { or } or , in the value part of an alias you have to -# escape them by means of a backslash (\), this can lead to conflicts with the -# commands \{ and \} for these it is advised to use the version @{ and @} or use -# a double escape (\\{ and \\}) +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) ALIASES = @@ -273,13 +313,21 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, JavaScript, -# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, -# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: # FortranFree, unknown formatted Fortran: Fortran. In the later case the parser # tries to guess whether the code is fixed or free formatted code, this is the # default for Fortran type files). For instance to make doxygen treat .inc files @@ -315,13 +363,24 @@ MARKDOWN_SUPPORT = YES TOC_INCLUDE_HEADINGS = 0 +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0 and GITHUB use the lower case version of title +# with any whitespace replaced by '-' and punctuation characters removed. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. -AUTOLINK_SUPPORT = YES +AUTOLINK_SUPPORT = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this @@ -426,6 +485,27 @@ TYPEDEF_HIDES_STRUCT = NO LOOKUP_CACHE_SIZE = 0 +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = NO + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -446,6 +526,12 @@ EXTRACT_ALL = NO EXTRACT_PRIVATE = NO +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. @@ -483,6 +569,13 @@ EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation @@ -494,7 +587,8 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO @@ -525,14 +619,15 @@ INTERNAL_DOCS = NO # filesystem is case sensitive (i.e. it supports files in the same directory # whose names only differ in casing), the option must be set to YES to properly # deal with such files in case they appear in the input. For filesystems that -# are not case sensitive the option should be be set to NO to properly deal with +# are not case sensitive the option should be set to NO to properly deal with # output files written for symbols that only differ in casing, such as for two # classes, one named CLASS and the other named Class, and to also support # references to files without having to specify the exact matching casing. On # Windows (including Cygwin) and MacOS, users should typically set this option # to NO, whereas on Linux or other Unix flavors it should typically be set to # YES. -# The default value is: system dependent. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. CASE_SENSE_NAMES = NO @@ -550,6 +645,12 @@ HIDE_SCOPE_NAMES = NO HIDE_COMPOUND_REFERENCE= NO +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -707,7 +808,8 @@ FILE_VERSION_FILTER = # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE @@ -753,27 +855,50 @@ WARNINGS = YES WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. If -# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC # The default value is: NO. WARN_NO_PARAMDOC = YES +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when # a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS # then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but # at the end of the doxygen process doxygen will return with a non-zero status. -# Possible values are: NO, YES and FAIL_ON_WARNINGS. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. # The default value is: NO. WARN_AS_ERROR = NO @@ -784,13 +909,27 @@ WARN_AS_ERROR = NO # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard -# error (stderr). +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). WARN_LOGFILE = @@ -811,10 +950,21 @@ INPUT = # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: # https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING # The default value is: UTF-8. INPUT_ENCODING = UTF-8 +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. @@ -826,12 +976,12 @@ INPUT_ENCODING = UTF-8 # Note the list of default checked file patterns might differ from the list of # default file extension mappings. # -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), -# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl, -# *.ucf, *.qsf and *.ice. +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm, +# *.cpp, *.cppm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, +# *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.ixx, *.l, *.cs, *.d, *.php, +# *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be +# provided as doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.c \ *.cc \ @@ -863,7 +1013,8 @@ EXCLUDE = EXCLUDE \ src/nanopb \ src/provisioning/tinyusb/fatfs \ src/pb.h \ - src/provisioning + src/provisioning \ + src/protos # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -885,10 +1036,7 @@ EXCLUDE_PATTERNS = *.md # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* +# ANamespace::AClass, ANamespace::*Test EXCLUDE_SYMBOLS = @@ -933,6 +1081,11 @@ IMAGE_PATH = # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. @@ -974,6 +1127,15 @@ FILTER_SOURCE_PATTERNS = USE_MDFILE_AS_MAINPAGE = +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- @@ -1071,10 +1233,11 @@ VERBATIM_HEADERS = YES ALPHABETICAL_INDEX = YES -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = @@ -1153,7 +1316,12 @@ HTML_STYLESHEET = # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1168,9 +1336,22 @@ HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see +# this color. Hue is specified as an angle on a color-wheel, see # https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. @@ -1180,7 +1361,7 @@ HTML_EXTRA_FILES = HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A +# in the HTML output. For a value of 0 the output will use gray-scales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1198,14 +1379,16 @@ HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_GAMMA = 80 -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_TIMESTAMP = NO +HTML_DYNAMIC_MENUS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the @@ -1215,6 +1398,13 @@ HTML_TIMESTAMP = NO HTML_DYNAMIC_SECTIONS = NO +# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be +# dynamically folded and expanded in the generated HTML source code. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_CODE_FOLDING = YES + # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to @@ -1251,6 +1441,13 @@ GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. @@ -1276,8 +1473,12 @@ DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: -# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows. +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML @@ -1334,6 +1535,16 @@ BINARY_TOC = NO TOC_EXPAND = NO +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help @@ -1436,16 +1647,28 @@ DISABLE_INDEX = NO # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # @@ -1470,6 +1693,24 @@ TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML @@ -1479,16 +1720,11 @@ EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANSPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. -FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # https://www.mathjax.org) which uses client side JavaScript for the rendering @@ -1501,11 +1737,29 @@ FORMULA_TRANSPARENT = YES USE_MATHJAX = NO +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + # When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). # Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1518,15 +1772,21 @@ MATHJAX_FORMAT = HTML-CSS # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of -# MathJax from https://www.mathjax.org before deployment. -# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = @@ -1667,6 +1927,16 @@ LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to +# generate index for LaTeX. In case there is no backslash (\) as first character +# it will be automatically added in the LaTeX code. +# Note: This tag is used in the generated output file (.tex). +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. +# The default value is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_MAKEINDEX_CMD = makeindex + # If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. @@ -1696,29 +1966,31 @@ PAPER_TYPE = a4 EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. +# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for +# the generated LaTeX document. The header should contain everything until the +# first chapter. If it is left blank doxygen will generate a standard header. It +# is highly recommended to start with a default header using +# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty +# and then modify the file new_header.tex. See also section "Doxygen usage" for +# information on how to generate the default header that doxygen normally uses. # -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empty -# string, for the replacement values of the other commands the user is referred -# to HTML_HEADER. +# Note: Only use a user-defined header if you know what you are doing! +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. The following +# commands have a special meaning inside the header (and footer): For a +# description of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. See +# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for +# the generated LaTeX document. The footer should contain everything after the +# last chapter. If it is left blank doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. -# -# Note: Only use a user-defined footer if you know what you are doing! +# special commands can be used inside the footer. See also section "Doxygen +# usage" for information on how to generate the default footer that doxygen +# normally uses. Note: Only use a user-defined footer if you know what you are +# doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = @@ -1761,10 +2033,16 @@ PDF_HYPERLINKS = YES USE_PDFLATEX = YES -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode -# command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. +# The LATEX_BATCHMODE tag signals the behavior of LaTeX in case of an error. +# Possible values are: NO same as ERROR_STOP, YES same as BATCH, BATCH In batch +# mode nothing is printed on the terminal, errors are scrolled as if is +# hit at every error; missing files that TeX tries to input or request from +# keyboard input (\read on a not open input stream) cause the job to abort, +# NON_STOP In nonstop mode the diagnostic message will appear on the terminal, +# but there is no possibility of user interaction just like in batch mode, +# SCROLL In scroll mode, TeX will stop only for missing files to input or if +# keyboard input is necessary and ERROR_STOP In errorstop mode, TeX will stop at +# each error, asking for user intervention. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1777,16 +2055,6 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See # https://en.wikipedia.org/wiki/BibTeX and \cite for more info. @@ -1795,13 +2063,13 @@ LATEX_SOURCE_CODE = NO LATEX_BIB_STYLE = plain -# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: NO. +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) +# path from which the emoji images will be read. If a relative path is entered, +# it will be relative to the LATEX_OUTPUT directory. If left blank the +# LATEX_OUTPUT directory will be used. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_TIMESTAMP = NO +LATEX_EMOJI_DIRECTORY = #--------------------------------------------------------------------------- # Configuration options related to the RTF output @@ -1859,16 +2127,6 @@ RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = -# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code -# with syntax highlighting in the RTF output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_SOURCE_CODE = NO - #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- @@ -1940,6 +2198,13 @@ XML_OUTPUT = xml XML_PROGRAMLISTING = YES +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# namespace members in file scope as well, matching the HTML output. +# The default value is: NO. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_NS_MEMB_FILE_SCOPE = NO + #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- @@ -1958,27 +2223,44 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook -# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the -# program listings (including syntax highlighting and cross-referencing -# information) to the DOCBOOK output. Note that enabling this will significantly -# increase the size of the DOCBOOK output. -# The default value is: NO. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_PROGRAMLISTING = NO - #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# AutoGen Definitions (see https://autogen.sourceforge.net/) file that captures # the structure of the code including all documentation. Note that this feature # is still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to Sqlite3 output +#--------------------------------------------------------------------------- + +# If the GENERATE_SQLITE3 tag is set to YES doxygen will generate a Sqlite3 +# database with symbols found by doxygen stored in tables. +# The default value is: NO. + +GENERATE_SQLITE3 = NO + +# The SQLITE3_OUTPUT tag is used to specify where the Sqlite3 database will be +# put. If a relative path is entered the value of OUTPUT_DIRECTORY will be put +# in front of it. +# The default directory is: sqlite3. +# This tag requires that the tag GENERATE_SQLITE3 is set to YES. + +SQLITE3_OUTPUT = sqlite3 + +# The SQLITE3_OVERWRITE_DB tag is set to YES, the existing doxygen_sqlite3.db +# database file will be recreated with each doxygen run. If set to NO, doxygen +# will warn if an a database file is already found and not modify it. +# The default value is: YES. +# This tag requires that the tag GENERATE_SQLITE3 is set to YES. + +SQLITE3_RECREATE_DB = YES + #--------------------------------------------------------------------------- # Configuration options related to the Perl module output #--------------------------------------------------------------------------- @@ -2053,7 +2335,8 @@ SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the -# preprocessor. +# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of +# RECURSIVE has no effect here. # This tag requires that the tag SEARCH_INCLUDES is set to YES. INCLUDE_PATH = @@ -2074,7 +2357,9 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = __cdecl=, ARDUINO_ARCH_ESP32=1, ARDUINO_FUNHOUSE_ESP32S2=1 +PREDEFINED = "__cdecl=," \ + "ARDUINO_ARCH_ESP32=1," \ + ARDUINO_FUNHOUSE_ESP32S2=1 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2120,15 +2405,15 @@ TAGFILES = GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES, all external class will be listed in -# the class index. If set to NO, only the inherited external classes will be -# listed. +# If the ALLEXTERNALS tag is set to YES, all external classes and namespaces +# will be listed in the class and namespace index. If set to NO, only the +# inherited external classes will be listed. # The default value is: NO. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will be +# in the topic index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. @@ -2142,25 +2427,9 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to diagram generator tools #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2169,7 +2438,7 @@ HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: -# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO # The default value is: NO. @@ -2186,49 +2455,73 @@ HAVE_DOT = NO DOT_NUM_THREADS = 0 -# When you want a differently looking font in the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. +# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of +# subgraphs. When you want a differently looking font in the dot files that +# doxygen generates you can specify fontname, fontcolor and fontsize attributes. +# For details please see Node, +# Edge and Graph Attributes specification You need to make sure dot is able +# to find the font, which can be done by putting it in a standard location or by +# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. Default graphviz fontsize is 14. +# The default value is: fontname=Helvetica,fontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTNAME = Helvetica +DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. +# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can +# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. Complete documentation about +# arrows shapes. +# The default value is: labelfontname=Helvetica,labelfontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTSIZE = 10 +DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10" -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. +# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes +# around nodes set 'shape=plain' or 'shape=plaintext' Shapes specification +# The default value is: shape=box,height=0.2,width=0.4. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" + +# You can set the path where dot can find font specified with fontname in +# DOT_COMMON_ATTR and others dot attributes. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTPATH = -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then doxygen will +# generate a graph for each documented class showing the direct and indirect +# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and +# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case +# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the +# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used. +# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance +# relations will be shown as texts / links. +# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a # graph for each documented class showing the direct and indirect implementation # dependencies (inheritance, containment, and class references variables) of the -# class with other documented classes. +# class with other documented classes. Explicit enabling a collaboration graph, +# when COLLABORATION_GRAPH is set to NO, can be accomplished by means of the +# command \collaborationgraph. Disabling a collaboration graph can be +# accomplished by means of the command \hidecollaborationgraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. +# groups, showing the direct groups dependencies. Explicit enabling a group +# dependency graph, when GROUP_GRAPHS is set to NO, can be accomplished by means +# of the command \groupgraph. Disabling a directory graph can be accomplished by +# means of the command \hidegroupgraph. See also the chapter Grouping in the +# manual. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2255,6 +2548,28 @@ UML_LOOK = NO UML_LIMIT_NUM_FIELDS = 10 +# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and +# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS +# tag is set to YES, doxygen will add type and arguments for attributes and +# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen +# will not generate fields with class member information in the UML graphs. The +# class diagrams will look similar to the default class diagrams but using UML +# notation for the relationships. +# Possible values are: NO, YES and NONE. +# The default value is: NO. +# This tag requires that the tag UML_LOOK is set to YES. + +DOT_UML_DETAILS = NO + +# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters +# to display on a single line. If the actual line length exceeds this threshold +# significantly it will wrapped across multiple lines. Some heuristics are apply +# to avoid ugly line breaks. +# Minimum value: 0, maximum value: 1000, default value: 17. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_WRAP_THRESHOLD = 17 + # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their # instances. @@ -2266,7 +2581,9 @@ TEMPLATE_RELATIONS = NO # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to # YES then doxygen will generate a graph for each documented file showing the # direct and indirect include dependencies of the file with other documented -# files. +# files. Explicit enabling an include graph, when INCLUDE_GRAPH is is set to NO, +# can be accomplished by means of the command \includegraph. Disabling an +# include graph can be accomplished by means of the command \hideincludegraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2275,7 +2592,10 @@ INCLUDE_GRAPH = YES # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then doxygen will generate a graph for each documented file showing # the direct and indirect include dependencies of the file with other documented -# files. +# files. Explicit enabling an included by graph, when INCLUDED_BY_GRAPH is set +# to NO, can be accomplished by means of the command \includedbygraph. Disabling +# an included by graph can be accomplished by means of the command +# \hideincludedbygraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2315,16 +2635,26 @@ GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the # dependencies a directory has on other directories in a graphical way. The # dependency relations are determined by the #include relations between the -# files in the directories. +# files in the directories. Explicit enabling a directory graph, when +# DIRECTORY_GRAPH is set to NO, can be accomplished by means of the command +# \directorygraph. Disabling a directory graph can be accomplished by means of +# the command \hidedirectorygraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. DIRECTORY_GRAPH = YES +# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels +# of child directories generated in directory dependency graphs by dot. +# Minimum value: 1, maximum value: 25, default value: 1. +# This tag requires that the tag DIRECTORY_GRAPH is set to YES. + +DIR_GRAPH_MAX_DEPTH = 1 + # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: -# http://www.graphviz.org/)). +# https://www.graphviz.org/)). # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). @@ -2361,11 +2691,12 @@ DOT_PATH = DOTFILE_DIRS = -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. -MSCFILE_DIRS = +DIA_PATH = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile @@ -2374,10 +2705,10 @@ MSCFILE_DIRS = DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file. If left blank, it is assumed -# PlantUML is not used or called during a preprocessing step. Doxygen will -# generate a warning when it encounters a \startuml command in this case and -# will not generate output for the diagram. +# path where java can find the plantuml.jar file or to the filename of jar file +# to be used. If left blank, it is assumed PlantUML is not used or called during +# a preprocessing step. Doxygen will generate a warning when it encounters a +# \startuml command in this case and will not generate output for the diagram. PLANTUML_JAR_PATH = @@ -2415,18 +2746,6 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = NO - # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support @@ -2439,6 +2758,8 @@ DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. +# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal +# graphical representation for inheritance and collaboration diagrams is used. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2447,8 +2768,24 @@ GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate # files that are used to generate the various graphs. # -# Note: This setting is not only used for dot files but also for msc and -# plantuml temporary files. +# Note: This setting is not only used for dot files but also for msc temporary +# files. # The default value is: YES. DOT_CLEANUP = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. If the MSCGEN_TOOL tag is left empty (the default), then doxygen will +# use a built-in version of mscgen tool to produce the charts. Alternatively, +# the MSCGEN_TOOL tag can also specify the name an external tool. For instance, +# specifying prog as the value, doxygen will call the tool as prog -T +# -o . The external tool should support +# output file formats "png", "eps", "svg", and "ismap". + +MSCGEN_TOOL = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = diff --git a/LICENSE b/LICENSE index bee399aa1..9bd427e0e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020-2021 Adafruit Industries +Copyright (c) 2020-2024 Adafruit Industries Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index d72345c81..5044a03b2 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,9 @@ Adafruit.io WipperSnapper is a firmware designed to turn any Wi-Fi capable board into an Internet-of-Things (IoT) device. No code required! -WipperSnapper works with multiple microcontroller architectures such as ESP8266, ESP32, ESP32-S2, ESP32-C3, RP2040, and ATSAMD51. +WipperSnapper works with [multiple microcontroller architectures](https://github.com/adafruit/Adafruit_Wippersnapper_Arduino/?tab=readme-ov-file#supported-platforms) and development boards. It is designed to be easily extensible to support new sensors, inputs, and outputs. -You will need a **free** [Adafruit IO](https://io.adafruit.com) account to use WipperSnapper. - -**NOTE: WipperSnapper firmware is in beta** and is actively being developed. Please [report bugs via the issues page on this repository](https://github.com/adafruit/Adafruit_Wippersnapper_Arduino/issues/new?assignees=&labels=&projects=&template=bug_report.md&title=). +A **free** [Adafruit IO](https://io.adafruit.com) account is required to use WipperSnapper. # Get Started [Learn how to install and use WipperSnapper by following this guide on the Adafruit Learning System - QuickStart: Adafruit IO WipperSnapper](https://learn.adafruit.com/quickstart-adafruit-io-wippersnapper). @@ -24,7 +22,7 @@ Pre-compiled binaries and UF2 files for supported hardware are provided on the [ |Platform| MCU(s) | |--|--| -|[ESP32-x](https://github.com/espressif/arduino-esp32)| ESP32, ESP32-S2, ESP32-S3, ESP32-C3 | +|[ESP32-x](https://github.com/espressif/arduino-esp32)| ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6 | |[ESP8266](https://github.com/esp8266/Arduino)| ESP8266 | |[RP2040](https://github.com/earlephilhower/arduino-pico)| RP2040 MCU w/WiFi (i.e: Pico W) | |[ATSAMD](https://github.com/adafruit/ArduinoCore-samd/)| SAMD51 MCU w/separate WiFi Co-Processor (i.e: Adafruit "AirLift")| diff --git a/config.json b/config.json new file mode 100755 index 000000000..55198ba97 --- /dev/null +++ b/config.json @@ -0,0 +1 @@ +{"exportVersion": "1.0.0", "exportedBy": "tester", "exportedAt": "2024-10-28T18:58:23.976Z", "exportedFromDevice": {"board": "metroesp32s3", "firmwareVersion": "1.0.0-beta.93", "referenceVoltage": 2.6, "totalGPIOPins": 11, "totalAnalogPins": 6, "rtc": "DS3231", "statusLEDBrightness": 0.1}, "components": [{"componentAPI": "analogio", "name": "Analog Pin", "pinName": "A0", "type": "analog_pin", "mode": "ANALOG", "direction": "INPUT", "sampleMode": "TIMER", "analogReadMode": "PIN_VALUE", "period": 30}, {"componentAPI": "ds18x20", "name": "DS18B20: Temperature Sensor (\u00b0F)", "sensorTypeCount": 2, "sensorType1": "object-temp-fahrenheit", "sensorType2": "object-temp", "pinName": "D4", "sensorResolution": 12, "period": 30}], "checksum": 236} \ No newline at end of file diff --git a/data.json b/data.json new file mode 100644 index 000000000..0d03d5a66 --- /dev/null +++ b/data.json @@ -0,0 +1 @@ +{"exportVersion": "1.0.0", "exportedBy": "wokwi", "exportedAt": "2024-10-28T18:58:23.976Z", "exportedFromDevice": {"board": "metroesp32s3", "firmwareVersion": "1.0.0-beta.93", "referenceVoltage": 2.6, "totalGPIOPins": 11, "totalAnalogPins": 6}, "components": [{"componentAPI": "digitalio", "name": "Button (D4)", "pinName": "D4", "type": "push_button", "mode": "DIGITAL", "sampleMode": "TIMER", "direction": "INPUT", "period": 5, "pull": "UP", "isPin": true}]} \ No newline at end of file diff --git a/examples/Wippersnapper_NoFS/.DS_Store b/examples/Wippersnapper_NoFS/.DS_Store index d812294d0..19cc1c412 100644 Binary files a/examples/Wippersnapper_NoFS/.DS_Store and b/examples/Wippersnapper_NoFS/.DS_Store differ diff --git a/examples/Wippersnapper_demo/.picow_rp2040_tinyusb.generate b/examples/Wippersnapper_NoFS/.feather_rp2040_adalogger_tinyusb.test.skip similarity index 100% rename from examples/Wippersnapper_demo/.picow_rp2040_tinyusb.generate rename to examples/Wippersnapper_NoFS/.feather_rp2040_adalogger_tinyusb.test.skip diff --git a/examples/Wippersnapper_demo/.qtpy_esp32.generate b/examples/Wippersnapper_NoFS/.metro_esp32s3.test.skip similarity index 100% rename from examples/Wippersnapper_demo/.qtpy_esp32.generate rename to examples/Wippersnapper_NoFS/.metro_esp32s3.test.skip diff --git a/examples/Wippersnapper_NoFS/.metro_esp32s3_debug.test.skip b/examples/Wippersnapper_NoFS/.metro_esp32s3_debug.test.skip new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/examples/Wippersnapper_NoFS/.metro_esp32s3_debug.test.skip @@ -0,0 +1,2 @@ + + diff --git a/examples/Wippersnapper_demo/.qtpy_esp32c3.generate b/examples/Wippersnapper_NoFS/.metro_rp2350_tinyusb.test.skip similarity index 100% rename from examples/Wippersnapper_demo/.qtpy_esp32c3.generate rename to examples/Wippersnapper_NoFS/.metro_rp2350_tinyusb.test.skip diff --git a/examples/Wippersnapper_NoFS/.metroesp32s2_debug.test.skip b/examples/Wippersnapper_NoFS/.metroesp32s2_debug.test.skip new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/examples/Wippersnapper_NoFS/.metroesp32s2_debug.test.skip @@ -0,0 +1,2 @@ + + diff --git a/examples/Wippersnapper_NoFS/.pico_rp2040_tinyusb.test.skip b/examples/Wippersnapper_NoFS/.pico_rp2040_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_NoFS/.pico_rp2040_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_NoFS/.pico_rp2350_tinyusb.test.skip b/examples/Wippersnapper_NoFS/.pico_rp2350_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_NoFS/.pico_rp2350_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_NoFS/Wippersnapper_NoFS.ino b/examples/Wippersnapper_NoFS/Wippersnapper_NoFS.ino index ba42e6424..aa17f8133 100644 --- a/examples/Wippersnapper_NoFS/Wippersnapper_NoFS.ino +++ b/examples/Wippersnapper_NoFS/Wippersnapper_NoFS.ino @@ -30,7 +30,7 @@ #define WIFI_PASS "YOUR_WIFI_PASSWORD" #include "Wippersnapper_Networking.h" -Wippersnapper_WiFi wipper(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS); +ws_adapter_wifi wipper(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS); void setup() { // Provisioning must occur prior to serial init. diff --git a/examples/Wippersnapper_demo/.feather_rp2040_adalogger_tinyusb.test.skip b/examples/Wippersnapper_demo/.feather_rp2040_adalogger_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.feather_rp2040_adalogger_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo/.metro_esp32s3.generate b/examples/Wippersnapper_demo/.metro_esp32s3.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.metro_esp32s3.generate @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo/.metro_esp32s3_debug.test.skip b/examples/Wippersnapper_demo/.metro_esp32s3_debug.test.skip new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/examples/Wippersnapper_demo/.metro_esp32s3_debug.test.skip @@ -0,0 +1,2 @@ + + diff --git a/examples/Wippersnapper_demo/.metro_rp2350_tinyusb.test.skip b/examples/Wippersnapper_demo/.metro_rp2350_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.metro_rp2350_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo/.metroesp32s2_debug.test.skip b/examples/Wippersnapper_demo/.metroesp32s2_debug.test.skip new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/examples/Wippersnapper_demo/.metroesp32s2_debug.test.skip @@ -0,0 +1,2 @@ + + diff --git a/examples/Wippersnapper_demo/.pico_rp2040_tinyusb.test.skip b/examples/Wippersnapper_demo/.pico_rp2040_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.pico_rp2040_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo/.pico_rp2350_tinyusb.test.skip b/examples/Wippersnapper_demo/.pico_rp2350_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.pico_rp2350_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo/.picow_rp2040_tinyusb.test.skip b/examples/Wippersnapper_demo/.picow_rp2040_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.picow_rp2040_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo/.qtpy_esp32.test.skip b/examples/Wippersnapper_demo/.qtpy_esp32.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.qtpy_esp32.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo/.qtpy_esp32c3.test.skip b/examples/Wippersnapper_demo/.qtpy_esp32c3.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.qtpy_esp32c3.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo/Wippersnapper_demo.ino b/examples/Wippersnapper_demo/Wippersnapper_demo.ino index 489a3d96c..73628abdc 100644 --- a/examples/Wippersnapper_demo/Wippersnapper_demo.ino +++ b/examples/Wippersnapper_demo/Wippersnapper_demo.ino @@ -1,33 +1,22 @@ -// Adafruit IO WipperSnapper Beta -// -// -// NOTE: This software is a BETA release and in active development. -// Please report bugs or errors to https://github.com/adafruit/Adafruit_Wippersnapper_Arduino/issues -// +// Adafruit IO WipperSnapper // // Adafruit invests time and resources providing this open source code. // Please support Adafruit and open source hardware by purchasing // products from Adafruit! // -// Brent Rubell for Adafruit Industries, 2021-2022 +// Brent Rubell for Adafruit Industries, 2020-2025 // // All text above must be included in any redistribution. -#include "Wippersnapper_Networking.h" -Wippersnapper_WiFi wipper; +#include "ws_adapters.h" +ws_adapter_wifi wipper; -// Enable debug output for beta builds -#define WS_DEBUG +#define WS_DEBUG // Enable debug output! void setup() { - // Provisioning must occur prior to serial init. - wipper.provision(); - Serial.begin(115200); - //while (!Serial) delay(10); - + wipper.provision(); wipper.connect(); - } void loop() { diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32_v2.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32_v2.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32_v2.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32_v2_debug.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32_v2_debug.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32_v2_debug.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s2.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s2.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s2.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s2_debug.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s2_debug.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s2_debug.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s2_reverse_tft.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s2_reverse_tft.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s2_reverse_tft.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s2_tft.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s2_tft.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s2_tft.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s2_tft_debug.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s2_tft_debug.skip new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s2_tft_debug.skip @@ -0,0 +1,2 @@ + + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s2_tft_debug.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s2_tft_debug.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s2_tft_debug.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s3.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s3.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s3.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s3_4mbflash_2mbpsram.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s3_4mbflash_2mbpsram.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s3_4mbflash_2mbpsram.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s3_4mbflash_2mbpsram_debug.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s3_4mbflash_2mbpsram_debug.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s3_4mbflash_2mbpsram_debug.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s3_debug.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s3_debug.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s3_debug.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s3_reverse_tft.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s3_reverse_tft.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s3_reverse_tft.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s3_tft.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s3_tft.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s3_tft.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp32s3_tft_debug.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp32s3_tft_debug.test.skip new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp32s3_tft_debug.test.skip @@ -0,0 +1,2 @@ + + diff --git a/examples/Wippersnapper_demo_offline/.feather_esp8266.test.skip b/examples/Wippersnapper_demo_offline/.feather_esp8266.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_esp8266.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_rp2040_adalogger_tinyusb.generate b/examples/Wippersnapper_demo_offline/.feather_rp2040_adalogger_tinyusb.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_rp2040_adalogger_tinyusb.generate @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.feather_s2_tinyusb.test.skip b/examples/Wippersnapper_demo_offline/.feather_s2_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.feather_s2_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.funhouse.test.skip b/examples/Wippersnapper_demo_offline/.funhouse.test.skip new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.funhouse.test.skip @@ -0,0 +1,2 @@ + + diff --git a/examples/Wippersnapper_demo_offline/.funhouse_noota.test.skip b/examples/Wippersnapper_demo_offline/.funhouse_noota.test.skip new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.funhouse_noota.test.skip @@ -0,0 +1,2 @@ + + diff --git a/examples/Wippersnapper_demo_offline/.itsybitsy_esp32.test.skip b/examples/Wippersnapper_demo_offline/.itsybitsy_esp32.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.itsybitsy_esp32.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.magtag.test.skip b/examples/Wippersnapper_demo_offline/.magtag.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.magtag.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.metro_esp32s3.test.skip b/examples/Wippersnapper_demo_offline/.metro_esp32s3.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.metro_esp32s3.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.metro_esp32s3_debug.test.skip b/examples/Wippersnapper_demo_offline/.metro_esp32s3_debug.test.skip new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.metro_esp32s3_debug.test.skip @@ -0,0 +1,2 @@ + + diff --git a/examples/Wippersnapper_demo_offline/.metro_m4_airliftlite_tinyusb.test.skip b/examples/Wippersnapper_demo_offline/.metro_m4_airliftlite_tinyusb.test.skip new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.metro_m4_airliftlite_tinyusb.test.skip @@ -0,0 +1,2 @@ + + diff --git a/examples/Wippersnapper_demo_offline/.metro_rp2350_tinyusb.generate b/examples/Wippersnapper_demo_offline/.metro_rp2350_tinyusb.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.metro_rp2350_tinyusb.generate @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.metroesp32s2.test.skip b/examples/Wippersnapper_demo_offline/.metroesp32s2.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.metroesp32s2.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.metroesp32s2_debug.test.skip b/examples/Wippersnapper_demo_offline/.metroesp32s2_debug.test.skip new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.metroesp32s2_debug.test.skip @@ -0,0 +1,2 @@ + + diff --git a/examples/Wippersnapper_demo_offline/.pico_rp2040_tinyusb.generate b/examples/Wippersnapper_demo_offline/.pico_rp2040_tinyusb.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.pico_rp2040_tinyusb.generate @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.pico_rp2350_tinyusb.generate b/examples/Wippersnapper_demo_offline/.pico_rp2350_tinyusb.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.pico_rp2350_tinyusb.generate @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.picow_rp2040_tinyusb.test.skip b/examples/Wippersnapper_demo_offline/.picow_rp2040_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.picow_rp2040_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.pyportal_tinyusb.test.skip b/examples/Wippersnapper_demo_offline/.pyportal_tinyusb.test.skip new file mode 100644 index 000000000..b28b04f64 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.pyportal_tinyusb.test.skip @@ -0,0 +1,3 @@ + + + diff --git a/examples/Wippersnapper_demo_offline/.pyportal_titano_tinyusb.test.skip b/examples/Wippersnapper_demo_offline/.pyportal_titano_tinyusb.test.skip new file mode 100644 index 000000000..b28b04f64 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.pyportal_titano_tinyusb.test.skip @@ -0,0 +1,3 @@ + + + diff --git a/examples/Wippersnapper_demo_offline/.qtpy_esp32.test.skip b/examples/Wippersnapper_demo_offline/.qtpy_esp32.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.qtpy_esp32.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.qtpy_esp32c3.test.skip b/examples/Wippersnapper_demo_offline/.qtpy_esp32c3.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.qtpy_esp32c3.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.qtpy_esp32s2.test.skip b/examples/Wippersnapper_demo_offline/.qtpy_esp32s2.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.qtpy_esp32s2.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.qtpy_esp32s3.test.skip b/examples/Wippersnapper_demo_offline/.qtpy_esp32s3.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.qtpy_esp32s3.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.qtpy_esp32s3_n4r2.test.skip b/examples/Wippersnapper_demo_offline/.qtpy_esp32s3_n4r2.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.qtpy_esp32s3_n4r2.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.wippersnapper_feather_esp32.test.skip b/examples/Wippersnapper_demo_offline/.wippersnapper_feather_esp32.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.wippersnapper_feather_esp32.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.wippersnapper_qtpy_esp32c3.test.skip b/examples/Wippersnapper_demo_offline/.wippersnapper_qtpy_esp32c3.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.wippersnapper_qtpy_esp32c3.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/Wippersnapper_demo_offline.ino b/examples/Wippersnapper_demo_offline/Wippersnapper_demo_offline.ino new file mode 100644 index 000000000..07ecfcf1e --- /dev/null +++ b/examples/Wippersnapper_demo_offline/Wippersnapper_demo_offline.ino @@ -0,0 +1,24 @@ +// Adafruit IO WipperSnapper +// USE ONLY WITH DEVICES WITHOUT A NETWORK ADAPTER LIKE RP2040 PICO +// +// Adafruit invests time and resources providing this open source code. +// Please support Adafruit and open source hardware by purchasing +// products from Adafruit! +// +// Brent Rubell for Adafruit Industries, 2025 +// +// All text above must be included in any redistribution. + +#include "ws_adapters.h" +ws_adapter_offline wipper; +#define WS_DEBUG // Enable debug output! + +void setup() { + Serial.begin(115200); + wipper.provision(); + wipper.connect(); +} + +void loop() { + wipper.run(); +} \ No newline at end of file diff --git a/examples/wippersnapper_debug/.feather_rp2040_adalogger_tinyusb.test.skip b/examples/wippersnapper_debug/.feather_rp2040_adalogger_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.feather_rp2040_adalogger_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/.metro_esp32s3.test.skip b/examples/wippersnapper_debug/.metro_esp32s3.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.metro_esp32s3.test.skip @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/.metro_esp32s3_debug.generate b/examples/wippersnapper_debug/.metro_esp32s3_debug.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.metro_esp32s3_debug.generate @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/.metro_rp2350_tinyusb.test.skip b/examples/wippersnapper_debug/.metro_rp2350_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.metro_rp2350_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/.metroesp32s2_debug.generate b/examples/wippersnapper_debug/.metroesp32s2_debug.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.metroesp32s2_debug.generate @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/.pico_rp2040_tinyusb.test.skip b/examples/wippersnapper_debug/.pico_rp2040_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.pico_rp2040_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/.pico_rp2350_tinyusb.test.skip b/examples/wippersnapper_debug/.pico_rp2350_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.pico_rp2350_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/wippersnapper_debug.ino b/examples/wippersnapper_debug/wippersnapper_debug.ino index 339ce0b6b..5328b1e71 100644 --- a/examples/wippersnapper_debug/wippersnapper_debug.ino +++ b/examples/wippersnapper_debug/wippersnapper_debug.ino @@ -1,8 +1,10 @@ // Adafruit IO WipperSnapper Beta (DEBUG BUILD ONLY!) -// Brent Rubell for Adafruit Industries, 2021 - 2023 +// Brent Rubell for Adafruit Industries, 2021 - 2025 -#include "Wippersnapper_Networking.h" -Wippersnapper_WiFi wipper; +#include "ws_adapters.h" +ws_adapter_wifi wipper; +// Uncomment the following line to use the offline adapter for Pico +// ws_adapter_offline wipper; // Enable debug output for beta builds #define WS_DEBUG diff --git a/generate_json_checksum.py b/generate_json_checksum.py new file mode 100644 index 000000000..2138fd93a --- /dev/null +++ b/generate_json_checksum.py @@ -0,0 +1,32 @@ +# generates the 8-bit checksum from a JSON file, provided its path is given as an argument +import sys +import json + +# load json file from provided path +try: + with open(sys.argv[1], 'r') as f: + json_data = json.load(f) +except FileNotFoundError as e: + print("Error: JSON file not found, exiting...") + exit(1) + +if not json_data: + print("Error: JSON file did not contain any data or path didn't match exactly, exiting...") + exit(1) + +if 'checksum' in json_data: + del json_data['checksum'] + +# NOTE: This is important to re-serialize json data to match ArduinoJSON's compact serialization format +str_json_data = json.dumps(json_data, separators=(',', ':'), sort_keys=True) + +# calculate checksum +calculated_checksum = sum(bytearray(str_json_data.encode())) & 0xFF +print('Checksum: ', calculated_checksum) +print('Checksum (hex): ', hex(calculated_checksum)) + +# store and write checksum to new file +json_data['checksum'] = calculated_checksum +with open(sys.argv[1], 'w') as f: + json.dump(json_data, f) +print('SUCCESS: Checksum written to JSON file!') \ No newline at end of file diff --git a/library.properties b/library.properties index caa57f7ef..f19870bfb 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit WipperSnapper -version=1.0.0-beta.88 +version=1.0.0 author=Adafruit maintainer=Adafruit sentence=Arduino application for Adafruit.io WipperSnapper @@ -7,4 +7,4 @@ paragraph=Arduino application for Adafruit.io WipperSnapper category=Communication url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino architectures=* -depends=Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit INA219, 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, 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 VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, 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 +depends=Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit INA219, 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, 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 VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, 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, RTClib, StreamUtils, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, SdFat - Adafruit Fork, Adafruit GFX Library diff --git a/partitions-4MB.csv b/partitions-4MB.csv new file mode 100644 index 000000000..f3112a23b --- /dev/null +++ b/partitions-4MB.csv @@ -0,0 +1,11 @@ +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +# bootloader.bin,, 0x1000, 32K +# partition table, 0x8000, 4K + +nvs, data, nvs, 0x9000, 20K, +otadata, data, ota, 0xe000, 8K, +ota_0, app, ota_0, 0x10000, 1408K, +ota_1, app, ota_1, 0x170000, 1408K, +uf2, app, factory,0x2d0000, 256K, +ffat, data, fat, 0x310000, 960K, diff --git a/platformio.ini b/platformio.ini index 1ed2b6d54..22649a951 100644 --- a/platformio.ini +++ b/platformio.ini @@ -14,12 +14,13 @@ default_envs = adafruit_feather_esp32s3_tft, adafruit_magtag29_esp32s2, adafruit [env] framework = arduino monitor_speed = 115200 +extra_scripts = upload_no_build.py lib_compat_mode = strict lib_deps = - adafruit/Adafruit Zero DMA Library adafruit/Adafruit TinyUSB Library - adafruit/Adafruit NeoPixel + adafruit/Adafruit Zero DMA Library adafruit/Adafruit SPIFlash + adafruit/Adafruit NeoPixel adafruit/Adafruit DotStar adafruit/ENS160 - Adafruit Fork adafruit/Adafruit SleepyDog Library @@ -70,20 +71,24 @@ lib_deps = adafruit/Adafruit TouchScreen adafruit/Adafruit MQTT Library bblanchon/ArduinoJson - https://github.com/PaulStoffregen/OneWire.git - https://github.com/milesburton/Arduino-Temperature-Control-Library.git + https://github.com/adafruit/SdFat.git + https://github.com/pstolarz/OneWireNg.git https://github.com/Sensirion/arduino-sht.git - https://github.com/Sensirion/arduino-i2c-scd4x.git https://github.com/Sensirion/arduino-i2c-sen5x.git https://github.com/adafruit/WiFiNINA.git https://github.com/Starmbi/hp_BH1750.git - + https://github.com/adafruit/RTClib.git + https://github.com/bblanchon/ArduinoStreamUtils.git + https://github.com/Sensirion/arduino-i2c-scd4x.git ; Common build environment for ESP32 platform [common:esp32] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip +; platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip +; platform = https://github.com/pioarduino/platform-espressif32#develop +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.07/platform-espressif32.zip lib_ignore = WiFiNINA, WiFi101 monitor_filters = esp32_exception_decoder, time +; upload_speed = 921600 ; Common build environment for ESP8266 platform [common:esp8266] @@ -117,6 +122,18 @@ lib_compat_mode = soft ; can be strict once pio detects SleepyDog on RP2040 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Individual Board Definitions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ESP32-x Boards ; +; extra_scripts = post:pio_mergefs.py + +; Espressif ESP32 Dev Module +; for Wokwi Simulator and Testing +; NoFS +[env:esp32dev] +extends = common:esp32 +board = esp32dev +board_build.partitions = default_8MB.csv +build_flags = -DARDUINO_ESP32_DEV -DOFFLINE_MODE_DEBUG -DOFFLINE_MODE_WOKWI +board_build.filesystem = littlefs +upload_speed = 921600 ; Adafruit ESP32 Feather [env:featheresp32] @@ -132,7 +149,7 @@ board_build.partitions = min_spiffs.csv extends = common:esp32 board = adafruit_feather_esp32_v2 board_build.partitions = default_8MB.csv -build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32_V2 +build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32_V2 -DBUILD_OFFLINE_ONLY board_build.filesystem = littlefs ; Adafruit ItsyBitsy ESP32 @@ -148,7 +165,10 @@ board_build.filesystem = littlefs extends = common:esp32 board = featheresp32-s2 build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S2 -DBOARD_HAS_PSRAM -board_build.partitions = tinyuf2-partitions-4MB.csv +board_build.partitions = tinyuf2-partitions-4MB-noota.csv +;board_build.partitions = tinyuf2-partitions-4MB.csv +;build_type = debug +monitor_filters = esp32_exception_decoder extra_scripts = pre:rename_usb_config.py ; Adafruit Feather ESP32-S2 TFT @@ -164,7 +184,8 @@ extra_scripts = pre:rename_usb_config.py extends = common:esp32 board = adafruit_feather_esp32s2_reversetft build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S2_REVTFT -DBOARD_HAS_PSRAM -board_build.partitions = tinyuf2-partitions-4MB.csv +;board_build.partitions = tinyuf2-partitions-4MB.csv +board_build.partitions = tinyuf2-partitions-4MB-noota.csv extra_scripts = pre:rename_usb_config.py ; Adafruit Feather ESP32-S3 2MB PSRAM @@ -173,7 +194,8 @@ extends = common:esp32 board = adafruit_feather_esp32s3 build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S3 -DBOARD_HAS_PSRAM ;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1 -board_build.partitions = tinyuf2-partitions-4MB.csv +; board_build.partitions = tinyuf2-partitions-4MB.csv +board_build.partitions = tinyuf2-partitions-4MB-noota.csv extra_scripts = pre:rename_usb_config.py ; Adafruit Feather ESP32-S3 NO PSRAM @@ -200,7 +222,7 @@ extends = common:esp32 board = adafruit_feather_esp32s3_reversetft build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S3_REVTFT -DBOARD_HAS_PSRAM ;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1 -board_build.partitions = tinyuf2-partitions-4MB.csv +board_build.partitions = tinyuf2-partitions-4MB-noota.csv extra_scripts = pre:rename_usb_config.py ; Adafruit Magtag ESP32-S2 @@ -221,13 +243,59 @@ build_flags = -DARDUINO_METRO_ESP32S2 -DBOARD_HAS_PSRAM board_build.partitions = tinyuf2-partitions-4MB.csv extra_scripts = pre:rename_usb_config.py +; Adafruit Metro ESP32-S3 +[env:adafruit_metro_esp32s3] +extends = common:esp32 +board = adafruit_metro_esp32s3 +build_flags = -DARDUINO_METRO_ESP32S3 -DBOARD_HAS_PSRAM +;set partition to tinyuf2-partitions-16MB.csv as of idf 5.1 +board_build.partitions = tinyuf2-partitions-16MB.csv +extra_scripts = pre:rename_usb_config.py + +; Adafruit Funhouse ESP32-S2 +[env:adafruit_funhouse_esp32s2] +extends = common:esp32 +board = adafruit_funhouse_esp32s2 +build_flags = -DARDUINO_FUNHOUSE -DBOARD_HAS_PSRAM +;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1 +board_build.partitions = tinyuf2-partitions-4MB-noota.csv +extra_scripts = pre:rename_usb_config.py + +; Adafruit Funhouse ESP32-S2 +[env:adafruit_funhouse_esp32s2_debug] +extends = common:esp32 +board = adafruit_funhouse_esp32s2 +;lib_extra_dirs = +build_type = debug +build_flags = + -DARDUINO_FUNHOUSE + -DBOARD_HAS_PSRAM + -DCFG_TUSB_DEBUG=1 + -DDEBUG=1 + -DESP_LOG_LEVEL=ESP_LOG_VERBOSE + -DARDUINO_CORE_DEBUG_LEVEL=5 + -DCORE_DEBUG_LEVEL=5 + -DARDUHAL_LOG_LEVEL=5 + ; USB Configuration + ; Uncomment if USB CDC on boot is needed + ; -DARDUINO_USB_CDC_ON_BOOT=1 + ; -DARDUINO_USB_MODE=0 ; 0 for CDC + TinyUSB, 1 for Hardware CDC + JTAG + ; LVGL Debugging + -DLV_USE_DEBUG=1 + -DLV_USE_LOG=1 + -DLV_LOG_PRINTF=1 + -DLV_LOG_COLOR=1 + -DLV_LOG_LEVEL=LV_LOG_LEVEL_TRACE +;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1 +board_build.partitions = tinyuf2-partitions-4MB-noota.csv +extra_scripts = pre:rename_usb_config.py + ; Adafruit QT Py ESP32 Pico [env:adafruit_qtpy_esp32] extends = common:esp32 board = adafruit_qtpy_esp32 board_build.partitions = default_8MB.csv board_build.filesystem = littlefs -build_type = debug build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32 ; Adafruit QT Py ESP32-C3 @@ -237,14 +305,16 @@ board = adafruit_qtpy_esp32c3 build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32C3 board_build.filesystem = littlefs board_build.partitions = min_spiffs.csv +upload_port = /dev/cu.usbserial-120 ; Adafruit QT Py ESP32-S2 [env:adafruit_qtpy_esp32s2] extends = common:esp32 board = adafruit_qtpy_esp32s2 -build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32S2 -DBOARD_HAS_PSRAM +build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32S2 -DBOARD_HAS_PSRAM -DBUILD_OFFLINE_ONLY ;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1 -board_build.partitions = tinyuf2-partitions-4MB.csv +; board_build.partitions = tinyuf2-partitions-4MB.csv +board_build.partitions = tinyuf2-partitions-4MB-noota.csv extra_scripts = pre:rename_usb_config.py ; Adafruit QT Py ESP32-S3 NO PSRAM @@ -340,6 +410,41 @@ build_flags = -DUSE_TINYUSB=1 -DADAFRUIT_METRO_M4_AIRLIFT_LITE upload_port = /dev/cu.usbmodem1201 +[env:raspberrypi_pico] +platform = https://github.com/maxgerhardt/platform-raspberrypi.git#develop +board = rpipico +platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git +board_build.filesystem_size = 0.5m +build_flags = -DUSE_TINYUSB +; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed +lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library + +[env:raspberrypi_pico_2] +platform = https://github.com/maxgerhardt/platform-raspberrypi.git#develop +board = rpipico2 +platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git +board_build.filesystem_size = 0.5m +build_flags = -DUSE_TINYUSB -DBUILD_OFFLINE_ONLY +; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed +lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library + +[env:adafruit_feather_adalogger] +platform = https://github.com/maxgerhardt/platform-raspberrypi.git#develop +board = adafruit_feather_adalogger +platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git +board_build.filesystem_size = 0.5m +build_flags = -DUSE_TINYUSB -DBUILD_OFFLINE_ONLY +; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed +lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library + +[env:adafruit_metro_rp2350] +platform = https://github.com/brentru/platform-raspberrypi.git#develop +board = adafruit_metro_rp2350 +platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git +board_build.filesystem_size = 0.5m +build_flags = -DUSE_TINYUSB -DBUILD_OFFLINE_ONLY +; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed +lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library [env:raspberypi_picow] extends = common:rp2040 diff --git a/src/Wippersnapper.cpp b/src/Wippersnapper.cpp deleted file mode 100644 index a4c190825..000000000 --- a/src/Wippersnapper.cpp +++ /dev/null @@ -1,2888 +0,0 @@ -/*! - * @file Wippersnapper.cpp - * - * @mainpage Adafruit Wippersnapper Wrapper - * - * @section intro_sec Introduction - * - * This is the documentation for Adafruit's Wippersnapper wrapper for the - * Arduino platform. It is designed specifically to work with the - * Adafruit IO+ Wippersnapper IoT platform. - * - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * @section dependencies Dependencies - * - * This library depends on Adafruit_Sensor being - * present on your system. Please make sure you have installed the latest - * version before using this library. - * - * @section author Author - * - * Copyright (c) Brent Rubell 2020-2023 for Adafruit Industries. - * - * @section license License - * - * BSD license, all text here must be included in any redistribution. - * - */ - -#include "Wippersnapper.h" - -Wippersnapper WS; - -Wippersnapper::Wippersnapper() { - _mqtt = 0; // MQTT Client object - - // Reserved MQTT Topics - _topic_description = 0; - _topic_description_status = 0; - _topic_signal_device = 0; - _topic_signal_brkr = 0; - _err_topic = 0; - _throttle_topic = 0; - _err_sub = 0; - _throttle_sub = 0; - - // Init. component classes - // LEDC (ESP32-ONLY) -#ifdef ARDUINO_ARCH_ESP32 - WS._ledc = new ws_ledc(); -#endif - - // PWM (Arch-specific implementations) -#ifdef ARDUINO_ARCH_ESP32 - WS._pwmComponent = new ws_pwm(WS._ledc); -#else - WS._pwmComponent = new ws_pwm(); -#endif - - // Servo - WS._servoComponent = new ws_servo(); - - // UART - WS._uartComponent = new ws_uart(); - - // DallasSemi (OneWire) - WS._ds18x20Component = new ws_ds18x20(); -}; - -/**************************************************************************/ -/*! - @brief Wippersnapper destructor -*/ -/**************************************************************************/ -Wippersnapper::~Wippersnapper() { - // free topics - free(_topic_description); - free(_topic_signal_device); - free(_topic_signal_brkr); - free(_err_sub); - free(_throttle_sub); -} - -/**************************************************************************/ -/*! - @brief Provisions a WipperSnapper device with its network - configuration and Adafruit IO credentials. -*/ -/**************************************************************************/ -void Wippersnapper::provision() { - // Obtain device's MAC address - getMacAddr(); - - // Initialize the status LED for signaling FS errors - initStatusLED(); - -// Initialize the filesystem -#ifdef USE_TINYUSB - _fileSystem = new Wippersnapper_FS(); -#elif defined(USE_LITTLEFS) - _littleFS = new WipperSnapper_LittleFS(); -#endif - -#ifdef USE_DISPLAY - // Initialize the display - displayConfig config; - WS._fileSystem->parseDisplayConfig(config); - WS._display = new ws_display_driver(config); - // Begin display - if (!WS._display->begin()) { - WS_DEBUG_PRINTLN("Unable to enable display driver and LVGL"); - haltError("Unable to enable display driver, please check the json " - "configuration!"); - } - - WS._display->enableLogging(); - releaseStatusLED(); // don't use status LED if we are using the display - // UI Setup - WS._ui_helper = new ws_display_ui_helper(WS._display); - WS._ui_helper->set_bg_black(); - WS._ui_helper->show_scr_load(); - WS._ui_helper->set_label_status("Validating Credentials..."); -#endif - - // Parse secrets.json file -#ifdef USE_TINYUSB - _fileSystem->parseSecrets(); -#elif defined(USE_LITTLEFS) - _littleFS->parseSecrets(); -#else - set_user_key(); // non-fs-backed, sets global credentials within network iface -#endif - // Set the status pixel's brightness - setStatusLEDBrightness(WS._config.status_pixel_brightness); - // Set device's wireless credentials - set_ssid_pass(); - -#ifdef USE_DISPLAY - WS._ui_helper->set_label_status(""); - WS._ui_helper->set_load_bar_icon_complete(loadBarIconFile); -#endif -} - -/**************************************************************************/ -/*! - @brief Disconnects from Adafruit IO+ Wippersnapper. -*/ -/**************************************************************************/ -void Wippersnapper::disconnect() { _disconnect(); } - -// Concrete class definition for abstract classes - -/****************************************************************************/ -/*! - @brief Connects to wireless network. -*/ -/****************************************************************************/ -void Wippersnapper::_connect() { - WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); -} - -/****************************************************************************/ -/*! - @brief Disconnect Wippersnapper MQTT session and network. -*/ -/****************************************************************************/ -void Wippersnapper::_disconnect() { - WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); -} - -/****************************************************************************/ -/*! - @brief Sets the network interface's unique identifer, typically the - MAC address. -*/ -/****************************************************************************/ -void Wippersnapper::getMacAddr() { - WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); -} - -/****************************************************************************/ -/*! - @brief Gets the network's RSSI. - @return int32_t RSSI value, 0 to 255, in dB -*/ -/****************************************************************************/ -int32_t Wippersnapper::getRSSI() { - WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); - return 0; -} - -/****************************************************************************/ -/*! - @brief Sets up the MQTT client session. - @param clientID - A unique client identifier string. -*/ -/****************************************************************************/ -void Wippersnapper::setupMQTTClient(const char * /*clientID*/) { - WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); -} - -/****************************************************************************/ -/*! - @brief Returns the network's connection status - @returns Network status as ws_status_t. -*/ -/****************************************************************************/ -ws_status_t Wippersnapper::networkStatus() { - WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); - return WS_IDLE; -} - -/****************************************************************************/ -/*! - @brief Sets the device's wireless network credentials. - @param ssid - Your wireless network's SSID - @param ssidPassword - Your wireless network's password. -*/ -/****************************************************************************/ -void Wippersnapper::set_ssid_pass(const char * /*ssid*/, - const char * /*ssidPassword*/) { - WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); -} - -/****************************************************************************/ -/*! - @brief Sets the device's wireless network credentials from the - secrets.json configuration file. -*/ -/****************************************************************************/ -void Wippersnapper::set_ssid_pass() { - WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); -} - -/***********************************************************/ -/*! -@brief Performs a scan of local WiFi networks. -@returns True if `_network_ssid` is found, False otherwise. -*/ -/***********************************************************/ -bool Wippersnapper::check_valid_ssid() { - WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); - return false; -} - -/****************************************************************************/ -/*! - @brief Configures the device's Adafruit IO credentials. This method - should be used only if filesystem-backed provisioning is - not avaliable. -*/ -/****************************************************************************/ -void Wippersnapper::set_user_key() { - WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); -} - -// Decoders // - -/****************************************************************************/ -/*! - @brief Configures an analog input pin according to a - wippersnapper_pin_v1_ConfigurePinRequest message. - @param pinMsg - Pointer to a wippersnapper_pin_v1_ConfigurePinRequest message. - @returns True if analog pin configured successfully, False otherwise. -*/ -/****************************************************************************/ -bool Wippersnapper::configAnalogInPinReq( - wippersnapper_pin_v1_ConfigurePinRequest *pinMsg) { - bool is_success = true; - -#if defined(ARDUINO_ARCH_RP2040) - char *pinName = pinMsg->pin_name + 1; - int pin = atoi(pinName); -#else - char *pinName = pinMsg->pin_name + 1; - int pin = atoi(pinName); -#endif - - if (pinMsg->request_type == - wippersnapper_pin_v1_ConfigurePinRequest_RequestType_REQUEST_TYPE_CREATE) { - WS._analogIO->initAnalogInputPin(pin, pinMsg->period, pinMsg->pull, - pinMsg->analog_read_mode); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Pin] Reading %s every %0.2f seconds\n", - pinMsg->pin_name, pinMsg->period); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - } else if ( - pinMsg->request_type == - wippersnapper_pin_v1_ConfigurePinRequest_RequestType_REQUEST_TYPE_DELETE) { - WS._analogIO->deinitAnalogPin(pinMsg->direction, pin); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Pin] De-initialized pin %s\n.", pinMsg->pin_name); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - } else { - WS_DEBUG_PRINTLN("ERROR: Could not decode analog pin request!"); - is_success = false; - } - return is_success; -} - -/****************************************************************************/ -/*! - @brief Configures a pin according to a - wippersnapper_pin_v1_ConfigurePinRequest message. - @param pinMsg - Pointer to a wippersnapper_pin_v1_ConfigurePinRequest message. - @returns True if pin configured successfully, False otherwise. -*/ -/****************************************************************************/ -bool Wippersnapper::configureDigitalPinReq( - wippersnapper_pin_v1_ConfigurePinRequest *pinMsg) { - bool is_success = true; - char *pinName = pinMsg->pin_name + 1; - int pin = atoi(pinName); - - if (pinMsg->request_type == - wippersnapper_pin_v1_ConfigurePinRequest_RequestType_REQUEST_TYPE_CREATE) { - // Initialize GPIO pin - WS._digitalGPIO->initDigitalPin(pinMsg->direction, pin, pinMsg->period, - pinMsg->pull); - } else if ( - pinMsg->request_type == - wippersnapper_pin_v1_ConfigurePinRequest_RequestType_REQUEST_TYPE_DELETE) { - // Delete digital GPIO pin - WS._digitalGPIO->deinitDigitalPin(pinMsg->direction, pin); - } else { - WS_DEBUG_PRINTLN("ERROR: Could not decode digital pin request type"); - } - - return is_success; -} - -/*****************************************************************************/ -/*! - @brief Decodes a repeated ConfigurePinRequests messages. - @param stream - Input stream to read from. - @param field - Message descriptor, usually autogenerated. - @param arg - Stores any information the decoding callback may need. - @returns True if pin configuration decoded successfully, False otherwise. -*/ -/*****************************************************************************/ -bool cbDecodePinConfigMsg(pb_istream_t *stream, const pb_field_t *field, - void **arg) { - (void)field; // marking unused parameters to avoid compiler warning - (void)arg; // marking unused parameters to avoid compiler warning - bool is_success = true; - WS_DEBUG_PRINTLN("cbDecodePinConfigMsg"); - - // pb_decode the stream into a pinReqMessage - wippersnapper_pin_v1_ConfigurePinRequest pinReqMsg = - wippersnapper_pin_v1_ConfigurePinRequest_init_zero; - if (!ws_pb_decode(stream, wippersnapper_pin_v1_ConfigurePinRequest_fields, - &pinReqMsg)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode CreateSignalRequest") - is_success = false; - } - - // Decode pin configuration request msg - if (pinReqMsg.mode == wippersnapper_pin_v1_Mode_MODE_DIGITAL) { - is_success = WS.configureDigitalPinReq(&pinReqMsg); - } else if (pinReqMsg.mode == wippersnapper_pin_v1_Mode_MODE_ANALOG) { - is_success = WS.configAnalogInPinReq(&pinReqMsg); - } else { - WS_DEBUG_PRINTLN("ERROR: Pin mode invalid!"); - is_success = false; - } - - return is_success; -} - -/**************************************************************************/ -/*! - @brief Decodes repeated PinEvents (digital pin write) messages. - @param stream - Input stream to read from. - @param field - Message descriptor, usually autogenerated. - @param arg - Stores any information the decoding callback may need. - @returns True if successfully decoded, False otherwise. -*/ -/**************************************************************************/ -bool cbDecodeDigitalPinWriteMsg(pb_istream_t *stream, const pb_field_t *field, - void **arg) { - bool is_success = true; - (void)field; // marking unused parameters to avoid compiler warning - (void)arg; // marking unused parameters to avoid compiler warning - WS_DEBUG_PRINTLN("cbDecodeDigitalPinWriteMsg"); - - // Decode stream into a PinEvent - wippersnapper_pin_v1_PinEvent pinEventMsg = - wippersnapper_pin_v1_PinEvent_init_zero; - if (!ws_pb_decode(stream, wippersnapper_pin_v1_PinEvent_fields, - &pinEventMsg)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode PinEvents") - is_success = false; - } - - // execute callback - char *pinName = pinEventMsg.pin_name + 1; - WS._digitalGPIO->digitalWriteSvc(atoi(pinName), atoi(pinEventMsg.pin_value)); - - return is_success; -} - -/**************************************************************************/ -/*! - @brief Sets payload callbacks inside the signal message's - submessage. - @param stream - Input stream to read from. - @param field - Message descriptor, usually autogenerated. - @param arg - Stores any information the decoding callback may need. - @returns True if successfully decoded, false otherwise. -*/ -/**************************************************************************/ -bool cbSignalMsg(pb_istream_t *stream, const pb_field_t *field, void **arg) { - (void)arg; // marking unused parameters to avoid compiler warning - bool is_success = true; - WS_DEBUG_PRINTLN("cbSignalMsg"); - - pb_size_t arr_sz = field->array_size; - WS_DEBUG_PRINT("Sub-messages found: "); - WS_DEBUG_PRINTLN(arr_sz); - - if (field->tag == - wippersnapper_signal_v1_CreateSignalRequest_pin_configs_tag) { - WS_DEBUG_PRINTLN("Signal Msg Tag: Pin Configuration"); - // array to store the decoded CreateSignalRequests data - wippersnapper_pin_v1_ConfigurePinRequests msg = - wippersnapper_pin_v1_ConfigurePinRequests_init_zero; - // set up callback - msg.list.funcs.decode = cbDecodePinConfigMsg; - msg.list.arg = field->pData; - // decode each ConfigurePinRequest sub-message - if (!ws_pb_decode(stream, wippersnapper_pin_v1_ConfigurePinRequests_fields, - &msg)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode CreateSignalRequest") - is_success = false; - WS.pinCfgCompleted = false; - } - // If this is the initial configuration - if (!WS.pinCfgCompleted) { - WS_DEBUG_PRINTLN("Initial Pin Configuration Complete!"); - WS.pinCfgCompleted = true; - } - } else if (field->tag == - wippersnapper_signal_v1_CreateSignalRequest_pin_events_tag) { - WS_DEBUG_PRINTLN("Signal Msg Tag: Pin Event"); - // array to store the decoded PinEvents data - wippersnapper_pin_v1_PinEvents msg = - wippersnapper_pin_v1_PinEvents_init_zero; - // set up callback - msg.list.funcs.decode = cbDecodeDigitalPinWriteMsg; - msg.list.arg = field->pData; - // decode each PinEvents sub-message - if (!ws_pb_decode(stream, wippersnapper_pin_v1_PinEvents_fields, &msg)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode CreateSign2alRequest") - is_success = false; - } - } else { - WS_DEBUG_PRINTLN("ERROR: Unexpected signal msg tag."); - } - - // once this is returned, pb_dec_submessage() - // decodes the submessage contents. - return is_success; -} - -/**************************************************************************/ -/*! - @brief Decodes a signal buffer protobuf message. - NOTE: Should be executed in-order after a new _buffer is recieved. - @param encodedSignalMsg - Encoded signal message. - @return true if successfully decoded signal message, false otherwise. -*/ -/**************************************************************************/ -bool Wippersnapper::decodeSignalMsg( - wippersnapper_signal_v1_CreateSignalRequest *encodedSignalMsg) { - bool is_success = true; - WS_DEBUG_PRINTLN("decodeSignalMsg"); - - /* Set up the payload callback, which will set up the callbacks for - each oneof payload field once the field tag is known */ - encodedSignalMsg->cb_payload.funcs.decode = cbSignalMsg; - - // decode the CreateSignalRequest, calls cbSignalMessage and assoc. callbacks - pb_istream_t stream = pb_istream_from_buffer(WS._buffer, WS.bufSize); - if (!ws_pb_decode(&stream, wippersnapper_signal_v1_CreateSignalRequest_fields, - encodedSignalMsg)) { - WS_DEBUG_PRINTLN( - "ERROR (decodeSignalMsg):, Could not decode CreateSignalRequest") - is_success = false; - } - return is_success; -} - -/**************************************************************************/ -/*! - @brief Called when signal topic receives a new message. Fills - shared buffer with data from payload. - @param data - Data from MQTT broker. - @param len - Length of data received from MQTT broker. -*/ -/**************************************************************************/ -void cbSignalTopic(char *data, uint16_t len) { - WS_DEBUG_PRINTLN("cbSignalTopic: New Msg on Signal Topic"); - WS_DEBUG_PRINT(len); - WS_DEBUG_PRINTLN(" bytes."); - // zero-out current buffer - memset(WS._buffer, 0, sizeof(WS._buffer)); - // copy data to buffer - memcpy(WS._buffer, data, len); - WS.bufSize = len; - - // Empty struct for storing the signal message - WS._incomingSignalMsg = wippersnapper_signal_v1_CreateSignalRequest_init_zero; - - // Attempt to decode a signal message - if (!WS.decodeSignalMsg(&WS._incomingSignalMsg)) { - WS_DEBUG_PRINTLN("ERROR: Failed to decode signal message"); - } -} - -/******************************************************************************************/ -/*! - @brief Publishes an I2C response signal message to the broker. - @param msgi2cResponse - A pointer to an I2C response message typedef. -*/ -/******************************************************************************************/ -void publishI2CResponse(wippersnapper_signal_v1_I2CResponse *msgi2cResponse) { - size_t msgSz; - pb_get_encoded_size(&msgSz, wippersnapper_signal_v1_I2CResponse_fields, - msgi2cResponse); - WS_DEBUG_PRINT("Publishing Message: I2CResponse..."); - if (!WS._mqtt->publish(WS._topic_signal_i2c_device, WS._buffer_outgoing, - msgSz, 1)) { - WS_DEBUG_PRINTLN("ERROR: Failed to publish I2C Response!"); - } else { - WS_DEBUG_PRINTLN("Published!"); - } -} - -/******************************************************************************************/ -/*! - @brief Encodes an wippersnapper_signal_v1_I2CResponse message. - @param msgi2cResponse - A pointer to an wippersnapper_signal_v1_I2CResponse. - @return True if encoded successfully, False otherwise. -*/ -/******************************************************************************************/ -bool encodeI2CResponse(wippersnapper_signal_v1_I2CResponse *msgi2cResponse) { - memset(WS._buffer_outgoing, 0, sizeof(WS._buffer_outgoing)); - pb_ostream_t ostream = - pb_ostream_from_buffer(WS._buffer_outgoing, sizeof(WS._buffer_outgoing)); - if (!ws_pb_encode(&ostream, wippersnapper_signal_v1_I2CResponse_fields, - msgi2cResponse)) { - WS_DEBUG_PRINTLN("ERROR: Unable to encode I2C response message!"); - return false; - } - return true; -} - -/******************************************************************************************/ -/*! - @brief Initializes an I2C bus component - @param msgInitRequest - A pointer to an i2c bus initialization message. - @return True if initialized successfully, False otherwise. -*/ -/******************************************************************************************/ -bool initializeI2CBus(wippersnapper_i2c_v1_I2CBusInitRequest msgInitRequest) { - // FUTURE TODO:we should add support for multiple i2c ports! - if (WS._isI2CPort0Init) - return true; - // Initialize bus - WS._i2cPort0 = new WipperSnapper_Component_I2C(&msgInitRequest); - WS.i2cComponents.push_back(WS._i2cPort0); - WS._isI2CPort0Init = WS._i2cPort0->isInitialized(); - return WS._isI2CPort0Init; -} - -/******************************************************************************************/ -/*! - @brief Decodes a list of I2C Device Initialization messages. - @param stream - Incoming data stream from buffer. - @param field - Protobuf message's tag type. - @param arg - Optional arguments from pb_decode calling function. - @returns True if decoded successfully, False otherwise. -*/ -/******************************************************************************************/ -bool cbDecodeI2CDeviceInitRequestList(pb_istream_t *stream, - const pb_field_t *field, void **arg) { - (void)field; // marking unused parameters to avoid compiler warning - (void)arg; // marking unused parameters to avoid compiler warning - WS_DEBUG_PRINTLN("EXEC: cbDecodeI2CDeviceInitRequestList"); - // Decode stream into individual msgI2CDeviceInitRequest messages - wippersnapper_i2c_v1_I2CDeviceInitRequest msgI2CDeviceInitRequest = - wippersnapper_i2c_v1_I2CDeviceInitRequest_init_zero; - if (!ws_pb_decode(stream, wippersnapper_i2c_v1_I2CDeviceInitRequest_fields, - &msgI2CDeviceInitRequest)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode I2CDeviceInitRequest message."); - return false; - } - - // Create response - wippersnapper_signal_v1_I2CResponse msgi2cResponse = - wippersnapper_signal_v1_I2CResponse_init_zero; - msgi2cResponse.which_payload = - wippersnapper_signal_v1_I2CResponse_resp_i2c_device_init_tag; - - // Check I2C bus - if (!initializeI2CBus(msgI2CDeviceInitRequest.i2c_bus_init_req)) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize I2C Bus"); - msgi2cResponse.payload.resp_i2c_device_init.bus_response = - WS._i2cPort0->getBusStatus(); - if (!encodeI2CResponse(&msgi2cResponse)) { - WS_DEBUG_PRINTLN("ERROR: encoding I2C Response!"); - return false; - } - publishI2CResponse(&msgi2cResponse); - return true; - } - - WS._i2cPort0->initI2CDevice(&msgI2CDeviceInitRequest); - - // Fill device's address and the initialization status - // TODO: The filling should be done within the method though? - msgi2cResponse.payload.resp_i2c_device_init.i2c_device_address = - msgI2CDeviceInitRequest.i2c_device_address; - msgi2cResponse.payload.resp_i2c_device_init.bus_response = - WS._i2cPort0->getBusStatus(); - - // Encode response - if (!encodeI2CResponse(&msgi2cResponse)) { - return false; - } - - // Publish a response for the I2C device - publishI2CResponse(&msgi2cResponse); - return true; -} - -/******************************************************************************************/ -/*! - @brief Decodes an I2C signal request message and executes the - callback based on the message's tag. If successful, - publishes an I2C signal response back to the broker. - @param stream - Incoming data stream from buffer. - @param field - Protobuf message's tag type. - @param arg - Optional arguments from decoder calling function. - @returns True if decoded successfully, False otherwise. -*/ -/******************************************************************************************/ -bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field, - void **arg) { - bool is_success = true; - (void)arg; // marking unused parameter to avoid compiler warning - WS_DEBUG_PRINTLN("cbDecodeSignalRequestI2C"); - // Create I2C Response - wippersnapper_signal_v1_I2CResponse msgi2cResponse = - wippersnapper_signal_v1_I2CResponse_init_zero; - - if (field->tag == wippersnapper_signal_v1_I2CRequest_req_i2c_scan_tag) { - WS_DEBUG_PRINTLN("I2C Scan Request"); - - // Decode I2CBusScanRequest - wippersnapper_i2c_v1_I2CBusScanRequest msgScanReq = - wippersnapper_i2c_v1_I2CBusScanRequest_init_zero; - if (!ws_pb_decode(stream, wippersnapper_i2c_v1_I2CBusScanRequest_fields, - &msgScanReq)) { - WS_DEBUG_PRINTLN( - "ERROR: Could not decode wippersnapper_i2c_v1_I2CBusScanRequest"); - return false; // fail out if we can't decode the request - } - - // Empty response message - wippersnapper_i2c_v1_I2CBusScanResponse scanResp = - wippersnapper_i2c_v1_I2CBusScanResponse_init_zero; - - // Check I2C bus - if (!initializeI2CBus(msgScanReq.bus_init_request)) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize I2C Bus"); - msgi2cResponse.payload.resp_i2c_scan.bus_response = - WS._i2cPort0->getBusStatus(); - if (!encodeI2CResponse(&msgi2cResponse)) { - WS_DEBUG_PRINTLN("ERROR: encoding I2C Response!"); - return false; - } - publishI2CResponse(&msgi2cResponse); - return true; - } - - // Scan I2C bus - scanResp = WS._i2cPort0->scanAddresses(); - - // Fill I2CResponse - msgi2cResponse.which_payload = - wippersnapper_signal_v1_I2CResponse_resp_i2c_scan_tag; - memcpy(msgi2cResponse.payload.resp_i2c_scan.addresses_found, - scanResp.addresses_found, sizeof(scanResp.addresses_found)); - msgi2cResponse.payload.resp_i2c_scan.addresses_found_count = - scanResp.addresses_found_count; - - msgi2cResponse.payload.resp_i2c_scan.bus_response = scanResp.bus_response; - // Encode I2CResponse - if (!encodeI2CResponse(&msgi2cResponse)) { - return false; - } - } else if ( - field->tag == - wippersnapper_signal_v1_I2CRequest_req_i2c_device_init_requests_tag) { - WS_DEBUG_PRINTLN("I2C Device LIST Init Request Found!"); - - // Decode stream - wippersnapper_i2c_v1_I2CDeviceInitRequests msgI2CDeviceInitRequestList = - wippersnapper_i2c_v1_I2CDeviceInitRequests_init_zero; - // Set up callback - msgI2CDeviceInitRequestList.list.funcs.decode = - cbDecodeI2CDeviceInitRequestList; - msgI2CDeviceInitRequestList.list.arg = field->pData; - // Decode each sub-message - if (!ws_pb_decode(stream, wippersnapper_i2c_v1_I2CDeviceInitRequests_fields, - &msgI2CDeviceInitRequestList)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode I2CDeviceInitRequests"); - is_success = false; - } - // return so we don't publish an empty message, we already published within - // cbDecodeI2CDeviceInitRequestList() for each device - return is_success; - } else if (field->tag == - wippersnapper_signal_v1_I2CRequest_req_i2c_device_init_tag) { - WS_DEBUG_PRINTLN("I2C Device Init Request Found!"); - - // Decode stream into an I2CDeviceInitRequest - wippersnapper_i2c_v1_I2CDeviceInitRequest msgI2CDeviceInitRequest = - wippersnapper_i2c_v1_I2CDeviceInitRequest_init_zero; - // Decode stream into struct, msgI2CDeviceInitRequest - if (!ws_pb_decode(stream, wippersnapper_i2c_v1_I2CDeviceInitRequest_fields, - &msgI2CDeviceInitRequest)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode I2CDeviceInitRequest message."); - return false; // fail out if we can't decode - } - - // Create empty response - msgi2cResponse = wippersnapper_signal_v1_I2CResponse_init_zero; - msgi2cResponse.which_payload = - wippersnapper_signal_v1_I2CResponse_resp_i2c_device_init_tag; - - // Check I2C bus - if (!initializeI2CBus(msgI2CDeviceInitRequest.i2c_bus_init_req)) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize I2C Bus"); - msgi2cResponse.payload.resp_i2c_device_init.bus_response = - WS._i2cPort0->getBusStatus(); - if (!encodeI2CResponse(&msgi2cResponse)) { - WS_DEBUG_PRINTLN("ERROR: encoding I2C Response!"); - return false; - } - publishI2CResponse(&msgi2cResponse); - return true; - } - - // Initialize I2C device - WS._i2cPort0->initI2CDevice(&msgI2CDeviceInitRequest); - - // Fill device's address and bus status - msgi2cResponse.payload.resp_i2c_device_init.i2c_device_address = - msgI2CDeviceInitRequest.i2c_device_address; - msgi2cResponse.payload.resp_i2c_device_init.bus_response = - WS._i2cPort0->getBusStatus(); - - // Encode response - if (!encodeI2CResponse(&msgi2cResponse)) { - return false; - } - } else if (field->tag == - wippersnapper_signal_v1_I2CRequest_req_i2c_device_update_tag) { - WS_DEBUG_PRINTLN("=> INCOMING REQUEST: I2CDeviceUpdateRequest"); - - // New I2CDeviceUpdateRequest message - wippersnapper_i2c_v1_I2CDeviceUpdateRequest msgI2CDeviceUpdateRequest = - wippersnapper_i2c_v1_I2CDeviceUpdateRequest_init_zero; - - // Decode stream into message - if (!ws_pb_decode(stream, - wippersnapper_i2c_v1_I2CDeviceUpdateRequest_fields, - &msgI2CDeviceUpdateRequest)) { - WS_DEBUG_PRINTLN( - "ERROR: Could not decode I2CDeviceUpdateRequest message."); - return false; // fail out if we can't decode - } - - // Empty I2C response to fill out - msgi2cResponse = wippersnapper_signal_v1_I2CResponse_init_zero; - msgi2cResponse.which_payload = - wippersnapper_signal_v1_I2CResponse_resp_i2c_device_update_tag; - - // Update I2C device's properties - WS._i2cPort0->updateI2CDeviceProperties(&msgI2CDeviceUpdateRequest); - - // Fill address - msgi2cResponse.payload.resp_i2c_device_update.i2c_device_address = - msgI2CDeviceUpdateRequest.i2c_device_address; - msgi2cResponse.payload.resp_i2c_device_update.bus_response = - WS._i2cPort0->getBusStatus(); - - // Encode response - if (!encodeI2CResponse(&msgi2cResponse)) { - return false; - } - } else if (field->tag == - wippersnapper_signal_v1_I2CRequest_req_i2c_device_deinit_tag) { - WS_DEBUG_PRINTLN("NEW COMMAND: I2C Device Deinit"); - // Decode stream into an I2CDeviceDeinitRequest - wippersnapper_i2c_v1_I2CDeviceDeinitRequest msgI2CDeviceDeinitRequest = - wippersnapper_i2c_v1_I2CDeviceDeinitRequest_init_zero; - // Decode stream into struct, msgI2CDeviceDeinitRequest - if (!ws_pb_decode(stream, - wippersnapper_i2c_v1_I2CDeviceDeinitRequest_fields, - &msgI2CDeviceDeinitRequest)) { - WS_DEBUG_PRINTLN( - "ERROR: Could not decode I2CDeviceDeinitRequest message."); - return false; // fail out if we can't decode - } - - // Empty I2C response to fill out - msgi2cResponse = wippersnapper_signal_v1_I2CResponse_init_zero; - msgi2cResponse.which_payload = - wippersnapper_signal_v1_I2CResponse_resp_i2c_device_deinit_tag; - - // Deinitialize I2C device - WS._i2cPort0->deinitI2CDevice(&msgI2CDeviceDeinitRequest); - // Fill deinit response - msgi2cResponse.payload.resp_i2c_device_deinit.i2c_device_address = - msgI2CDeviceDeinitRequest.i2c_device_address; - msgi2cResponse.payload.resp_i2c_device_deinit.bus_response = - WS._i2cPort0->getBusStatus(); - - // Encode response - if (!encodeI2CResponse(&msgi2cResponse)) { - return false; - } - } else { - WS_DEBUG_PRINTLN("ERROR: Undefined I2C message tag"); - return false; // fail out, we didn't encode anything to publish - } - // Publish the I2CResponse - publishI2CResponse(&msgi2cResponse); - return is_success; -} - -/**************************************************************************/ -/*! - @brief Called when i2c signal sub-topic receives a new message and - attempts to decode a signal request message. - @param data - Incoming data from MQTT broker. - @param len - Length of incoming data. -*/ -/**************************************************************************/ -void cbSignalI2CReq(char *data, uint16_t len) { - WS_DEBUG_PRINTLN("* NEW MESSAGE [Topic: Signal-I2C]: "); - WS_DEBUG_PRINT(len); - WS_DEBUG_PRINTLN(" bytes."); - // zero-out current buffer - memset(WS._buffer, 0, sizeof(WS._buffer)); - // copy mqtt data into buffer - memcpy(WS._buffer, data, len); - WS.bufSize = len; - - // Zero-out existing I2C signal msg. - WS.msgSignalI2C = wippersnapper_signal_v1_I2CRequest_init_zero; - - // Set up the payload callback, which will set up the callbacks for - // each oneof payload field once the field tag is known - WS.msgSignalI2C.cb_payload.funcs.decode = cbDecodeSignalRequestI2C; - - // Decode I2C signal request - pb_istream_t istream = pb_istream_from_buffer(WS._buffer, WS.bufSize); - if (!ws_pb_decode(&istream, wippersnapper_signal_v1_I2CRequest_fields, - &WS.msgSignalI2C)) - WS_DEBUG_PRINTLN("ERROR: Unable to decode I2C message"); -} - -/******************************************************************************************/ -/*! - @brief Decodes a servo message and dispatches to the servo component. - @param stream - Incoming data stream from buffer. - @param field - Protobuf message's tag type. - @param arg - Optional arguments from decoder calling function. - @returns True if decoded and executed successfully, False otherwise. -*/ -/******************************************************************************************/ -bool cbDecodeServoMsg(pb_istream_t *stream, const pb_field_t *field, - void **arg) { - WS_DEBUG_PRINTLN("Decoding Servo Message..."); - (void)arg; // marking unused parameter to avoid compiler warning - if (field->tag == wippersnapper_signal_v1_ServoRequest_servo_attach_tag) { - WS_DEBUG_PRINTLN("GOT: Servo Attach"); - // Attempt to decode contents of servo_attach message - wippersnapper_servo_v1_ServoAttachRequest msgServoAttachReq = - wippersnapper_servo_v1_ServoAttachRequest_init_zero; - if (!ws_pb_decode(stream, wippersnapper_servo_v1_ServoAttachRequest_fields, - &msgServoAttachReq)) { - WS_DEBUG_PRINTLN( - "ERROR: Could not decode wippersnapper_servo_v1_ServoAttachRequest"); -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal( - "[Servo ERROR] Could not decode servo request from IO!\n"); -#endif - return false; // fail out if we can't decode the request - } - // execute servo attach request - char *servoPin = msgServoAttachReq.servo_pin + 1; - bool attached = true; - if (!WS._servoComponent->servo_attach( - atoi(servoPin), msgServoAttachReq.min_pulse_width, - msgServoAttachReq.max_pulse_width, msgServoAttachReq.servo_freq)) { - WS_DEBUG_PRINTLN("ERROR: Unable to attach servo to pin!"); -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal( - "[Servo ERROR] Unable to attach servo to pin! Is it already in " - "use?\n"); -#endif - attached = false; - } else { - WS_DEBUG_PRINT("ATTACHED servo w/minPulseWidth: "); - WS_DEBUG_PRINT(msgServoAttachReq.min_pulse_width); - WS_DEBUG_PRINT(" uS and maxPulseWidth: "); - WS_DEBUG_PRINT(msgServoAttachReq.min_pulse_width); - WS_DEBUG_PRINT("uS on pin: "); - WS_DEBUG_PRINTLN(servoPin); -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Servo] Attached servo on pin %s\n.", - msgServoAttachReq.servo_pin); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - } - - // Create and fill a servo response message - size_t msgSz; // message's encoded size - wippersnapper_signal_v1_ServoResponse msgServoResp = - wippersnapper_signal_v1_ServoResponse_init_zero; - msgServoResp.which_payload = - wippersnapper_signal_v1_ServoResponse_servo_attach_resp_tag; - msgServoResp.payload.servo_attach_resp.attach_success = attached; - strcpy(msgServoResp.payload.servo_attach_resp.servo_pin, - msgServoAttachReq.servo_pin); - - // Encode and publish response back to broker - memset(WS._buffer_outgoing, 0, sizeof(WS._buffer_outgoing)); - pb_ostream_t ostream = pb_ostream_from_buffer(WS._buffer_outgoing, - sizeof(WS._buffer_outgoing)); - if (!ws_pb_encode(&ostream, wippersnapper_signal_v1_ServoResponse_fields, - &msgServoResp)) { - WS_DEBUG_PRINTLN("ERROR: Unable to encode servo response message!"); - return false; - } - pb_get_encoded_size(&msgSz, wippersnapper_signal_v1_ServoResponse_fields, - &msgServoResp); - WS_DEBUG_PRINT("-> Servo Attach Response..."); - WS._mqtt->publish(WS._topic_signal_servo_device, WS._buffer_outgoing, msgSz, - 1); - WS_DEBUG_PRINTLN("Published!"); - } else if (field->tag == - wippersnapper_signal_v1_ServoRequest_servo_write_tag) { - WS_DEBUG_PRINTLN("GOT: Servo Write"); - - // Attempt to decode contents of servo write message - wippersnapper_servo_v1_ServoWriteRequest msgServoWriteReq = - wippersnapper_servo_v1_ServoWriteRequest_init_zero; - - if (!ws_pb_decode(stream, wippersnapper_servo_v1_ServoWriteRequest_fields, - &msgServoWriteReq)) { - WS_DEBUG_PRINTLN( - "ERROR: Could not decode wippersnapper_servo_v1_ServoWriteRequest"); - return false; // fail out if we can't decode the request - } - // execute servo write request - char *servoPin = msgServoWriteReq.servo_pin + 1; - - WS_DEBUG_PRINT("Writing pulse width of "); - WS_DEBUG_PRINT((int)msgServoWriteReq.pulse_width); - WS_DEBUG_PRINT("uS to servo on pin#: "); - WS_DEBUG_PRINTLN(servoPin); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Servo] Writing pulse width of %u uS to pin %s\n.", - (int)msgServoWriteReq.pulse_width, msgServoWriteReq.servo_pin); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - WS._servoComponent->servo_write(atoi(servoPin), - (int)msgServoWriteReq.pulse_width); - } else if (field->tag == - wippersnapper_signal_v1_ServoRequest_servo_detach_tag) { - WS_DEBUG_PRINTLN("GOT: Servo Detach"); - - // Attempt to decode contents of servo detach message - wippersnapper_servo_v1_ServoDetachRequest msgServoDetachReq = - wippersnapper_servo_v1_ServoDetachRequest_init_zero; - if (!ws_pb_decode(stream, wippersnapper_servo_v1_ServoDetachRequest_fields, - &msgServoDetachReq)) { - WS_DEBUG_PRINTLN( - "ERROR: Could not decode wippersnapper_servo_v1_ServoDetachRequest"); - return false; // fail out if we can't decode the request - } - - // execute servo detach request - char *servoPin = msgServoDetachReq.servo_pin + 1; - WS_DEBUG_PRINT("Detaching servo from pin "); - WS_DEBUG_PRINTLN(servoPin); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Servo] Detaching from pin %s\n.", - msgServoDetachReq.servo_pin); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - WS._servoComponent->servo_detach(atoi(servoPin)); - } else { - WS_DEBUG_PRINTLN("Unable to decode servo message type!"); - return false; - } - return true; -} - -/**************************************************************************/ -/*! - @brief Called when the device recieves a new message from the - /servo/ topic. - @param data - Incoming data from MQTT broker. - @param len - Length of incoming data. -*/ -/**************************************************************************/ -void cbServoMsg(char *data, uint16_t len) { - WS_DEBUG_PRINTLN("* NEW MESSAGE [Topic: Servo]: "); - WS_DEBUG_PRINT(len); - WS_DEBUG_PRINTLN(" bytes."); - // zero-out current buffer - memset(WS._buffer, 0, sizeof(WS._buffer)); - // copy mqtt data into buffer - memcpy(WS._buffer, data, len); - WS.bufSize = len; - - // Set up the payload callback, which will set up the callbacks for - // each oneof payload field once the field tag is known - WS.msgServo.cb_payload.funcs.decode = cbDecodeServoMsg; - - // Decode servo message from buffer - pb_istream_t istream = pb_istream_from_buffer(WS._buffer, WS.bufSize); - if (!ws_pb_decode(&istream, wippersnapper_signal_v1_ServoRequest_fields, - &WS.msgServo)) - WS_DEBUG_PRINTLN("ERROR: Unable to decode servo message"); -} - -/******************************************************************************************/ -/*! - @brief Decodes a servo message and dispatches to the servo component. - @param stream - Incoming data stream from buffer. - @param field - Protobuf message's tag type. - @param arg - Optional arguments from decoder calling function. - @returns True if decoded and executed successfully, False otherwise. -*/ -/******************************************************************************************/ -bool cbPWMDecodeMsg(pb_istream_t *stream, const pb_field_t *field, void **arg) { - WS_DEBUG_PRINTLN("Decoding PWM Message..."); - (void)arg; // marking unused parameter to avoid compiler warning - if (field->tag == wippersnapper_signal_v1_PWMRequest_attach_request_tag) { - WS_DEBUG_PRINTLN("GOT: PWM Pin Attach"); - // Attempt to decode contents of PWM attach message - wippersnapper_pwm_v1_PWMAttachRequest msgPWMAttachRequest = - wippersnapper_pwm_v1_PWMAttachRequest_init_zero; - if (!ws_pb_decode(stream, wippersnapper_pwm_v1_PWMAttachRequest_fields, - &msgPWMAttachRequest)) { - WS_DEBUG_PRINTLN( - "ERROR: Could not decode wippersnapper_pwm_v1_PWMAttachRequest"); -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal( - "[PWM ERROR]: Could not decode pin attach request!\n"); -#endif - return false; // fail out if we can't decode the request - } - - // execute PWM pin attach request - char *pwmPin = msgPWMAttachRequest.pin + 1; - bool attached = WS._pwmComponent->attach( - atoi(pwmPin), (double)msgPWMAttachRequest.frequency, - (uint8_t)msgPWMAttachRequest.resolution); - if (!attached) { - WS_DEBUG_PRINTLN("ERROR: Unable to attach PWM pin"); -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal( - "[PWM ERROR]: Failed to attach PWM to pin! Is this pin already in " - "use?\n"); -#endif - attached = false; - } - - // Create and fill the response message - wippersnapper_signal_v1_PWMResponse msgPWMResponse = - wippersnapper_signal_v1_PWMResponse_init_zero; - msgPWMResponse.which_payload = - wippersnapper_signal_v1_PWMResponse_attach_response_tag; - msgPWMResponse.payload.attach_response.did_attach = attached; - strcpy(msgPWMResponse.payload.attach_response.pin, msgPWMAttachRequest.pin); - - // Encode and publish response back to broker - memset(WS._buffer_outgoing, 0, sizeof(WS._buffer_outgoing)); - pb_ostream_t ostream = pb_ostream_from_buffer(WS._buffer_outgoing, - sizeof(WS._buffer_outgoing)); - if (!ws_pb_encode(&ostream, wippersnapper_signal_v1_PWMResponse_fields, - &msgPWMResponse)) { - WS_DEBUG_PRINTLN("ERROR: Unable to encode PWM response message!"); - return false; - } - size_t msgSz; // message's encoded size - pb_get_encoded_size(&msgSz, wippersnapper_signal_v1_PWMResponse_fields, - &msgPWMResponse); - WS_DEBUG_PRINT("PUBLISHING: PWM Attach Response..."); - if (!WS._mqtt->publish(WS._topic_signal_pwm_device, WS._buffer_outgoing, - msgSz, 1)) { - WS_DEBUG_PRINTLN("ERROR: Failed to publish PWM Attach Response!"); - return false; - } - WS_DEBUG_PRINTLN("Published!"); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[PWM] Attached on pin %s\n.", - msgPWMResponse.payload.attach_response.pin); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - } else if (field->tag == - wippersnapper_signal_v1_PWMRequest_detach_request_tag) { - WS_DEBUG_PRINTLN("GOT: PWM Pin Detach"); - // Attempt to decode contents of PWM detach message - wippersnapper_pwm_v1_PWMDetachRequest msgPWMDetachRequest = - wippersnapper_pwm_v1_PWMDetachRequest_init_zero; - if (!ws_pb_decode(stream, wippersnapper_pwm_v1_PWMDetachRequest_fields, - &msgPWMDetachRequest)) { - WS_DEBUG_PRINTLN( - "ERROR: Could not decode wippersnapper_pwm_v1_PWMDetachRequest"); -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal( - "[PWM ERROR] Failed to decode pin detach request from IO!\n"); -#endif - return false; // fail out if we can't decode the request - } - // execute PWM pin detatch request - char *pwmPin = msgPWMDetachRequest.pin + 1; - WS._pwmComponent->detach(atoi(pwmPin)); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[PWM] Detached on pin %s\n.", - msgPWMDetachRequest.pin); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - } else if (field->tag == - wippersnapper_signal_v1_PWMRequest_write_freq_request_tag) { - WS_DEBUG_PRINTLN("GOT: PWM Write Tone"); - // Attempt to decode contents of PWM detach message - wippersnapper_pwm_v1_PWMWriteFrequencyRequest msgPWMWriteFreqRequest = - wippersnapper_pwm_v1_PWMWriteFrequencyRequest_init_zero; - if (!ws_pb_decode(stream, - wippersnapper_pwm_v1_PWMWriteFrequencyRequest_fields, - &msgPWMWriteFreqRequest)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode " - "wippersnapper_pwm_v1_PWMWriteFrequencyRequest"); -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal( - "[PWM ERROR] Failed to decode frequency write request from IO!\n"); -#endif - return false; // fail out if we can't decode the request - } - - // execute PWM pin duty cycle write request - char *pwmPin = msgPWMWriteFreqRequest.pin + 1; - WS_DEBUG_PRINT("Writing frequency: "); - WS_DEBUG_PRINT(msgPWMWriteFreqRequest.frequency); - WS_DEBUG_PRINT("Hz to pin "); - WS_DEBUG_PRINTLN(atoi(pwmPin)); - WS._pwmComponent->writeTone(atoi(pwmPin), msgPWMWriteFreqRequest.frequency); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[PWM] Writing %ld Hz to pin %s\n.", - msgPWMWriteFreqRequest.frequency, msgPWMWriteFreqRequest.pin); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - } else if (field->tag == - wippersnapper_signal_v1_PWMRequest_write_duty_request_tag) { - WS_DEBUG_PRINTLN("GOT: PWM Write Duty Cycle"); - - // Attempt to decode contents of PWM detach message - wippersnapper_pwm_v1_PWMWriteDutyCycleRequest msgPWMWriteDutyCycleRequest = - wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_init_zero; - if (!ws_pb_decode(stream, - wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_fields, - &msgPWMWriteDutyCycleRequest)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode " - "wippersnapper_pwm_v1_PWMWriteDutyCycleRequest"); -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal( - "[PWM ERROR] Failed to decode duty cycle write request from IO!\n"); -#endif - return false; // fail out if we can't decode the request - } - // execute PWM duty cycle write request - char *pwmPin = msgPWMWriteDutyCycleRequest.pin + 1; - WS._pwmComponent->writeDutyCycle( - atoi(pwmPin), (int)msgPWMWriteDutyCycleRequest.duty_cycle); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[PWM] Writing duty cycle %d to pin %d\n.", - (int)msgPWMWriteDutyCycleRequest.duty_cycle, atoi(pwmPin)); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - } else { - WS_DEBUG_PRINTLN("Unable to decode PWM message type!"); - return false; - } - return true; -} - -/**************************************************************************/ -/*! - @brief Called when the device recieves a new message from the - /pwm/ topic. - @param data - Incoming data from MQTT broker. - @param len - Length of incoming data. -*/ -/**************************************************************************/ -void cbPWMMsg(char *data, uint16_t len) { - WS_DEBUG_PRINTLN("* NEW MESSAGE [Topic: PWM]: "); - WS_DEBUG_PRINT(len); - WS_DEBUG_PRINTLN(" bytes."); - // zero-out current buffer - memset(WS._buffer, 0, sizeof(WS._buffer)); - // copy mqtt data into buffer - memcpy(WS._buffer, data, len); - WS.bufSize = len; - - // Set up the payload callback, which will set up the callbacks for - // each oneof payload field once the field tag is known - WS.msgPWM.cb_payload.funcs.decode = cbPWMDecodeMsg; - - // Decode servo message from buffer - pb_istream_t istream = pb_istream_from_buffer(WS._buffer, WS.bufSize); - if (!ws_pb_decode(&istream, wippersnapper_signal_v1_PWMRequest_fields, - &WS.msgPWM)) - WS_DEBUG_PRINTLN("ERROR: Unable to decode PWM message"); -} - -/******************************************************************************************/ -/*! - @brief Decodes a Dallas Sensor (ds18x20) signal request message and - executes the callback based on the message's tag. - @param stream - Incoming data stream from buffer. - @param field - Protobuf message's tag type. - @param arg - Optional arguments from decoder calling function. - @returns True if decoded successfully, False otherwise. -*/ -/******************************************************************************************/ -bool cbDecodeDs18x20Msg(pb_istream_t *stream, const pb_field_t *field, - void **arg) { - (void)arg; // marking unused parameter to avoid compiler warning - if (field->tag == - wippersnapper_signal_v1_Ds18x20Request_req_ds18x20_init_tag) { - WS_DEBUG_PRINTLN("[Message Type] Init. DS Sensor"); - // Attempt to decode contents of DS18x20 message - wippersnapper_ds18x20_v1_Ds18x20InitRequest msgDS18xInitReq = - wippersnapper_ds18x20_v1_Ds18x20InitRequest_init_zero; - - if (!ws_pb_decode(stream, - wippersnapper_ds18x20_v1_Ds18x20InitRequest_fields, - &msgDS18xInitReq)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode " - "wippersnapper_ds18x20_v1_Ds18x20InitRequest"); - return false; // fail out if we can't decode the request - } - WS_DEBUG_PRINT("Adding DS18x20 Component..."); - if (!WS._ds18x20Component->addDS18x20(&msgDS18xInitReq)) - return false; - WS_DEBUG_PRINTLN("Added!"); - } else if (field->tag == - wippersnapper_signal_v1_Ds18x20Request_req_ds18x20_deinit_tag) { - WS_DEBUG_PRINTLN("[Message Type] De-init. DS Sensor"); - // Attempt to decode contents of message - wippersnapper_ds18x20_v1_Ds18x20DeInitRequest msgDS18xDeInitReq = - wippersnapper_ds18x20_v1_Ds18x20DeInitRequest_init_zero; - if (!ws_pb_decode(stream, - wippersnapper_ds18x20_v1_Ds18x20DeInitRequest_fields, - &msgDS18xDeInitReq)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode " - "wippersnapper_ds18x20_v1_Ds18x20DeInitRequest"); - return false; // fail out if we can't decode the request - } - // exec. deinit request - WS._ds18x20Component->deleteDS18x20(&msgDS18xDeInitReq); - } else { - WS_DEBUG_PRINTLN("ERROR: DS Message type not found!"); - return false; - } - return true; -} - -/**************************************************************************/ -/*! - @brief Called when DallasSensor (DS) signal sub-topic receives a - new message and attempts to decode the message. - @param data - Incoming data from MQTT broker. - @param len - Length of incoming data. -*/ -/**************************************************************************/ -void cbSignalDSReq(char *data, uint16_t len) { - WS_DEBUG_PRINTLN("* NEW MESSAGE [Topic: Signal-DS]: "); - WS_DEBUG_PRINT(len); - WS_DEBUG_PRINTLN(" bytes."); - // zero-out current buffer - memset(WS._buffer, 0, sizeof(WS._buffer)); - // copy mqtt data into buffer - memcpy(WS._buffer, data, len); - WS.bufSize = len; - - // Zero-out existing I2C signal msg. - // WS.msgSignalDS = wippersnapper_signal_v1_Ds18x20Request_init_zero; - - // Set up the payload callback, which will set up the callbacks for - // each oneof payload field once the field tag is known - WS.msgSignalDS.cb_payload.funcs.decode = cbDecodeDs18x20Msg; - - // Decode DS signal request - pb_istream_t istream = pb_istream_from_buffer(WS._buffer, WS.bufSize); - if (!ws_pb_decode(&istream, wippersnapper_signal_v1_Ds18x20Request_fields, - &WS.msgSignalDS)) - WS_DEBUG_PRINTLN("ERROR: Unable to decode DS message"); -} - -/******************************************************************************************/ -/*! - @brief Decodes a pixel strand request message and executes the callback - based on the message's tag. - @param stream - Incoming data stream from buffer. - @param field - Protobuf message's tag type. - @param arg - Optional arguments from decoder calling function. - @returns True if decoded successfully, False otherwise. -*/ -/******************************************************************************************/ -bool cbDecodePixelsMsg(pb_istream_t *stream, const pb_field_t *field, - void **arg) { - (void)arg; // marking unused parameter to avoid compiler warning - if (field->tag == - wippersnapper_signal_v1_PixelsRequest_req_pixels_create_tag) { - WS_DEBUG_PRINTLN( - "[Message Type]: " - "wippersnapper_signal_v1_PixelsRequest_req_pixels_create_tag"); - - // attempt to decode create message - wippersnapper_pixels_v1_PixelsCreateRequest msgPixelsCreateReq = - wippersnapper_pixels_v1_PixelsCreateRequest_init_zero; - if (!ws_pb_decode(stream, - wippersnapper_pixels_v1_PixelsCreateRequest_fields, - &msgPixelsCreateReq)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode message of type " - "wippersnapper_pixels_v1_PixelsCreateRequest!"); -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal("[Pixel] Error decoding message!\n"); -#endif - return false; - } - - // Add a new strand - return WS._ws_pixelsComponent->addStrand(&msgPixelsCreateReq); - } else if (field->tag == - wippersnapper_signal_v1_PixelsRequest_req_pixels_delete_tag) { - WS_DEBUG_PRINTLN( - "[Message Type]: " - "wippersnapper_signal_v1_PixelsRequest_req_pixels_delete_tag"); - - // attempt to decode delete strand message - wippersnapper_pixels_v1_PixelsDeleteRequest msgPixelsDeleteReq = - wippersnapper_pixels_v1_PixelsDeleteRequest_init_zero; - if (!ws_pb_decode(stream, - wippersnapper_pixels_v1_PixelsDeleteRequest_fields, - &msgPixelsDeleteReq)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode message of type " - "wippersnapper_pixels_v1_PixelsDeleteRequest!"); - return false; - } - - // delete strand - WS._ws_pixelsComponent->deleteStrand(&msgPixelsDeleteReq); - } else if (field->tag == - wippersnapper_signal_v1_PixelsRequest_req_pixels_write_tag) { - WS_DEBUG_PRINTLN( - "[Message Type]: " - "wippersnapper_signal_v1_PixelsRequest_req_pixels_write_tag"); - - // attempt to decode pixel write message - wippersnapper_pixels_v1_PixelsWriteRequest msgPixelsWritereq = - wippersnapper_pixels_v1_PixelsWriteRequest_init_zero; - if (!ws_pb_decode(stream, wippersnapper_pixels_v1_PixelsWriteRequest_fields, - &msgPixelsWritereq)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode message of type " - "wippersnapper_pixels_v1_PixelsWriteRequest!"); - return false; - } - - // fill strand - WS._ws_pixelsComponent->fillStrand(&msgPixelsWritereq); - } else { - WS_DEBUG_PRINTLN("ERROR: Pixels message type not found!"); - return false; - } - return true; -} - -/**************************************************************************/ -/*! - @brief Called when the device recieves a new message from the - /pixels/ topic. - @param data - Incoming data from MQTT broker. - @param len - Length of incoming data. -*/ -/**************************************************************************/ -void cbPixelsMsg(char *data, uint16_t len) { - WS_DEBUG_PRINTLN("* NEW MESSAGE [Topic: Pixels]: "); - WS_DEBUG_PRINT(len); - WS_DEBUG_PRINTLN(" bytes."); - // zero-out current buffer - memset(WS._buffer, 0, sizeof(WS._buffer)); - // copy mqtt data into buffer - memcpy(WS._buffer, data, len); - WS.bufSize = len; - - // Set up the payload callback, which will set up the callbacks for - // each oneof payload field once the field tag is known - WS.msgPixels.cb_payload.funcs.decode = cbDecodePixelsMsg; - - // Decode pixel message from buffer - pb_istream_t istream = pb_istream_from_buffer(WS._buffer, WS.bufSize); - if (!ws_pb_decode(&istream, wippersnapper_signal_v1_PixelsRequest_fields, - &WS.msgPixels)) - WS_DEBUG_PRINTLN("ERROR: Unable to decode pixel topic message"); -} - -/******************************************************************************************/ -/*! - @brief Decodes a UART message and executes the callback based on the - message's tag. - @param stream - Incoming data stream from buffer. - @param field - Protobuf message's tag type. - @param arg - Optional arguments from decoder calling function. - @returns True if decoded successfully, False otherwise. -*/ -/******************************************************************************************/ -bool cbDecodeUARTMessage(pb_istream_t *stream, const pb_field_t *field, - void **arg) { - if (field->tag == - wippersnapper_signal_v1_UARTRequest_req_uart_device_attach_tag) { - WS_DEBUG_PRINTLN( - "[Message Type]: " - "wippersnapper_signal_v1_UARTRequest_req_uart_device_attach_tag"); - - // attempt to decode create message - wippersnapper_uart_v1_UARTDeviceAttachRequest msgUARTInitReq = - wippersnapper_uart_v1_UARTDeviceAttachRequest_init_zero; - if (!ws_pb_decode(stream, - wippersnapper_uart_v1_UARTDeviceAttachRequest_fields, - &msgUARTInitReq)) { - WS_DEBUG_PRINTLN( - "ERROR: Could not decode message of type: UARTDeviceAttachRequest!"); - return false; - } - - // Check if bus_info is within the message - if (!msgUARTInitReq.has_bus_info) { - WS_DEBUG_PRINTLN("ERROR: UART bus info not found within message!"); - return false; - } - - // Have we previously initialized the UART bus? - if (!WS._uartComponent->isUARTBusInitialized()) - WS._uartComponent->initUARTBus(&msgUARTInitReq); // Init. UART bus - - // Attach UART device to the bus specified in the message - bool did_begin = WS._uartComponent->initUARTDevice(&msgUARTInitReq); - - // Create a UARTResponse message - wippersnapper_signal_v1_UARTResponse msgUARTResponse = - wippersnapper_signal_v1_UARTResponse_init_zero; - msgUARTResponse.which_payload = - wippersnapper_signal_v1_UARTResponse_resp_uart_device_attach_tag; - msgUARTResponse.payload.resp_uart_device_attach.is_success = did_begin; - strcpy(msgUARTResponse.payload.resp_uart_device_attach.device_id, - msgUARTInitReq.device_id); - memset(WS._buffer_outgoing, 0, sizeof(WS._buffer_outgoing)); - pb_ostream_t ostream = pb_ostream_from_buffer(WS._buffer_outgoing, - sizeof(WS._buffer_outgoing)); - if (!ws_pb_encode(&ostream, wippersnapper_signal_v1_UARTResponse_fields, - &msgUARTResponse)) { - WS_DEBUG_PRINTLN("ERROR: Unable to encode UART response message!"); - return false; - } - size_t msgSz; // message's encoded size - pb_get_encoded_size(&msgSz, wippersnapper_signal_v1_UARTResponse_fields, - &msgUARTResponse); - WS_DEBUG_PRINT("PUBLISHING: UART Attach Response..."); - if (!WS._mqtt->publish(WS._topic_signal_uart_device, WS._buffer_outgoing, - msgSz, 1)) { - WS_DEBUG_PRINTLN("ERROR: Failed to publish UART Attach Response!"); - return false; - } - WS_DEBUG_PRINTLN("Published!"); - - } else if (field->tag == - wippersnapper_signal_v1_UARTRequest_req_uart_device_detach_tag) { - WS_DEBUG_PRINTLN("[New Message] UART Detach"); - // attempt to decode uart detach request message - wippersnapper_uart_v1_UARTDeviceDetachRequest msgUARTDetachReq = - wippersnapper_uart_v1_UARTDeviceDetachRequest_init_zero; - if (!ws_pb_decode(stream, - wippersnapper_uart_v1_UARTDeviceDetachRequest_fields, - &msgUARTDetachReq)) { - WS_DEBUG_PRINTLN("ERROR: Could not decode message!"); - return false; - } - // detach UART device - WS._uartComponent->detachUARTDevice(&msgUARTDetachReq); - WS_DEBUG_PRINTLN("Detached uart device from bus"); - } else { - WS_DEBUG_PRINTLN("ERROR: UART message type not found!"); - return false; - } - return true; -} - -/**************************************************************************/ -/*! - @brief Called when the signal UART sub-topic receives a - new message. Performs decoding. - @param data - Incoming data from MQTT broker. - @param len - Length of incoming data. -*/ -/**************************************************************************/ -void cbSignalUARTReq(char *data, uint16_t len) { - WS_DEBUG_PRINTLN("* NEW MESSAGE on Signal of type UART: "); - WS_DEBUG_PRINT(len); - WS_DEBUG_PRINTLN(" bytes."); - // zero-out current buffer - memset(WS._buffer, 0, sizeof(WS._buffer)); - // copy mqtt data into buffer - memcpy(WS._buffer, data, len); - WS.bufSize = len; - - // Set up the payload callback, which will set up the callbacks for - // each oneof payload field once the field tag is known - WS.msgSignalUART.cb_payload.funcs.decode = cbDecodeUARTMessage; - - // Decode DS signal request - pb_istream_t istream = pb_istream_from_buffer(WS._buffer, WS.bufSize); - if (!ws_pb_decode(&istream, wippersnapper_signal_v1_UARTRequest_fields, - &WS.msgSignalUART)) - WS_DEBUG_PRINTLN("ERROR: Unable to decode UART Signal message"); -} - -/****************************************************************************/ -/*! - @brief Handles MQTT messages on signal topic until timeout. - @param outgoingSignalMsg - Empty signal message struct. - @param pinName - Name of pin. - @param pinVal - Value of pin. - @returns True if pinEvent message encoded successfully, false otherwise. -*/ -/****************************************************************************/ -bool Wippersnapper::encodePinEvent( - wippersnapper_signal_v1_CreateSignalRequest *outgoingSignalMsg, - uint8_t pinName, int pinVal) { - bool is_success = true; - outgoingSignalMsg->which_payload = - wippersnapper_signal_v1_CreateSignalRequest_pin_event_tag; - // fill the pin_event message - sprintf(outgoingSignalMsg->payload.pin_event.pin_name, "D%d", pinName); - sprintf(outgoingSignalMsg->payload.pin_event.pin_value, "%d", pinVal); - - // Encode signal message - pb_ostream_t stream = - pb_ostream_from_buffer(WS._buffer_outgoing, sizeof(WS._buffer_outgoing)); - if (!ws_pb_encode(&stream, wippersnapper_signal_v1_CreateSignalRequest_fields, - outgoingSignalMsg)) { - WS_DEBUG_PRINTLN("ERROR: Unable to encode signal message"); - is_success = false; - } - - return is_success; -} - -/**************************************************************************/ -/*! - @brief Called when broker responds to a device's publish across - the registration topic. - @param data - Data from MQTT broker. - @param len - Length of data received from MQTT broker. -*/ -/**************************************************************************/ -void cbRegistrationStatus(char *data, uint16_t len) { - // call decoder for registration response msg - WS.decodeRegistrationResp(data, len); -} - -/**************************************************************************/ -/*! - @brief Called when client receives a message published across the - Adafruit IO MQTT /error special topic. - @param errorData - Data from MQTT broker. - @param len - Length of data received from MQTT broker. -*/ -/**************************************************************************/ -void cbErrorTopic(char *errorData, uint16_t len) { - (void)len; // marking unused parameter to avoid compiler warning - WS_DEBUG_PRINT("IO Ban Error: "); - WS_DEBUG_PRINTLN(errorData); - // Disconnect client from broker - WS_DEBUG_PRINT("Disconnecting from MQTT.."); - if (!WS._mqtt->disconnect()) { - WS_DEBUG_PRINTLN("ERROR: Unable to disconnect from MQTT broker!"); - } - -#ifdef USE_DISPLAY - WS._ui_helper->show_scr_error("IO Ban Error", errorData); -#endif - - // WDT reset - WS.haltError("IO MQTT Ban Error"); -} - -/**************************************************************************/ -/*! - @brief Called when client receives a message published across the - Adafruit IO MQTT /throttle special topic. Delays until - throttle is released. - @param throttleData - Throttle message from Adafruit IO. - @param len - Length of data received from MQTT broker. -*/ -/**************************************************************************/ -void cbThrottleTopic(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; - // Parse out # of seconds from message buffer - throttleMessage = strtok(throttleData, ","); - throttleMessage = strtok(NULL, " "); - // Convert from seconds to to millis - int throttleDuration = atoi(throttleMessage) * 1000; - - WS_DEBUG_PRINT("Device is throttled for "); - WS_DEBUG_PRINT(throttleDuration); - WS_DEBUG_PRINTLN("ms and blocking command execution."); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf( - buffer, 100, - "[IO ERROR] Device is throttled for %d mS and blocking execution..\n.", - throttleDuration); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - // If throttle duration is less than the keepalive interval, delay for the - // full keepalive interval - if (throttleDuration < WS_KEEPALIVE_INTERVAL_MS) { - delay(WS_KEEPALIVE_INTERVAL_MS); - } else { - // round to nearest millis to prevent delaying for less time than req'd. - float throttleLoops = ceil(throttleDuration / WS_KEEPALIVE_INTERVAL_MS); - // block the run() loop - while (throttleLoops > 0) { - delay(WS_KEEPALIVE_INTERVAL_MS); - WS.feedWDT(); - WS._mqtt->ping(); - throttleLoops--; - } - } - WS_DEBUG_PRINTLN("Device is un-throttled, resumed command execution"); -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal( - "[IO] Device is un-throttled, resuming...\n"); -#endif -} - -/**************************************************************************/ -/*! - @brief Builds MQTT topics for handling errors returned from the - Adafruit IO broker and subscribes to them - @returns True if memory for error topics allocated successfully, - False otherwise. -*/ -/**************************************************************************/ -bool Wippersnapper::generateWSErrorTopics() { -// dynamically allocate memory for err topic -#ifdef USE_PSRAM - WS._err_topic = - (char *)ps_malloc(sizeof(char) * (strlen(WS._config.aio_user) + - strlen(TOPIC_IO_ERRORS) + 1)); -#else - WS._err_topic = (char *)malloc(sizeof(char) * (strlen(WS._config.aio_user) + - strlen(TOPIC_IO_ERRORS) + 1)); -#endif - - if (WS._err_topic) { // build error topic - strcpy(WS._err_topic, WS._config.aio_user); - strcat(WS._err_topic, TOPIC_IO_ERRORS); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate global error topic!"); - return false; - } - - // Subscribe to error topic - _err_sub = new Adafruit_MQTT_Subscribe(WS._mqtt, WS._err_topic); - WS._mqtt->subscribe(_err_sub); - _err_sub->setCallback(cbErrorTopic); - -// dynamically allocate memory for throttle topic -#ifdef USE_PSRAM - WS._throttle_topic = - (char *)ps_malloc(sizeof(char) * (strlen(WS._config.aio_user) + - strlen(TOPIC_IO_THROTTLE) + 1)); -#else - WS._throttle_topic = - (char *)malloc(sizeof(char) * (strlen(WS._config.aio_user) + - strlen(TOPIC_IO_THROTTLE) + 1)); -#endif - - if (WS._throttle_topic) { // build throttle topic - strcpy(WS._throttle_topic, WS._config.aio_user); - strcat(WS._throttle_topic, TOPIC_IO_THROTTLE); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate global throttle topic!"); - return false; - } - - // Subscribe to throttle topic - _throttle_sub = new Adafruit_MQTT_Subscribe(WS._mqtt, WS._throttle_topic); - WS._mqtt->subscribe(_throttle_sub); - _throttle_sub->setCallback(cbThrottleTopic); - - return true; -} - -/**************************************************************************/ -/*! - @brief Attempts to generate unique device identifier. - @returns True if device identifier generated successfully, - False otherwise. -*/ -/**************************************************************************/ -bool Wippersnapper::generateDeviceUID() { - // Generate device unique identifier - // Set machine_name - WS._boardId = BOARD_ID; - // Move the top 3 bytes from the UID - for (int i = 5; i > 2; i--) { - WS._macAddr[6 - 1 - i] = WS._macAddr[i]; - } - snprintf(WS.sUID, sizeof(WS.sUID), "%02d%02d%02d", WS._macAddr[0], - WS._macAddr[1], WS._macAddr[2]); - // Conversion to match integer UID sent by encodePubRegistrationReq() - char mac_uid[13]; - itoa(atoi(WS.sUID), mac_uid, 10); - -// Attempt to malloc a the device identifier string -#ifdef USE_PSRAM - _device_uid = (char *)ps_malloc(sizeof(char) + strlen("io-wipper-") + - strlen(WS._boardId) + strlen(mac_uid) + 1); -#else - _device_uid = (char *)malloc(sizeof(char) + strlen("io-wipper-") + - strlen(WS._boardId) + strlen(mac_uid) + 1); -#endif - if (_device_uid == NULL) { - WS_DEBUG_PRINTLN("ERROR: Unable to create device uid, Malloc failure"); - return false; - } - // Create the device identifier - strcpy(_device_uid, "io-wipper-"); - strcat(_device_uid, WS._boardId); - strcat(_device_uid, mac_uid); - return true; -} - -/**************************************************************************/ -/*! - @brief Generates device-specific Wippersnapper control topics and - subscribes to them. - @returns True if memory for control topics allocated successfully, - False otherwise. -*/ -/**************************************************************************/ -bool Wippersnapper::generateWSTopics() { -// Create global registration topic -#ifdef USE_PSRAM - WS._topic_description = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/wprsnpr") + - strlen(TOPIC_INFO) + strlen("status") + 1); -#else - WS._topic_description = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/wprsnpr") + - strlen(TOPIC_INFO) + strlen("status") + 1); -#endif - if (WS._topic_description != NULL) { - strcpy(WS._topic_description, WS._config.aio_user); - strcat(WS._topic_description, "/wprsnpr"); - strcat(WS._topic_description, TOPIC_INFO); - strcat(WS._topic_description, "status"); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate registration topic!"); - return false; - } - -// Create registration status topic -#ifdef USE_PSRAM - WS._topic_description_status = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/wprsnpr/") + - strlen(_device_uid) + strlen(TOPIC_INFO) + strlen("status/") + - strlen("broker") + 1); -#else - WS._topic_description_status = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/wprsnpr/") + - strlen(_device_uid) + strlen(TOPIC_INFO) + strlen("status/") + - strlen("broker") + 1); -#endif - if (WS._topic_description_status != NULL) { - strcpy(WS._topic_description_status, WS._config.aio_user); - strcat(WS._topic_description_status, "/wprsnpr/"); - strcat(WS._topic_description_status, _device_uid); - strcat(WS._topic_description_status, TOPIC_INFO); - strcat(WS._topic_description_status, "status"); - strcat(WS._topic_description_status, "/broker"); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate registration status topic!"); - return false; - } - - // Subscribe to registration status topic - _topic_description_sub = - new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_description_status, 1); - WS._mqtt->subscribe(_topic_description_sub); - _topic_description_sub->setCallback(cbRegistrationStatus); - -// Create registration status complete topic -#ifdef USE_PSRAM - WS._topic_description_status_complete = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/wprsnpr/") + - strlen(_device_uid) + strlen(TOPIC_INFO) + strlen("status") + - strlen("/device/complete") + 1); -#else - WS._topic_description_status_complete = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/wprsnpr/") + - strlen(_device_uid) + strlen(TOPIC_INFO) + strlen("status") + - strlen("/device/complete") + 1); -#endif - if (WS._topic_description_status_complete != NULL) { - strcpy(WS._topic_description_status_complete, WS._config.aio_user); - strcat(WS._topic_description_status_complete, "/wprsnpr/"); - strcat(WS._topic_description_status_complete, _device_uid); - strcat(WS._topic_description_status_complete, TOPIC_INFO); - strcat(WS._topic_description_status_complete, "status"); - strcat(WS._topic_description_status_complete, "/device/complete"); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate registration complete topic!"); - return false; - } - -// Create device-to-broker signal topic -#ifdef USE_PSRAM - WS._topic_signal_device = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/wprsnpr/") + - strlen(_device_uid) + strlen(TOPIC_SIGNALS) + strlen("device") + 1); -#else - WS._topic_signal_device = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/wprsnpr/") + - strlen(_device_uid) + strlen(TOPIC_SIGNALS) + strlen("device") + 1); -#endif - if (WS._topic_signal_device != NULL) { - strcpy(WS._topic_signal_device, WS._config.aio_user); - strcat(WS._topic_signal_device, "/wprsnpr/"); - strcat(WS._topic_signal_device, _device_uid); - strcat(WS._topic_signal_device, TOPIC_SIGNALS); - strcat(WS._topic_signal_device, "device"); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate d2c signal topic!"); - return false; - } - -// Create pin configuration complete topic -#ifdef USE_PSRAM - WS._topic_device_pin_config_complete = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/wprsnpr/") + - strlen(_device_uid) + strlen(TOPIC_SIGNALS) + - strlen("device/pinConfigComplete") + 1); -#else - WS._topic_device_pin_config_complete = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/wprsnpr/") + - strlen(_device_uid) + strlen(TOPIC_SIGNALS) + - strlen("device/pinConfigComplete") + 1); -#endif - if (WS._topic_device_pin_config_complete != NULL) { - strcpy(WS._topic_device_pin_config_complete, WS._config.aio_user); - strcat(WS._topic_device_pin_config_complete, "/wprsnpr/"); - strcat(WS._topic_device_pin_config_complete, _device_uid); - strcat(WS._topic_device_pin_config_complete, TOPIC_SIGNALS); - strcat(WS._topic_device_pin_config_complete, "device/pinConfigComplete"); - } else { // malloc failed - WS_DEBUG_PRINTLN( - "ERROR: Failed to allocate pin config complete flag topic!"); - return false; - } - -// Create broker-to-device signal topic -#ifdef USE_PSRAM - WS._topic_signal_brkr = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/wprsnpr/") + - strlen(_device_uid) + strlen(TOPIC_SIGNALS) + strlen("broker") + 1); -#else - WS._topic_signal_brkr = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/wprsnpr/") + - strlen(_device_uid) + strlen(TOPIC_SIGNALS) + strlen("broker") + 1); -#endif - if (WS._topic_signal_brkr != NULL) { - strcpy(WS._topic_signal_brkr, WS._config.aio_user); - strcat(WS._topic_signal_brkr, "/wprsnpr/"); - strcat(WS._topic_signal_brkr, _device_uid); - strcat(WS._topic_signal_brkr, TOPIC_SIGNALS); - strcat(WS._topic_signal_brkr, "broker"); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate c2d signal topic!"); - return false; - } - - // Subscribe to signal topic - _topic_signal_brkr_sub = - new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_signal_brkr, 1); - WS._mqtt->subscribe(_topic_signal_brkr_sub); - _topic_signal_brkr_sub->setCallback(cbSignalTopic); - -// Create device-to-broker i2c signal topic -#ifdef USE_PSRAM - WS._topic_signal_i2c_brkr = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + +strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + - strlen("broker") + strlen(TOPIC_I2C) + 1); -#else - WS._topic_signal_i2c_brkr = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + +strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + - strlen("broker") + strlen(TOPIC_I2C) + 1); -#endif - if (WS._topic_signal_i2c_brkr != NULL) { - strcpy(WS._topic_signal_i2c_brkr, WS._config.aio_user); - strcat(WS._topic_signal_i2c_brkr, TOPIC_WS); - strcat(WS._topic_signal_i2c_brkr, _device_uid); - strcat(WS._topic_signal_i2c_brkr, TOPIC_SIGNALS); - strcat(WS._topic_signal_i2c_brkr, "broker"); - strcat(WS._topic_signal_i2c_brkr, TOPIC_I2C); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate d2c i2c topic!"); - return false; - } - - // Subscribe to signal's I2C sub-topic - _topic_signal_i2c_sub = - new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_signal_i2c_brkr, 1); - WS._mqtt->subscribe(_topic_signal_i2c_sub); - _topic_signal_i2c_sub->setCallback(cbSignalI2CReq); - -// Create broker-to-device i2c signal topic -#ifdef USE_PSRAM - WS._topic_signal_i2c_device = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + +strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + - strlen("device") + strlen(TOPIC_I2C) + 1); -#else - WS._topic_signal_i2c_device = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + +strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + - strlen("device") + strlen(TOPIC_I2C) + 1); -#endif - if (WS._topic_signal_i2c_device != NULL) { - strcpy(WS._topic_signal_i2c_device, WS._config.aio_user); - strcat(WS._topic_signal_i2c_device, TOPIC_WS); - strcat(WS._topic_signal_i2c_device, _device_uid); - strcat(WS._topic_signal_i2c_device, TOPIC_SIGNALS); - strcat(WS._topic_signal_i2c_device, "device"); - strcat(WS._topic_signal_i2c_device, TOPIC_I2C); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to c2d i2c topic!"); - return false; - } - -// Create device-to-broker ds18x20 topic -#ifdef USE_PSRAM - WS._topic_signal_ds18_brkr = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + +strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + - strlen("broker/") + strlen("ds18x20") + 1); -#else - WS._topic_signal_ds18_brkr = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + +strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + - strlen("broker/") + strlen("ds18x20") + 1); -#endif - if (WS._topic_signal_ds18_brkr != NULL) { - strcpy(WS._topic_signal_ds18_brkr, WS._config.aio_user); - strcat(WS._topic_signal_ds18_brkr, TOPIC_WS); - strcat(WS._topic_signal_ds18_brkr, _device_uid); - strcat(WS._topic_signal_ds18_brkr, TOPIC_SIGNALS); - strcat(WS._topic_signal_ds18_brkr, "broker/ds18x20"); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate d2c ds18x20 topic!"); - return false; - } - - // Subscribe to signal's ds18x20 sub-topic - _topic_signal_ds18_sub = - new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_signal_ds18_brkr, 1); - WS._mqtt->subscribe(_topic_signal_ds18_sub); - _topic_signal_ds18_sub->setCallback(cbSignalDSReq); - -// Create broker-to-device ds18x20 topic -#ifdef USE_PSRAM - WS._topic_signal_ds18_device = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + +strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + - strlen("device/") + strlen("ds18x20") + 1); -#else - WS._topic_signal_ds18_device = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + +strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + - strlen("device/") + strlen("ds18x20") + 1); -#endif - if (WS._topic_signal_ds18_device != NULL) { - strcpy(WS._topic_signal_ds18_device, WS._config.aio_user); - strcat(WS._topic_signal_ds18_device, TOPIC_WS); - strcat(WS._topic_signal_ds18_device, _device_uid); - strcat(WS._topic_signal_ds18_device, TOPIC_SIGNALS); - strcat(WS._topic_signal_ds18_device, "device/ds18x20"); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate c2d ds18x20 topic!"); - return false; - } - -// Create device-to-broker servo signal topic -#ifdef USE_PSRAM - WS._topic_signal_servo_brkr = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/signals/broker/servo") + 1); -#else - WS._topic_signal_servo_brkr = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/signals/broker/servo") + 1); -#endif - if (WS._topic_signal_servo_brkr != NULL) { - strcpy(WS._topic_signal_servo_brkr, WS._config.aio_user); - strcat(WS._topic_signal_servo_brkr, TOPIC_WS); - strcat(WS._topic_signal_servo_brkr, _device_uid); - strcat(WS._topic_signal_servo_brkr, TOPIC_SIGNALS); - strcat(WS._topic_signal_servo_brkr, "broker/servo"); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate d2c servo topic!"); - return false; - } - - // Subscribe to servo sub-topic - _topic_signal_servo_sub = - new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_signal_servo_brkr, 1); - WS._mqtt->subscribe(_topic_signal_servo_sub); - _topic_signal_servo_sub->setCallback(cbServoMsg); - -// Create broker-to-device servo signal topic -#ifdef USE_PSRAM - WS._topic_signal_servo_device = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/signals/device/servo") + 1); -#else - WS._topic_signal_servo_device = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/signals/device/servo") + 1); -#endif - if (WS._topic_signal_servo_device != NULL) { - strcpy(WS._topic_signal_servo_device, WS._config.aio_user); - strcat(WS._topic_signal_servo_device, TOPIC_WS); - strcat(WS._topic_signal_servo_device, _device_uid); - strcat(WS._topic_signal_servo_device, TOPIC_SIGNALS); - strcat(WS._topic_signal_servo_device, "device/servo"); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate c2d servo topic!"); - return false; - } - -// Topic for pwm messages from broker->device -#ifdef USE_PSRAM - WS._topic_signal_pwm_brkr = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/signals/broker/pwm") + 1); -#else - WS._topic_signal_pwm_brkr = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/signals/broker/pwm") + 1); -#endif - // Create device-to-broker pwm signal topic - if (WS._topic_signal_pwm_brkr != NULL) { - strcpy(WS._topic_signal_pwm_brkr, WS._config.aio_user); - strcat(WS._topic_signal_pwm_brkr, TOPIC_WS); - strcat(WS._topic_signal_pwm_brkr, _device_uid); - strcat(WS._topic_signal_pwm_brkr, TOPIC_SIGNALS); - strcat(WS._topic_signal_pwm_brkr, "broker/pwm"); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate c2d pwm topic!"); - return false; - } - - // Subscribe to PWM sub-topic - _topic_signal_pwm_sub = - new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_signal_pwm_brkr, 1); - WS._mqtt->subscribe(_topic_signal_pwm_sub); - _topic_signal_pwm_sub->setCallback(cbPWMMsg); - -// Topic for pwm messages from device->broker -#ifdef USE_PSRAM - WS._topic_signal_pwm_device = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/signals/device/pwm") + 1); -#else - WS._topic_signal_pwm_device = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/signals/device/pwm") + 1); -#endif - if (WS._topic_signal_pwm_device != NULL) { - strcpy(WS._topic_signal_pwm_device, WS._config.aio_user); - strcat(WS._topic_signal_pwm_device, TOPIC_WS); - strcat(WS._topic_signal_pwm_device, _device_uid); - strcat(WS._topic_signal_pwm_device, TOPIC_SIGNALS); - strcat(WS._topic_signal_pwm_device, "device/pwm"); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate d2c pwm topic!"); - return false; - } - -// Topic for pixel messages from broker->device -#ifdef USE_PSRAM - WS._topic_signal_pixels_brkr = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/signals/broker/pixels") + 1); -#else - WS._topic_signal_pixels_brkr = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/signals/broker/pixels") + 1); -#endif - if (WS._topic_signal_pixels_brkr != NULL) { - strcpy(WS._topic_signal_pixels_brkr, WS._config.aio_user); - strcat(WS._topic_signal_pixels_brkr, TOPIC_WS); - strcat(WS._topic_signal_pixels_brkr, _device_uid); - strcat(WS._topic_signal_pixels_brkr, MQTT_TOPIC_PIXELS_BROKER); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate c2d pixel topic!"); - return false; - } - - // Subscribe to pixels sub-topic - _topic_signal_pixels_sub = - new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_signal_pixels_brkr, 1); - WS._mqtt->subscribe(_topic_signal_pixels_sub); - _topic_signal_pixels_sub->setCallback(cbPixelsMsg); - -// Topic for pixel messages from device->broker -#ifdef USE_PSRAM - WS._topic_signal_pixels_device = (char *)ps_malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/signals/device/pixels") + 1); -#else - WS._topic_signal_pixels_device = (char *)malloc( - sizeof(char) * strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/signals/device/pixels") + 1); -#endif - if (WS._topic_signal_pixels_device != NULL) { - strcpy(WS._topic_signal_pixels_device, WS._config.aio_user); - strcat(WS._topic_signal_pixels_device, TOPIC_WS); - strcat(WS._topic_signal_pixels_device, _device_uid); - strcat(WS._topic_signal_pixels_device, MQTT_TOPIC_PIXELS_DEVICE); - } else { // malloc failed - WS_DEBUG_PRINTLN("ERROR: Failed to allocate d2c pixels topic!"); - return false; - } - - // Create device-to-broker UART topic - - // Calculate size for dynamic MQTT topic - size_t topicLen = strlen(WS._config.aio_user) + strlen("/") + - strlen(_device_uid) + strlen("/wprsnpr/") + - strlen(TOPIC_SIGNALS) + strlen("broker/uart") + 1; - -// Allocate memory for dynamic MQTT topic -#ifdef USE_PSRAM - WS._topic_signal_uart_brkr = (char *)ps_malloc(topicLen); -#else - WS._topic_signal_uart_brkr = (char *)malloc(topicLen); -#endif - - // Generate the topic if memory was allocated successfully - if (WS._topic_signal_uart_brkr != NULL) { - snprintf(WS._topic_signal_uart_brkr, topicLen, "%s/wprsnpr/%s%sbroker/uart", - WS._config.aio_user, _device_uid, TOPIC_SIGNALS); - } else { - WS_DEBUG_PRINTLN("FATAL ERROR: Failed to allocate memory for UART topic!"); - return false; - } - - // Subscribe to signal's UART sub-topic - _topic_signal_uart_sub = - new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_signal_uart_brkr, 1); - WS._mqtt->subscribe(_topic_signal_uart_sub); - // Set MQTT callback function - _topic_signal_uart_sub->setCallback(cbSignalUARTReq); - - // Create broker-to-device UART topic - // Calculate size for dynamic MQTT topic - topicLen = strlen(WS._config.aio_user) + strlen("/") + strlen(_device_uid) + - strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + - strlen("device/uart") + 1; - -// Allocate memory for dynamic MQTT topic -#ifdef USE_PSRAM - WS._topic_signal_uart_device = (char *)ps_malloc(topicLen); -#else - WS._topic_signal_uart_device = (char *)malloc(topicLen); -#endif - - // Generate the topic if memory was allocated successfully - if (WS._topic_signal_uart_device != NULL) { - snprintf(WS._topic_signal_uart_device, topicLen, - "%s/wprsnpr/%s%sdevice/uart", WS._config.aio_user, _device_uid, - TOPIC_SIGNALS); - } else { - WS_DEBUG_PRINTLN("FATAL ERROR: Failed to allocate memory for UART topic!"); - return false; - } - return true; -} - -/**************************************************************************/ -/*! - @brief Writes an error message to the serial and the filesystem, - blinks WS_LED_STATUS_ERROR_RUNTIME pattern and hangs. - @param error - The error message to write to the serial and filesystem. -*/ -/**************************************************************************/ -void Wippersnapper::errorWriteHang(String error) { - // Print error - WS_DEBUG_PRINTLN(error); -#ifdef USE_TINYUSB - _fileSystem->writeToBootOut(error.c_str()); - TinyUSBDevice.attach(); - delay(500); -#endif - // Signal and hang forever - while (1) { - WS_DEBUG_PRINTLN("ERROR: Halted execution"); - WS_DEBUG_PRINTLN(error.c_str()); - WS.feedWDT(); - statusLEDBlink(WS_LED_STATUS_ERROR_RUNTIME); - delay(1000); - } -} - -/**************************************************************************/ -/*! - @brief Checks network and MQTT connectivity. Handles network - re-connection and mqtt re-establishment. -*/ -/**************************************************************************/ -void Wippersnapper::runNetFSM() { - WS.feedWDT(); - // Initial state - fsm_net_t fsmNetwork; - fsmNetwork = FSM_NET_CHECK_MQTT; - int maxAttempts; - while (fsmNetwork != FSM_NET_CONNECTED) { - switch (fsmNetwork) { - case FSM_NET_CHECK_MQTT: - if (WS._mqtt->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 (WS._ui_helper->getLoadingState()) - WS._ui_helper->set_load_bar_icon_complete(loadBarIconWifi); -#endif - fsmNetwork = FSM_NET_ESTABLISH_MQTT; - break; - } - fsmNetwork = FSM_NET_ESTABLISH_NETWORK; - break; - case FSM_NET_ESTABLISH_NETWORK: - WS_DEBUG_PRINTLN("Establishing network connection..."); - WS_PRINTER.flush(); -#ifdef USE_DISPLAY - if (WS._ui_helper->getLoadingState()) - WS._ui_helper->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()) { -#ifdef USE_DISPLAY - WS._ui_helper->show_scr_error("ERROR", - "Unable to find WiFi network listed in " - "the secrets file. Rebooting soon..."); -#endif - haltError("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); - feedWDT(); - // attempt to connect - WS_DEBUG_PRINT("Connecting to WiFi (attempt #"); - WS_DEBUG_PRINT(5 - maxAttempts); - WS_DEBUG_PRINTLN(")"); - WS_PRINTER.flush(); - feedWDT(); - _connect(); - feedWDT(); - // 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 - WS._ui_helper->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 - haltError("ERROR: Unable to connect to WiFi, rebooting soon...", - WS_LED_STATUS_WIFI_CONNECTING); - } - - fsmNetwork = FSM_NET_CHECK_NETWORK; - break; - case FSM_NET_ESTABLISH_MQTT: -#ifdef USE_DISPLAY - if (WS._ui_helper->getLoadingState()) - WS._ui_helper->set_label_status("Connecting to IO..."); -#endif - WS._mqtt->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(); - feedWDT(); - statusLEDBlink(WS_LED_STATUS_MQTT_CONNECTING); - feedWDT(); - int8_t mqttRC = WS._mqtt->connect(); - feedWDT(); - if (mqttRC == WS_MQTT_CONNECTED) { - fsmNetwork = FSM_NET_CHECK_MQTT; - break; - } - WS_DEBUG_PRINT("MQTT Connection Error: "); - WS_DEBUG_PRINTLN(mqttRC); - WS_DEBUG_PRINTLN(WS._mqtt->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 - WS._ui_helper->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 - haltError( - "ERROR: Unable to connect to Adafruit.IO MQTT, rebooting soon...", - WS_LED_STATUS_MQTT_CONNECTING); - } - break; - default: - break; - } - } -} - -/**************************************************************************/ -/*! - @brief Prints an error to the serial and halts the hardware until - the WDT bites. - @param error - The desired error to print to serial. - @param ledStatusColor - The desired color to blink. -*/ -/**************************************************************************/ -void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor) { - for (;;) { - WS_DEBUG_PRINT("ERROR [WDT RESET]: "); - WS_DEBUG_PRINTLN(error); - // let the WDT fail out and reset! - statusLEDSolid(ledStatusColor); -#ifndef ARDUINO_ARCH_ESP8266 - delay(1000); -#else - // Calls to delay() and yield() feed the ESP8266's - // hardware and software watchdog timers, delayMicroseconds does not. - delayMicroseconds(1000000); -#endif - } -} - -/**************************************************************************/ -/*! - @brief Attempts to register hardware with Adafruit.io WipperSnapper. - @returns True if successful, False otherwise. -*/ -/**************************************************************************/ -bool Wippersnapper::registerBoard() { - WS_DEBUG_PRINTLN("Registering hardware with IO..."); - - // Encode and publish registration request message to broker - runNetFSM(); - WS.feedWDT(); - WS_DEBUG_PRINT("Encoding registration request..."); - if (!encodePubRegistrationReq()) - return false; - - // Blocking, attempt to obtain broker's response message - runNetFSM(); - WS.feedWDT(); - pollRegistrationResp(); - - return true; -} - -/**************************************************************************/ -/*! - @brief Returns the board definition status - @return Wippersnapper board definition status -*/ -/**************************************************************************/ -ws_board_status_t Wippersnapper::getBoardStatus() { return WS._boardStatus; } - -/**************************************************************************/ -/*! - @brief Pings the MQTT broker within the keepalive interval - to keep the connection alive. Blinks the keepalive LED - every STATUS_LED_KAT_BLINK_TIME milliseconds. -*/ -/**************************************************************************/ -void Wippersnapper::pingBroker() { - // ping within keepalive-10% to keep connection open - if (millis() > (_prv_ping + (WS_KEEPALIVE_INTERVAL_MS - - (WS_KEEPALIVE_INTERVAL_MS * 0.10)))) { - WS_DEBUG_PRINT("Sending MQTT PING: "); - if (WS._mqtt->ping()) { - WS_DEBUG_PRINTLN("SUCCESS!"); - } else { - WS_DEBUG_PRINTLN("FAILURE! Running network FSM..."); - WS._mqtt->disconnect(); - runNetFSM(); - } - _prv_ping = millis(); - WS_DEBUG_PRINT("WiFi RSSI: "); - WS_DEBUG_PRINTLN(getRSSI()); - } - // blink status LED every STATUS_LED_KAT_BLINK_TIME millis - if (millis() > (_prvKATBlink + STATUS_LED_KAT_BLINK_TIME)) { - WS_DEBUG_PRINTLN("STATUS LED BLINK KAT"); -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal("[NET] Sent KeepAlive ping!\n"); -#endif - statusLEDBlink(WS_LED_STATUS_KAT); - _prvKATBlink = millis(); - } -} - -/********************************************************/ -/*! - @brief Feeds the WDT to prevent hardware reset. -*/ -/*******************************************************/ -void Wippersnapper::feedWDT() { Watchdog.reset(); } - -/********************************************************/ -/*! - @brief Enables the watchdog timer. - @param timeoutMS - The desired amount of time to elapse before - the WDT executes. -*/ -/*******************************************************/ -void Wippersnapper::enableWDT(int timeoutMS) { -#ifndef ARDUINO_ARCH_RP2040 - Watchdog.disable(); -#endif - if (Watchdog.enable(timeoutMS) == 0) { - WS.haltError("WDT initialization failure!"); - } -} - -/********************************************************/ -/*! - @brief Process all incoming packets from the - Adafruit IO MQTT broker. Handles network - connectivity. -*/ -/*******************************************************/ -void Wippersnapper::processPackets() { - // runNetFSM(); // NOTE: Removed for now, causes error with virtual _connect - // method when caused with WS object in another file. - WS.feedWDT(); - // Process all incoming packets from Wippersnapper MQTT Broker - WS._mqtt->processPackets(10); -} - -/********************************************************/ -/*! - @brief Publishes a message to the Adafruit IO - MQTT broker. Handles network connectivity. - @param topic - The MQTT topic to publish to. - @param payload - The payload to publish. - @param bLen - The length of the payload. - @param qos - The Quality of Service to publish with. -*/ -/*******************************************************/ -void Wippersnapper::publish(const char *topic, uint8_t *payload, uint16_t bLen, - uint8_t qos) { - // runNetFSM(); // NOTE: Removed for now, causes error with virtual _connect - // method when caused with WS object in another file. - WS.feedWDT(); - if (!WS._mqtt->publish(topic, payload, bLen, qos)) { - WS_DEBUG_PRINTLN("Failed to publish MQTT message!"); - } -} - -/**************************************************************/ -/*! - @brief Prints last reset reason of ESP32 - @param reason - The return code of rtc_get_reset_reason(coreNum) -*/ -/**************************************************************/ -void print_reset_reason(int reason) { - // // - // https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/ResetReason/ResetReason.ino - switch (reason) { - case 1: - WS_DEBUG_PRINTLN("POWERON_RESET"); - break; /**<1, Vbat power on reset*/ - case 3: - WS_DEBUG_PRINTLN("SW_RESET"); - break; /**<3, Software reset digital core*/ - case 4: - WS_DEBUG_PRINTLN("OWDT_RESET"); - break; /**<4, Legacy watch dog reset digital core*/ - case 5: - WS_DEBUG_PRINTLN("DEEPSLEEP_RESET"); - break; /**<5, Deep Sleep reset digital core*/ - case 6: - WS_DEBUG_PRINTLN("SDIO_RESET"); - break; /**<6, Reset by SLC module, reset digital core*/ - case 7: - WS_DEBUG_PRINTLN("TG0WDT_SYS_RESET"); - break; /**<7, Timer Group0 Watch dog reset digital core*/ - case 8: - WS_DEBUG_PRINTLN("TG1WDT_SYS_RESET"); - break; /**<8, Timer Group1 Watch dog reset digital core*/ - case 9: - WS_DEBUG_PRINTLN("RTCWDT_SYS_RESET"); - break; /**<9, RTC Watch dog Reset digital core*/ - case 10: - WS_DEBUG_PRINTLN("INTRUSION_RESET"); - break; /**<10, Instrusion tested to reset CPU*/ - case 11: - WS_DEBUG_PRINTLN("TGWDT_CPU_RESET"); - break; /**<11, Time Group reset CPU*/ - case 12: - WS_DEBUG_PRINTLN("SW_CPU_RESET"); - break; /**<12, Software reset CPU*/ - case 13: - WS_DEBUG_PRINTLN("RTCWDT_CPU_RESET"); - break; /**<13, RTC Watch dog Reset CPU*/ - case 14: - WS_DEBUG_PRINTLN("EXT_CPU_RESET"); - break; /**<14, for APP CPU, reseted by PRO CPU*/ - case 15: - WS_DEBUG_PRINTLN("RTCWDT_BROWN_OUT_RESET"); - break; /**<15, Reset when the vdd voltage is not stable*/ - case 16: - WS_DEBUG_PRINTLN("RTCWDT_RTC_RESET"); - break; /**<16, RTC Watch dog reset digital core and rtc module*/ - default: - WS_DEBUG_PRINTLN("NO_MEAN"); - } -} - -/**************************************************************************/ -/*! - @brief Prints information about the WS device to the serial monitor. -*/ -/**************************************************************************/ -void printDeviceInfo() { - WS_DEBUG_PRINTLN("-------Device Information-------"); - WS_DEBUG_PRINT("Firmware Version: "); - WS_DEBUG_PRINTLN(WS_VERSION); - WS_DEBUG_PRINT("Board ID: "); - WS_DEBUG_PRINTLN(BOARD_ID); - WS_DEBUG_PRINT("Adafruit.io User: "); - WS_DEBUG_PRINTLN(WS._config.aio_user); - WS_DEBUG_PRINT("WiFi Network: "); - WS_DEBUG_PRINTLN(WS._config.network.ssid); - - char sMAC[18] = {0}; - sprintf(sMAC, "%02X:%02X:%02X:%02X:%02X:%02X", WS._macAddr[0], WS._macAddr[1], - WS._macAddr[2], WS._macAddr[3], WS._macAddr[4], WS._macAddr[5]); - WS_DEBUG_PRINT("MAC Address: "); - WS_DEBUG_PRINTLN(sMAC); - WS_DEBUG_PRINTLN("-------------------------------"); - -// (ESP32-Only) Print reason why device was reset -#ifdef ARDUINO_ARCH_ESP32 - WS_DEBUG_PRINT("ESP32 CPU0 RESET REASON: "); - print_reset_reason(0); - WS_DEBUG_PRINT("ESP32 CPU1 RESET REASON: "); - print_reset_reason(1); -#endif -} - -/**************************************************************************/ -/*! - @brief Connects to Adafruit IO+ Wippersnapper broker. -*/ -/**************************************************************************/ -void Wippersnapper::connect() { - WS_DEBUG_PRINTLN("Adafruit.io WipperSnapper"); - - // Dump device info to the serial monitor - printDeviceInfo(); - - // enable global WDT - WS.enableWDT(WS_WDT_TIMEOUT); - - // Generate device identifier - if (!generateDeviceUID()) { - haltError("Unable to generate Device UID"); - } - - // Initialize MQTT client with device identifer - setupMQTTClient(_device_uid); - - WS_DEBUG_PRINTLN("Generating device's MQTT topics..."); - if (!generateWSTopics()) { - haltError("Unable to allocate space for MQTT topics"); - } - - if (!generateWSErrorTopics()) { - haltError("Unable to allocate space for MQTT error topics"); - } - - // Connect to Network - WS_DEBUG_PRINTLN("Running Network FSM..."); - // Run the network fsm - runNetFSM(); - WS.feedWDT(); - -#ifdef USE_DISPLAY - WS._ui_helper->set_load_bar_icon_complete(loadBarIconCloud); - WS._ui_helper->set_label_status("Sending device info..."); -#endif - - // Register hardware with Wippersnapper - WS_DEBUG_PRINTLN("Registering hardware with WipperSnapper...") - if (!registerBoard()) { - haltError("Unable to register with WipperSnapper."); - } - runNetFSM(); - WS.feedWDT(); - -// switch to monitor screen -#ifdef USE_DISPLAY - WS_DEBUG_PRINTLN("Clearing loading screen..."); - WS._ui_helper->clear_scr_load(); - WS_DEBUG_PRINTLN("building monitor screen..."); - WS._ui_helper->build_scr_monitor(); -#endif - - // Configure hardware - WS.pinCfgCompleted = false; - while (!WS.pinCfgCompleted) { - WS_DEBUG_PRINTLN( - "Polling for message containing hardware configuration..."); - WS._mqtt->processPackets(10); // poll - } - // Publish that we have completed the configuration workflow - WS.feedWDT(); - runNetFSM(); - publishPinConfigComplete(); - WS_DEBUG_PRINTLN("Hardware configured successfully!"); - - statusLEDFade(GREEN, 3); - WS_DEBUG_PRINTLN( - "Registration and configuration complete!\nRunning application..."); -} - -/**************************************************************************/ -/*! - @brief Publishes an ACK to the broker that the device has completed - its hardware configuration. -*/ -/**************************************************************************/ -void Wippersnapper::publishPinConfigComplete() { - // Publish that we've set up the pins and are ready to run - wippersnapper_signal_v1_SignalResponse msg = - wippersnapper_signal_v1_SignalResponse_init_zero; - msg.which_payload = - wippersnapper_signal_v1_SignalResponse_configuration_complete_tag; - msg.payload.configuration_complete = true; - - // encode registration request message - uint8_t _message_buffer[128]; - pb_ostream_t _msg_stream = - pb_ostream_from_buffer(_message_buffer, sizeof(_message_buffer)); - - bool _status = ws_pb_encode( - &_msg_stream, wippersnapper_description_v1_RegistrationComplete_fields, - &msg); - size_t _message_len = _msg_stream.bytes_written; - - // verify message encoded correctly - if (!_status) - haltError("Could not encode, resetting..."); - - // Publish message - WS_DEBUG_PRINTLN("Publishing to pin config complete..."); - WS.publish(WS._topic_device_pin_config_complete, _message_buffer, - _message_len, 1); -} - -/**************************************************************************/ -/*! - @brief Processes incoming commands and handles network connection. - @returns Network status, as ws_status_t. -*/ -/**************************************************************************/ -ws_status_t Wippersnapper::run() { - // Check networking - runNetFSM(); - WS.feedWDT(); - pingBroker(); - - // Process all incoming packets from Wippersnapper MQTT Broker - WS._mqtt->processPackets(10); - WS.feedWDT(); - - // Process digital inputs, digitalGPIO module - WS._digitalGPIO->processDigitalInputs(); - WS.feedWDT(); - - // Process analog inputs - WS._analogIO->update(); - WS.feedWDT(); - - // Process I2C sensor events - if (WS._isI2CPort0Init) - WS._i2cPort0->update(); - WS.feedWDT(); - - // Process DS18x20 sensor events - WS._ds18x20Component->update(); - WS.feedWDT(); - - // Process UART sensor events - WS._uartComponent->update(); - WS.feedWDT(); - - return WS_NET_CONNECTED; // TODO: Make this funcn void! -} diff --git a/src/Wippersnapper.h b/src/Wippersnapper.h deleted file mode 100644 index 6966dd058..000000000 --- a/src/Wippersnapper.h +++ /dev/null @@ -1,498 +0,0 @@ -/*! - * @file Wippersnapper.h - * - * This is the documentation for Adafruit's Wippersnapper firmware for the - * Arduino platform. It is designed specifically to work with - * Adafruit IO Wippersnapper IoT platform. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2020-2024 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ - -#ifndef WIPPERSNAPPER_H -#define WIPPERSNAPPER_H - -// Cpp STD -#include - -// Nanopb dependencies -#include -#include -#include -#include - -#include // description.proto -#include // signal.proto - -// External libraries -#include "Adafruit_MQTT.h" // MQTT Client -#include "Adafruit_SleepyDog.h" // Watchdog -#include "Arduino.h" // Wiring -#include // SPI - -// Wippersnapper API Helpers -#include "Wippersnapper_Boards.h" -#include "components/statusLED/Wippersnapper_StatusLED.h" -#include "provisioning/ConfigJson.h" - -#define WS_DEBUG ///< Define to enable debugging to serial terminal -#define WS_PRINTER Serial ///< Where debug messages will be printed - -// Define actual debug output functions when necessary. -#ifdef WS_DEBUG -#define WS_DEBUG_PRINT(...) \ - { WS_PRINTER.print(__VA_ARGS__); } ///< Prints debug output. -#define WS_DEBUG_PRINTLN(...) \ - { WS_PRINTER.println(__VA_ARGS__); } ///< Prints line from debug output. -#define WS_DEBUG_PRINTHEX(...) \ - { WS_PRINTER.print(__VA_ARGS__, HEX); } ///< Prints debug output. -#else -#define WS_DEBUG_PRINT(...) \ - {} ///< Prints debug output -#define WS_DEBUG_PRINTLN(...) \ - {} ///< Prints line from debug output. -#endif - -#define WS_DELAY_WITH_WDT(timeout) \ - { \ - unsigned long start = millis(); \ - while (millis() - start < timeout) { \ - delay(10); \ - yield(); \ - feedWDT(); \ - if (millis() < start) { \ - start = millis(); /* if rollover */ \ - } \ - } \ - } ///< Delay function - -/**************************************************************************/ -/*! - @brief Retry a function until a condition is met or a timeout is reached. - @param func - The function to retry. - @param result_type - The type of the result of the function. - @param result_var - The variable to store the last result of the function. - @param condition - The condition to check the result against. - @param timeout - The maximum time to retry the function. - @param interval - The time to wait between retries. - @param ... - The arguments to pass to the function. -*/ -/**************************************************************************/ -#define RETRY_FUNCTION_UNTIL_TIMEOUT(func, result_type, result_var, condition, \ - timeout, interval, ...) \ - { \ - unsigned long startTime = millis(); \ - while (millis() - startTime < timeout) { \ - result_type result_var = func(__VA_ARGS__); \ - if (condition(result_var)) { \ - break; \ - } \ - if (startTime > millis()) { \ - startTime = millis(); /* if rollover */ \ - } \ - WS_DELAY_WITH_WDT(interval); \ - } \ - } ///< Retry a function until a condition is met or a timeout is reached. - -// Wippersnapper pb helpers -#include - -// Wippersnapper components -#include "components/analogIO/Wippersnapper_AnalogIO.h" -#include "components/digitalIO/Wippersnapper_DigitalGPIO.h" -#include "components/i2c/WipperSnapper_I2C.h" - -// Includes for ESP32-only -#ifdef ARDUINO_ARCH_ESP32 -#include "components/ledc/ws_ledc.h" -#include -#endif - -// Display -#ifdef USE_DISPLAY -#include "display/ws_display_driver.h" -#include "display/ws_display_ui_helper.h" -#endif - -#include "components/ds18x20/ws_ds18x20.h" -#include "components/pixels/ws_pixels.h" -#include "components/pwm/ws_pwm.h" -#include "components/servo/ws_servo.h" -#include "components/uart/ws_uart.h" - -#if defined(USE_TINYUSB) -#include "provisioning/tinyusb/Wippersnapper_FS.h" -#endif - -#if defined(USE_LITTLEFS) -#include "provisioning/littlefs/WipperSnapper_LittleFS.h" -#endif - -#define WS_VERSION \ - "1.0.0-beta.88" ///< WipperSnapper app. version (semver-formatted) - -// Reserved Adafruit IO MQTT topics -#define TOPIC_IO_THROTTLE "/throttle" ///< Adafruit IO Throttle MQTT Topic -#define TOPIC_IO_ERRORS "/errors" ///< Adafruit IO Error MQTT Topic - -// Reserved Wippersnapper topics -#define TOPIC_WS "/wprsnpr/" ///< WipperSnapper topic -#define TOPIC_INFO "/info/" ///< Registration sub-topic -#define TOPIC_SIGNALS "/signals/" ///< Signals sub-topic -#define TOPIC_I2C "/i2c" ///< I2C sub-topic -#define MQTT_TOPIC_PIXELS_DEVICE \ - "/signals/device/pixel" ///< Pixels device->broker topic -#define MQTT_TOPIC_PIXELS_BROKER \ - "/signals/broker/pixel" ///< Pixels broker->device topic - -/** Defines the Adafruit IO connection status */ -typedef enum { - WS_IDLE = 0, // Waiting for connection establishement - WS_NET_DISCONNECTED = 1, // Network disconnected - WS_DISCONNECTED = 2, // Disconnected from Adafruit IO - WS_FINGERPRINT_UNKOWN = 3, // Unknown WS_SSL_FINGERPRINT - - WS_NET_CONNECT_FAILED = 10, // Failed to connect to network - WS_CONNECT_FAILED = 11, // Failed to connect to Adafruit IO - WS_FINGERPRINT_INVALID = 12, // Unknown WS_SSL_FINGERPRINT - WS_AUTH_FAILED = 13, // Invalid Adafruit IO login credentials provided. - WS_SSID_INVALID = - 14, // SSID is "" or otherwise invalid, connection not attempted - - WS_NET_CONNECTED = 20, // Connected to Adafruit IO - WS_CONNECTED = 21, // Connected to network - WS_CONNECTED_INSECURE = 22, // Insecurely (non-SSL) connected to network - WS_FINGERPRINT_UNSUPPORTED = 23, // Unsupported WS_SSL_FINGERPRINT - WS_FINGERPRINT_VALID = 24, // Valid WS_SSL_FINGERPRINT - WS_BOARD_DESC_INVALID = 25, // Unable to send board description - WS_BOARD_RESYNC_FAILED = 26 // Board sync failure -} ws_status_t; - -/** Defines the Adafruit IO MQTT broker's connection return codes */ -typedef enum { - WS_MQTT_CONNECTED = 0, // Connected - WS_MQTT_INVALID_PROTOCOL = 1, // Invalid mqtt protocol - WS_MQTT_INVALID_CID = 2, // Client id rejected - WS_MQTT_SERVICE_UNAVALIABLE = 3, // Malformed user/pass - WS_MQTT_INVALID_USER_PASS = 4, // Unauthorized access to resource - WS_MQTT_UNAUTHORIZED = 5, // MQTT service unavailable - WS_MQTT_THROTTLED = 6, // Account throttled - WS_MQTT_BANNED = 7 // Account banned -} ws_mqtt_status_t; - -/** Defines the Wippersnapper client's hardware registration status */ -typedef enum { - WS_BOARD_DEF_IDLE, - WS_BOARD_DEF_SEND_FAILED, - WS_BOARD_DEF_SENT, - WS_BOARD_DEF_OK, - WS_BOARD_DEF_INVALID, - WS_BOARD_DEF_UNSPECIFIED -} ws_board_status_t; - -/** Defines the Wippersnapper client's network status */ -typedef enum { - FSM_NET_IDLE, - FSM_NET_CONNECTED, - FSM_MQTT_CONNECTED, - FSM_NET_CHECK_MQTT, - FSM_NET_CHECK_NETWORK, - FSM_NET_ESTABLISH_NETWORK, - FSM_NET_ESTABLISH_MQTT, -} fsm_net_t; - -#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 \ - 5000 ///< Session keepalive interval time, in milliseconds - -#define WS_MQTT_MAX_PAYLOAD_SIZE \ - 512 ///< MAXIMUM expected payload size, in bytes - -class Wippersnapper_DigitalGPIO; -class Wippersnapper_AnalogIO; -class Wippersnapper_FS; -class WipperSnapper_LittleFS; -#ifdef USE_DISPLAY -class ws_display_driver; -class ws_display_ui_helper; -#endif -#ifdef ARDUINO_ARCH_ESP32 -class ws_ledc; -#endif -class WipperSnapper_Component_I2C; -class ws_servo; -class ws_pwm; -class ws_ds18x20; -class ws_pixels; -class ws_uart; - -/**************************************************************************/ -/*! - @brief Class that provides storage and functions for the Adafruit IO - Wippersnapper interface. -*/ -/**************************************************************************/ -class Wippersnapper { -public: - Wippersnapper(); - virtual ~Wippersnapper(); - - void provision(); - - bool lockStatusNeoPixel; ///< True if status LED is using the status neopixel - bool lockStatusDotStar; ///< True if status LED is using the status dotstar - bool lockStatusLED; ///< True if status LED is using the built-in LED - float status_pixel_brightness = - STATUS_PIXEL_BRIGHTNESS_DEFAULT; ///< Global status pixel's brightness - ///< (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(); - virtual bool check_valid_ssid(); - - virtual void _connect(); - virtual void _disconnect(); - void connect(); - void disconnect(); - - virtual void getMacAddr(); - virtual int32_t getRSSI(); - virtual void setupMQTTClient(const char *clientID); - - virtual ws_status_t networkStatus(); - ws_board_status_t getBoardStatus(); - - bool generateDeviceUID(); - bool generateWSTopics(); - bool generateWSErrorTopics(); - - // Registration API - bool registerBoard(); - bool encodePubRegistrationReq(); - void decodeRegistrationResp(char *data, uint16_t len); - void pollRegistrationResp(); - // Configuration API - void publishPinConfigComplete(); - - // run() loop - ws_status_t run(); - void processPackets(); - void publish(const char *topic, uint8_t *payload, uint16_t bLen, - uint8_t qos = 0); - - // Networking helpers - void pingBroker(); - void runNetFSM(); - - // WDT helpers - void enableWDT(int timeoutMS = 0); - void feedWDT(); - - // Error handling helpers - void haltError(String error, - ws_led_status_t ledStatusColor = WS_LED_STATUS_ERROR_RUNTIME); - void errorWriteHang(String error); - - // MQTT topic callbacks // - // Decodes a signal message - bool decodeSignalMsg( - wippersnapper_signal_v1_CreateSignalRequest *encodedSignalMsg); - - // Encodes a pin event message - bool - encodePinEvent(wippersnapper_signal_v1_CreateSignalRequest *outgoingSignalMsg, - uint8_t pinName, int pinVal); - - // Pin configure message - bool configureDigitalPinReq(wippersnapper_pin_v1_ConfigurePinRequest *pinMsg); - bool configAnalogInPinReq(wippersnapper_pin_v1_ConfigurePinRequest *pinMsg); - - // I2C - std::vector - i2cComponents; ///< Vector containing all I2C components - WipperSnapper_Component_I2C *_i2cPort0 = - NULL; ///< WipperSnapper I2C Component for I2C port #0 - WipperSnapper_Component_I2C *_i2cPort1 = - NULL; ///< WipperSnapper I2C Component for I2C port #1 - bool _isI2CPort0Init = - false; ///< True if I2C port 0 has been initialized, False otherwise. - bool _isI2CPort1Init = - false; ///< True if I2C port 1 has been initialized, False otherwise. - - uint8_t _buffer[WS_MQTT_MAX_PAYLOAD_SIZE]; /*!< Shared buffer to save callback - payload */ - uint8_t - _buffer_outgoing[WS_MQTT_MAX_PAYLOAD_SIZE]; /*!< buffer which contains - outgoing payload data */ - uint16_t bufSize; /*!< Length of data inside buffer */ - - ws_board_status_t _boardStatus = - WS_BOARD_DEF_IDLE; ///< Hardware's registration status - - // TODO: We really should look at making these static definitions, not dynamic - // to free up space on the heap - Wippersnapper_DigitalGPIO *_digitalGPIO; ///< Instance of digital gpio class - Wippersnapper_AnalogIO *_analogIO; ///< Instance of analog io class - Wippersnapper_FS *_fileSystem; ///< Instance of Filesystem (native USB) - WipperSnapper_LittleFS - *_littleFS; ///< Instance of LittleFS Filesystem (non-native USB) -#ifdef USE_DISPLAY - ws_display_driver *_display = nullptr; ///< Instance of display driver class - ws_display_ui_helper *_ui_helper = - nullptr; ///< Instance of display UI helper class -#endif - ws_pixels *_ws_pixelsComponent; ///< ptr to instance of ws_pixels class - ws_pwm *_pwmComponent; ///< Instance of pwm class - ws_servo *_servoComponent; ///< Instance of servo class - ws_ds18x20 *_ds18x20Component; ///< Instance of DS18x20 class - ws_uart *_uartComponent; ///< Instance of UART class - - // TODO: does this really need to be global? - uint8_t _macAddr[6]; /*!< Unique network iface identifier */ - char sUID[13]; /*!< Unique network iface identifier */ - const char *_boardId; /*!< Adafruit IO+ board string */ - Adafruit_MQTT *_mqtt; /*!< Reference to Adafruit_MQTT, _mqtt. */ - - secretsConfig _config; /*!< Wippersnapper secrets.json as a struct. */ - networkConfig _multiNetworks[3]; /*!< Wippersnapper networks as structs. */ - bool _isWiFiMulti = false; /*!< True if multiple networks are defined. */ - - // TODO: Does this need to be within this class? - int32_t totalDigitalPins; /*!< Total number of digital-input capable pins */ - - char *_topic_description = NULL; /*!< MQTT topic for the device description */ - char *_topic_signal_device = NULL; /*!< Device->Wprsnpr messages */ - char *_topic_signal_i2c_brkr = NULL; /*!< Topic carries messages from a device - to a broker. */ - char *_topic_signal_i2c_device = NULL; /*!< Topic carries messages from a - broker to a device. */ - char *_topic_signal_servo_brkr = NULL; /*!< Topic carries messages from a - device to a broker. */ - char *_topic_signal_servo_device = NULL; /*!< Topic carries messages from a - broker to a device. */ - char *_topic_signal_pwm_brkr = - NULL; /*!< Topic carries PWM messages from a device to a broker. */ - char *_topic_signal_pwm_device = - NULL; /*!< Topic carries PWM messages from a broker to a device. */ - char *_topic_signal_ds18_brkr = NULL; /*!< Topic carries ds18x20 messages from - a device to a broker. */ - char *_topic_signal_ds18_device = NULL; /*!< Topic carries ds18x20 messages - from a broker to a device. */ - char *_topic_signal_pixels_brkr = NULL; /*!< Topic carries pixel messages */ - char *_topic_signal_pixels_device = NULL; /*!< Topic carries pixel messages */ - char *_topic_signal_uart_brkr = NULL; /*!< Topic carries UART messages */ - char *_topic_signal_uart_device = NULL; /*!< Topic carries UART messages */ - - wippersnapper_signal_v1_CreateSignalRequest - _incomingSignalMsg; /*!< Incoming signal message from broker */ - wippersnapper_signal_v1_I2CRequest msgSignalI2C = - wippersnapper_signal_v1_I2CRequest_init_zero; ///< I2C request wrapper - ///< message - - // ds signal msg - wippersnapper_signal_v1_Ds18x20Request msgSignalDS = - wippersnapper_signal_v1_Ds18x20Request_init_zero; ///< DS request message - ///< wrapper - - // servo message - wippersnapper_signal_v1_ServoRequest - msgServo; ///< ServoRequest wrapper message - wippersnapper_signal_v1_PWMRequest msgPWM = - wippersnapper_signal_v1_PWMRequest_init_zero; ///< PWM request wrapper - ///< message. - - // pixels signal message - wippersnapper_signal_v1_PixelsRequest - msgPixels; ///< PixelsRequest wrapper message - - wippersnapper_signal_v1_UARTRequest - msgSignalUART; ///< UARTReq wrapper message - - char *throttleMessage; /*!< Pointer to throttle message data. */ - int throttleTime; /*!< Total amount of time to throttle the device, in - milliseconds. */ - - bool pinCfgCompleted = false; /*!< Did initial pin sync complete? */ - -// enable LEDC if esp32 -#ifdef ARDUINO_ARCH_ESP32 - ws_ledc *_ledc = nullptr; ///< Pointer to LEDC object -#endif - -private: - void _init(); - -protected: - ws_status_t _status = WS_IDLE; /*!< Adafruit IO connection status */ - uint32_t _last_mqtt_connect = 0; /*!< Previous time when client connected to - Adafruit IO, in milliseconds. */ - uint32_t _prv_ping = 0; /*!< Previous time when client pinged Adafruit IO's - MQTT broker, in milliseconds. */ - uint32_t _prvKATBlink = 0; /*!< Previous time when client pinged Adafruit IO's - MQTT broker, in milliseconds. */ - - // Device information - const char *_deviceId; /*!< Adafruit IO+ device identifier string */ - char *_device_uid; /*!< Unique device identifier */ - - // MQTT topics - char *_topic_description_status = - NULL; /*!< MQTT subtopic carrying the description - status resp. from the broker */ - char *_topic_description_status_complete = NULL; /*!< MQTT topic carrying the - ACK signal from the device to the - broker after registration */ - char *_topic_device_pin_config_complete = - NULL; /*!< MQTT topic carrying the ACK signal - from the device to the broker after - hardware configuration */ - char *_topic_signal_brkr = NULL; /*!< Wprsnpr->Device messages */ - char *_err_topic = NULL; /*!< Adafruit IO MQTT error message topic. */ - char *_throttle_topic = NULL; /*!< Adafruit IO MQTT throttle message topic. */ - - Adafruit_MQTT_Subscribe *_topic_description_sub; /*!< Subscription callback - for registration topic. */ - Adafruit_MQTT_Publish *_topic_signal_device_pub; /*!< Subscription callback - for D2C signal topic. */ - Adafruit_MQTT_Subscribe *_topic_signal_brkr_sub; /*!< Subscription callback - for C2D signal topic. */ - Adafruit_MQTT_Subscribe - *_topic_signal_i2c_sub; /*!< Subscription callback for I2C topic. */ - Adafruit_MQTT_Subscribe - *_topic_signal_servo_sub; /*!< Subscription callback for servo topic. */ - Adafruit_MQTT_Subscribe - *_topic_signal_pwm_sub; /*!< Subscription callback for pwm topic. */ - Adafruit_MQTT_Subscribe - *_topic_signal_ds18_sub; /*!< Subscribes to signal's ds18x20 topic. */ - Adafruit_MQTT_Subscribe - *_topic_signal_pixels_sub; /*!< Subscribes to pixel device topic. */ - Adafruit_MQTT_Subscribe - *_topic_signal_uart_sub; /*!< Subscribes to signal's UART topic. */ - - Adafruit_MQTT_Subscribe - *_err_sub; /*!< Subscription to Adafruit IO Error topic. */ - Adafruit_MQTT_Subscribe - *_throttle_sub; /*!< Subscription to Adafruit IO Throttle topic. */ - - wippersnapper_signal_v1_CreateSignalRequest - _outgoingSignalMsg; /*!< Outgoing signal message from device */ -}; -extern Wippersnapper WS; ///< Global member variable for callbacks - -#endif // ADAFRUIT_WIPPERSNAPPER_H diff --git a/src/Wippersnapper_Boards.h b/src/Wippersnapper_Boards.h index bd3c263a6..01babf8a5 100644 --- a/src/Wippersnapper_Boards.h +++ b/src/Wippersnapper_Boards.h @@ -51,6 +51,13 @@ #define STATUS_NEOPIXEL_PIN 45 #define STATUS_NEOPIXEL_NUM 1 #define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation +#elif defined(ARDUINO_METRO_ESP32S3) +#define BOARD_ID "metroesp32s3" +#define USE_TINYUSB +#define USE_STATUS_NEOPIXEL +#define STATUS_NEOPIXEL_PIN 46 +#define STATUS_NEOPIXEL_NUM 1 +#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation #elif defined(ARDUINO_MAGTAG29_ESP32S2) #define BOARD_ID "magtag" #define USE_TINYUSB @@ -114,12 +121,14 @@ #define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL #define STATUS_NEOPIXEL_NUM 1 #define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation +#define I2c_STEMMA_WIRE1 #elif defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) #define BOARD_ID "qtpy-esp32s3" #define USE_TINYUSB #define USE_STATUS_NEOPIXEL -#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL #define STATUS_NEOPIXEL_NUM 1 +#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL +#define I2c_STEMMA_WIRE1 #elif defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_N4R2) #define BOARD_ID "qtpy-esp32s3-n4r2" #define USE_TINYUSB @@ -127,6 +136,7 @@ #define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL #define STATUS_NEOPIXEL_NUM 1 #define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation +#define I2c_STEMMA_WIRE1 #elif defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3) #define BOARD_ID "qtpy-esp32c3" #define USE_LITTLEFS @@ -150,6 +160,10 @@ #define USE_LITTLEFS #define USE_STATUS_LED #define STATUS_LED_PIN 13 +#elif defined(ARDUINO_ESP32_DEV) || defined(ESP32_DEV) +#define BOARD_ID "feather-esp32" +#define USE_STATUS_LED +#define STATUS_LED_PIN 13 #elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2) #define BOARD_ID "feather-esp32-v2" #define USE_LITTLEFS @@ -164,6 +178,7 @@ #define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL #define STATUS_NEOPIXEL_NUM 1 #define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation +#define I2c_STEMMA_WIRE1 #elif defined(ARDUINO_SAMD_NANO_33_IOT) #define BOARD_ID "nano-33-iot" #define USE_STATUS_LED @@ -177,6 +192,30 @@ #define USE_TINYUSB #define USE_STATUS_LED #define STATUS_LED_PIN 32 +#elif defined(ARDUINO_RASPBERRY_PI_PICO) +#define BOARD_ID "rpi-pico" +#define USE_TINYUSB +#define USE_STATUS_LED +#define STATUS_LED_PIN LED_BUILTIN +#elif defined(ARDUINO_RASPBERRY_PI_PICO_2) +#define BOARD_ID "rpi-pico-2" +#define USE_TINYUSB +#define USE_STATUS_LED +#define STATUS_LED_PIN LED_BUILTIN +#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER) +#define BOARD_ID "feather-rp2040-adalogger" +#define USE_TINYUSB +#define USE_STATUS_NEOPIXEL +#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL +#define STATUS_NEOPIXEL_NUM 1 +#define SD_USE_SPI_1 +#elif defined(ARDUINO_ADAFRUIT_METRO_RP2350) +#define BOARD_ID "metro-rp2350" +#define USE_TINYUSB +#define USE_STATUS_NEOPIXEL +#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL +#define STATUS_NEOPIXEL_NUM NUM_NEOPIXEL +#define SD_USE_SPI_1 #else #warning "Board type not identified within Wippersnapper_Boards.h!" #endif diff --git a/src/Wippersnapper_Networking.h b/src/Wippersnapper_Networking.h deleted file mode 100644 index 5e401a4ff..000000000 --- a/src/Wippersnapper_Networking.h +++ /dev/null @@ -1,44 +0,0 @@ -/*! - * @file Wippersnapper_Networking.h - * - * This file includes network interfaces at compile-time. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2020-2021 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ - -#ifndef WIPPERSNAPPER_NETWORKING_H -#define WIPPERSNAPPER_NETWORKING_H - -#if defined(ADAFRUIT_METRO_M4_EXPRESS) || \ - defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE) || defined(ADAFRUIT_PYPORTAL) || \ - defined(ADAFRUIT_PYPORTAL_M4_TITANO) || defined(USE_AIRLIFT) -#include "network_interfaces/Wippersnapper_AIRLIFT.h" -/** Nina-FW (adafruit fork) networking class */ -typedef Wippersnapper_AIRLIFT Wippersnapper_WiFi; -#elif defined(ARDUINO_ARCH_ESP8266) -#include "network_interfaces/Wippersnapper_ESP8266.h" -/** ESP8266's networking class */ -typedef Wippersnapper_ESP8266 Wippersnapper_WiFi; -#elif defined(ARDUINO_ARCH_ESP32) -#include "network_interfaces/Wippersnapper_ESP32.h" -/** ESP32's networking class */ -typedef Wippersnapper_ESP32 Wippersnapper_WiFi; -#elif defined(ARDUINO_ARCH_RP2040) -#include "network_interfaces/ws_networking_pico.h" -typedef ws_networking_pico Wippersnapper_WiFi; -#elif defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRWIFI1010) -/** Nina-FW (arduino) networking class */ -#include "network_interfaces/Wippersnapper_WIFININA.h" -typedef Wippersnapper_WIFININA Wippersnapper_WiFi; -#else -#warning "Must define network interface in config.h!" -#endif - -#endif // WIPPERSNAPPER_NETWORKING_H \ No newline at end of file diff --git a/src/Wippersnapper_V2.cpp b/src/Wippersnapper_V2.cpp new file mode 100644 index 000000000..1814aa0e5 --- /dev/null +++ b/src/Wippersnapper_V2.cpp @@ -0,0 +1,1331 @@ +/*! + * @file Wippersnapper_v2.cpp + * + * @mainpage Adafruit Wippersnapper Wrapper + * + * @section intro_sec Introduction + * + * This is the documentation for Adafruit's Wippersnapper wrapper for the + * Arduino platform. It is designed specifically to work with the + * Adafruit IO+ Wippersnapper IoT platform. + * + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * @section dependencies Dependencies + * + * This library depends on Adafruit_Sensor being + * present on your system. Please make sure you have installed the latest + * version before using this library. + * + * @section author Author + * + * Copyright (c) Brent Rubell 2020-2025 for Adafruit Industries. + * + * @section license License + * + * BSD license, all text here must be included in any redistribution. + * + */ + +#include "Wippersnapper_V2.h" + +Wippersnapper_V2 WsV2; + +Wippersnapper_V2::Wippersnapper_V2() { + // TODO: Scope out how much of this we can remove + // and what should be here (if we are wrong!) + _mqttV2 = 0; // MQTT Client object + + // Reserved MQTT Topics + _topicError = 0; + _topicThrottle = 0; + _subscribeError = 0; + _subscribeThrottle = 0; + + // Initialize model classes + WsV2.sensorModel = new SensorModel(); + + // Initialize controller classes + WsV2.digital_io_controller = new DigitalIOController(); + WsV2.analogio_controller = new AnalogIOController(); + WsV2._ds18x20_controller = new DS18X20Controller(); + WsV2._i2c_controller = new I2cController(); +}; + +/**************************************************************************/ +/*! + @brief Wippersnapper_V2 destructor +*/ +/**************************************************************************/ +Wippersnapper_V2::~Wippersnapper_V2() {} + +/**************************************************************************/ +/*! + @brief Provisions a WipperSnapper device with its network + configuration and Adafruit IO credentials. +*/ +/**************************************************************************/ +void Wippersnapper_V2::provision() { + // Obtain device's MAC address + getMacAddr(); + + // Initialize the status LED for signaling FS errors + initStatusLED(); + +// Initialize the filesystem +#ifdef USE_TINYUSB + _fileSystemV2 = new Wippersnapper_FS(); +#elif defined(USE_LITTLEFS) + _littleFSV2 = new WipperSnapper_LittleFS(); +#endif + +// Determine if app is in SDLogger mode +#ifdef USE_TINYUSB + _fileSystemV2->GetSDCSPin(); +#elif defined(USE_LITTLEFS) + _littleFSV2->GetSDCSPin(); +#elif defined(OFFLINE_MODE_WOKWI) + WsV2.pin_sd_cs = 15; +#endif + WsV2._sdCardV2 = new ws_sdcard(); + if (WsV2._sdCardV2->isSDCardInitialized()) { + return; // SD card initialized, cede control back to loop() + } else { +#ifdef BUILD_OFFLINE_ONLY + haltErrorV2("SD initialization failed.\nDo not reformat the card!\nIs the " + "card correctly inserted?\nIs there a wiring/soldering " + "problem\nIs the config.json file malformed?"); +#endif + // SD card not initialized, so just continue with online-mode provisioning + } + +#ifdef USE_DISPLAY + // Initialize the display + displayConfig config; + WsV2._fileSystemV2->parseDisplayConfig(config); + WsV2._display = new ws_display_driver(config); + // Begin display + if (!WsV2._display->begin()) { + WS_DEBUG_PRINTLN("Unable to enable display driver and LVGL"); + haltErrorV2("Unable to enable display driver, please check the json " + "configuration!"); + } + + WsV2._display->enableLogging(); + releaseStatusLED(); // don't use status LED if we are using the display + // UI Setup + WsV2._ui_helper = new ws_display_ui_helper(WsV2._display); + WsV2._ui_helper->set_bg_black(); + WsV2._ui_helper->show_scr_load(); + WsV2._ui_helper->set_label_status("Validating Credentials..."); +#endif + +#ifdef USE_TINYUSB + _fileSystemV2->parseSecrets(); +#elif defined(USE_LITTLEFS) + _littleFSV2->parseSecrets(); +#else + check_valid_ssid(); // non-fs-backed, sets global credentials within network + // iface +#endif + // Set the status pixel's brightness + setStatusLEDBrightness(WsV2._configV2.status_pixel_brightness); + // Set device's wireless credentials + set_ssid_pass(); + +#ifdef USE_DISPLAY + WsV2._ui_helper->set_label_status(""); + WsV2._ui_helper->set_load_bar_icon_complete(loadBarIconFile); +#endif +} + +/**************************************************************************/ +/*! + @brief Disconnects from Adafruit IO+ Wippersnapper_V2. +*/ +/**************************************************************************/ +void Wippersnapper_V2::disconnect() { _disconnect(); } + +// Concrete class definition for abstract classes + +/****************************************************************************/ +/*! + @brief Connects to wireless network. +*/ +/****************************************************************************/ +void Wippersnapper_V2::_connect() { + WS_DEBUG_PRINTLN("Wippersnapper_V2::_connect()"); + WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); +} + +/****************************************************************************/ +/*! + @brief Disconnect Wippersnapper MQTT session and network. +*/ +/****************************************************************************/ +void Wippersnapper_V2::_disconnect() { + WS_DEBUG_PRINTLN("WIppersnapper_V2::_disconnect"); + WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); +} + +/****************************************************************************/ +/*! + @brief Sets the network interface's unique identifer, typically the + MAC address. +*/ +/****************************************************************************/ +void Wippersnapper_V2::getMacAddr() { + WS_DEBUG_PRINTLN("Wippersnapper_V2::getMacAddr"); + WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); +} + +/****************************************************************************/ +/*! + @brief Gets the network's RSSI. + @return int32_t RSSI value, 0 to 255, in dB +*/ +/****************************************************************************/ +int32_t Wippersnapper_V2::getRSSI() { + WS_DEBUG_PRINTLN("Wiippersnapper_V2::getRSSI"); + WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); + return 0; +} + +/****************************************************************************/ +/*! + @brief Sets up the MQTT client session. + @param clientID + A unique client identifier string. +*/ +/****************************************************************************/ +void Wippersnapper_V2::setupMQTTClient(const char * /*clientID*/) { + WS_DEBUG_PRINTLN("Wippersnapper_V2::setupMQTTClient"); + WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); +} + +/****************************************************************************/ +/*! + @brief Returns the network's connection status + @returns Network status as ws_status_t. +*/ +/****************************************************************************/ +ws_status_t Wippersnapper_V2::networkStatus() { + WS_DEBUG_PRINTLN("Wippersnapper_V2::networkStatus"); + WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); + return WS_IDLE; +} + +/****************************************************************************/ +/*! + @brief Sets the device's wireless network credentials. + @param ssid + Your wireless network's SSID + @param ssidPassword + Your wireless network's password. +*/ +/****************************************************************************/ +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!"); +} + +/****************************************************************************/ +/*! + @brief Sets the device's wireless network credentials from the + secrets.json configuration file. +*/ +/****************************************************************************/ +void Wippersnapper_V2::set_ssid_pass() { + WS_DEBUG_PRINTLN("Wippersnapper_V2::set_ssid_pass"); + WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); +} + +/***********************************************************/ +/*! +@brief Performs a scan of local WiFi networks. +@returns True if `_network_ssid` is found, False otherwise. +*/ +/***********************************************************/ +bool Wippersnapper_V2::check_valid_ssid() { + WS_DEBUG_PRINTLN("Wippersnapper_V2::check_valid_ssid"); + WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); + return false; +} + +/****************************************************************************/ +/*! + @brief Configures the device's Adafruit IO credentials. This method + should be used only if filesystem-backed provisioning is + not avaliable. +*/ +/****************************************************************************/ +void Wippersnapper_V2::set_user_key() { + WS_DEBUG_PRINTLN("Wippersnapper_V2::set_user_key"); + WS_DEBUG_PRINTLN("ERROR: Please define a network interface!"); +} + +/****************************************************************************/ +/*! + @brief Handles a Checkin Response message and initializes the + device's GPIO classes. + @param stream + Incoming data stream from buffer. + @returns True if Checkin Response decoded and parsed successfully, + False otherwise. +*/ +/****************************************************************************/ +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"); + return false; + } + + // Parse the response message + WsV2.CheckInModel->ParseCheckinResponse(); + + // Validate the checkin response message + if (WsV2.CheckInModel->getCheckinResponse() != + wippersnapper_checkin_CheckinResponse_Response_RESPONSE_OK) { + WS_DEBUG_PRINTLN("ERROR: CheckinResponse not RESPONSE_OK, backing out!"); + return false; + } + + // Configure GPIO classes based on checkin response message + WsV2.digital_io_controller->SetMaxDigitalPins( + WsV2.CheckInModel->getTotalGPIOPins()); + + WsV2.analogio_controller->SetRefVoltage( + WsV2.CheckInModel->getReferenceVoltage()); + WsV2.analogio_controller->SetTotalAnalogPins( + WsV2.CheckInModel->getTotalAnalogPins()); + + // set glob flag so we don't keep the polling loop open + WsV2.got_checkin_response = true; + return true; +} + +// Decoders // + +/******************************************************************************************/ +/*! + @brief Decodes a BrokerToDevice message and executes the asscoiated + callback. + @param stream + Incoming data stream from buffer. + @param field + Protobuf message's tag type. + @param arg + 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) { + (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)) { + WS_DEBUG_PRINTLN("Failure handling Checkin Response!"); + 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)) { + WS_DEBUG_PRINTLN("ERROR: Unable to add digitalio pin!"); + 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)) { + WS_DEBUG_PRINTLN("ERROR: Unable to remove digitalio pin!"); + 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)) { + WS_DEBUG_PRINTLN("ERROR: Unable to write to digitalio pin!"); + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_analogio_add_tag: + WS_DEBUG_PRINTLN("-> AnalogIO Add Message Type"); + if (!WsV2.analogio_controller->Handle_AnalogIOAdd(stream)) { + WS_DEBUG_PRINTLN("ERROR: Unable to add analogio pin!"); + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_analogio_remove_tag: + WS_DEBUG_PRINTLN("-> AnalogIO Remove Message Type"); + if (!WsV2.analogio_controller->Handle_AnalogIORemove(stream)) { + WS_DEBUG_PRINTLN("ERROR: Unable to remove analogio pin!"); + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_ds18x20_add_tag: + WS_DEBUG_PRINTLN("-> DS18X20 Add Message Type"); + if (!WsV2._ds18x20_controller->Handle_Ds18x20Add(stream)) { + WS_DEBUG_PRINTLN("ERROR: Unable to add DS18X20 sensor!"); + return false; + } + break; + case wippersnapper_signal_BrokerToDevice_ds18x20_remove_tag: + WS_DEBUG_PRINTLN("-> DS18X20 Remove Message Type"); + if (!WsV2._ds18x20_controller->Handle_Ds18x20Remove(stream)) { + WS_DEBUG_PRINTLN("ERROR: Unable to remove DS18X20 sensor!"); + 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)) { + WS_DEBUG_PRINTLN("ERROR: Unable to add/replace I2C device!"); + 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)) { + WS_DEBUG_PRINTLN("ERROR: Unable to remove I2C device!"); + return false; + } + default: + WS_DEBUG_PRINTLN("ERROR: BrokerToDevice message type not found!"); + return false; + } + + // once this is returned, pb_dec_submessage() + // decodes the submessage contents. + return true; +} + +/**************************************************************************/ +/*! + @brief Called when client receives a message published across the + Adafruit IO MQTT /ws-b2d/ "signal topic". + @param data + Data (payload) from MQTT broker. + @param len + Length of data received from MQTT broker. +*/ +/**************************************************************************/ +void cbBrokerToDevice(char *data, uint16_t len) { + WS_DEBUG_PRINTLN("=> New B2D message!"); + wippersnapper_signal_BrokerToDevice msg_signal = + wippersnapper_signal_BrokerToDevice_init_default; + + // Configure the payload callback + msg_signal.cb_payload.funcs.decode = cbDecodeBrokerToDevice; + + // Decode msg_signal + WS_DEBUG_PRINTLN("Creating input stream..."); + 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)) { + WS_DEBUG_PRINTLN("ERROR: Unable to decode BrokerToDevice message!"); + return; + } + WS_DEBUG_PRINTLN("Decoded BrokerToDevice message!"); +} + +/**************************************************************************/ +/*! + @brief Decodes and parses a buffer containing configuration + messages from the SD card. +*/ +/**************************************************************************/ +void callDecodeB2D() { + for (size_t i = 0; i < WsV2._sharedConfigBuffers.size(); i++) { + wippersnapper_signal_BrokerToDevice msg_signal = + wippersnapper_signal_BrokerToDevice_init_default; + // Configure the payload callback + msg_signal.cb_payload.funcs.decode = cbDecodeBrokerToDevice; + 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, + &msg_signal)) { + WS_DEBUG_PRINTLN("ERROR: Unable to decode BrokerToDevice message!"); + continue; // Skip this message and move on! + } + } +} + +/**************************************************************************/ +/*! + @brief Called when client receives a message published across the + Adafruit IO MQTT /error special topic. + @param errorData + Data from MQTT broker. + @param len + Length of data received from MQTT broker. +*/ +/**************************************************************************/ +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); + // Disconnect client from broker + WS_DEBUG_PRINT("Disconnecting from MQTT.."); + if (!WsV2._mqttV2->disconnect()) { + WS_DEBUG_PRINTLN("ERROR: Unable to disconnect from MQTT broker!"); + } + +#ifdef USE_DISPLAY + WsV2._ui_helper->show_scr_error("IO Ban Error", errorData); +#endif + + // WDT reset + WsV2.haltErrorV2("IO MQTT Ban Error"); +} + +/**************************************************************************/ +/*! + @brief Called when client receives a message published across the + Adafruit IO MQTT /throttle special topic. Delays until + throttle is released. + @param throttleData + Throttle message from Adafruit IO. + @param len + Length of data received from MQTT broker. +*/ +/**************************************************************************/ +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; + // Parse out # of seconds from message buffer + throttleMessage = strtok(throttleData, ","); + throttleMessage = strtok(NULL, " "); + // Convert from seconds to to millis + int throttleDuration = atoi(throttleMessage) * 1000; + + WS_DEBUG_PRINT("Device is throttled for "); + WS_DEBUG_PRINT(throttleDuration); + WS_DEBUG_PRINTLN("ms and blocking command execution."); + +#ifdef USE_DISPLAY + char buffer[100]; + snprintf( + buffer, 100, + "[IO ERROR] Device is throttled for %d mS and blocking execution..\n.", + throttleDuration); + WsV2._ui_helper->add_text_to_terminal(buffer); +#endif + + // If throttle duration is less than the keepalive interval, delay for the + // full keepalive interval + if (throttleDuration < WS_KEEPALIVE_INTERVAL_MS) { + delay(WS_KEEPALIVE_INTERVAL_MS); + } else { + // round to nearest millis to prevent delaying for less time than req'd. + float throttleLoops = ceil(throttleDuration / WS_KEEPALIVE_INTERVAL_MS); + // block the run() loop + while (throttleLoops > 0) { + delay(WS_KEEPALIVE_INTERVAL_MS); + WsV2.feedWDTV2(); + WsV2._mqttV2->ping(); + throttleLoops--; + } + } + WS_DEBUG_PRINTLN("Device is un-throttled, resumed command execution"); +#ifdef USE_DISPLAY + WsV2._ui_helper->add_text_to_terminal( + "[IO] Device is un-throttled, resuming...\n"); +#endif +} + +/**************************************************************************/ +/*! + @brief Attempts to generate unique device identifier. + @returns True if device identifier generated successfully, + False otherwise. +*/ +/**************************************************************************/ +bool Wippersnapper_V2::generateDeviceUID() { + // Generate device unique identifier + // Set machine_name + WsV2._boardIdV2 = BOARD_ID; + // Move the top 3 bytes from the UID + for (int i = 5; i > 2; i--) { + WsV2._macAddrV2[6 - 1 - i] = WsV2._macAddrV2[i]; + } + snprintf(WsV2.sUIDV2, sizeof(WsV2.sUIDV2), "%02d%02d%02d", WsV2._macAddrV2[0], + WsV2._macAddrV2[1], WsV2._macAddrV2[2]); + // Conversion to match integer UID sent by createMsgCheckinRequest() + itoa(atoi(WsV2.sUIDV2), WsV2.sUIDV2, 10); + + // Calculate the length of device and UID strings + WS_DEBUG_PRINTLN("Calculating device UID length..."); + size_t lenBoardId = strlen(WsV2._boardIdV2); + size_t lenUID = strlen(WsV2.sUIDV2); + size_t lenIOWipper = strlen("io-wipper-"); + size_t lenDeviceUID = lenBoardId + lenUID + lenIOWipper + 1; + + // 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); +#else + _device_uidV2 = (char *)malloc(sizeof(char) * lenDeviceUID); +#endif + + // Check if memory allocation was successful + if (_device_uidV2 == NULL) { + WS_DEBUG_PRINTLN("ERROR: Unable to create device uid, Malloc failure"); + return false; + } + + // Create the device identifier + snprintf(_device_uidV2, lenDeviceUID, "io-wipper-%s%s", WsV2._boardIdV2, + WsV2.sUIDV2); + WS_DEBUG_PRINT("Device UID: "); + WS_DEBUG_PRINTLN(_device_uidV2); + + return true; +} + +/**************************************************************************/ +/*! + @brief Generates device-specific Wippersnapper control topics and + subscribes to them. + @returns True if memory for control topics allocated successfully, + False otherwise. +*/ +/**************************************************************************/ +bool Wippersnapper_V2::generateWSTopics() { + WS_DEBUG_PRINTLN("Pre-calculating topic lengths..."); + // Calculate length of strings that are are dynamic within the secrets file + size_t lenUser = strlen(WsV2._configV2.aio_user); + size_t lenBoardId = strlen(_device_uidV2); + // Calculate length of static strings + size_t lenTopicX2x = strlen("/ws-x2x/"); + size_t lenTopicErrorStr = strlen("/errors/"); + size_t lenTopicThrottleStr = strlen("/throttle/"); + // Calculate length of complete topic strings + // NOTE: We are using "+2" to account for the null terminator and the "/" at + // the end of the topic + size_t lenTopicB2d = lenUser + lenTopicX2x + lenBoardId + 2; + size_t lenTopicD2b = lenUser + lenTopicX2x + lenBoardId + 2; + size_t lenTopicError = lenUser + lenTopicErrorStr + 2; + size_t lenTopicThrottle = lenUser + lenTopicThrottleStr + 2; + + // Attempt to allocate memory for the broker-to-device topic +#ifdef USE_PSRAM + WsV2._topicB2d = (char *)ps_malloc(sizeof(char) * lenTopicB2d); +#else + WsV2._topicB2d = (char *)malloc(sizeof(char) * lenTopicB2d); +#endif + // Check if memory allocation was successful + if (WsV2._topicB2d == NULL) + return false; + // Build the broker-to-device topic + snprintf(WsV2._topicB2d, lenTopicB2d, "%s/ws-b2d/%s/", + WsV2._configV2.aio_user, _device_uidV2); + WS_DEBUG_PRINT("Broker-to-device topic: "); + WS_DEBUG_PRINTLN(WsV2._topicB2d); + // Subscribe to broker-to-device topic + _subscribeB2d = new Adafruit_MQTT_Subscribe(WsV2._mqttV2, WsV2._topicB2d, 1); + WsV2._mqttV2->subscribe(_subscribeB2d); + _subscribeB2d->setCallback(cbBrokerToDevice); + + // 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); +#else + WsV2._topicD2b = (char *)malloc(sizeof(char) * lenTopicD2b); +#endif + // Check if memory allocation was successful + if (WsV2._topicD2b == NULL) + return false; + // Build the broker-to-device topic + snprintf(WsV2._topicD2b, lenTopicD2b, "%s/ws-d2b/%s/", + WsV2._configV2.aio_user, _device_uidV2); + WS_DEBUG_PRINT("Device-to-broker topic: "); + WS_DEBUG_PRINTLN(WsV2._topicD2b); + + // Attempt to allocate memory for the error topic +#ifdef USE_PSRAM + WsV2._topicError = (char *)ps_malloc(sizeof(char) * lenTopicError); +#else + WsV2._topicError = (char *)malloc(sizeof(char) * lenTopicError); +#endif + // Check if memory allocation was successful + if (WsV2._topicError == NULL) + return false; + // Build the error topic + snprintf(WsV2._topicError, lenTopicError, "%s/%s/", WsV2._configV2.aio_user, + "errors"); + WS_DEBUG_PRINT("Error topic: "); + WS_DEBUG_PRINTLN(WsV2._topicError); + // Subscribe to the error topic + _subscribeError = new Adafruit_MQTT_Subscribe(WsV2._mqttV2, WsV2._topicError); + WsV2._mqttV2->subscribe(_subscribeError); + // TODO: Implement the error topic callback + _subscribeError->setCallback(cbErrorTopicV2); + +// Attempt to allocate memory for the error topic +#ifdef USE_PSRAM + WsV2._topicThrottle = (char *)ps_malloc(sizeof(char) * lenTopicThrottle); +#else + WsV2._topicThrottle = (char *)malloc(sizeof(char) * lenTopicThrottle); +#endif + // Check if memory allocation was successful + if (WsV2._topicThrottle == NULL) + return false; + // Build the throttle topic + snprintf(WsV2._topicThrottle, lenTopicThrottle, "%s/%s/", + WsV2._configV2.aio_user, "throttle"); + WS_DEBUG_PRINT("Throttle topic: "); + WS_DEBUG_PRINTLN(WsV2._topicThrottle); + // Subscribe to throttle topic + _subscribeThrottle = + new Adafruit_MQTT_Subscribe(WsV2._mqttV2, WsV2._topicThrottle); + WsV2._mqttV2->subscribe(_subscribeThrottle); + _subscribeThrottle->setCallback(cbThrottleTopicV2); + + return true; +} + +/**************************************************************************/ +/*! + @brief Writes an error message to the serial and the filesystem, + blinks WS_LED_STATUS_ERROR_RUNTIME pattern and hangs. + @param error + The error message to write to the serial and filesystem. +*/ +/**************************************************************************/ +void Wippersnapper_V2::errorWriteHangV2(String error) { + // Print error + WS_DEBUG_PRINTLN(error); +#ifdef USE_TINYUSB + _fileSystemV2->writeToBootOut(error.c_str()); + TinyUSBDevice.attach(); + delay(500); +#endif + // Signal and hang forever + while (1) { + WS_DEBUG_PRINTLN("ERROR: Halted execution"); + WS_DEBUG_PRINTLN(error.c_str()); + WsV2.feedWDTV2(); + statusLEDBlink(WS_LED_STATUS_ERROR_RUNTIME); + delay(1000); + } +} + +/**************************************************************************/ +/*! + @brief Checks network and MQTT connectivity. Handles network + re-connection and mqtt re-establishment. +*/ +/**************************************************************************/ +void Wippersnapper_V2::runNetFSMV2() { + WsV2.feedWDTV2(); + // Initial state + fsm_net_t fsmNetwork; + fsmNetwork = FSM_NET_CHECK_MQTT; + 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!"); +#ifdef USE_DISPLAY + if (WsV2._ui_helper->getLoadingState()) + WsV2._ui_helper->set_load_bar_icon_complete(loadBarIconWifi); +#endif + fsmNetwork = FSM_NET_ESTABLISH_MQTT; + break; + } + 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_helper->getLoadingState()) + WsV2._ui_helper->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()) { +#ifdef USE_DISPLAY + WsV2._ui_helper->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!"); +#ifdef USE_DISPLAY + WsV2._ui_helper->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); + } + + fsmNetwork = FSM_NET_CHECK_NETWORK; + break; + case FSM_NET_ESTABLISH_MQTT: +#ifdef USE_DISPLAY + if (WsV2._ui_helper->getLoadingState()) + WsV2._ui_helper->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--; + } + if (fsmNetwork != FSM_NET_CHECK_MQTT) { +#ifdef USE_DISPLAY + WsV2._ui_helper->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; + } + } +} + +/**************************************************************************/ +/*! + @brief Prints an error to the serial and halts the hardware until + the WDT bites. + @param error + The desired error to print to serial. + @param ledStatusColor + The desired color to blink. + @param reboot + If true, the device will reboot after the WDT bites. + If false, the device will not allow the WDT to bite and + instead hang indefinitely, holding the WIPPER drive open +*/ +/**************************************************************************/ +void Wippersnapper_V2::haltErrorV2(String error, ws_led_status_t ledStatusColor, + bool reboot) { + WS_DEBUG_PRINT("ERROR "); + if (reboot) { + WS_DEBUG_PRINT("[RESET]: "); + } else { + WS_DEBUG_PRINT("[HANG]: "); + } + WS_DEBUG_PRINTLN(error); + statusLEDSolid(ledStatusColor); + for (;;) { + if (!reboot) { + WsV2.feedWDTV2(); // Feed the WDT indefinitely to hold the WIPPER drive + // open + } else { +// Let the WDT fail out and reset! +#ifndef ARDUINO_ARCH_ESP8266 + delay(1000); +#else + // Calls to delay() and yield() feed the ESP8266's + // hardware and software watchdog timers, delayMicroseconds does not. + delayMicroseconds(1000000); +#endif + } + } +} + +/**************************************************************************/ +/*! + @brief Publishes a signal message to the broker. + @param which_payload + The type of signal payload to publish. + @param payload + The payload to publish. + @returns True if the signal message published successfully, + False otherwise. +*/ +/**************************************************************************/ +bool Wippersnapper_V2::PublishSignal(pb_size_t which_payload, void *payload) { + +#ifdef DEBUG_PROFILE + unsigned long total_start_time = micros(); +#endif + + size_t szMessageBuf; + wippersnapper_signal_DeviceToBroker MsgSignal = + wippersnapper_signal_DeviceToBroker_init_default; + + // 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; + default: + WS_DEBUG_PRINTLN("ERROR: Invalid signal payload type, bailing out!"); + return false; + } + + // Get the encoded size of the signal message + if (!pb_get_encoded_size(&szMessageBuf, + wippersnapper_signal_DeviceToBroker_fields, + &MsgSignal)) { + WS_DEBUG_PRINTLN( + "ERROR: Unable to get encoded size of signal message, bailing out!"); + return false; + } + + // Size the message buffer to fit the encoded signal message + uint8_t msgBuf[szMessageBuf]; + + // Encode the signal message + WS_DEBUG_PRINT("Encoding signal message..."); + pb_ostream_t stream = pb_ostream_from_buffer(msgBuf, szMessageBuf); + if (!ws_pb_encode(&stream, wippersnapper_signal_DeviceToBroker_fields, + &MsgSignal)) { + WS_DEBUG_PRINTLN( + "ERROR: Unable to encode d2b signal message, bailing out!"); + return false; + } + WS_DEBUG_PRINTLN("Encoded!"); + + // Check that we are still connected + runNetFSMV2(); + WsV2.feedWDTV2(); + +#ifdef DEBUG_PROFILE + unsigned long publish_start_time = micros(); +#endif + + // Attempt to publish the signal message to the broker + WS_DEBUG_PRINT("Publishing signal message to broker..."); +#ifdef DEBUG_PROFILE + WS_DEBUG_PRINT("Message buffer size: "); + WS_DEBUG_PRINTLN(szMessageBuf); +#endif + if (!WsV2._mqttV2->publish(WsV2._topicD2b, msgBuf, szMessageBuf, 1)) { + WS_DEBUG_PRINTLN("ERROR: Failed to publish signal message to broker!"); + return false; + } + WS_DEBUG_PRINTLN("Published!"); + +#ifdef DEBUG_PROFILE + unsigned long publish_end_time = micros(); + WS_DEBUG_PRINT("Publishing time: "); + WS_DEBUG_PRINTLN(publish_end_time - publish_start_time); + unsigned long total_end_time = micros(); + WS_DEBUG_PRINT("Total PublishSignal() execution time: "); + WS_DEBUG_PRINTLN(total_end_time - total_start_time); +#endif + + return true; +} + +/**************************************************************************/ +/*! + @brief Creates, fills, encodes and publishes a checkin request + message to the broker. + @returns True if the Checkin request message published successfully, + False otherwise. +*/ +/**************************************************************************/ +bool Wippersnapper_V2::CreateCheckinRequest() { + WS_DEBUG_PRINT("Creating the CheckinRequest message..."); + WsV2.CheckInModel = new CheckinModel(); + WsV2.CheckInModel->CreateCheckinRequest(WsV2.sUIDV2, WS_VERSION); + WS_DEBUG_PRINTLN("Created!"); + + WS_DEBUG_PRINT("Encoding the CheckinRequest message..."); + if (!WsV2.CheckInModel->EncodeCheckinRequest()) + return false; + WS_DEBUG_PRINTLN("Encoded!"); + + WS_DEBUG_PRINT("Publishing Checkin Request..."); + if (!PublishSignal(wippersnapper_signal_DeviceToBroker_checkin_request_tag, + WsV2.CheckInModel->getCheckinRequest())) + return false; + WS_DEBUG_PRINTLN("Published!"); + + return true; +} + +/**************************************************************************/ +/*! + @brief Polls for and handles the checkin response + message from the broker. +*/ +/**************************************************************************/ +void Wippersnapper_V2::PollCheckinResponse() { + WsV2.got_checkin_response = false; + WS_DEBUG_PRINTLN("Waiting for checkin response..."); + // If we don't get a response within WS_WDT_TIMEOUT seconds, the WDT + // will expire and reset the device + while (!WsV2.got_checkin_response) { + pingBrokerV2(); // Pinging the broker to keep the connection alive + WsV2._mqttV2->processPackets(10); // Process incoming packets + } + WS_DEBUG_PRINTLN("Completed checkin process!"); +} + +/**************************************************************************/ +/*! + @brief Pings the MQTT broker within the keepalive interval + to keep the connection alive. Blinks the keepalive LED + every STATUS_LED_KAT_BLINK_TIME milliseconds. +*/ +/**************************************************************************/ +void Wippersnapper_V2::pingBrokerV2() { + // ping within keepalive-10% to keep connection open + if (millis() > (_prv_pingV2 + (WS_KEEPALIVE_INTERVAL_MS - + (WS_KEEPALIVE_INTERVAL_MS * 0.10)))) { + WS_DEBUG_PRINT("Sending MQTT PING: "); + if (WsV2._mqttV2->ping()) { + WS_DEBUG_PRINTLN("SUCCESS!"); +#ifdef USE_DISPLAY + WsV2._ui_helper->add_text_to_terminal("[NET] Sent KeepAlive ping!\n"); +#endif + } else { + WS_DEBUG_PRINTLN("FAILURE! Running network FSM..."); +#ifdef USE_DISPLAY + WsV2._ui_helper->add_text_to_terminal( + "[NET] EROR: Failed to send KeepAlive ping!\n"); +#endif + WsV2._mqttV2->disconnect(); + runNetFSMV2(); + } + _prv_pingV2 = millis(); + WS_DEBUG_PRINT("WiFi RSSI: "); + WS_DEBUG_PRINTLN(getRSSI()); + } + // Blink the status LED to indicate that the device is still alive + BlinkKATStatus(); +} + +/**************************************************************************/ +/*! + @brief Blinks the status LED every STATUS_LED_KAT_BLINK_TIME + milliseconds to indicate that the device is still alive. +*/ +/**************************************************************************/ +void Wippersnapper_V2::BlinkKATStatus() { + if (millis() > (_prvKATBlinkV2 + STATUS_LED_KAT_BLINK_TIME)) { + statusLEDBlink(WS_LED_STATUS_KAT); + _prvKATBlinkV2 = millis(); + } +} + +/********************************************************/ +/*! + @brief Feeds the WDT to prevent hardware reset. +*/ +/*******************************************************/ +void Wippersnapper_V2::feedWDTV2() { +#ifndef OFFLINE_MODE_WOKWI + // TODO: This is a temporary fix for watchdog.reset() not firing + Watchdog.reset(); +// esp_task_wdt_reset(); // TODO: Putback for ESP32 WDT +#endif +} + +/********************************************************/ +/*! + @brief Enables the watchdog timer. + @param timeoutMS + The desired amount of time to elapse before + the WDT executes. +*/ +/*******************************************************/ +void Wippersnapper_V2::enableWDTV2(int timeoutMS) { +#ifndef ARDUINO_ARCH_RP2040 + Watchdog.disable(); +#endif + if (Watchdog.enable(timeoutMS) == 0) { + WsV2.haltErrorV2("WDT initialization failure!"); + } +} + +/********************************************************/ +/*! + @brief Process all incoming packets from the + Adafruit IO MQTT broker. Handles network + connectivity. +*/ +/*******************************************************/ +void Wippersnapper_V2::processPacketsV2() { + // runNetFSMV2(); // NOTE: Removed for now, causes error with virtual + // _connect() method when caused with WsV2 object in another file. + WsV2.feedWDTV2(); + // Process all incoming packets from Wippersnapper_V2 MQTT Broker + WsV2._mqttV2->processPackets(10); +} + +/**************************************************************************/ +/*! + @brief Prints information about the WsV2 device to the serial monitor. +*/ +/**************************************************************************/ +void printDeviceInfoV2() { + WS_DEBUG_PRINTLN("-------Device Information-------"); + WS_DEBUG_PRINT("Firmware Version: "); + WS_DEBUG_PRINTLN(WS_VERSION); + WS_DEBUG_PRINTLN("API: Version 2"); + WS_DEBUG_PRINT("Board ID: "); + WS_DEBUG_PRINTLN(BOARD_ID); + WS_DEBUG_PRINT("Adafruit.io User: "); + WS_DEBUG_PRINTLN(WsV2._configV2.aio_user); + WS_DEBUG_PRINT("WiFi Network: "); + WS_DEBUG_PRINTLN(WsV2._configV2.network.ssid); + + char sMAC[18] = {0}; + sprintf(sMAC, "%02X:%02X:%02X:%02X:%02X:%02X", WsV2._macAddrV2[0], + WsV2._macAddrV2[1], WsV2._macAddrV2[2], WsV2._macAddrV2[3], + WsV2._macAddrV2[4], WsV2._macAddrV2[5]); + WS_DEBUG_PRINT("MAC Address: "); + WS_DEBUG_PRINTLN(sMAC); + WS_DEBUG_PRINTLN("-------------------------------"); + +// (ESP32-Only) Print reason why device was reset +#ifdef ARDUINO_ARCH_ESP32 + esp_reset_reason_t r = esp_reset_reason(); + WS_DEBUG_PRINT("ESP Reset Reason: "); + WS_DEBUG_PRINTLN(resetReasonName(r)); +#endif +} + +/**************************************************************************/ +/*! + @brief Connects to Adafruit IO+ Wippersnapper_V2 broker. +*/ +/**************************************************************************/ +void Wippersnapper_V2::connect() { + WS_DEBUG_PRINTLN("Adafruit.io WipperSnapper"); + // Dump device info to the serial monitor + printDeviceInfoV2(); + + // enable global WDT + WsV2.enableWDTV2(WS_WDT_TIMEOUT); + + // Generate device identifier + WS_DEBUG_PRINTLN("Generating device UID..."); + if (!generateDeviceUID()) { + haltErrorV2("Unable to generate Device UID"); + } + WS_DEBUG_PRINTLN("Device UID generated successfully!"); + + // If we are running in offline mode, we skip the network setup + // and MQTT connection process and jump to the offline device config process + // NOTE: After this, bail out of this function and run the app loop!!! + if (WsV2._sdCardV2->isModeOffline() == true) { + WS_DEBUG_PRINTLN("[Offline] Running device configuration..."); +// If debug mode, wait for serial config +#ifdef OFFLINE_MODE_DEBUG + WsV2._sdCardV2->waitForSerialConfig(); +#endif + // Parse the JSON file + if (!WsV2._sdCardV2->parseConfigFile()) + haltErrorV2("Failed to parse config.json!"); + WS_DEBUG_PRINTLN("[Offline] Attempting to configure hardware..."); +#ifndef OFFLINE_MODE_DEBUG + if (!WsV2._sdCardV2->CreateNewLogFile()) + haltErrorV2("Unable to create new .log file on SD card!"); +#endif + // Call the TL signal decoder to parse the incoming JSON data + callDecodeB2D(); + WS_DEBUG_PRINTLN("[Offline] Hardware configured, skipping network setup " + "and running app..."); + // Blink status LED to green to indicate successful configuration + setStatusLEDColor(0x00A300, WsV2.status_pixel_brightnessV2 * 255.0); + delay(500); + setStatusLEDColor(0x000000, WsV2.status_pixel_brightnessV2 * 255.0); + return; + } else { + WS_DEBUG_PRINTLN("Running in online mode..."); + } + + // Configures an Adafruit Arduino MQTT object + WS_DEBUG_PRINTLN("Setting up MQTT client..."); + setupMQTTClient(_device_uidV2); + WS_DEBUG_PRINTLN("Set up MQTT client successfully!"); + + WS_DEBUG_PRINTLN("Generating device's MQTT topics..."); + if (!generateWSTopics()) { + haltErrorV2("Unable to allocate space for MQTT topics"); + } + WS_DEBUG_PRINTLN("Generated device's MQTT topics successfully!"); + + // Connect to Network + WS_DEBUG_PRINTLN("Running Network FSM..."); + // Run the network fsm + runNetFSMV2(); + WsV2.feedWDTV2(); + +#ifdef USE_DISPLAY + WsV2._ui_helper->set_load_bar_icon_complete(loadBarIconCloud); + WsV2._ui_helper->set_label_status("Sending device info..."); +#endif + + WS_DEBUG_PRINTLN("Performing checkin handshake..."); + // Publish the checkin request + if (!CreateCheckinRequest()) { + haltErrorV2("Unable to publish checkin request"); + } + // Handle the checkin response + PollCheckinResponse(); + + // Set the status LED to green to indicate successful configuration + setStatusLEDColor(0x00A300, WsV2.status_pixel_brightnessV2); + delay(100); + // Set the status LED to off during app runtime + setStatusLEDColor(0x000000, WsV2.status_pixel_brightnessV2); + +// switch to monitor screen +#ifdef USE_DISPLAY + WS_DEBUG_PRINTLN("Clearing loading screen..."); + WsV2._ui_helper->clear_scr_load(); + WS_DEBUG_PRINTLN("building monitor screen..."); + WsV2._ui_helper->build_scr_monitor(); +#endif + WS_DEBUG_PRINTLN("Running app loop..."); +} + +/**************************************************************************/ +/*! + @brief Processes incoming commands and handles network connection. + @returns Network status, as ws_status_t. +*/ +/**************************************************************************/ +ws_status_t Wippersnapper_V2::run() { + WsV2.feedWDTV2(); + if (!WsV2._sdCardV2->isModeOffline()) { + // Handle networking functions + runNetFSMV2(); + pingBrokerV2(); + // Process all incoming packets from Wippersnapper_V2 MQTT Broker + WsV2._mqttV2->processPackets(10); + } else { + BlinkKATStatus(); // Offline Mode - Blink every KAT interval + } + + // Process all digital events + WsV2.digital_io_controller->Update(); + + // Process all analog inputs + WsV2.analogio_controller->update(); + + // Process all DS18x20 sensor events + WsV2._ds18x20_controller->update(); + + // TODO: Process I2C sensor events + WsV2._i2c_controller->update(); + + // TODO: Process UART sensor events + + return WS_NET_CONNECTED; // TODO: Make this funcn void! +} diff --git a/src/Wippersnapper_V2.h b/src/Wippersnapper_V2.h new file mode 100644 index 000000000..77478e930 --- /dev/null +++ b/src/Wippersnapper_V2.h @@ -0,0 +1,313 @@ +/*! + * @file Wippersnapper_V2.h + * + * This is the documentation for Adafruit's Wippersnapper firmware for the + * Arduino platform. It is designed specifically to work with + * Adafruit IO Wippersnapper IoT platform. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * @copyright Copyright (c) Brent Rubell 2020-2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + */ + +#ifndef WIPPERSNAPPER_V2_H +#define WIPPERSNAPPER_V2_H + +// Debug Flags +// #DEBUG_PROFILE 1 ///< Enable debug output for function profiling +// Debug Flags +#define WS_DEBUG /**< Define to enable debugging to serial terminal */ +#define WS_PRINTER Serial /**< Where debug messages will be printed */ + +/**************************************************************************/ +/*! + @brief Debug print macros for WipperSnapper debugging output + @details These macros provide debug output functionality when WS_DEBUG is + 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_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 */ +#endif + +/**************************************************************************/ +/*! + @brief delay() function for use with a watchdog timer + @param timeout + Delay duration in milliseconds +*/ +/**************************************************************************/ +#define WS_DELAY_WITH_WDT(timeout) \ + { \ + unsigned long start = millis(); \ + while (millis() - start < timeout) { \ + delay(10); \ + yield(); \ + feedWDT(); \ + if (millis() < start) { \ + start = millis(); \ + } \ + } \ + } + +// Cpp STD +#include +#include +#include +#include + +// Nanopb dependencies +#include +#include +#include +#include +#include + +// Include Signal Proto +#include "protos/checkin.pb.h" +#include "protos/digitalio.pb.h" +#include "protos/ds18x20.pb.h" +#include "protos/signal.pb.h" + +// External libraries +#include "Adafruit_MQTT.h" // MQTT Client +#include "Adafruit_SleepyDog.h" // Watchdog +#include "Arduino.h" // Wiring +#include // SPI +#include // I2C + +// Wippersnapper API Helpers +#include "Wippersnapper_Boards.h" +#include "components/statusLED/Wippersnapper_StatusLED.h" +#include "helpers/ws_helper_status.h" +#ifdef ARDUINO_ARCH_ESP32 +#include "helpers/ws_helper_esp.h" +#endif + +// Components (API v2) +#include "components/analogIO/controller.h" +#include "components/checkin/model.h" +#include "components/digitalIO/controller.h" +#include "components/ds18x20/controller.h" +#include "components/i2c/controller.h" +#include "components/sensor/model.h" + +// Display +#ifdef USE_DISPLAY +#include "display/ws_display_driver.h" +#include "display/ws_display_ui_helper.h" +#endif + +#include "provisioning/ConfigJson.h" +#include "provisioning/sdcard/ws_sdcard.h" +#if defined(USE_TINYUSB) +#include "provisioning/tinyusb/Wippersnapper_FS.h" +#endif +#if defined(USE_LITTLEFS) +#include "provisioning/littlefs/WipperSnapper_LittleFS.h" +#endif + +#define WS_VERSION \ + "1.0.0-offline-beta.1" ///< 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 \ + 5000 ///< Session keepalive interval time, in milliseconds + +// Forward declarations +class Wippersnapper_FS; +class WipperSnapper_LittleFS; +class ws_sdcard; +#ifdef USE_DISPLAY +class ws_display_driver; +class ws_display_ui_helper; +#endif +class CheckinModel; +class SensorModel; +class DigitalIOController; +class AnalogIOController; +class DS18X20Controller; +class I2cController; + +/**************************************************************************/ +/*! + @brief Class that provides storage and functions for the Adafruit IO + Wippersnapper interface. +*/ +/**************************************************************************/ +class Wippersnapper_V2 { +public: + Wippersnapper_V2(); + virtual ~Wippersnapper_V2(); + + void provision(); + + // Global flags for the status led + bool + lockStatusNeoPixelV2; ///< True if status LED is using the status neopixel + bool lockStatusDotStarV2; ///< True if status LED is using the status dotstar + bool lockStatusLEDV2; ///< True if status LED is using the built-in LED + float status_pixel_brightnessV2 = + STATUS_PIXEL_BRIGHTNESS_DEFAULT; ///< Global status pixel's brightness + ///< (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(); + virtual bool check_valid_ssid(); + + virtual void _connect(); + virtual void _disconnect(); + void connect(); + void disconnect(); + + virtual void getMacAddr(); + virtual int32_t getRSSI(); + virtual void setupMQTTClient(const char *clientID); + + virtual ws_status_t networkStatus(); + + // Generators for device UID and MQTT topics + bool generateDeviceUID(); + bool generateWSTopics(); + + // High-level MQTT Publish + bool PublishSignal(pb_size_t which_payload, void *payload); + + // Checkin API + bool CreateCheckinRequest(); + void PollCheckinResponse(); + + // run() loop + ws_status_t run(); + void processPacketsV2(); + + // Networking helpers + void pingBrokerV2(); + void runNetFSMV2(); + + // WDT helpers + void enableWDTV2(int timeoutMS = 0); + void feedWDTV2(); + void BlinkKATStatus(); + + // Error handling helpers + void haltErrorV2(String error, + ws_led_status_t ledStatusColor = WS_LED_STATUS_ERROR_RUNTIME, + bool reboot = true); + void errorWriteHangV2(String error); + + bool _is_offline_mode; ///< Global flag for if the device is in offline mode + + // TODO: Do we need this? + ws_board_status_t _boardStatusV2 = + WS_BOARD_DEF_IDLE; ///< Hardware's registration status + + // 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 +#ifdef USE_DISPLAY + ws_display_driver *_displayV2 = nullptr; ///< Instance of display driver class + ws_display_ui_helper *_ui_helperV2 = + nullptr; ///< Instance of display UI helper class +#endif + // ws_pixels *_ws_pixelsComponentV2; ///< ptr to instance of ws_pixels class + // ws_pwm *_pwmComponentV2; ///< Instance of pwm class + // ws_servo *_servoComponentV2; ///< Instance of servo class + // ws_uart *_uartComponentV2; ///< Instance of UART class + + // API v2 Components + 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 = + nullptr; ///< Instance of AnalogIO controller + DS18X20Controller *_ds18x20_controller = + nullptr; ///< Instance of DS18X20 controller + I2cController *_i2c_controller = nullptr; ///< Instance of I2C 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. */ + + // TODO: Audit this, does it need to be here? + secretsConfig _configV2; /*!< Wippersnapper secrets.json as a struct. */ + networkConfig _multiNetworksV2[3]; /*!< Wippersnapper networks as structs. */ + bool _isWiFiMultiV2 = false; /*!< True if multiple networks are defined. */ + + // TODO: Does this need to be within this class? + 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. */ + int throttleTimeV2; /*!< Total amount of time to throttle the device, in + milliseconds. */ + + // enable LEDC if esp32 + // #ifdef ARDUINO_ARCH_ESP32 + // ws_ledc *_ledcV2 = nullptr; ///< Pointer to LEDC object + // #endif + bool got_checkin_response; ///< True if a checkin response was received, False + ///< otherwise. + std::vector> + _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: + void _initV2(); + + // MQTT topics + char *_topicB2d; + char *_topicD2b; + char *_topicError; + char *_topicThrottle; + + // Adafruit_MQTT Subscription objects + Adafruit_MQTT_Subscribe *_subscribeB2d; + Adafruit_MQTT_Subscribe *_subscribeError; + Adafruit_MQTT_Subscribe *_subscribeThrottle; + +protected: + ws_status_t _statusV2 = WS_IDLE; ///< Wippersnapper status + + uint32_t _last_mqtt_connectV2 = 0; /*!< Previous time when client connected to + Adafruit IO, in milliseconds. */ + uint32_t _prv_pingV2 = 0; /*!< Previous time when client pinged Adafruit IO's + MQTT broker, in milliseconds. */ + uint32_t _prvKATBlinkV2 = 0; /*!< Previous time when client pinged Adafruit + IO's MQTT broker, in milliseconds. */ + + // Device information + const char *_deviceIdV2; /*!< Adafruit IO+ device identifier string */ + char *_device_uidV2; /*!< Unique device identifier */ +}; +extern Wippersnapper_V2 WsV2; ///< Global member variable for callbacks + +#endif // WIPPERSNAPPER_V2_H diff --git a/src/Wippersnapper_demo.ino b/src/Wippersnapper_demo.ino index 4327de9e4..e8617803d 100644 --- a/src/Wippersnapper_demo.ino +++ b/src/Wippersnapper_demo.ino @@ -1,35 +1,25 @@ -// Adafruit IO WipperSnapper Beta -// -// -// NOTE: This software is a BETA release and in active development. -// Please report bugs or errors to https://github.com/adafruit/Adafruit_Wippersnapper_Arduino/issues -// +// Adafruit IO WipperSnapper // // Adafruit invests time and resources providing this open source code. // Please support Adafruit and open source hardware by purchasing // products from Adafruit! // -// Brent Rubell for Adafruit Industries, 2021-2022 +// Brent Rubell for Adafruit Industries, 2020-2025 // // All text above must be included in any redistribution. -#include "Wippersnapper_Networking.h" -Wippersnapper_WiFi wipper; - -// Enable debug output for beta builds -#define WS_DEBUG +#include "ws_adapters.h" +ws_adapter_wifi wipper; +// Uncomment the following line to use the offline adapter for Pico +// ws_adapter_offline wipper; +#define WS_DEBUG // Enable debug output! void setup() { - // Provisioning must occur prior to serial init. - wipper.provision(); - Serial.begin(115200); - // while (!Serial) delay(10); - + while (!Serial) + delay(10); + wipper.provision(); wipper.connect(); - } -void loop() { - wipper.run(); -} \ No newline at end of file +void loop() { wipper.run(); } \ No newline at end of file diff --git a/src/Wippersnapper_demo_wokwi.ino.skip b/src/Wippersnapper_demo_wokwi.ino.skip new file mode 100644 index 000000000..180ffc382 --- /dev/null +++ b/src/Wippersnapper_demo_wokwi.ino.skip @@ -0,0 +1,45 @@ +// Adafruit IO WipperSnapper Beta, Wokwi Test Sketch +// +// ***NOTICE*** +// This sketch is not intended to be uploaded to a physical device +// This sketch is for testing Wokwi-CLI and Wokwi-VSCode +// +// Brent Rubell for Adafruit Industries, 2024 +// +// All text above must be included in any redistribution. + +/************************ Adafruit IO Config *******************************/ +// Visit io.adafruit.com if you need to create an account, +// or if you need your Adafruit IO key. +#define IO_USERNAME "brubell" +#define IO_KEY "YOUR_AIO_KEY" +/**************************** WiFi Config ***********************************/ +#define WIFI_SSID "Wokwi-GUEST" +#define WIFI_PASS "" +// Enable debug output for beta builds +#define WS_DEBUG +// Pin to check for API version +#define API_PIN 0 +#include "ws_manager.h" +//#include "Wippersnapper_Networking.h" +//ws_adapter_wifi wipper; +Wippersnapper_Manager manager; +Wippersnapper_WiFiV2 wipper(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS, "io.adafruit.com", 8883); + + +void setup() { + // NOTE: Provisioning must occur prior to serial init. + manager.checkAPIVersion(API_PIN); + manager.provision(); + + Serial.begin(115200); + // while (!Serial) delay(10); + Serial.println("Adafruit Wippersnapper API Manager Demo"); + Serial.print("Running Wippersnapper API Version: "); + Serial.println(manager.getAPIVersion()); + manager.connect(); +} + +void loop() { + manager.run(); +} \ No newline at end of file diff --git a/src/adapters/offline/ws_offline_pico.h b/src/adapters/offline/ws_offline_pico.h new file mode 100644 index 000000000..d3817b3c1 --- /dev/null +++ b/src/adapters/offline/ws_offline_pico.h @@ -0,0 +1,176 @@ +/*! + * @file ws_offline_pico.h + * + * This is a stub class for using the RP2040/RP2350 without a network interface + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2025 for Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + * + */ + +#ifndef WS_OFFLINE_PICO +#define WS_OFFLINE_PICO + +#if defined(ARDUINO_RASPBERRY_PI_PICO) || \ + defined(ARDUINO_RASPBERRY_PI_PICO_2) || \ + defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER) || \ + defined(ARDUINO_ADAFRUIT_METRO_RP2350) + +#define PICO_CONNECT_TIMEOUT_MS 20000 /*!< Connection timeout (in ms) */ +#define PICO_CONNECT_RETRY_DELAY_MS 200 /*!< delay time between retries. */ + +#include "Arduino.h" +#include "Wippersnapper_V2.h" + +extern Wippersnapper_V2 WsV2; + +/****************************************************************************/ +/*! + @brief Class for using the Raspberry Pi Pico network interface. +*/ +/****************************************************************************/ +class ws_offline_pico : public Wippersnapper_V2 { + +public: + /**************************************************************************/ + /*! + @brief Initializes the WipperSnapper class for RPi Pico. + */ + /**************************************************************************/ + ws_offline_pico() : Wippersnapper_V2() { + // Do-nothing + } + + /**************************************************************************/ + /*! + @brief Destructor + */ + /**************************************************************************/ + ~ws_offline_pico() { + // Do-nothing - this class has no resources to release + } + + /********************************************************/ + /*! + @brief Sets the WiFi client's ssid and password. + @param ssid + WiFi network's SSID. + @param ssidPassword + WiFi network's password. + */ + /********************************************************/ + void set_ssid_pass(const char *ssid, const char *ssidPassword) { + WS_DEBUG_PRINTLN("[ws_offline_pico] Error: set_ssid_pass() is not " + "supported in this implementation!"); + } + + /**********************************************************/ + /*! + @brief Sets the WiFi client's ssid and password. + */ + /**********************************************************/ + void set_ssid_pass() { + WS_DEBUG_PRINTLN("[ws_offline_pico] Error: set_ssid_pass() is not " + "supported in this implementation!"); + } + + /***********************************************************/ + /*! + @brief Performs a scan of local WiFi networks. + @returns True if `_network_ssid` is found, False otherwise. + */ + /***********************************************************/ + bool check_valid_ssid() { + WS_DEBUG_PRINTLN("[ws_offline_pico] Error: check_valid_ssid() is not " + "supported in this implementation!"); + return false; // return an invalid value + } + + /********************************************************/ + /*! + @brief Sets the RPi Pico's unique client identifier + @note On RPi Pico, the UID is the MAC address. + */ + /********************************************************/ + void getMacAddr() { + // Do Nothing + } + + /********************************************************/ + /*! + @brief Gets the current network RSSI value + @return int32_t RSSI value + */ + /********************************************************/ + int32_t getRSSI() { + WS_DEBUG_PRINTLN("[ws_offline_pico] Error: getRSSI() is not supported in " + "this implementation!"); + return -9999; // return an invalid value + } + + /********************************************************/ + /*! + @brief Initializes the MQTT client + @param clientID + MQTT client identifier + */ + /********************************************************/ + void setupMQTTClient(const char *clientID) { + WS_DEBUG_PRINTLN("[ws_offline_pico] Error: setupMQTTClient() is not " + "supported in this implementation!"); + } + + /********************************************************/ + /*! + @brief Returns the network status of an RPi Pico. + @return ws_status_t + */ + /********************************************************/ + ws_status_t networkStatus() { + WS_DEBUG_PRINTLN("[ws_offline_pico] Error: networkStatus() is not " + "supported in this implementation!"); + return WS_NET_DISCONNECTED; // this value is valid, we are not connected to + // a network + } + + /*******************************************************************/ + /*! + @brief Returns the type of network connection used by Wippersnapper + @return Pico + */ + /*******************************************************************/ + const char *connectionType() { + WS_DEBUG_PRINTLN("[ws_offline_pico] Error: connectionType() is not " + "supported in this implementation!"); + return "ws-offline-pico"; + } + +protected: + /**************************************************************************/ + /*! + @brief Establishes a connection with the wireless network. + */ + /**************************************************************************/ + void _connect() { + WS_DEBUG_PRINTLN("[ws_offline_pico] Error: _connect() is not supported in " + "this implementation!"); + } + + /**************************************************************************/ + /*! + @brief Disconnects from the wireless network. + */ + /**************************************************************************/ + void _disconnect() { + WS_DEBUG_PRINTLN("[ws_offline_pico] Error: _disconnect() is not supported " + "in this implementation!"); + } +}; + +#endif // RASPBERRY_PI_PICO +#endif // WS_OFFLINE_PICO \ No newline at end of file diff --git a/src/network_interfaces/Wippersnapper_AIRLIFT.h b/src/adapters/wifi/ws_wifi_airlift.h similarity index 97% rename from src/network_interfaces/Wippersnapper_AIRLIFT.h rename to src/adapters/wifi/ws_wifi_airlift.h index 4c564b4e1..d9904c329 100644 --- a/src/network_interfaces/Wippersnapper_AIRLIFT.h +++ b/src/adapters/wifi/ws_wifi_airlift.h @@ -1,5 +1,5 @@ /*! - * @file Wippersnapper_AIRLIFT.h + * @file ws_wifi_airlift.h * * This is a driver for using the Adafruit AirLift * ESP32 Co-Processor's network interface with Wippersnapper. @@ -17,8 +17,8 @@ * */ -#ifndef WIPPERSNAPPER_AIRLIFT_H -#define WIPPERSNAPPER_AIRLIFT_H +#ifndef WS_WIFI_AIRLIFT_H +#define WS_WIFI_AIRLIFT_H #include "Adafruit_MQTT.h" #include "Adafruit_MQTT_Client.h" @@ -34,13 +34,13 @@ #define SPIWIFI SPI /*!< Instance of SPI interface used by an AirLift. */ -extern Wippersnapper WS; +extern Wippersnapper WS; ///< Global Wippersnapper instance /****************************************************************************/ /*! @brief Class for using the AirLift Co-Processor network iface. */ /****************************************************************************/ -class Wippersnapper_AIRLIFT : public Wippersnapper { +class ws_wifi_airlift : public Wippersnapper { public: /**************************************************************************/ @@ -48,7 +48,7 @@ class Wippersnapper_AIRLIFT : public Wippersnapper { @brief Initializes the Adafruit IO class for AirLift devices. */ /**************************************************************************/ - Wippersnapper_AIRLIFT() : Wippersnapper() { + ws_wifi_airlift() : Wippersnapper() { _ssPin = SPIWIFI_SS; // 10; _ackPin = SPIWIFI_ACK; // 7; _rstPin = SPIWIFI_RESET; // 5; // should be 7 on PyPortals @@ -71,7 +71,7 @@ class Wippersnapper_AIRLIFT : public Wippersnapper { @brief Destructor for the Adafruit IO AirLift class. */ /**************************************************************************/ - ~Wippersnapper_AIRLIFT() { + ~ws_wifi_airlift() { if (_mqtt) delete _mqtt; } @@ -394,4 +394,4 @@ class Wippersnapper_AIRLIFT : public Wippersnapper { } }; -#endif // WIPPERSNAPPER_AIRLIFT_H \ No newline at end of file +#endif // WS_WIFI_AIRLIFT_H \ No newline at end of file diff --git a/src/network_interfaces/Wippersnapper_ESP32.h b/src/adapters/wifi/ws_wifi_esp32.h similarity index 78% rename from src/network_interfaces/Wippersnapper_ESP32.h rename to src/adapters/wifi/ws_wifi_esp32.h index c95f65864..2de415682 100644 --- a/src/network_interfaces/Wippersnapper_ESP32.h +++ b/src/adapters/wifi/ws_wifi_esp32.h @@ -1,5 +1,5 @@ /*! - * @file Wippersnapper_ESP32.h + * @file ws_wifi_esp32.h * * This is a driver for using the ESP32's network interface * with Adafruit IO Wippersnapper. @@ -8,17 +8,17 @@ * please support Adafruit and open-source hardware by purchasing * products from Adafruit! * - * Copyright (c) Brent Rubell 2020-2024 for Adafruit Industries. + * Copyright (c) Brent Rubell 2020-2025 for Adafruit Industries. * * MIT license, all text here must be included in any redistribution. * */ -#ifndef Wippersnapper_ESP32_H -#define Wippersnapper_ESP32_H +#ifndef WS_WIFI_ESP32_H +#define WS_WIFI_ESP32_H #ifdef ARDUINO_ARCH_ESP32 -#include "Wippersnapper.h" +#include "Wippersnapper_V2.h" #include "Adafruit_MQTT.h" #include "Adafruit_MQTT_Client.h" @@ -27,14 +27,14 @@ #include "WiFiMulti.h" #include #include -extern Wippersnapper WS; +extern Wippersnapper_V2 WsV2; ///< Wippersnapper client instance /****************************************************************************/ /*! @brief Class for using the ESP32 network interface. */ /****************************************************************************/ -class Wippersnapper_ESP32 : public Wippersnapper { +class ws_wifi_esp32 : public Wippersnapper_V2 { public: /**************************************************************************/ @@ -42,17 +42,53 @@ class Wippersnapper_ESP32 : public Wippersnapper { @brief Initializes the Adafruit IO class for ESP32 devices. */ /**************************************************************************/ - Wippersnapper_ESP32() : Wippersnapper() { + ws_wifi_esp32() : Wippersnapper_V2() { _ssid = 0; _pass = 0; } + /**************************************************************************/ + /*! + @brief Overload for ESP32 devices without filesystem-backed provisioning. + @param aioUsername + Adafruit IO username. + @param aioKey + Adafruit IO key. + @param netSSID + WiFi network's SSID. + @param netPass + WiFi network's password. + @param brokerURL + Adafruit IO broker URL. + @param brokerPort + Adafruit IO broker port. + */ + /**************************************************************************/ + ws_wifi_esp32(const char *aioUsername, const char *aioKey, + const char *netSSID, const char *netPass, const char *brokerURL, + uint16_t brokerPort) + : Wippersnapper_V2() { + _ssid = netSSID; + _pass = netPass; + + // Move credentials to the config struct + strncpy(WsV2._configV2.network.ssid, _ssid, + sizeof(WsV2._configV2.network.ssid)); + strncpy(WsV2._configV2.network.pass, _pass, + sizeof(WsV2._configV2.network.pass)); + strncpy(WsV2._configV2.aio_key, aioKey, sizeof(WsV2._configV2.aio_key)); + strncpy(WsV2._configV2.aio_user, aioUsername, + sizeof(WsV2._configV2.aio_user)); + strncpy(WsV2._configV2.aio_url, brokerURL, sizeof(WsV2._configV2.aio_url)); + WsV2._configV2.io_port = brokerPort; + } + /**************************************************************************/ /*! @brief Destructor for the Adafruit IO AirLift class. */ /**************************************************************************/ - ~Wippersnapper_ESP32() { + ~ws_wifi_esp32() { if (_mqtt_client_secure) delete _mqtt_client_secure; if (_mqtt_client_insecure) @@ -86,8 +122,8 @@ class Wippersnapper_ESP32 : public Wippersnapper { */ /**********************************************************/ void set_ssid_pass() { - _ssid = WS._config.network.ssid; - _pass = WS._config.network.pass; + _ssid = WsV2._configV2.network.ssid; + _pass = WsV2._configV2.network.pass; } /***********************************************************/ @@ -119,12 +155,13 @@ class Wippersnapper_ESP32 : public Wippersnapper { WS_DEBUG_PRINTLN(WiFi.RSSI(i)); return true; } - if (WS._isWiFiMulti) { + if (WsV2._isWiFiMultiV2) { // multi network mode for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) { - if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i).c_str()) == 0) { + if (strcmp(WsV2._multiNetworksV2[j].ssid, WiFi.SSID(i).c_str()) == + 0) { WS_DEBUG_PRINT("SSID ("); - WS_DEBUG_PRINT(WS._multiNetworks[j].ssid); + WS_DEBUG_PRINT(WsV2._multiNetworksV2[j].ssid); WS_DEBUG_PRINT(") found! RSSI: "); WS_DEBUG_PRINTLN(WiFi.RSSI(i)); return true; @@ -155,7 +192,7 @@ class Wippersnapper_ESP32 : public Wippersnapper { void getMacAddr() { uint8_t mac[6] = {0}; Network.macAddress(mac); - memcpy(WS._macAddr, mac, sizeof(mac)); + memcpy(WsV2._macAddrV2, mac, sizeof(mac)); } /********************************************************/ @@ -174,23 +211,23 @@ class Wippersnapper_ESP32 : public Wippersnapper { */ /********************************************************/ void setupMQTTClient(const char *clientID) { - if (strcmp(WS._config.aio_url, "io.adafruit.com") == 0 || - strcmp(WS._config.aio_url, "io.adafruit.us") == 0) { + if (strcmp(WsV2._configV2.aio_url, "io.adafruit.com") == 0 || + strcmp(WsV2._configV2.aio_url, "io.adafruit.us") == 0) { _mqtt_client_secure = new NetworkClientSecure(); _mqtt_client_secure->setCACert( - strcmp(WS._config.aio_url, "io.adafruit.com") == 0 + strcmp(WsV2._configV2.aio_url, "io.adafruit.com") == 0 ? _aio_root_ca_prod : _aio_root_ca_staging); - WS._mqtt = new Adafruit_MQTT_Client( - _mqtt_client_secure, WS._config.aio_url, WS._config.io_port, clientID, - WS._config.aio_user, WS._config.aio_key); + WsV2._mqttV2 = new Adafruit_MQTT_Client( + _mqtt_client_secure, WsV2._configV2.aio_url, WsV2._configV2.io_port, + clientID, WsV2._configV2.aio_user, WsV2._configV2.aio_key); } else { // Insecure connections require a NetworkClient object rather than a // NetworkClientSecure object _mqtt_client_insecure = new NetworkClient(); - WS._mqtt = new Adafruit_MQTT_Client( - _mqtt_client_insecure, WS._config.aio_url, WS._config.io_port, - clientID, WS._config.aio_user, WS._config.aio_key); + WsV2._mqttV2 = new Adafruit_MQTT_Client( + _mqtt_client_insecure, WsV2._configV2.aio_url, WsV2._configV2.io_port, + clientID, WsV2._configV2.aio_user, WsV2._configV2.aio_key); } } @@ -298,12 +335,12 @@ class Wippersnapper_ESP32 : public Wippersnapper { return; if (strlen(_ssid) == 0) { - _status = WS_SSID_INVALID; + _statusV2 = WS_SSID_INVALID; } else { WiFi.setAutoReconnect(false); _disconnect(); delay(100); - if (WS._isWiFiMulti) { + if (WsV2._isWiFiMultiV2) { // multi network mode _wifiMulti.APlistClean(); _wifiMulti.setAllowOpenAP(false); @@ -311,24 +348,24 @@ class Wippersnapper_ESP32 : public Wippersnapper { _wifiMulti.addAP(_ssid, _pass); // add array of alternative networks for (int i = 0; i < WS_MAX_ALT_WIFI_NETWORKS; i++) { - if (strlen(WS._multiNetworks[i].ssid) > 0) { - _wifiMulti.addAP(WS._multiNetworks[i].ssid, - WS._multiNetworks[i].pass); + if (strlen(WsV2._multiNetworksV2[i].ssid) > 0) { + _wifiMulti.addAP(WsV2._multiNetworksV2[i].ssid, + WsV2._multiNetworksV2[i].pass); } } if (_wifiMulti.run(20000) == WL_CONNECTED) { - _status = WS_NET_CONNECTED; + _statusV2 = WS_NET_CONNECTED; } else { - _status = WS_NET_DISCONNECTED; + _statusV2 = WS_NET_DISCONNECTED; } } else { // single network mode WiFi.begin(_ssid, _pass); - _status = WS_NET_DISCONNECTED; - WS.feedWDT(); + _statusV2 = WS_NET_DISCONNECTED; + WsV2.feedWDTV2(); delay(5000); } - WS.feedWDT(); + WsV2.feedWDTV2(); } } @@ -344,4 +381,4 @@ class Wippersnapper_ESP32 : public Wippersnapper { }; #endif // ARDUINO_ARCH_ESP32_H -#endif // Wippersnapper_ESP32_H \ No newline at end of file +#endif // WS_WIFI_ESP32_H \ No newline at end of file diff --git a/src/network_interfaces/Wippersnapper_ESP8266.h b/src/adapters/wifi/ws_wifi_esp8266.h similarity index 86% rename from src/network_interfaces/Wippersnapper_ESP8266.h rename to src/adapters/wifi/ws_wifi_esp8266.h index c7fa6b693..73e25250d 100644 --- a/src/network_interfaces/Wippersnapper_ESP8266.h +++ b/src/adapters/wifi/ws_wifi_esp8266.h @@ -1,8 +1,8 @@ /*! - * @file Wippersnapper_ESP8266.h + * @file ws_wifi_esp8266.h * * This is a driver for using the ESP8266's network interface - * with Wippersnapper. + * with Wippersnapper_V2. * * Adafruit invests time and resources providing this open source code, * please support Adafruit and open-source hardware by purchasing @@ -14,15 +14,15 @@ * */ -#ifndef WIPPERSNAPPER_ESP8266_H -#define WIPPERSNAPPER_ESP8266_H +#ifndef WS_WIFI_ESP8266_H +#define WS_WIFI_ESP8266_H #ifdef ARDUINO_ARCH_ESP8266 #include "Adafruit_MQTT.h" #include "Adafruit_MQTT_Client.h" #include "ESP8266WiFi.h" #include "ESP8266WiFiMulti.h" -#include "Wippersnapper.h" +#include "Wippersnapper_V2.h" /* NOTE - Projects that require "Secure MQTT" (TLS/SSL) also require a new * SSL certificate every year. If adding Secure MQTT to your ESP8266 project is @@ -37,7 +37,7 @@ // static const char *fingerprint PROGMEM = "4E C1 52 73 24 A8 36 D6 7A 4C 67 // C7 91 0C 0A 22 B9 2D 5B CA"; -extern Wippersnapper WS; +extern Wippersnapper_V2 WsV2; /******************************************************************************/ /*! @@ -45,7 +45,7 @@ extern Wippersnapper WS; interface. */ /******************************************************************************/ -class Wippersnapper_ESP8266 : public Wippersnapper { +class ws_wifi_esp8266 : public Wippersnapper_V2 { public: /**************************************************************************/ @@ -61,7 +61,7 @@ class Wippersnapper_ESP8266 : public Wippersnapper { Wireless Network password */ /**************************************************************************/ - Wippersnapper_ESP8266() : Wippersnapper() { + ws_wifi_esp8266() : Wippersnapper_V2() { _ssid = 0; _pass = 0; _wifi_client = new WiFiClient; @@ -74,7 +74,7 @@ class Wippersnapper_ESP8266 : public Wippersnapper { @brief Destructor for the ESP8266's network iface. */ /**************************************************************************/ - ~Wippersnapper_ESP8266() { + ~ws_wifi_esp8266() { if (_wifi_client) delete _wifi_client; if (_mqtt) @@ -142,12 +142,13 @@ class Wippersnapper_ESP8266 : public Wippersnapper { WS_DEBUG_PRINTLN(WiFi.RSSI(i)); return true; } - if (WS._isWiFiMulti) { + if (WS._isWiFiMultiV2) { // multi network mode for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) { - if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i).c_str()) == 0) { + if (strcmp(WsV2._multiNetworksV2[j].ssid, WiFi.SSID(i).c_str()) == + 0) { WS_DEBUG_PRINT("SSID ("); - WS_DEBUG_PRINT(WS._multiNetworks[j].ssid); + WS_DEBUG_PRINT(WsV2._multiNetworksV2[j].ssid); WS_DEBUG_PRINT(") found! RSSI: "); WS_DEBUG_PRINTLN(WiFi.RSSI(i)); return true; @@ -178,7 +179,7 @@ class Wippersnapper_ESP8266 : public Wippersnapper { void getMacAddr() { uint8_t mac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; WiFi.macAddress(mac); - memcpy(WS._macAddr, mac, sizeof(mac)); + memcpy(WsV2._macAddrV2, mac, sizeof(mac)); } /********************************************************/ @@ -201,11 +202,11 @@ class Wippersnapper_ESP8266 : public Wippersnapper { // re-compile after. _wifi_client->setFingerprint(fingerprint); WS._mqtt = // new Adafruit_MQTT_Client(_wifi_client, WS._config.aio_url, // WS._config.io_port, clientID, WS._config.aio_user, WS._config.aio_key); - if (WS._config.io_port == 8883) - WS._config.io_port = 1883; - WS._mqtt = new Adafruit_MQTT_Client( - _wifi_client, WS._config.aio_url, WS._config.io_port, clientID, - WS._config.aio_user, WS._config.aio_key); + if (WsV2._configV2.io_port == 8883) + WsV2._configV2.io_port = 1883; + WsV2._mqttV2 = new Adafruit_MQTT_Client( + _wifi_client, WsV2._configV2.aio_url, WsV2._configV2.io_port, clientID, + WsV2._configV2.aio_user, WsV2._configV2.aio_key); } /********************************************************/ @@ -229,7 +230,7 @@ class Wippersnapper_ESP8266 : public Wippersnapper { /*******************************************************************/ /*! - @brief Returns the type of network connection used by Wippersnapper + @brief Returns the type of network connection used by Wippersnapper_V2 @return "ESP8266" */ /*******************************************************************/ @@ -246,13 +247,13 @@ class Wippersnapper_ESP8266 : public Wippersnapper { @brief Establishes a connection with the wireless network. */ /**************************************************************************/ - void _connect() { + void _connect()() { if (WiFi.status() == WL_CONNECTED) return; if (strlen(_ssid) == 0) { - _status = WS_SSID_INVALID; + _statusV2 = WS_SSID_INVALID; } else { WiFi.setAutoReconnect(false); // Attempt connection @@ -261,17 +262,17 @@ class Wippersnapper_ESP8266 : public Wippersnapper { // ESP8266 MUST be in STA mode to avoid device acting as client/server WiFi.mode(WIFI_STA); WiFi.begin(_ssid, _pass); - _status = WS_NET_DISCONNECTED; + _statusV2 = WS_NET_DISCONNECTED; delay(100); - if (WS._isWiFiMulti) { + if (WS._isWiFiMultiV2) { // multi network mode for (int i = 0; i < WS_MAX_ALT_WIFI_NETWORKS; i++) { - if (strlen(WS._multiNetworks[i].ssid) > 0 && - (_wifiMulti.existsAP(WS._multiNetworks[i].ssid) == false)) { + if (strlen(WsV2._multiNetworksV2[i].ssid) > 0 && + (_wifiMulti.existsAP(WsV2._multiNetworksV2[i].ssid) == false)) { // doesn't exist, add it - _wifiMulti.addAP(WS._multiNetworks[i].ssid, - WS._multiNetworks[i].pass); + _wifiMulti.addAP(WsV2._multiNetworksV2[i].ssid, + WsV2._multiNetworksV2[i].pass); } } // add default network @@ -286,9 +287,9 @@ class Wippersnapper_ESP8266 : public Wippersnapper { yield(); } if (WiFi.status() == WL_CONNECTED) { - _status = WS_NET_CONNECTED; + _statusV2 = WS_NET_CONNECTED; } else { - _status = WS_NET_DISCONNECTED; + _statusV2 = WS_NET_DISCONNECTED; } } else { // single network mode @@ -301,12 +302,12 @@ class Wippersnapper_ESP8266 : public Wippersnapper { yield(); } if (WiFi.status() == WL_CONNECTED) { - _status = WS_NET_CONNECTED; + _statusV2 = WS_NET_CONNECTED; } else { - _status = WS_NET_DISCONNECTED; + _statusV2 = WS_NET_DISCONNECTED; } } - WS.feedWDT(); + WsV2.feedWDT(); } } @@ -322,4 +323,4 @@ class Wippersnapper_ESP8266 : public Wippersnapper { }; #endif // ARDUINO_ARCH_ESP8266 -#endif // WIPPERSNAPPER_ESP8266_H \ No newline at end of file +#endif // WS_WIFI_ESP8266_H \ No newline at end of file diff --git a/src/network_interfaces/Wippersnapper_WIFININA.h b/src/adapters/wifi/ws_wifi_ninafw.h similarity index 95% rename from src/network_interfaces/Wippersnapper_WIFININA.h rename to src/adapters/wifi/ws_wifi_ninafw.h index 74f50bffe..1db1ff53e 100644 --- a/src/network_interfaces/Wippersnapper_WIFININA.h +++ b/src/adapters/wifi/ws_wifi_ninafw.h @@ -1,5 +1,5 @@ /*! - * @file Wippersnapper_WIFININA.h + * @file ws_wifi_ninafw.h * * Network interface for the ublox wifi module on the * Arduino MKR WiFi 1010, Arduino Nano 33 IoT and Arduino UNO WiFi Rev.2. @@ -14,8 +14,8 @@ * */ -#ifndef WIPPERSNAPPER_WIFININA_H -#define WIPPERSNAPPER_WIFININA_H +#ifndef WS_WIFI_NINAFW_H +#define WS_WIFI_NINAFW_H #include #include #include @@ -27,13 +27,13 @@ #define SPIWIFI \ SPI /*!< Instance of SPI interface used by an external uBlox module. */ -extern Wippersnapper WS; +extern Wippersnapper WS; ///< Global Wippersnapper instance /****************************************************************************/ /*! @brief Class for using the AirLift Co-Processor network iface. */ /****************************************************************************/ -class Wippersnapper_WIFININA : public Wippersnapper { +class ws_wifi_ninafw : public Wippersnapper { public: /**************************************************************************/ @@ -49,8 +49,8 @@ class Wippersnapper_WIFININA : public Wippersnapper { Wireless Network password */ /**************************************************************************/ - Wippersnapper_WIFININA(const char *aioUsername, const char *aioKey, - const char *netSSID, const char *netPass) + ws_wifi_ninafw(const char *aioUsername, const char *aioKey, + const char *netSSID, const char *netPass) : Wippersnapper() { _ssid = netSSID; _pass = netPass; @@ -66,7 +66,7 @@ class Wippersnapper_WIFININA : public Wippersnapper { @brief Destructor for the Adafruit IO ublox class. */ /**************************************************************************/ - ~Wippersnapper_WIFININA() { + ~ws_wifi_ninafw() { if (_mqtt) delete _mqtt; } @@ -283,4 +283,4 @@ class Wippersnapper_WIFININA : public Wippersnapper { } }; -#endif // WIPPERSNAPPER_WIFININA_H \ No newline at end of file +#endif // WS_WIFI_NINAFW_H \ No newline at end of file diff --git a/src/network_interfaces/ws_networking_pico.h b/src/adapters/wifi/ws_wifi_pico.h similarity index 83% rename from src/network_interfaces/ws_networking_pico.h rename to src/adapters/wifi/ws_wifi_pico.h index 283a24467..07ba5066a 100644 --- a/src/network_interfaces/ws_networking_pico.h +++ b/src/adapters/wifi/ws_wifi_pico.h @@ -1,5 +1,5 @@ /*! - * @file ws_networking_pico.h + * @file ws_wifi_pico.h * * This is a driver for using the Raspberry Pi Pico (RP2040) * network interface with Adafruit IO Wippersnapper. @@ -14,29 +14,29 @@ * */ -#ifndef WS_NETWORKING_PICO_H -#define WS_NETWORKING_PICO_H +#ifndef WS_WIFI_PICO_H +#define WS_WIFI_PICO_H -#ifdef ARDUINO_ARCH_RP2040 +#ifdef ARDUINO_RASPBERRY_PI_PICO_W #define PICO_CONNECT_TIMEOUT_MS 20000 /*!< Connection timeout (in ms) */ #define PICO_CONNECT_RETRY_DELAY_MS 200 /*!< delay time between retries. */ -#include "Wippersnapper.h" +#include "Wippersnapper_V2.h" #include "Adafruit_MQTT.h" #include "Adafruit_MQTT_Client.h" #include "Arduino.h" #include #include -extern Wippersnapper WS; +extern Wippersnapper_V2 WsV2; /****************************************************************************/ /*! @brief Class for using the Raspberry Pi Pico network interface. */ /****************************************************************************/ -class ws_networking_pico : public Wippersnapper { +class ws_wifi_pico : public Wippersnapper_V2 { public: /**************************************************************************/ @@ -44,7 +44,7 @@ class ws_networking_pico : public Wippersnapper { @brief Initializes the WipperSnapper class for RPi Pico. */ /**************************************************************************/ - ws_networking_pico() : Wippersnapper() { + ws_wifi_pico() : Wippersnapper_V2() { _ssid = 0; _pass = 0; } @@ -54,7 +54,7 @@ class ws_networking_pico : public Wippersnapper { @brief Destructor */ /**************************************************************************/ - ~ws_networking_pico() { + ~ws_wifi_pico() { if (_mqtt_client_secure) delete _mqtt_client_secure; if (_mqtt_client_secure) @@ -88,8 +88,8 @@ class ws_networking_pico : public Wippersnapper { */ /**********************************************************/ void set_ssid_pass() { - _ssid = WS._config.network.ssid; - _pass = WS._config.network.pass; + _ssid = WsV2._configV2.network.ssid; + _pass = WsV2._configV2.network.pass; } /***********************************************************/ @@ -121,12 +121,12 @@ class ws_networking_pico : public Wippersnapper { WS_DEBUG_PRINTLN(WiFi.RSSI(i)); return true; } - if (WS._isWiFiMulti) { + if (WsV2._isWiFiMultiV2) { // multi network mode for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) { - if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i)) == 0) { + if (strcmp(WsV2._multiNetworksV2[j].ssid, WiFi.SSID(i)) == 0) { WS_DEBUG_PRINT("SSID ("); - WS_DEBUG_PRINT(WS._multiNetworks[j].ssid); + WS_DEBUG_PRINT(WsV2._multiNetworksV2[j].ssid); WS_DEBUG_PRINT(") found! RSSI: "); WS_DEBUG_PRINTLN(WiFi.RSSI(i)); return true; @@ -157,7 +157,7 @@ class ws_networking_pico : public Wippersnapper { void getMacAddr() { uint8_t mac[6] = {0}; WiFi.macAddress(mac); - memcpy(WS._macAddr, mac, sizeof(mac)); + memcpy(WsV2._macAddrV2, mac, sizeof(mac)); } /********************************************************/ @@ -176,21 +176,21 @@ class ws_networking_pico : public Wippersnapper { */ /********************************************************/ void setupMQTTClient(const char *clientID) { - if (strcmp(WS._config.aio_url, "io.adafruit.com") == 0 || - strcmp(WS._config.aio_url, "io.adafruit.us") == 0) { + if (strcmp(WsV2._configV2.aio_url, "io.adafruit.com") == 0 || + strcmp(WsV2._configV2.aio_url, "io.adafruit.us") == 0) { _mqtt_client_secure = new WiFiClientSecure(); _mqtt_client_secure->setCACert( - strcmp(WS._config.aio_url, "io.adafruit.com") == 0 + strcmp(WsV2._configV2.aio_url, "io.adafruit.com") == 0 ? _aio_root_ca_prod : _aio_root_ca_staging); - WS._mqtt = new Adafruit_MQTT_Client( - _mqtt_client_secure, WS._config.aio_url, WS._config.io_port, clientID, - WS._config.aio_user, WS._config.aio_key); + WsV2._mqttV2 = new Adafruit_MQTT_Client( + _mqtt_client_secure, WsV2._configV2.aio_url, WsV2._configV2.io_port, + clientID, WsV2._configV2.aio_user, WsV2._configV2.aio_key); } else { _mqtt_client_insecure = new WiFiClient(); - WS._mqtt = new Adafruit_MQTT_Client( - _mqtt_client_insecure, WS._config.aio_url, WS._config.io_port, - clientID, WS._config.aio_user, WS._config.aio_key); + WsV2._mqttV2 = new Adafruit_MQTT_Client( + _mqtt_client_insecure, WsV2._configV2.aio_url, WsV2._configV2.io_port, + clientID, WsV2._configV2.aio_user, WsV2._configV2.aio_key); } } @@ -298,54 +298,54 @@ class ws_networking_pico : public Wippersnapper { return; WiFi.mode(WIFI_STA); - WS.feedWDT(); + WsV2.feedWDTV2(); WiFi.setTimeout(20000); - WS.feedWDT(); + WsV2.feedWDTV2(); if (strlen(_ssid) == 0) { - _status = WS_SSID_INVALID; + _statusV2 = WS_SSID_INVALID; } else { _disconnect(); delay(5000); - WS.feedWDT(); - if (WS._isWiFiMulti) { + WsV2.feedWDTV2(); + if (WsV2._isWiFiMultiV2) { // multi network mode _wifiMulti.clearAPList(); // add default network _wifiMulti.addAP(_ssid, _pass); // add array of alternative networks for (int i = 0; i < WS_MAX_ALT_WIFI_NETWORKS; i++) { - _wifiMulti.addAP(WS._multiNetworks[i].ssid, - WS._multiNetworks[i].pass); + _wifiMulti.addAP(WsV2._multiNetworksV2[i].ssid, + WsV2._multiNetworksV2[i].pass); } - WS.feedWDT(); + WsV2.feedWDTV2(); if (_wifiMulti.run(10000) == WL_CONNECTED) { - WS.feedWDT(); - _status = WS_NET_CONNECTED; + WsV2.feedWDTV2(); + _statusV2 = WS_NET_CONNECTED; return; } - WS.feedWDT(); + WsV2.feedWDTV2(); } else { WiFi.begin(_ssid, _pass); // Use the macro to retry the status check until connected / timed out int lastResult; - RETRY_FUNCTION_UNTIL_TIMEOUT( - []() -> int { return WiFi.status(); }, // Function call each cycle - int, // return type - lastResult, // return variable (unused here) - [](int status) { return status == WL_CONNECTED; }, // check - PICO_CONNECT_TIMEOUT_MS, // timeout interval (ms) - PICO_CONNECT_RETRY_DELAY_MS); // interval between retries + /* RETRY_FUNCTION_UNTIL_TIMEOUT( + []() -> int { return WiFi.status(); }, // Function call each + cycle int, // return type + lastResult, // return variable (unused here) + [](int status) { return status == WL_CONNECTED; }, // check + PICO_CONNECT_TIMEOUT_MS, // timeout interval (ms) + PICO_CONNECT_RETRY_DELAY_MS); // interval between retries */ if (lastResult == WL_CONNECTED) { - _status = WS_NET_CONNECTED; + _statusV2 = WS_NET_CONNECTED; // wait 2seconds for connection to stabilize - WS_DELAY_WITH_WDT(2000); + // WS_DELAY_WITH_WDT(2000); return; } } - _status = WS_NET_DISCONNECTED; + _statusV2 = WS_NET_DISCONNECTED; } } @@ -355,12 +355,12 @@ class ws_networking_pico : public Wippersnapper { */ /**************************************************************************/ void _disconnect() { - WS.feedWDT(); + WsV2.feedWDTV2(); WiFi.disconnect(); delay(5000); - WS.feedWDT(); + WsV2.feedWDTV2(); } }; -#endif // ARDUINO_ARCH_RP2040 -#endif // WS_NETWORKING_PICO_H \ No newline at end of file +#endif // RASPBERRY_PI_PICO_W +#endif // WS_WIFI_PICO_H \ No newline at end of file diff --git a/src/components/analogIO/Wippersnapper_AnalogIO.cpp b/src/components/analogIO/Wippersnapper_AnalogIO.cpp deleted file mode 100644 index 660208de2..000000000 --- a/src/components/analogIO/Wippersnapper_AnalogIO.cpp +++ /dev/null @@ -1,401 +0,0 @@ -/*! - * @file Wippersnapper_AnalogIO.cpp - * - * This file provides an API for interacting with - * a board's analog IO pins. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2020-2023 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ - -#include "Wippersnapper_AnalogIO.h" - -/***********************************************************************************/ -/*! - @brief Initializes Analog IO class. - @param totalAnalogInputPins - Total number of analog input pins to allocate. - @param aRef - ADC's voltage reference value, in volts. -*/ -/***********************************************************************************/ -Wippersnapper_AnalogIO::Wippersnapper_AnalogIO(int32_t totalAnalogInputPins, - float aRef) { - _totalAnalogInputPins = totalAnalogInputPins; - - // Set aref - setAref(aRef); - - // Set ADC resolution, default to 16-bit - setADCResolution(16); - - // allocate analog input pins - _analog_input_pins = new analogInputPin[_totalAnalogInputPins]; - - // TODO: Refactor this to use list-based initialization - for (int pin = 0; pin < _totalAnalogInputPins; pin++) { - // turn sampling off - _analog_input_pins[pin].enabled = false; - } -} - -/***********************************************************************************/ -/*! - @brief Destructor for Analog IO class. -*/ -/***********************************************************************************/ -Wippersnapper_AnalogIO::~Wippersnapper_AnalogIO() { - _aRef = 0.0; - _totalAnalogInputPins = 0; - delete _analog_input_pins; -} - -/***********************************************************************************/ -/*! - @brief Sets the device's reference voltage. - @param refVoltage - The voltage reference to use during conversions. -*/ -/***********************************************************************************/ -void Wippersnapper_AnalogIO::setAref(float refVoltage) { _aRef = refVoltage; } - -/***********************************************************************************/ -/*! - @brief Returns the device's reference voltage. - @returns Analog reference voltage, in volts. -*/ -/***********************************************************************************/ -float Wippersnapper_AnalogIO::getAref() { return _aRef; } - -/***********************************************************************************/ -/*! - @brief Sets the device's ADC resolution, either natively via calling - Arduino API's analogReadResolution() or via scaling. - @param resolution - The desired analog resolution, in bits. -*/ -/***********************************************************************************/ -void Wippersnapper_AnalogIO::setADCResolution(int resolution) { -// set the resolution natively in the BSP -#if defined(ARDUINO_ARCH_SAMD) - analogReadResolution(16); - _nativeResolution = 12; -#elif defined(ARDUINO_ARCH_ESP32) - scaleAnalogRead = true; - _nativeResolution = 13; -#elif defined(ARDUINO_ARCH_RP2040) - scaleAnalogRead = true; - _nativeResolution = 10; -#else - scaleAnalogRead = true; - _nativeResolution = 10; -#endif - - _adcResolution = resolution; -} - -/***********************************************************************************/ -/*! - @brief Gets the scaled ADC resolution. - @returns resolution - The scaled analog resolution, in bits. -*/ -/***********************************************************************************/ -int Wippersnapper_AnalogIO::getADCresolution() { return _adcResolution; } - -/***********************************************************************************/ -/*! - @brief Gets the device's native ADC resolution. - @returns resolution - The native analog resolution, in bits. -*/ -/***********************************************************************************/ -int Wippersnapper_AnalogIO::getNativeResolution() { return _nativeResolution; } - -/***********************************************************************************/ -/*! - @brief Initializes an analog input pin - @param pin - The analog pin to read from. - @param period - Time between measurements, in seconds. - @param pullMode - The pin's pull value. - @param analogReadMode - Defines if pin will read and return an ADC value or a voltage value. -*/ -/***********************************************************************************/ -void Wippersnapper_AnalogIO::initAnalogInputPin( - int pin, float period, - wippersnapper_pin_v1_ConfigurePinRequest_Pull pullMode, - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode analogReadMode) { - - // Set analog read pull mode - if (pullMode == wippersnapper_pin_v1_ConfigurePinRequest_Pull_PULL_UP) - pinMode(pin, INPUT_PULLUP); - else - pinMode(pin, INPUT); - - // Period is in seconds, cast it to long and convert it to milliseconds - long periodMs = (long)period * 1000; - - // TODO: Maybe pull this out into a func. or use map() lookup instead - // attempt to allocate pin within _analog_input_pins[] - for (int i = 0; i < _totalAnalogInputPins; i++) { - if (_analog_input_pins[i].enabled == false) { - _analog_input_pins[i].pinName = pin; - _analog_input_pins[i].period = periodMs; - _analog_input_pins[i].prvPeriod = 0L; - _analog_input_pins[i].readMode = analogReadMode; - _analog_input_pins[i].enabled = true; - break; - } - } - WS_DEBUG_PRINT("Configured Analog Input pin with polling time (ms):"); - WS_DEBUG_PRINTLN(periodMs); -} - -/***********************************************************************************/ -/*! - @brief Disables an analog input pin from sampling - @param pin - The analog input pin to disable. -*/ -/***********************************************************************************/ -void Wippersnapper_AnalogIO::disableAnalogInPin(int pin) { - for (int i = 0; i < _totalAnalogInputPins; i++) { - if (_analog_input_pins[i].pinName == pin) { - _analog_input_pins[i].enabled = false; - break; - } - } -} - -/***********************************************************************************/ -/*! - @brief Deinitializes an analog pin. - @param direction - The analog pin's direction. - @param pin - The analog pin to deinitialize. - -*/ -/***********************************************************************************/ -void Wippersnapper_AnalogIO::deinitAnalogPin( - wippersnapper_pin_v1_ConfigurePinRequest_Direction direction, int pin) { - WS_DEBUG_PRINT("Deinitializing analog pin A"); - WS_DEBUG_PRINTLN(pin); - if (direction == - wippersnapper_pin_v1_ConfigurePinRequest_Direction_DIRECTION_INPUT) { - WS_DEBUG_PRINTLN("Deinitialized analog input pin obj."); - disableAnalogInPin(pin); - } - pinMode(pin, INPUT); // hi-z -} - -/**********************************************************/ -/*! - @brief Reads the raw ADC value of an analog pin. - Value is always scaled to 16-bit. - @param pin - The pin to be read. - @returns The pin's ADC value. -*/ -/**********************************************************/ -uint16_t Wippersnapper_AnalogIO::getPinValue(int pin) { - // get pin value - uint16_t value = analogRead(pin); - // scale by the ADC resolution manually if not implemented by BSP - if (scaleAnalogRead) { - if (getADCresolution() > getNativeResolution()) { - value = value << (getADCresolution() - getNativeResolution()); - } else { - value = value >> (getNativeResolution() - getADCresolution()); - } - } - return value; -} - -/**********************************************************/ -/*! - @brief Calculates analog pin's voltage provided - a 16-bit ADC value. - @param pin - The value from a previous ADC reading. - @returns The pin's voltage. -*/ -/**********************************************************/ -float Wippersnapper_AnalogIO::getPinValueVolts(int pin) { - uint16_t rawValue = getPinValue(pin); - return rawValue * getAref() / 65536; -} - -/******************************************************************/ -/*! - @brief Encodes an analog input pin event into a - signal message and publish it to IO. - @param pinName - Specifies the pin's name. - @param readMode - Read mode - raw ADC or voltage. - @param pinValRaw - Raw pin value, used if readmode is raw. - @param pinValVolts - Raw pin value expressed in Volts, used if readmode is - volts. - @returns True if successfully encoded a PinEvent signal - message, False otherwise. -*/ -/******************************************************************/ -bool Wippersnapper_AnalogIO::encodePinEvent( - uint8_t pinName, - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode readMode, - uint16_t pinValRaw, float pinValVolts) { - // Create new signal message - wippersnapper_signal_v1_CreateSignalRequest outgoingSignalMsg = - wippersnapper_signal_v1_CreateSignalRequest_init_zero; - - // Fill payload - outgoingSignalMsg.which_payload = - wippersnapper_signal_v1_CreateSignalRequest_pin_event_tag; - sprintf(outgoingSignalMsg.payload.pin_event.pin_name, "A%d", pinName); - - // Fill pinValue based on the analog read mode - char buffer[100]; - if (readMode == - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_PIN_VALUE) { - sprintf(outgoingSignalMsg.payload.pin_event.pin_value, "%u", pinValRaw); - snprintf(buffer, 100, "[Pin] A%d read: %u\n", pinName, pinValRaw); - } else { - sprintf(outgoingSignalMsg.payload.pin_event.pin_value, "%0.3f", - pinValVolts); - snprintf(buffer, 100, "[Pin] A%d read: %0.2f\n", pinName, pinValVolts); - } -// display analog pin read on terminal -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - // Encode signal message - pb_ostream_t stream = - pb_ostream_from_buffer(WS._buffer_outgoing, sizeof(WS._buffer_outgoing)); - if (!ws_pb_encode(&stream, wippersnapper_signal_v1_CreateSignalRequest_fields, - &outgoingSignalMsg)) { - WS_DEBUG_PRINTLN("ERROR: Unable to encode signal message"); - return false; - } - - // Publish out to IO - size_t msgSz; - pb_get_encoded_size(&msgSz, - wippersnapper_signal_v1_CreateSignalRequest_fields, - &outgoingSignalMsg); - WS_DEBUG_PRINT("Publishing pinEvent..."); - WS.publish(WS._topic_signal_device, WS._buffer_outgoing, msgSz, 1); - WS_DEBUG_PRINTLN("Published!"); - - return true; -} - -/**********************************************************/ -/*! - @brief Checks if pin's period is expired. - @param currentTime - The current software timer value. - @param pin - The desired analog pin to check - @returns True if pin's period expired, False otherwise. -*/ -/**********************************************************/ -bool Wippersnapper_AnalogIO::timerExpired(long currentTime, - analogInputPin pin) { - if (currentTime - pin.prvPeriod > pin.period && pin.period != 0L) - return true; - return false; -} - -/**********************************************************/ -/*! - @brief Iterates thru analog inputs -*/ -/**********************************************************/ -void Wippersnapper_AnalogIO::update() { - // TODO: Globally scope these, dont have them here every time - float pinValVolts = 0.0; - uint16_t pinValRaw = 0; - // Process analog input pins - for (int i = 0; i < _totalAnalogInputPins; i++) { - // TODO: Can we collapse the conditionals below? - if (_analog_input_pins[i].enabled == true) { - - // Does the pin execute on-period? - if ((long)millis() - _analog_input_pins[i].prvPeriod > - _analog_input_pins[i].period && - _analog_input_pins[i].period != 0L) { - WS_DEBUG_PRINT("Executing periodic event on A"); - WS_DEBUG_PRINTLN(_analog_input_pins[i].pinName); - - // Read from analog pin - if (_analog_input_pins[i].readMode == - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_PIN_VOLTAGE) { - pinValVolts = getPinValueVolts(_analog_input_pins[i].pinName); - } else if ( - _analog_input_pins[i].readMode == - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_PIN_VALUE) { - pinValRaw = getPinValue(_analog_input_pins[i].pinName); - } else { - WS_DEBUG_PRINTLN("ERROR: Unable to read pin value, cannot determine " - "analog read mode!"); - pinValRaw = 0.0; - } - - // Publish a new pin event - encodePinEvent(_analog_input_pins[i].pinName, - _analog_input_pins[i].readMode, pinValRaw, pinValVolts); - - // IMPT - reset the digital pin - _analog_input_pins[i].prvPeriod = millis(); - } - // Does the pin execute on_change? - else if (_analog_input_pins[i].period == 0L) { - - // note: on-change requires ADC DEFAULT_HYSTERISIS to check against prv - // pin value - uint16_t pinValRaw = getPinValue(_analog_input_pins[i].pinName); - - uint16_t _pinValThreshHi = - _analog_input_pins[i].prvPinVal + - (_analog_input_pins[i].prvPinVal * DEFAULT_HYSTERISIS); - uint16_t _pinValThreshLow = - _analog_input_pins[i].prvPinVal - - (_analog_input_pins[i].prvPinVal * DEFAULT_HYSTERISIS); - - if (pinValRaw > _pinValThreshHi || pinValRaw < _pinValThreshLow) { - // Perform voltage conversion if we need to - if (_analog_input_pins[i].readMode == - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_PIN_VOLTAGE) { - pinValVolts = pinValRaw * getAref() / 65536; - } - - // Publish pin event to IO - encodePinEvent(_analog_input_pins[i].pinName, - _analog_input_pins[i].readMode, pinValRaw, - pinValVolts); - - } else { - // WS_DEBUG_PRINTLN("ADC has not changed enough, continue..."); - continue; - } - // set the pin value in the digital pin object for comparison on next - // run - _analog_input_pins[i].prvPinVal = pinValRaw; - } - } - } -} \ No newline at end of file diff --git a/src/components/analogIO/Wippersnapper_AnalogIO.h b/src/components/analogIO/Wippersnapper_AnalogIO.h deleted file mode 100644 index 91b62a489..000000000 --- a/src/components/analogIO/Wippersnapper_AnalogIO.h +++ /dev/null @@ -1,85 +0,0 @@ -/*! - * @file Wippersnapper_AnalogIO.h - * - * This file provides digital GPIO control and access. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2020-2023 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ - -#ifndef WIPPERSNAPPER_ANALOGIO_H -#define WIPPERSNAPPER_ANALOGIO_H - -#include "Wippersnapper.h" - -#define DEFAULT_HYSTERISIS 0.02 ///< Default DEFAULT_HYSTERISIS of 2% - -/** Data about an analog input pin */ -struct analogInputPin { - int pinName; ///< Pin name - bool enabled; ///< Pin is enabled for sampling - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode - readMode; ///< Which type of analog read to perform - long period; ///< Pin timer interval, in millis, -1 if disabled. - long prvPeriod; ///< When Pin's timer was previously serviced, in millis - float prvPinVal; ///< Previous pin value -}; - -// forward decl. -class Wippersnapper; - -/**************************************************************************/ -/*! - @brief Class that provides an interface for reading and controlling - analog pins. Stores information about analog input pins. -*/ -/**************************************************************************/ -class Wippersnapper_AnalogIO { -public: - Wippersnapper_AnalogIO(int32_t totalAnalogInputPins, float aRef); - ~Wippersnapper_AnalogIO(); - - void setAref(float refVoltage); - float getAref(); - - void initAnalogInputPin( - int pin, float period, - wippersnapper_pin_v1_ConfigurePinRequest_Pull pullMode, - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode analogReadMode); - void - deinitAnalogPin(wippersnapper_pin_v1_ConfigurePinRequest_Direction direction, - int pin); - void disableAnalogInPin(int pin); - - uint16_t getPinValue(int pin); - float getPinValueVolts(int pin); - - void setADCResolution(int resolution); - int getADCresolution(); - int getNativeResolution(); - bool timerExpired(long currentTime, analogInputPin pin); - - void update(); - bool encodePinEvent( - uint8_t pinName, - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode readMode, - uint16_t pinValRaw = 0, float pinValVolts = 0.0); - -private: - float _aRef; /*!< Hardware's reported voltage reference */ - int _adcResolution; /*!< Resolution returned by the analogRead() funcn. */ - int _nativeResolution; /*!< Hardware's native ADC resolution. */ - bool scaleAnalogRead = false; /*!< True if we need to manually scale the value - returned by analogRead(). */ - int32_t _totalAnalogInputPins; /*!< Total number of analog input pins */ - analogInputPin *_analog_input_pins; /*!< Array of analog pin objects */ -}; -extern Wippersnapper WS; /*!< Wippersnapper variable. */ - -#endif // WIPPERSNAPPER_DIGITALGPIO_H \ No newline at end of file diff --git a/src/components/analogIO/controller.cpp b/src/components/analogIO/controller.cpp new file mode 100644 index 000000000..7fae11b54 --- /dev/null +++ b/src/components/analogIO/controller.cpp @@ -0,0 +1,284 @@ +/*! + * @file controller.cpp + * + * Controller for the analogio.proto API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024-2025 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "controller.h" + +/***********************************************************************/ +/*! + @brief AnalogIO controller constructor +*/ +/***********************************************************************/ +AnalogIOController::AnalogIOController() { + _analogio_hardware = new AnalogIOHardware(); + _analogio_model = new AnalogIOModel(); + _analogio_hardware->SetResolution(16); // Default to 16-bit resolution + SetRefVoltage(3.3); // Default to 3.3V +} + +/***********************************************************************/ +/*! + @brief AnalogIO controller destructor +*/ +/***********************************************************************/ +AnalogIOController::~AnalogIOController() { + delete _analogio_hardware; + delete _analogio_model; +} + +/***********************************************************************/ +/*! + @brief Set the reference voltage for the analog pins + @param voltage + The reference voltage. +*/ +/***********************************************************************/ +void AnalogIOController::SetRefVoltage(float voltage) { + // To set the reference voltage, we call into the hardware + _analogio_hardware->SetReferenceVoltage(voltage); +} + +/***********************************************************************/ +/*! + @brief Set the total number of analog pins present on the hardware. + @param total_pins + The hardware's total number of analog pins. +*/ +/***********************************************************************/ +void AnalogIOController::SetTotalAnalogPins(uint8_t total_pins) { + _total_analogio_pins = total_pins; +} + +/***********************************************************************/ +/*! + @brief Handles an AnalogIOAdd message from the broker and adds a + new analog pin to the controller. + @param stream + The nanopb input stream. + @return True if the pin was successfully added, False otherwise. +*/ +/***********************************************************************/ +bool AnalogIOController::Handle_AnalogIOAdd(pb_istream_t *stream) { + // Attempt to decode the incoming message into an AnalogIOAdd object + if (!_analogio_model->DecodeAnalogIOAdd(stream)) { + WS_DEBUG_PRINTLN("[analogio] ERROR: Unable to decode Add message"); + return false; + } + + // Get the pin name + uint8_t pin_name = atoi(_analogio_model->GetAnalogIOAddMsg()->pin_name + 1); + + // Create a new analogioPin object + // TODO: Replicate this within the digitalio controller, much cleaner way to + // assign! + analogioPin new_pin = { + .name = pin_name, + .period = long(_analogio_model->GetAnalogIOAddMsg()->period) * 1000, + .prv_period = 0, + .read_mode = _analogio_model->GetAnalogIOAddMsg()->read_mode}; + + // Initialize the pin + _analogio_hardware->InitPin(pin_name); + + // Print out the pin's details + WS_DEBUG_PRINTLN("[analogio] Added new pin:"); + WS_DEBUG_PRINT("Pin Name: "); + WS_DEBUG_PRINTLN(new_pin.name); + WS_DEBUG_PRINT("Period: "); + WS_DEBUG_PRINTLN(new_pin.period); + WS_DEBUG_PRINT("Read Mode: "); + WS_DEBUG_PRINTLN(new_pin.read_mode); + + // Add the new pin to the vector + _analogio_pins.push_back(new_pin); + + return true; +} + +/***************************************************************************/ +/*! + @brief Handles an AnalogIORemove message from the broker and removes + the requested analog pin from the controller. + @param stream + The nanopb input stream. + @return True if the pin was successfully removed, False otherwise. +*/ +/***************************************************************************/ +bool AnalogIOController::Handle_AnalogIORemove(pb_istream_t *stream) { + // Attempt to decode the incoming message into an AnalogIORemove object + if (!_analogio_model->DecodeAnalogIORemove(stream)) { + WS_DEBUG_PRINTLN("ERROR: Unable to decode AnalogIORemove message"); + return false; + } + + // Get the pin name + int pin_name = atoi(_analogio_model->GetAnalogIORemoveMsg()->pin_name + 1); + + // Remove the pin from the hardware + _analogio_hardware->DeinitPin(pin_name); + + // Remove the pin from the vector + // TODO: Refactor this out? TODO: Make this better?? + for (int i = 0; i < _analogio_pins.size(); i++) { + if (_analogio_pins[i].name == pin_name) { + _analogio_pins.erase(_analogio_pins.begin() + i); + break; + } + } + return true; +} + +/***************************************************************************/ +/*! + @brief Checks if a pin's periodic timer has expired. + @param pin + The requested pin to check. + @param cur_time + The current time (called from millis()). + @return True if the pin's period has expired, False otherwise. +*/ +/***************************************************************************/ +bool AnalogIOController::IsPinTimerExpired(analogioPin *pin, ulong cur_time) { + return cur_time - pin->prv_period > pin->period; +} + +/***************************************************************************/ +/*! + @brief Encodes and publishes an AnalogIOEvent message to the broker. + @param pin + The pin to encode and publish. + @param value + The pin's value. + @param read_type + The type of read to perform on the pin. + @return True if the message was successfully encoded and published. +*/ +/***************************************************************************/ +bool AnalogIOController::EncodePublishPinEvent( + uint8_t pin, float value, wippersnapper_sensor_SensorType read_type) { + char c_pin_name[12]; + sprintf(c_pin_name, "A%d", pin); + + if (read_type == wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW) { + if (!_analogio_model->EncodeAnalogIOEventRaw(c_pin_name, value)) { + WS_DEBUG_PRINTLN("ERROR: Unable to encode AnalogIO raw adc message!"); + return false; + } + } else if (read_type == wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE) { + if (!_analogio_model->EncodeAnalogIOEventVoltage(c_pin_name, value)) { + WS_DEBUG_PRINTLN("ERROR: Unable to encode AnalogIO voltage message!"); + return false; + } + } else { + WS_DEBUG_PRINTLN("ERROR: Invalid read type for AnalogIOEvent message!"); + return false; + } + + // Publish the AnalogIO message to the broker + WS_DEBUG_PRINTLN("Publishing AnalogIOEvent message to broker..."); + if (!WsV2.PublishSignal( + wippersnapper_signal_DeviceToBroker_analogio_event_tag, + _analogio_model->GetAnalogIOEvent())) { + WS_DEBUG_PRINTLN("ERROR: Unable to publish analogio voltage event message, " + "moving onto the next pin!"); + return false; + } + WS_DEBUG_PRINTLN("Published AnalogIOEvent message to broker!") + + return true; +} + +/***************************************************************************/ +/*! + @brief Encodes and publishes an AnalogIOEvent message to the broker. + @param pin + The requested pin. + @param value + The pin's value. + @return True if the message was successfully encoded and published, + False othewise. +*/ +/***************************************************************************/ +bool AnalogIOController::EncodePublishPinValue(uint8_t pin, uint16_t value) { + if (WsV2._sdCardV2->isModeOffline()) { + return WsV2._sdCardV2->LogGPIOSensorEventToSD( + pin, value, wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW); + } else { + return EncodePublishPinEvent( + pin, (float)value, wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW); + } +} + +/***************************************************************************/ +/*! + @brief Encodes and publishes an AnalogIOEvent message to the broker. + @param pin + The requested pin. + @param value + The pin's value, as a voltage. + @return True if the message was successfully encoded and published, + False othewise. +*/ +/***************************************************************************/ +bool AnalogIOController::EncodePublishPinVoltage(uint8_t pin, float value) { + if (WsV2._sdCardV2->isModeOffline()) { + return WsV2._sdCardV2->LogGPIOSensorEventToSD( + pin, value, wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE); + } else { + return EncodePublishPinEvent( + pin, value, wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE); + } +} + +/***************************************************************************/ +/*! + @brief Update/polling loop for the AnalogIO controller. +*/ +/***************************************************************************/ +void AnalogIOController::update() { + // Bail-out if the vector is empty + if (_analogio_pins.empty()) { + return; + } + + // Process analog input pins + for (int i = 0; i < _analogio_pins.size(); i++) { + // Create a pin object for this iteration + analogioPin &pin = _analogio_pins[i]; + // Go to the next pin if the period hasn't expired yet + ulong cur_time = millis(); + if (!IsPinTimerExpired(&pin, cur_time)) + continue; + + // Pins timer has expired, lets read the pin + if (pin.read_mode == wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW) { + // Read the pin's raw value + uint16_t value = _analogio_hardware->GetPinValue(pin.name); + // Encode and publish it to the broker + if (!EncodePublishPinValue(pin.name, value)) { + WS_DEBUG_PRINTLN("[analogio] ERROR: Unable to record pin value!"); + continue; + } + pin.prv_period = cur_time; // Reset the pin's period + } else if (pin.read_mode == + wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE) { + // Convert the raw value into voltage + float pin_value = _analogio_hardware->GetPinVoltage(pin.name); + // Encode and publish the voltage value to the broker + EncodePublishPinVoltage(pin.name, pin_value); + pin.prv_period = cur_time; // Reset the pin's period + } else { + WS_DEBUG_PRINTLN("[analogio] ERROR: Invalid read mode for analog pin!"); + } + } +} \ No newline at end of file diff --git a/src/components/analogIO/controller.h b/src/components/analogIO/controller.h new file mode 100644 index 000000000..d046578c8 --- /dev/null +++ b/src/components/analogIO/controller.h @@ -0,0 +1,69 @@ +/*! + * @file controller.h + * + * Controller for the AnalogIO API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_ANALOGIO_CONTROLLER_H +#define WS_ANALOGIO_CONTROLLER_H +#include "Wippersnapper_V2.h" +#include "hardware.h" +#include "model.h" + +class Wippersnapper_V2; ///< Forward declaration +class AnalogIOModel; ///< Forward declaration +class AnalogIOHardware; ///< Forward declaration + +/** + * @struct analogioPin + * @brief Represents a device's analogio pin. + */ +struct analogioPin { + uint8_t name; ///< The pin's name. + float period; ///< The pin's period, in milliseconds. + float prv_period; ///< The pin's previous period, in milliseconds. + wippersnapper_sensor_SensorType read_mode; ///< Type of analog read to perform +}; + +/**************************************************************************/ +/*! + @brief Routes messages using the analogio.proto API to the + appropriate hardware and model classes, controls and tracks + the state of the hardware's digital I/O pins. +*/ +/**************************************************************************/ +class AnalogIOController { +public: + AnalogIOController(); + ~AnalogIOController(); + // Routing + bool Handle_AnalogIOAdd(pb_istream_t *stream); + bool Handle_AnalogIORemove(pb_istream_t *stream); + // Polling loop + void update(); + // Encoder + bool EncodePublishPinEvent(uint8_t pin, float value, + wippersnapper_sensor_SensorType read_type); + bool EncodePublishPinValue(uint8_t pin, uint16_t value); + bool EncodePublishPinVoltage(uint8_t pin, float value); + // Helpers + void SetTotalAnalogPins(uint8_t total_pins); + void SetRefVoltage(float voltage); + bool IsPinTimerExpired(analogioPin *pin, ulong cur_time); + +private: + AnalogIOModel *_analogio_model; ///< AnalogIO model + AnalogIOHardware *_analogio_hardware; ///< AnalogIO hardware + std::vector _analogio_pins; ///< Vector of analogio pins + uint8_t _total_analogio_pins; ///< Total number of analogio pins +}; +extern Wippersnapper_V2 WsV2; ///< Wippersnapper V2 instance +#endif // WS_ANALOGIO_CONTROLLER_H \ No newline at end of file diff --git a/src/components/analogIO/hardware.cpp b/src/components/analogIO/hardware.cpp new file mode 100644 index 000000000..038143fff --- /dev/null +++ b/src/components/analogIO/hardware.cpp @@ -0,0 +1,145 @@ +/*! + * @file hardware.cpp + * + * Hardware interface for the analogio.proto API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "hardware.h" + +/***********************************************************************/ +/*! + @brief AnalogIO hardware constructor +*/ +/***********************************************************************/ +AnalogIOHardware::AnalogIOHardware() { + SetNativeADCResolution(); // Configure the device's native ADC resolution + SetResolution(16); // Wippersnapper's default resolution is 16-bit +} + +/***********************************************************************/ +/*! + @brief AnalogIO hardware destructor +*/ +/***********************************************************************/ +AnalogIOHardware::~AnalogIOHardware() {} + +/***********************************************************************/ +/*! + @brief Initializes an analog input pin. + @param pin + The requested pin. +*/ +/***********************************************************************/ +void AnalogIOHardware::InitPin(uint8_t pin) { pinMode(pin, INPUT); } + +/***********************************************************************/ +/*! + @brief Deinitializes an analog input pin and frees it for + other uses. + @param pin + The requested pin. +*/ +/***********************************************************************/ +void AnalogIOHardware::DeinitPin(uint8_t pin) { + pinMode(pin, INPUT); // set to a hi-z floating pin +} + +/*************************************************************************/ +/*! + @brief Sets the hardware's reference voltage for reading analog pins + @param voltage + The reference voltage. +*/ +/*************************************************************************/ +void AnalogIOHardware::SetReferenceVoltage(float voltage) { + _ref_voltage = voltage; +} + +/*************************************************************************/ +/*! + @brief Configures the hardware's native ADC resolution. +*/ +/*************************************************************************/ +void AnalogIOHardware::SetNativeADCResolution() { +#if defined(ARDUINO_ARCH_SAMD) + _native_adc_resolution = 12; +#elif defined(ARDUINO_ARCH_ESP32) +#if defined(CONFIG_IDF_TARGET_ESP32S3) + // In arduino-esp32, the ESP32-S3 ADC uses a 13-bit resolution + _native_adc_resolution = 13; +#else + // The ESP32, ESP32-S2, ESP32-C3 ADCs uses 12-bit resolution + _native_adc_resolution = 12; +#endif +#elif defined(ARDUINO_ARCH_RP2040) + _native_adc_resolution = 10; +#else + _native_adc_resolution = 10; +#endif + // Set the resolution (in bits) of the hardware's ADC + analogReadResolution(_native_adc_resolution); +} + +/*************************************************************************/ +/*! + @brief Sets the hardware ADC's resolution. + @param resolution + The requested resolution, in bits. +*/ +/*************************************************************************/ +void AnalogIOHardware::SetResolution(uint8_t resolution) { + _desired_adc_resolution = resolution; + // Calculate (or re-calculate) the scale factor whenever we set the desired + // read resolution + CalculateScaleFactor(); +} + +/*************************************************************************/ +/*! + @brief Calculates a factor used by the hardware for scaling + the ADC's resolution. +*/ +/*************************************************************************/ +void AnalogIOHardware::CalculateScaleFactor() { + _max_scale_resolution_desired = + pow(2, 16); // TODO: Change to _desired_adc_resolution + _max_scale_resolution_native = + pow(2, 13); // TODO: Change to _native_adc_resolution +} + +/*************************************************************************/ +/*! + @brief Gets the "raw" value of an analog pin from the ADC. + @param pin + The requested pin. + @return The pin's value. +*/ +/*************************************************************************/ +uint16_t AnalogIOHardware::GetPinValue(uint8_t pin) { + return (analogRead(pin) * _max_scale_resolution_desired) / + _max_scale_resolution_native; +} + +/*************************************************************************/ +/*! + @brief Gets the voltage of an analog pin. + @param pin + The requested pin. + @return The pin's voltage. +*/ +/*************************************************************************/ +float AnalogIOHardware::GetPinVoltage(uint8_t pin) { +#ifdef ARDUINO_ARCH_ESP32 + return analogReadMilliVolts(pin) / 1000.0; +#else + return (GetPinValue(pin) * _ref_voltage) / 65536; +#endif // ARDUINO_ARCH_ESP32 +} \ No newline at end of file diff --git a/src/components/analogIO/hardware.h b/src/components/analogIO/hardware.h new file mode 100644 index 000000000..447495034 --- /dev/null +++ b/src/components/analogIO/hardware.h @@ -0,0 +1,48 @@ +/*! + * @file model.h + * + * Hardware implementation for the analogio.proto message. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_ANALOGIO_HARDWARE_H +#define WS_ANALOGIO_HARDWARE_H +#include "Wippersnapper_V2.h" + +/**************************************************************************/ +/*! + @brief Interface for interacting with hardware's analog i/o pin API. +*/ +/**************************************************************************/ +class AnalogIOHardware { +public: + AnalogIOHardware(); + ~AnalogIOHardware(); + void SetNativeADCResolution(); + void SetResolution(uint8_t resolution); + void SetReferenceVoltage(float voltage); + void CalculateScaleFactor(); + // Arduino/Wiring API + void InitPin(uint8_t pin); + void DeinitPin(uint8_t pin); + uint16_t GetPinValue(uint8_t pin); + float GetPinVoltage(uint8_t pin); + +private: + uint8_t _native_adc_resolution; ///< Hardware's native ADC resolution. + uint8_t _desired_adc_resolution; ///< Desired (final) ADC resolution. + int _max_scale_resolution_desired; ///< Maximum scale resolution desired. + int _max_scale_resolution_native; ///< Maximum scale resolution native. + + bool _is_adc_resolution_scaled; ///< True if the ADC's resolution is scaled, + ///< False otherwise. + float _ref_voltage; ///< Reference voltage for reading analog pins. +}; +#endif // WS_ANALOGIO_HARDWARE_H \ No newline at end of file diff --git a/src/components/analogIO/model.cpp b/src/components/analogIO/model.cpp new file mode 100644 index 000000000..b5c9f9854 --- /dev/null +++ b/src/components/analogIO/model.cpp @@ -0,0 +1,168 @@ +/*! + * @file model.cpp + * + * Interfaces for the analogio.proto API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "model.h" + +/***********************************************************************/ +/*! + @brief AnalogIOModel constructor +*/ +/***********************************************************************/ +AnalogIOModel::AnalogIOModel() { + _msg_AnalogioAdd = wippersnapper_analogio_AnalogIOAdd_init_default; +} + +/***********************************************************************/ +/*! + @brief AnalogIOModel destructor +*/ +/***********************************************************************/ +AnalogIOModel::~AnalogIOModel() {} + +/***********************************************************************/ +/*! + @brief Decodes an AnalogIOAdd message from a stream into an + AnalogIOAdd message struct. + @param stream + The pb_istream_t stream to decode. + @return True if successful, False otherwise. +*/ +/***********************************************************************/ +bool AnalogIOModel::DecodeAnalogIOAdd(pb_istream_t *stream) { + // Zero-out the AnalogIOAdd message struct. to ensure we don't have any old + // data + _msg_AnalogioAdd = wippersnapper_analogio_AnalogIOAdd_init_default; + // Decode the stream into a AnalogIOAdd message + return pb_decode(stream, wippersnapper_analogio_AnalogIOAdd_fields, + &_msg_AnalogioAdd); +} + +/***********************************************************************/ +/*! + @brief Gets an AnalogIOAdd message struct. + @return Pointer to an AnalogIOAdd message struct. +*/ +/***********************************************************************/ +wippersnapper_analogio_AnalogIOAdd *AnalogIOModel::GetAnalogIOAddMsg() { + return &_msg_AnalogioAdd; +} + +/***********************************************************************/ +/*! + @brief Decodes an AnalogIORemove message from a stream into an + AnalogIORemove message struct. + @param stream + The pb_istream_t stream to decode. + @return True if successful, False otherwise. +*/ +/***********************************************************************/ +bool AnalogIOModel::DecodeAnalogIORemove(pb_istream_t *stream) { + // Zero-out the AnalogIORemove message struct. to ensure we don't have any old + // data + _msg_AnalogioRemove = wippersnapper_analogio_AnalogIORemove_init_default; + // Decode the stream into a AnalogIORemove message + return pb_decode(stream, wippersnapper_analogio_AnalogIORemove_fields, + &_msg_AnalogioRemove); +} + +/*****************************************************************************/ +/*! + @brief Gets an AnalogIORemove message struct. + @return Pointer to an AnalogIORemove message struct. +*/ +/*****************************************************************************/ +wippersnapper_analogio_AnalogIORemove *AnalogIOModel::GetAnalogIORemoveMsg() { + return &_msg_AnalogioRemove; +} + +/*****************************************************************************/ +/*! + @brief Gets an AnalogIOEvent message struct. + @return Pointer to an AnalogIOEvent message struct. +*/ +/*****************************************************************************/ +wippersnapper_analogio_AnalogIOEvent *AnalogIOModel::GetAnalogIOEvent() { + return &_msg_AnalogioEvent; +} + +/*****************************************************************************/ +/*! + @brief Encodes an AnalogIOEvent message. + @param pin_name + The requested pin's name. + @param pin_value + The value of the pin. + @param read_type + The type of sensor event to encode. + @return True if successful, False otherwise. +*/ +/*****************************************************************************/ +bool AnalogIOModel::EncodeAnalogIOEvent( + char *pin_name, float pin_value, + wippersnapper_sensor_SensorType read_type) { + // Initialize the AnalogIOEvent message to default values + _msg_AnalogioEvent = wippersnapper_analogio_AnalogIOEvent_init_zero; + // Fill the AnalogIOEvent message's fields + strncpy(_msg_AnalogioEvent.pin_name, pin_name, + sizeof(_msg_AnalogioEvent.pin_name)); + _msg_AnalogioEvent.has_sensor_event = true; + _msg_AnalogioEvent.sensor_event.type = read_type; + _msg_AnalogioEvent.sensor_event.which_value = + wippersnapper_sensor_SensorEvent_float_value_tag; + _msg_AnalogioEvent.sensor_event.value.float_value = pin_value; + + // Obtain size of an encoded AnalogIOEvent message + size_t sz_aio_event_msg; + if (!pb_get_encoded_size(&sz_aio_event_msg, + wippersnapper_analogio_AnalogIOEvent_fields, + &_msg_AnalogioEvent)) + return false; + + // Encode the AnalogIOEvent message + uint8_t buf[sz_aio_event_msg]; + pb_ostream_t msg_stream = pb_ostream_from_buffer(buf, sizeof(buf)); + return pb_encode(&msg_stream, wippersnapper_analogio_AnalogIOEvent_fields, + &_msg_AnalogioEvent); +} + +/********************************************************************************/ +/*! + @brief Encodes an AnalogIOEvent message with a raw pin value. + @param pin_name + The requested pin's name. + @param pin_value + The value of the pin. + @return True if successful, False otherwise. +*/ +/********************************************************************************/ +bool AnalogIOModel::EncodeAnalogIOEventRaw(char *pin_name, float pin_value) { + return EncodeAnalogIOEvent(pin_name, pin_value, + wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW); +} + +/********************************************************************************/ +/*! + @brief Encodes an AnalogIOEvent message with a voltage pin value. + @param pin_name + The requested pin's name. + @param pin_value + The value of the pin. + @return True if successful, False otherwise. +*/ +/********************************************************************************/ +bool AnalogIOModel::EncodeAnalogIOEventVoltage(char *pin_name, + float pin_value) { + return EncodeAnalogIOEvent( + pin_name, pin_value, wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE); +} \ No newline at end of file diff --git a/src/components/analogIO/model.h b/src/components/analogIO/model.h new file mode 100644 index 000000000..f20fd4c46 --- /dev/null +++ b/src/components/analogIO/model.h @@ -0,0 +1,49 @@ +/*! + * @file model.h + * + * Model interface for the analogio.proto message. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_ANALOGIO_MODEL_H +#define WS_ANALOGIO_MODEL_H +#include "Wippersnapper_V2.h" + +/**************************************************************************/ +/*! + @brief Provides an interface for creating, encoding, and parsing + messages from analogio.proto. +*/ +/**************************************************************************/ +class AnalogIOModel { +public: + AnalogIOModel(); + ~AnalogIOModel(); + // AnalogIOAdd + bool DecodeAnalogIOAdd(pb_istream_t *stream); + wippersnapper_analogio_AnalogIOAdd *GetAnalogIOAddMsg(); + // AnalogIORemove + bool DecodeAnalogIORemove(pb_istream_t *stream); + wippersnapper_analogio_AnalogIORemove *GetAnalogIORemoveMsg(); + // AnalogIOEvent + bool EncodeAnalogIOEvent(char *pin_name, float pin_value, + wippersnapper_sensor_SensorType read_type); + bool EncodeAnalogIOEventVoltage(char *pin_name, float pin_value); + bool EncodeAnalogIOEventRaw(char *pin_name, float pin_value); + wippersnapper_analogio_AnalogIOEvent *GetAnalogIOEvent(); + +private: + wippersnapper_analogio_AnalogIOAdd _msg_AnalogioAdd; ///< AnalogIOAdd message + wippersnapper_analogio_AnalogIORemove + _msg_AnalogioRemove; ///< AnalogIORemove message + wippersnapper_analogio_AnalogIOEvent + _msg_AnalogioEvent; ///< AnalogIOEvent message +}; +#endif // WS_DIGITALIO_MODEL_H \ No newline at end of file diff --git a/src/components/checkin/model.cpp b/src/components/checkin/model.cpp new file mode 100644 index 000000000..3ddf0d38b --- /dev/null +++ b/src/components/checkin/model.cpp @@ -0,0 +1,190 @@ +/*! + * @file model.cpp + * + * Model for the Wippersnapper checkin proto API. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "model.h" + +/***********************************************************************/ +/*! + @brief CheckinModel constructor +*/ +/***********************************************************************/ +CheckinModel::CheckinModel() { + _CheckinRequest = wippersnapper_checkin_CheckinRequest_init_default; + _CheckinResponse = wippersnapper_checkin_CheckinResponse_init_default; +} + +/***********************************************************************/ +/*! + @brief CheckinModel destructor +*/ +/***********************************************************************/ +CheckinModel::~CheckinModel() { + _CheckinRequest = wippersnapper_checkin_CheckinRequest_init_default; + _CheckinResponse = wippersnapper_checkin_CheckinResponse_init_default; +} + +/***********************************************************************/ +/*! + @brief Fills and creates a CheckinRequest message + @param hardware_uid + Hardware's unique identifier. + @param firmware_version + WipperSnapper firmware version. +*/ +/***********************************************************************/ +void CheckinModel::CreateCheckinRequest(const char *hardware_uid, + const char *firmware_version) { + strcpy(_CheckinRequest.hardware_uid, hardware_uid); + strcpy(_CheckinRequest.firmware_version, firmware_version); +} + +/***********************************************************************/ +/*! + @brief Encodes a CheckinRequest message + @returns True if the message was successfully encoded, + False otherwise. +*/ +/***********************************************************************/ +bool CheckinModel::EncodeCheckinRequest() { + // Obtain size of the CheckinRequest message + size_t CheckinRequestSz; + if (!pb_get_encoded_size(&CheckinRequestSz, + wippersnapper_checkin_CheckinRequest_fields, + &_CheckinRequest)) + return false; + // Create a buffer for holding the CheckinRequest message + uint8_t buf[CheckinRequestSz]; + + // Create a stream that will write to buf + pb_ostream_t msg_stream = pb_ostream_from_buffer(buf, sizeof(buf)); + // Encode the message + return pb_encode(&msg_stream, wippersnapper_checkin_CheckinRequest_fields, + &_CheckinRequest); +} + +/***********************************************************************/ +/*! + @brief Decodes a CheckinResponse message + @param stream + Incoming data stream from buffer. + @returns True if the message was successfully decoded, + False otherwise. +*/ +/***********************************************************************/ +bool CheckinModel::DecodeCheckinResponse(pb_istream_t *stream) { + return pb_decode(stream, wippersnapper_checkin_CheckinResponse_fields, + &_CheckinResponse); +} + +/***********************************************************************/ +/*! + @brief Parses the fields of a CheckinResponse message. +*/ +/***********************************************************************/ +void CheckinModel::ParseCheckinResponse() { + setCheckinResponse(_CheckinResponse.response); + setTotalGPIOPins(_CheckinResponse.total_gpio_pins); + setTotalAnalogPins(_CheckinResponse.total_analog_pins); + setReferenceVoltage(_CheckinResponse.reference_voltage); +} + +/***********************************************************************/ +/*! + @brief Sets the CheckinResponse message's Response field + @param response + CheckinResponse message. +*/ +/***********************************************************************/ +void CheckinModel::setCheckinResponse( + wippersnapper_checkin_CheckinResponse_Response response) { + _response = _CheckinResponse.response; +} + +/***********************************************************************/ +/*! + @brief Gets the CheckinResponse message's Response field + @returns CheckinResponse message. +*/ +/***********************************************************************/ +wippersnapper_checkin_CheckinResponse_Response +CheckinModel::getCheckinResponse() { + return _response; +}; + +/***********************************************************************/ +/*! + @brief Gets the CheckinRequest message + @returns CheckinRequest message. +*/ +/***********************************************************************/ +wippersnapper_checkin_CheckinRequest *CheckinModel::getCheckinRequest() { + return &_CheckinRequest; +} + +/***********************************************************************/ +/*! + @brief Sets the CheckinResponse message's total GPIO pins field + @param total_gpio_pins + Total number of GPIO pins. +*/ +/***********************************************************************/ +void CheckinModel::setTotalGPIOPins(int32_t total_gpio_pins) { + _total_gpio_pins = total_gpio_pins; +} + +/***********************************************************************/ +/*! + @brief Gets the CheckinResponse message's total GPIO pins field + @returns Total number of GPIO pins. +*/ +/***********************************************************************/ +int32_t CheckinModel::getTotalGPIOPins() { return _total_gpio_pins; } + +/***********************************************************************/ +/*! + @brief Sets the CheckinResponse message's total analog pins field + @param total_analog_pins + Total number of analog pins. +*/ +/***********************************************************************/ +void CheckinModel::setTotalAnalogPins(int32_t total_analog_pins) { + _total_analog_pins = total_analog_pins; +} + +/***********************************************************************/ +/*! + @brief Gets the CheckinResponse message's total analog pins field + @returns Total number of analog pins. +*/ +/***********************************************************************/ +int32_t CheckinModel::getTotalAnalogPins() { return _total_analog_pins; } + +/***********************************************************************/ +/*! + @brief Sets the CheckinResponse message's reference voltage field + @param reference_voltage + Reference voltage. +*/ +/***********************************************************************/ +void CheckinModel::setReferenceVoltage(float reference_voltage) { + _reference_voltage = reference_voltage; +} + +/***********************************************************************/ +/*! + @brief Gets the CheckinResponse message's reference voltage field + @returns Reference voltage. +*/ +/***********************************************************************/ +float CheckinModel::getReferenceVoltage() { return _reference_voltage; } \ No newline at end of file diff --git a/src/components/checkin/model.h b/src/components/checkin/model.h new file mode 100644 index 000000000..280d62a6c --- /dev/null +++ b/src/components/checkin/model.h @@ -0,0 +1,55 @@ +/*! + * @file model.h + * + * Model for the Wippersnapper checkin proto API. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_CHECKIN_MODEL_H +#define WS_CHECKIN_MODEL_H +#include "Wippersnapper_V2.h" + +/**************************************************************************/ +/*! + @brief Provides an interface for creating, encoding, and parsing + messages from checkin.proto. +*/ +/**************************************************************************/ +class CheckinModel { +public: + CheckinModel(); + ~CheckinModel(); + // Request Message + void CreateCheckinRequest(const char *hardware_uid, + const char *firmware_version); + bool EncodeCheckinRequest(); + wippersnapper_checkin_CheckinRequest *getCheckinRequest(); + // Response Message + bool DecodeCheckinResponse(pb_istream_t *stream); + void ParseCheckinResponse(); + void + setCheckinResponse(wippersnapper_checkin_CheckinResponse_Response response); + wippersnapper_checkin_CheckinResponse_Response getCheckinResponse(); + void setTotalGPIOPins(int32_t total_gpio_pins); + int32_t getTotalGPIOPins(); + void setTotalAnalogPins(int32_t total_analog_pins); + int32_t getTotalAnalogPins(); + void setReferenceVoltage(float reference_voltage); + float getReferenceVoltage(); + +private: + wippersnapper_checkin_CheckinRequest _CheckinRequest; + wippersnapper_checkin_CheckinResponse _CheckinResponse; + wippersnapper_checkin_CheckinResponse_Response _response; + int32_t _total_gpio_pins; + int32_t _total_analog_pins; + float _reference_voltage; +}; +#endif // WS_CHECKIN_H \ No newline at end of file diff --git a/src/components/digitalIO/Wippersnapper_DigitalGPIO.cpp b/src/components/digitalIO/Wippersnapper_DigitalGPIO.cpp deleted file mode 100644 index f3ab478d9..000000000 --- a/src/components/digitalIO/Wippersnapper_DigitalGPIO.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/*! - * @file Wippersnapper_DigitalGPIO.cpp - * - * This file provides an API for interacting with - * a board's digital GPIO pins. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2020-2021 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ - -#include "Wippersnapper_DigitalGPIO.h" - -/***********************************************************************************/ -/*! - @brief Initializes DigitalGPIO class. - @param totalDigitalInputPins - Total number of digital gpio input-capable pins to allocate. -*/ -/***********************************************************************************/ -Wippersnapper_DigitalGPIO::Wippersnapper_DigitalGPIO( - int32_t totalDigitalInputPins) { - _totalDigitalInputPins = totalDigitalInputPins; - _digital_input_pins = new digitalInputPin[_totalDigitalInputPins]; - // turn input sampling off for all digital pins - for (int i = 0; i < _totalDigitalInputPins; i++) { - _digital_input_pins[i].pinName = -1; - _digital_input_pins[i].period = -1; - _digital_input_pins[i].prvPeriod = 0L; - _digital_input_pins[i].prvPinVal = 0; - } -} - -/*********************************************************/ -/*! - @brief Digital GPIO destructor. -*/ -/*********************************************************/ -Wippersnapper_DigitalGPIO::~Wippersnapper_DigitalGPIO() { - delete _digital_input_pins; -} - -/*******************************************************************************************************************************/ -/*! - @brief Configures a digital pin to behave as an input or an output. - @param direction - The pin's direction. - @param pinName - The pin's name. - @param period - The pin's period, in seconds. - @param pull - The pin's pull mode. -*/ -/*******************************************************************************************************************************/ -void Wippersnapper_DigitalGPIO::initDigitalPin( - wippersnapper_pin_v1_ConfigurePinRequest_Direction direction, - uint8_t pinName, float period, - wippersnapper_pin_v1_ConfigurePinRequest_Pull pull) { - if (direction == - wippersnapper_pin_v1_ConfigurePinRequest_Direction_DIRECTION_OUTPUT) { - -#ifdef STATUS_LED_PIN - // deinit status led, use it as a dio component instead - if (pinName == STATUS_LED_PIN) - releaseStatusLED(); -#endif - pinMode(pinName, OUTPUT); - - WS_DEBUG_PRINT("Configured digital output pin on D"); - WS_DEBUG_PRINTLN(pinName); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Pin] Configured Digital Output on D%u\n", pinName); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - -// Initialize LOW -#if defined(ARDUINO_ESP8266_ADAFRUIT_HUZZAH) - // The Adafruit Feather ESP8266's built-in LED is reverse wired so setting - // the pin LOW will turn the LED on. - digitalWrite(STATUS_LED_PIN, !0); -#else - pinMode(pinName, OUTPUT); - digitalWrite(pinName, LOW); // initialize LOW -#endif - } else if ( - direction == - wippersnapper_pin_v1_ConfigurePinRequest_Direction_DIRECTION_INPUT) { - WS_DEBUG_PRINT("Configuring digital input pin on D"); - WS_DEBUG_PRINT(pinName); - - if (pull == wippersnapper_pin_v1_ConfigurePinRequest_Pull_PULL_UP) { - WS_DEBUG_PRINTLN("with internal pull-up enabled"); - pinMode(pinName, INPUT_PULLUP); - } else { - pinMode(pinName, INPUT); - WS_DEBUG_PRINT("\n"); - } - - // Period is in seconds, cast it to long and convert it to milliseconds - long periodMs = (long)period * 1000; - WS_DEBUG_PRINT("Interval (ms):"); - WS_DEBUG_PRINTLN(periodMs); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, - "[Pin] Configured Digital Input on D%u, polling every %lu mS\n", - pinName, periodMs); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - // get current time - ulong curTime = millis() - 1; - - // attempt to allocate a pinName within _digital_input_pins[] - for (int i = 0; i < _totalDigitalInputPins; i++) { - if (_digital_input_pins[i].period == -1L) { - _digital_input_pins[i].pinName = pinName; - _digital_input_pins[i].period = periodMs; - _digital_input_pins[i].prvPeriod = curTime - periodMs; - break; - } - } - - } else { - WS_DEBUG_PRINTLN("ERROR: Invalid digital pin direction!"); - } -} - -/********************************************************************************************************************************/ -/*! - @brief Deinitializes a previously configured digital pin. - @param direction - The pin's direction. - @param pinName - The pin's name. -*/ -/********************************************************************************************************************************/ -void Wippersnapper_DigitalGPIO::deinitDigitalPin( - wippersnapper_pin_v1_ConfigurePinRequest_Direction direction, - uint8_t pinName) { - WS_DEBUG_PRINT("Deinitializing digital pin "); - WS_DEBUG_PRINTLN(pinName); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Pin] De-initialized D%u\n", pinName); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - if (direction == - wippersnapper_pin_v1_ConfigurePinRequest_Direction_DIRECTION_INPUT) { - // de-allocate the pin within digital_input_pins[] - for (int i = 0; i < _totalDigitalInputPins; i++) { - if (_digital_input_pins[i].pinName == pinName) { - _digital_input_pins[i].pinName = -1; - _digital_input_pins[i].period = -1; - _digital_input_pins[i].prvPeriod = 0L; - _digital_input_pins[i].prvPinVal = 0; - break; - } - } - } - char cstr[16]; - itoa(pinName, cstr, 10); - pinMode(pinName, INPUT); // hi-z - -// if prv. in-use by DIO, release pin back to application -#ifdef STATUS_LED_PIN - if (pinName == STATUS_LED_PIN) - initStatusLED(); -#endif -} - -/********************************************************************/ -/*! - @brief High-level digitalRead service impl. which performs a - digitalRead. - @param pinName - The pin's name - @returns The pin's value. -*/ -/********************************************************************/ -int Wippersnapper_DigitalGPIO::digitalReadSvc(int pinName) { - // Service using arduino `digitalRead` - int pinVal = digitalRead(pinName); - return pinVal; -} - -/*******************************************************************************/ -/*! - @brief Writes a value to a pin. - @param pinName - The pin's name. - @param pinValue - The pin's value. -*/ -/*******************************************************************************/ -void Wippersnapper_DigitalGPIO::digitalWriteSvc(uint8_t pinName, int pinValue) { - WS_DEBUG_PRINT("Digital Pin Event: Set "); - WS_DEBUG_PRINT(pinName); - WS_DEBUG_PRINT(" to "); - WS_DEBUG_PRINTLN(pinValue); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Pin] Writing %d to D%u\n", pinValue, pinName); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - -// Write to the GPIO pin -#if defined(ARDUINO_ESP8266_ADAFRUIT_HUZZAH) - // The Adafruit Feather ESP8266's built-in LED is reverse wired so setting the - // pin LOW will turn the LED on. - if (pinName == 0) - digitalWrite(pinName, !pinValue); - else - digitalWrite(pinName, pinValue); -#else - digitalWrite(pinName, pinValue); -#endif -} - -/**********************************************************/ -/*! - @brief Iterates thru digital inputs, checks if they - should send data to the broker. -*/ -/**********************************************************/ -void Wippersnapper_DigitalGPIO::processDigitalInputs() { - long curTime = millis(); - // Process digital digital pins - for (int i = 0; i < _totalDigitalInputPins; i++) { - if (_digital_input_pins[i].period > - -1L) { // validate if digital pin is enabled - // Check if digital pin executes on a time period - if (curTime - _digital_input_pins[i].prvPeriod > - _digital_input_pins[i].period && - _digital_input_pins[i].period != 0L) { - WS_DEBUG_PRINT("Executing periodic event on D"); - WS_DEBUG_PRINTLN(_digital_input_pins[i].pinName); - // read the pin - int pinVal = digitalReadSvc(_digital_input_pins[i].pinName); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Pin] Read D%u: %d\n", - _digital_input_pins[i].pinName, pinVal); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - // Create new signal message - wippersnapper_signal_v1_CreateSignalRequest _outgoingSignalMsg = - wippersnapper_signal_v1_CreateSignalRequest_init_zero; - - WS_DEBUG_PRINT("Encoding...") - // Create and encode a pinEvent message - if (!WS.encodePinEvent(&_outgoingSignalMsg, - _digital_input_pins[i].pinName, pinVal)) { - WS_DEBUG_PRINTLN("ERROR: Unable to encode pinEvent"); - break; - } - WS_DEBUG_PRINTLN("Encoded!") - - // Obtain size and only write out buffer to end - size_t msgSz; - pb_get_encoded_size(&msgSz, - wippersnapper_signal_v1_CreateSignalRequest_fields, - &_outgoingSignalMsg); - - WS_DEBUG_PRINT("Publishing pinEvent..."); - WS.publish(WS._topic_signal_device, WS._buffer_outgoing, msgSz, 1); - WS_DEBUG_PRINTLN("Published!"); - - // reset the digital pin - _digital_input_pins[i].prvPeriod = curTime; - } else if (_digital_input_pins[i].period == 0L) { - // read pin - int pinVal = digitalReadSvc(_digital_input_pins[i].pinName); - // only send on-change - if (pinVal != _digital_input_pins[i].prvPinVal) { - WS_DEBUG_PRINT("Executing state-based event on D"); - WS_DEBUG_PRINTLN(_digital_input_pins[i].pinName); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Pin] Read D%u: %d\n", - _digital_input_pins[i].pinName, pinVal); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - // Create new signal message - wippersnapper_signal_v1_CreateSignalRequest _outgoingSignalMsg = - wippersnapper_signal_v1_CreateSignalRequest_init_zero; - - WS_DEBUG_PRINT("Encoding pinEvent..."); - // Create and encode a pinEvent message - if (!WS.encodePinEvent(&_outgoingSignalMsg, - _digital_input_pins[i].pinName, pinVal)) { - WS_DEBUG_PRINTLN("ERROR: Unable to encode pinEvent"); - break; - } - WS_DEBUG_PRINTLN("Encoded!"); - - // Obtain size and only write out buffer to end - size_t msgSz; - pb_get_encoded_size( - &msgSz, wippersnapper_signal_v1_CreateSignalRequest_fields, - &_outgoingSignalMsg); - WS_DEBUG_PRINT("Publishing pinEvent..."); - WS.publish(WS._topic_signal_device, WS._buffer_outgoing, msgSz, 1); - WS_DEBUG_PRINTLN("Published!"); - - // set the pin value in the digital pin object for comparison on next - // run - _digital_input_pins[i].prvPinVal = pinVal; - - // reset the digital pin - _digital_input_pins[i].prvPeriod = curTime; - } - } - } - } -} \ No newline at end of file diff --git a/src/components/digitalIO/Wippersnapper_DigitalGPIO.h b/src/components/digitalIO/Wippersnapper_DigitalGPIO.h deleted file mode 100644 index 960687ee5..000000000 --- a/src/components/digitalIO/Wippersnapper_DigitalGPIO.h +++ /dev/null @@ -1,62 +0,0 @@ -/*! - * @file Wippersnapper_DigitalGPIO.h - * - * This file provides digital GPIO control and access. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2020-2021 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ - -#ifndef WIPPERSNAPPER_DIGITALGPIO_H -#define WIPPERSNAPPER_DIGITALGPIO_H - -#include "Wippersnapper.h" - -/** Holds data about a digital input pin */ -struct digitalInputPin { - uint8_t pinName; ///< Pin name - long period; ///< Timer interval, in millis, -1 if disabled. - long prvPeriod; ///< When timer was previously serviced, in millis - int prvPinVal; ///< Previous pin value -}; - -// forward decl. -class Wippersnapper; - -/**************************************************************************/ -/*! - @brief Class that provides functions for reading and interacting with - digital inputs and outputs. -*/ -/**************************************************************************/ -class Wippersnapper_DigitalGPIO { -public: - Wippersnapper_DigitalGPIO(int32_t totalDigitalInputPins); - ~Wippersnapper_DigitalGPIO(); - - void - initDigitalPin(wippersnapper_pin_v1_ConfigurePinRequest_Direction direction, - uint8_t pinName, float period, - wippersnapper_pin_v1_ConfigurePinRequest_Pull pull); - void - deinitDigitalPin(wippersnapper_pin_v1_ConfigurePinRequest_Direction direction, - uint8_t pinName); - - int digitalReadSvc(int pinName); - void digitalWriteSvc(uint8_t pinName, int pinValue); - void processDigitalInputs(); - - digitalInputPin *_digital_input_pins; /*!< Array of gpio pin objects */ -private: - int32_t - _totalDigitalInputPins; /*!< Total number of digital-input capable pins */ -}; -extern Wippersnapper WS; - -#endif // WIPPERSNAPPER_DIGITALGPIO_H \ No newline at end of file diff --git a/src/components/digitalIO/controller.cpp b/src/components/digitalIO/controller.cpp new file mode 100644 index 000000000..1af117aaa --- /dev/null +++ b/src/components/digitalIO/controller.cpp @@ -0,0 +1,390 @@ +/*! + * @file controller.cpp + * + * Controller for the digitalio.proto API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "controller.h" + +/***********************************************************************/ +/*! + @brief DigitalIOController constructor +*/ +/***********************************************************************/ +DigitalIOController::DigitalIOController() { + _dio_model = new DigitalIOModel(); + _dio_hardware = new DigitalIOHardware(); + // Set the default maximum number of digital pins to 0 + // NOTE: This will be set during runtime by the CheckinResponse message + SetMaxDigitalPins(0); +} + +/***********************************************************************/ +/*! + @brief DigitalIOController destructor +*/ +/***********************************************************************/ +DigitalIOController::~DigitalIOController() { + delete _dio_model; + delete _dio_hardware; +} + +/***********************************************************************/ +/*! + @brief Set the maximum number of digital pins + @param max_digital_pins + The maximum number of digital pins +*/ +/***********************************************************************/ +void DigitalIOController::SetMaxDigitalPins(uint8_t max_digital_pins) { + _max_digitalio_pins = max_digital_pins; +} + +/***********************************************************************/ +/*! + @brief Add a new digital pin to the controller + @param stream + The nanopb input stream. + @return True if the digital pin was successfully added. +*/ +/***********************************************************************/ +bool DigitalIOController::Handle_DigitalIO_Add(pb_istream_t *stream) { + // Early-out if we have reached the maximum number of digital pins + if (_digitalio_pins.size() >= _max_digitalio_pins) { + WS_DEBUG_PRINTLN("[digitalio] ERROR: Can not add new pin, all pins have " + "already been allocated!"); + return false; + } + + // Attempt to decode the DigitalIOAdd message and parse it into the model + if (!_dio_model->DecodeDigitalIOAdd(stream)) { + WS_DEBUG_PRINTLN( + "[digitalio] ERROR: Unable to decode DigitalIOAdd message!"); + return false; + } + + // Strip the D/A prefix off the pin name and convert to a uint8_t pin number + int pin_name = atoi(_dio_model->GetDigitalIOAddMsg()->pin_name + 1); + + // Check if the provided pin is also the status LED pin + if (_dio_hardware->IsStatusLEDPin(pin_name)) + releaseStatusLED(); + + // Deinit the pin if it's already in use + if (GetPinIdx(pin_name) != -1) + _dio_hardware->deinit(pin_name); + + // Attempt to configure the pin + if (!_dio_hardware->ConfigurePin( + pin_name, _dio_model->GetDigitalIOAddMsg()->gpio_direction)) { + WS_DEBUG_PRINTLN( + "[digitalio] ERROR: Pin provided an invalid protobuf direction!"); + return false; + } + + ulong period = _dio_model->GetDigitalIOAddMsg()->period; + // Create the digital pin and add it to the vector + DigitalIOPin new_pin = { + .pin_name = pin_name, + .pin_direction = _dio_model->GetDigitalIOAddMsg()->gpio_direction, + .sample_mode = _dio_model->GetDigitalIOAddMsg()->sample_mode, + .pin_value = _dio_model->GetDigitalIOAddMsg()->value, + .pin_period = period * 1000, + .prv_pin_time = (millis() - 1) - period}; + _digitalio_pins.push_back(new_pin); + + // Print out the pin's details + WS_DEBUG_PRINTLN("[digitalio] Added new pin:"); + WS_DEBUG_PRINT("Pin Name: "); + WS_DEBUG_PRINTLN(new_pin.pin_name); + WS_DEBUG_PRINT("Period: "); + WS_DEBUG_PRINTLN(new_pin.pin_period); + WS_DEBUG_PRINT("Sample Mode: "); + WS_DEBUG_PRINTLN(new_pin.sample_mode); + WS_DEBUG_PRINT("Direction: "); + WS_DEBUG_PRINTLN(new_pin.pin_direction); + + return true; +} + +/***********************************************************************/ +/*! + @brief Removes a digital pin from the controller, if it exists + @param stream + The nanopb input stream. + @return True if the digital pin was successfully removed. +*/ +/***********************************************************************/ +bool DigitalIOController::Handle_DigitalIO_Remove(pb_istream_t *stream) { + // Attempt to decode the DigitalIORemove message + if (!_dio_model->DecodeDigitalIORemove(stream)) { + WS_DEBUG_PRINTLN( + "[digitalio] ERROR: Unable to decode DigitalIORemove message!"); + return false; + } + + // Get the pin's name + int pin_name = atoi(_dio_model->GetDigitalIOAddMsg()->pin_name + 1); + + // Bail out if the pin does not exist within controller + if (GetPinIdx(pin_name) == -1) { + WS_DEBUG_PRINTLN( + "[digitalio] ERROR: Unable to find output pin on the controller!"); + return false; + } + + // Deinitialize the pin + _dio_hardware->deinit(pin_name); + return true; +} + +/***********************************************************************/ +/*! + @brief Get the index of a digital output pin + @param pin_name + The pin's name. + @return The index of the digital output pin. +*/ +/***********************************************************************/ +int DigitalIOController::GetPinIdx(uint8_t pin_name) { + for (int i = 0; i < _digitalio_pins.size(); i++) { + if (_digitalio_pins[i].pin_name == pin_name) { + return i; + } + } + return -1; // Pin not found +} + +/***********************************************************************/ +/*! + @brief Write a digital pin + @param stream + The nanopb input stream. + @return True if the digital pin was successfully written. +*/ +/***********************************************************************/ +bool DigitalIOController::Handle_DigitalIO_Write(pb_istream_t *stream) { + // Attempt to decode the DigitalIOWrite message + if (!_dio_model->DecodeDigitalIOWrite(stream)) { + WS_DEBUG_PRINTLN("[digitalio] ERROR: Unable to decode Write message!"); + return false; + } + + // Get the digital pin + int pin_idx = + GetPinIdx(atoi(_dio_model->GetDigitalIOWriteMsg()->pin_name + 1)); + // Check if the pin was found and is a valid digital output pin + if (pin_idx == -1) { + WS_DEBUG_PRINTLN( + "[digitalio] ERROR: Unable to find the requested output pin!"); + return false; + } + + // Ensure we got the correct value type + if (!_dio_model->GetDigitalIOWriteMsg()->value.which_value == + wippersnapper_sensor_SensorEvent_bool_value_tag) { + WS_DEBUG_PRINTLN("[digitalio] ERROR: controller got invalid value type!"); + return false; + } + + WS_DEBUG_PRINT("[digitalio] Writing value: "); + WS_DEBUG_PRINTLN(_dio_model->GetDigitalIOWriteMsg()->value.value.bool_value); + WS_DEBUG_PRINT("on Pin: "); + WS_DEBUG_PRINTLN(_digitalio_pins[pin_idx].pin_name); + + // Is the pin already set to this value? If so, we don't need to write it + // again + if (_digitalio_pins[pin_idx].pin_value == + _dio_model->GetDigitalIOWriteMsg()->value.value.bool_value) + return true; + + // Call hardware to write the value type + _dio_hardware->SetValue( + _digitalio_pins[pin_idx].pin_name, + _dio_model->GetDigitalIOWriteMsg()->value.value.bool_value); + + // Update the pin's value + _digitalio_pins[pin_idx].pin_value = + _dio_model->GetDigitalIOWriteMsg()->value.value.bool_value; + + return true; +} + +/***********************************************************************/ +/*! + @brief Check if a pin's timer has expired + @param pin + The pin to check. + @param cur_time + The current time. + @return True if the pin's timer has expired. +*/ +/***********************************************************************/ +bool DigitalIOController::IsPinTimerExpired(DigitalIOPin *pin, ulong cur_time) { + return cur_time - pin->prv_pin_time > pin->pin_period; +} + +/***********************************************************************/ +/*! + @brief Print a pin's ID and value + @param pin + The specified pin. +*/ +/***********************************************************************/ +void DigitalIOController::PrintPinValue(DigitalIOPin *pin) { + if (WsV2._sdCardV2->isModeOffline()) + return; + WS_DEBUG_PRINT("[digitalio] DIO Pin D"); + WS_DEBUG_PRINT(pin->pin_name); + WS_DEBUG_PRINT(" | value: "); + WS_DEBUG_PRINTLN(pin->prv_pin_value); +} + +/***********************************************************************/ +/*! + @brief Check if a pin's timer has expired + @param pin + The pin to check. + @return True if the pin's timer has expired. +*/ +/***********************************************************************/ +bool DigitalIOController::CheckTimerPin(DigitalIOPin *pin) { + ulong cur_time = millis(); + // Bail out if the pin's timer has not expired + if (!IsPinTimerExpired(pin, cur_time)) + return false; + + // Fill in the pin's current time and value + pin->prv_pin_time = cur_time; + pin->pin_value = _dio_hardware->GetValue(pin->pin_name); + + PrintPinValue(pin); + return true; +} + +/***********************************************************************/ +/*! + @brief Check if a pin's value has changed + @param pin + The pin to check. + @return True if the pin's value has changed. +*/ +/***********************************************************************/ +bool DigitalIOController::CheckEventPin(DigitalIOPin *pin) { + // Get the pin's current value + pin->pin_value = _dio_hardware->GetValue(pin->pin_name); + // Bail out if the pin value hasn't changed + if (pin->pin_value == pin->prv_pin_value) + return false; + // Update the pin's previous value to the current value + pin->prv_pin_value = pin->pin_value; + + PrintPinValue(pin); + return true; +} + +/***********************************************************************/ +/*! + @brief Encode and publish a pin event + @param pin_name + The pin's name. + @param pin_value + The pin's value. + @return True if the pin event was successfully encoded and published. +*/ +/***********************************************************************/ +bool DigitalIOController::EncodePublishPinEvent(uint8_t pin_name, + bool pin_value) { + // Prefix pin_name with "D" to match the expected pin name format + char c_pin_name[12]; + sprintf(c_pin_name, "D%d", pin_name); + + // If we are in ONLINE mode, publish the event to the broker + if (!WsV2._sdCardV2->isModeOffline()) { + WS_DEBUG_PRINT( + "[digitalio] Publishing DigitalIOEvent message to broker for pin: "); + WS_DEBUG_PRINTLN(c_pin_name); + // Encode the DigitalIOEvent message + if (!_dio_model->EncodeDigitalIOEvent(c_pin_name, pin_value)) { + WS_DEBUG_PRINTLN("ERROR: Unable to encode DigitalIOEvent message!"); + return false; + } + + // Publish the DigitalIOEvent message to the broker + if (!WsV2.PublishSignal( + wippersnapper_signal_DeviceToBroker_digitalio_event_tag, + _dio_model->GetDigitalIOEventMsg())) { + WS_DEBUG_PRINTLN("[digitalio] ERROR: Unable to publish event message, " + "moving onto the next pin!"); + return false; + } + WS_DEBUG_PRINTLN("[digitalio] Published DigitalIOEvent to broker!") + } else { + // let's log the event to the SD card + if (!WsV2._sdCardV2->LogGPIOSensorEventToSD( + pin_name, pin_value, + wippersnapper_sensor_SensorType_SENSOR_TYPE_BOOLEAN)) + return false; + } + + return true; +} + +/***********************************************************************/ +/*! + @brief Iterates through the digital pins and updates their values + (if necessary) and publishes the event to the broker. +*/ +/***********************************************************************/ +void DigitalIOController::Update() { + // Bail out if we have no digital pins to poll + if (_digitalio_pins.empty()) + return; + + for (int i = 0; i < _digitalio_pins.size(); i++) { + // Create a pin object for this iteration + DigitalIOPin &pin = _digitalio_pins[i]; + // Skip if the pin is an output + if (pin.pin_direction == + wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_OUTPUT) + continue; + + if (pin.sample_mode == + wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_EVENT) { + // Check if the pin value has changed + if (!CheckEventPin(&pin)) + continue; // No change in pin value detected, move onto the next pin + + // Encode and publish the event + if (!EncodePublishPinEvent(pin.pin_name, pin.pin_value)) { + WS_DEBUG_PRINTLN("[digitalio] ERROR: Unable to record pin value!"); + continue; + } + } else if ( + pin.sample_mode == + wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_TIMER) { + // Check if the timer has expired + if (!CheckTimerPin(&pin)) + continue; // Timer has not expired yet, move onto the next pin + + // Encode and publish the event + if (!EncodePublishPinEvent(pin.pin_name, pin.pin_value)) { + WS_DEBUG_PRINTLN("[digitalio] ERROR: Unable to record pin value!"); + continue; + } + } else { + // Invalid sample mode + WS_DEBUG_PRINT("[digitalio] ERROR: DigitalIO Pin "); + WS_DEBUG_PRINT(pin.pin_name); + WS_DEBUG_PRINTLN(" contains an invalid sample mode!"); + } + } +} \ No newline at end of file diff --git a/src/components/digitalIO/controller.h b/src/components/digitalIO/controller.h new file mode 100644 index 000000000..e1de9666e --- /dev/null +++ b/src/components/digitalIO/controller.h @@ -0,0 +1,76 @@ +/*! + * @file controller.h + * + * Controller for the digitalio API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_DIGITALIO_CONTROLLER_H +#define WS_DIGITALIO_CONTROLLER_H +#include "Wippersnapper_V2.h" +#include "hardware.h" +#include "model.h" + +class Wippersnapper_V2; + +/** + * @struct DigitalIOPin + * @brief This struct represents a digital I/O pin. + */ +struct DigitalIOPin { + uint8_t pin_name; ///< The pin's name. + wippersnapper_digitalio_DigitalIODirection + pin_direction; ///< The pin's direction. + wippersnapper_digitalio_DigitalIOSampleMode + sample_mode; ///< The pin's sample mode. + bool pin_value; ///< The pin's value. + bool prv_pin_value; ///< The pin's previous value. + ulong pin_period; ///< The pin's period. + ulong prv_pin_time; ///< The pin's previous time. +}; + +class DigitalIOModel; // Forward declaration +class DigitalIOHardware; // Forward declaration + +/**************************************************************************/ +/*! + @brief Routes messages using the digitalio.proto API to the + appropriate hardware and model classes, controls and tracks + the state of the hardware's digital I/O pins. +*/ +/**************************************************************************/ +class DigitalIOController { +public: + DigitalIOController(); + ~DigitalIOController(); + // Called by the cbDecodeBrokerToDevice router function + bool Handle_DigitalIO_Add(pb_istream_t *stream); + bool Handle_DigitalIO_Write(pb_istream_t *stream); + bool Handle_DigitalIO_Remove(pb_istream_t *stream); + + void Update(); + + bool EncodePublishPinEvent(uint8_t pin_name, bool pin_value); + bool CheckEventPin(DigitalIOPin *pin); + bool CheckTimerPin(DigitalIOPin *pin); + bool IsPinTimerExpired(DigitalIOPin *pin, ulong cur_time); + + void PrintPinValue(DigitalIOPin *pin); + void SetMaxDigitalPins(uint8_t max_digital_pins); + int GetPinIdx(uint8_t pin_name); + +private: + std::vector _digitalio_pins; + uint8_t _max_digitalio_pins; + DigitalIOModel *_dio_model; + DigitalIOHardware *_dio_hardware; +}; +extern Wippersnapper_V2 WsV2; ///< Wippersnapper V2 instance +#endif // WS_DIGITALIO_CONTROLLER_H \ No newline at end of file diff --git a/src/components/digitalIO/hardware.cpp b/src/components/digitalIO/hardware.cpp new file mode 100644 index 000000000..f6503e1a8 --- /dev/null +++ b/src/components/digitalIO/hardware.cpp @@ -0,0 +1,127 @@ +/*! + * @file hardware.cpp + * + * Hardware driver for the digitalio.proto API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "hardware.h" + +/***********************************************************************/ +/*! + @brief DigitalIOHardware constructor +*/ +/***********************************************************************/ +DigitalIOHardware::DigitalIOHardware() {} + +/***********************************************************************/ +/*! + @brief DigitalIOHardware destructor +*/ +/***********************************************************************/ +DigitalIOHardware::~DigitalIOHardware() {} + +/***********************************************************************/ +/*! + @brief Configures a digital pin. + @param name + The pin's name. + @param direction + The pin's direction. + @return True if the pin was successfully configured. False otherwise. +*/ +/***********************************************************************/ +bool DigitalIOHardware::ConfigurePin( + uint8_t name, wippersnapper_digitalio_DigitalIODirection direction) { + // Configure an output pin + if (direction == + wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_OUTPUT) { + // Set pin mode to OUTPUT + pinMode(name, OUTPUT); +// Initialize pin value to LOW +#if defined(ARDUINO_ESP8266_ADAFRUIT_HUZZAH) + // The Adafruit Feather ESP8266's built-in LED is reverse wired so setting + // the pin LOW will turn the LED on. + digitalWrite(name, !0); +#else + pinMode(name, OUTPUT); + digitalWrite(name, LOW); // initialize LOW +#endif + } else if ( + direction == + wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_INPUT) { + pinMode(name, INPUT); + } else if ( + direction == + wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_INPUT_PULL_UP) { + pinMode(name, INPUT_PULLUP); + } else { + return false; // Invalid pin configuration + } + return true; +} + +/***********************************************************************/ +/*! + @brief Deinitializes a digital pin. + @param pin_name + The digital pin to deinitialize. +*/ +/***********************************************************************/ +void DigitalIOHardware::deinit(uint8_t pin_name) { + // Turn off pin output and reset mode to hi-z floating state + digitalWrite(pin_name, LOW); + pinMode(pin_name, INPUT); + // Prior to using this pin as a DIO, + // was this a status LED pin? + if (IsStatusLEDPin(pin_name)) { + initStatusLED(); // it was! re-init status led + } +} + +/***********************************************************************/ +/*! + @brief Sets a digital pin's value. + @param pin_name + The pin's name. + @param pin_value + The pin's value. +*/ +/***********************************************************************/ +void DigitalIOHardware::SetValue(uint8_t pin_name, bool pin_value) { + digitalWrite(pin_name, pin_value ? HIGH : LOW); +} + +/***********************************************************************/ +/*! + @brief Gets a digital pin's value. + @param pin_name + The pin's name. + @return The pin's value. +*/ +/***********************************************************************/ +bool DigitalIOHardware::GetValue(uint8_t pin_name) { + return digitalRead(pin_name); +} + +/***********************************************************************/ +/*! + @brief Checks if a pin is the status LED pin. + @param pin_name + The pin's name. + @return True if the pin is the status LED pin. +*/ +/***********************************************************************/ +bool DigitalIOHardware::IsStatusLEDPin(uint8_t pin_name) { +#ifdef STATUS_LED_PIN + return pin_name == STATUS_LED_PIN; +#endif + return false; +} \ No newline at end of file diff --git a/src/components/digitalIO/hardware.h b/src/components/digitalIO/hardware.h new file mode 100644 index 000000000..e471c6b7d --- /dev/null +++ b/src/components/digitalIO/hardware.h @@ -0,0 +1,37 @@ +/*! + * @file model.h + * + * Model for the digitalio.proto message. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_DIGITALIO_HARDWARE_H +#define WS_DIGITALIO_HARDWARE_H +#include "Wippersnapper_V2.h" + +/**************************************************************************/ +/*! + @brief Interface for interacting with hardware's digital I/O pin API. +*/ +/**************************************************************************/ +class DigitalIOHardware { +public: + DigitalIOHardware(); + ~DigitalIOHardware(); + bool ConfigurePin(uint8_t name, + wippersnapper_digitalio_DigitalIODirection direction); + void SetValue(uint8_t pin_name, bool pin_value); + bool GetValue(uint8_t pin_name); + void deinit(uint8_t pin_name); + bool IsStatusLEDPin(uint8_t pin_name); + +private: +}; +#endif // WS_DIGITALIO_HARDWARE_H \ No newline at end of file diff --git a/src/components/digitalIO/model.cpp b/src/components/digitalIO/model.cpp new file mode 100644 index 000000000..6643b1c49 --- /dev/null +++ b/src/components/digitalIO/model.cpp @@ -0,0 +1,159 @@ +/*! + * @file model.cpp + * + * Model for the digitalio.proto message. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "model.h" + +/***********************************************************************/ +/*! + @brief DigitalIOModel constructor +*/ +/***********************************************************************/ +DigitalIOModel::DigitalIOModel() { + _msg_dio_add = wippersnapper_digitalio_DigitalIOAdd_init_default; + _msg_dio_remove = wippersnapper_digitalio_DigitalIORemove_init_default; + _msg_dio_event = wippersnapper_digitalio_DigitalIOEvent_init_default; + _msg_dio_write = wippersnapper_digitalio_DigitalIOWrite_init_default; +} + +/***********************************************************************/ +/*! + @brief DigitalIOModel destructor +*/ +/***********************************************************************/ +DigitalIOModel::~DigitalIOModel() {} + +/***********************************************************************/ +/*! + @brief Parses a DigitalIOAdd message. + @return DigitalIOAdd message object. +*/ +/***********************************************************************/ +wippersnapper_digitalio_DigitalIOAdd *DigitalIOModel::GetDigitalIOAddMsg() { + return &_msg_dio_add; +} + +/***********************************************************************/ +/*! + @brief Parses a DigitalIORemove message. + @param stream + The nanopb input stream. + @return DigitalIORemove message object. +*/ +/***********************************************************************/ +bool DigitalIOModel::DecodeDigitalIORemove(pb_istream_t *stream) { + // Zero-out the DigitalIORemove message struct. to ensure we don't have any + // old data + _msg_dio_remove = wippersnapper_digitalio_DigitalIORemove_init_default; + + // Decode the stream into a DigitalIORemove message + return pb_decode(stream, wippersnapper_digitalio_DigitalIORemove_fields, + &_msg_dio_remove); +} + +/***********************************************************************/ +/*! + @brief Gets a DigitalIOWrite message. + @return DigitalIOWrite message object. +*/ +/***********************************************************************/ +wippersnapper_digitalio_DigitalIOWrite *DigitalIOModel::GetDigitalIOWriteMsg() { + return &_msg_dio_write; +} + +/***********************************************************************/ +/*! + @brief Gets a DigitalIOEvent message. + @return DigitalIOEvent message object. +*/ +/***********************************************************************/ +wippersnapper_digitalio_DigitalIOEvent *DigitalIOModel::GetDigitalIOEventMsg() { + return &_msg_dio_event; +} + +/***********************************************************************/ +/*! + @brief Decodes a DigitalIOAdd message into the _msg_dio_add object + from a nanopb stream. + @param stream + The nanopb input stream. + @return True if the DigitalIOAdd message was successfully decoded. +*/ +/***********************************************************************/ +bool DigitalIOModel::DecodeDigitalIOAdd(pb_istream_t *stream) { + // Zero-out the DigitalIOAdd message struct. to ensure we don't have any old + // data + _msg_dio_add = wippersnapper_digitalio_DigitalIOAdd_init_default; + + // Decode the stream into a DigitalIOAdd message + return pb_decode(stream, wippersnapper_digitalio_DigitalIOAdd_fields, + &_msg_dio_add); +} + +/***********************************************************************/ +/*! + @brief Decodes a DigitalIOWrite message into the _msg_dio_write + object from a nanopb stream. + @param stream + The nanopb input stream. + @return True if the DigitalIOWrite message was successfully decoded. +*/ +/***********************************************************************/ +bool DigitalIOModel::DecodeDigitalIOWrite(pb_istream_t *stream) { + // Zero-out the DigitalIOWrite message struct. to ensure we don't have any old + // data + _msg_dio_write = wippersnapper_digitalio_DigitalIOWrite_init_default; + // Decode the stream into a DigitalIOWrite message + return pb_decode(stream, wippersnapper_digitalio_DigitalIOWrite_fields, + &_msg_dio_write); +} + +/***********************************************************************/ +/*! + @brief Encodes a DigitalIOEvent message into the + _msg_dio_event object. + @param pin_name + The pin's name. + @param value + The pin's value. + @return True if the DigitalIOEvent message was successfully encoded. + False if encoding resulted in a failure. +*/ +/***********************************************************************/ +bool DigitalIOModel::EncodeDigitalIOEvent(char *pin_name, bool value) { + // Initialize the DigitalIOEvent + _msg_dio_event = wippersnapper_digitalio_DigitalIOEvent_init_default; + // Fill the DigitalIOEvent + strncpy(_msg_dio_event.pin_name, pin_name, sizeof(_msg_dio_event.pin_name)); + _msg_dio_event.has_value = true; + // Fill the DigitalIOEvent's SensorEvent sub-message + _msg_dio_event.value.type = + wippersnapper_sensor_SensorType_SENSOR_TYPE_BOOLEAN; + _msg_dio_event.value.which_value = + wippersnapper_sensor_SensorEvent_bool_value_tag; + _msg_dio_event.value.value.bool_value = value; + + // Encode the DigitalIOEvent message + size_t sz_dio_event_msg; + if (!pb_get_encoded_size(&sz_dio_event_msg, + wippersnapper_digitalio_DigitalIOEvent_fields, + &_msg_dio_event)) + return false; + + // Create an output stream + uint8_t buf[sz_dio_event_msg]; + pb_ostream_t msg_stream = pb_ostream_from_buffer(buf, sizeof(buf)); + // Encode the message + return pb_encode(&msg_stream, wippersnapper_digitalio_DigitalIOEvent_fields, + &_msg_dio_event); +} \ No newline at end of file diff --git a/src/components/digitalIO/model.h b/src/components/digitalIO/model.h new file mode 100644 index 000000000..d0840efd0 --- /dev/null +++ b/src/components/digitalIO/model.h @@ -0,0 +1,51 @@ +/*! + * @file model.h + * + * Model for the digitalio.proto message. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_DIGITALIO_MODEL_H +#define WS_DIGITALIO_MODEL_H +#include "Wippersnapper_V2.h" + +/**************************************************************************/ +/*! + @brief Provides an interface for creating, encoding, and parsing + messages from digitalio.proto. +*/ +/**************************************************************************/ +class DigitalIOModel { +public: + DigitalIOModel(); + ~DigitalIOModel(); + // DigitalIOAdd + bool DecodeDigitalIOAdd(pb_istream_t *stream); + wippersnapper_digitalio_DigitalIOAdd *GetDigitalIOAddMsg(); + // DigitalIORemove + bool DecodeDigitalIORemove(pb_istream_t *stream); + // DigitalIOWrite + bool DecodeDigitalIOWrite(pb_istream_t *stream); + wippersnapper_digitalio_DigitalIOWrite *GetDigitalIOWriteMsg(); + // DigitalIOEvent + bool EncodeDigitalIOEvent(char *pin_name, bool value); + wippersnapper_digitalio_DigitalIOEvent *GetDigitalIOEventMsg(); + +private: + wippersnapper_digitalio_DigitalIOAdd + _msg_dio_add; ///< DigitalIOAdd message object + wippersnapper_digitalio_DigitalIORemove + _msg_dio_remove; ///< DigitalIORemove message object + wippersnapper_digitalio_DigitalIOEvent + _msg_dio_event; ///< DigitalIOEvent message object + wippersnapper_digitalio_DigitalIOWrite + _msg_dio_write; ///< DigitalIOWrite message object +}; +#endif // WS_DIGITALIO_MODEL_H \ No newline at end of file diff --git a/src/components/ds18x20/controller.cpp b/src/components/ds18x20/controller.cpp new file mode 100644 index 000000000..7f46811f1 --- /dev/null +++ b/src/components/ds18x20/controller.cpp @@ -0,0 +1,286 @@ +/*! + * @file controller.cpp + * + * Controller for the ds18x20.proto API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "controller.h" + +/***********************************************************************/ +/*! + @brief DS18X20Controller constructor +*/ +/***********************************************************************/ +DS18X20Controller::DS18X20Controller() { _DS18X20_model = new DS18X20Model(); } + +/***********************************************************************/ +/*! + @brief DS18X20Controller destructor +*/ +/***********************************************************************/ +DS18X20Controller::~DS18X20Controller() { delete _DS18X20_model; } + +/***********************************************************************/ +/*! + @brief Handles a Ds18x20Add message from the broker. Attempts to + initialize a OneWire bus on the requested pin, attempts to + initialize a DSTherm driver on the OneWire bus, adds the + OneWire bus to the controller, and publishes a Ds18x20Added + message to the broker indicating the result of this function. + @param stream + The nanopb input stream. + @return True if the sensor was successfully initialized, + added to the controller, and a response was succesfully + published to the broker. False otherwise. +*/ +/***********************************************************************/ +bool DS18X20Controller::Handle_Ds18x20Add(pb_istream_t *stream) { + // Attempt to decode the incoming message into a Ds18x20Add message + if (!_DS18X20_model->DecodeDS18x20Add(stream)) { + WS_DEBUG_PRINTLN("ERROR | DS18x20: Unable to decode Ds18x20Add message"); + return false; + } + + // If we receive no sensor types to configure, bail out + if (_DS18X20_model->GetDS18x20AddMsg()->sensor_types_count == 0) { + WS_DEBUG_PRINTLN("ERROR | DS18x20: No ds18x sensor types provided!"); + return false; + } + + // Extract the OneWire pin from the message + uint8_t pin_name = atoi(_DS18X20_model->GetDS18x20AddMsg()->onewire_pin + 1); + + // Initialize the DS18X20Hardware object + auto new_dsx_driver = std::make_unique(pin_name); + // Attempt to get the sensor's ID on the OneWire bus to show it's been init'd + bool is_initialized = new_dsx_driver->GetSensor(); + + if (is_initialized) { + WS_DEBUG_PRINTLN("Sensor found on OneWire bus and initialized"); + + // Set the sensor's pin name (non-logical name) + new_dsx_driver->setOneWirePinName( + _DS18X20_model->GetDS18x20AddMsg()->onewire_pin); + + // Set the sensor's resolution + new_dsx_driver->SetResolution( + _DS18X20_model->GetDS18x20AddMsg()->sensor_resolution); + + // Set the sensor's period + new_dsx_driver->SetPeriod(_DS18X20_model->GetDS18x20AddMsg()->period); + + // Configure the types of sensor reads to perform + for (int i = 0; i < _DS18X20_model->GetDS18x20AddMsg()->sensor_types_count; + i++) { + if (_DS18X20_model->GetDS18x20AddMsg()->sensor_types[i] == + wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE) { + new_dsx_driver->is_read_temp_c = true; + } else if ( + _DS18X20_model->GetDS18x20AddMsg()->sensor_types[i] == + wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT) { + new_dsx_driver->is_read_temp_f = true; + } else { + WS_DEBUG_PRINTLN( + "ERROR | DS18x20: Unknown SensorType, failed to add sensor!"); + is_initialized = false; + } + } + + // If the sensor was successfully initialized, add it to the controller + if (is_initialized == true) + _DS18X20_pins.push_back(std::move(new_dsx_driver)); + + // Print out the details + WS_DEBUG_PRINTLN("[ds18x] New Sensor Added!"); + WS_DEBUG_PRINT("\tPin: "); + WS_DEBUG_PRINTLN(pin_name); + WS_DEBUG_PRINT("\tResolution: "); + WS_DEBUG_PRINTLN(_DS18X20_model->GetDS18x20AddMsg()->sensor_resolution); + WS_DEBUG_PRINT("\tPeriod: "); + WS_DEBUG_PRINTLN(_DS18X20_model->GetDS18x20AddMsg()->period); + WS_DEBUG_PRINT("\tSI Units: "); + for (int i = 0; i < _DS18X20_model->GetDS18x20AddMsg()->sensor_types_count; + i++) { + WS_DEBUG_PRINT(_DS18X20_model->GetDS18x20AddMsg()->sensor_types[i]); + WS_DEBUG_PRINT(", "); + } + WS_DEBUG_PRINTLN(""); + } else { + WS_DEBUG_PRINTLN("ERROR | DS18x20: Unable to get sensor ID!"); + is_initialized = false; + } + + // If we're not in offline mode, publish a Ds18x20Added message back to the + // broker + if (!WsV2._sdCardV2->isModeOffline()) { + // Encode and publish a Ds18x20Added message back to the broker + if (!_DS18X20_model->EncodeDS18x20Added( + _DS18X20_model->GetDS18x20AddMsg()->onewire_pin, is_initialized)) { + WS_DEBUG_PRINTLN( + "ERROR | DS18x20: Unable to encode Ds18x20Added message!"); + return false; + } + + if (!WsV2.PublishSignal( + wippersnapper_signal_DeviceToBroker_ds18x20_added_tag, + _DS18X20_model->GetDS18x20AddedMsg())) { + WS_DEBUG_PRINTLN( + "ERROR | DS18x20: Unable to publish Ds18x20Added message!"); + return false; + } + } + + return true; +} + +/***********************************************************************/ +/*! + @brief Handles a Ds18x20Remove message from the broker. Attempts to + remove a DS18X20Hardware object from the controller and + release the OneWire pin for other uses. + @param stream + The nanopb input stream. + @return True if the sensor was successfully removed from the + controller, False otherwise. +*/ +/***********************************************************************/ +bool DS18X20Controller::Handle_Ds18x20Remove(pb_istream_t *stream) { + WS_DEBUG_PRINT("Removing DS18X20 sensor..."); + // Attempt to decode the stream + if (!_DS18X20_model->DecodeDS18x20Remove(stream)) { + WS_DEBUG_PRINTLN("ERROR | DS18x20: Unable to decode Ds18x20Remove message"); + return false; + } + // Create a temp. instance of the Ds18x20Remove message + wippersnapper_ds18x20_Ds18x20Remove *msg_remove = + _DS18X20_model->GetDS18x20RemoveMsg(); + uint8_t pin_name = atoi(msg_remove->onewire_pin + 1); + + // Find the driver/bus in the vector and remove it + for (size_t i = 0; i < _DS18X20_pins.size(); ++i) { + if (_DS18X20_pins[i]->GetOneWirePin() == pin_name) { + _DS18X20_pins.erase(_DS18X20_pins.begin() + i); + return true; + } + } + WS_DEBUG_PRINTLN("Removed!"); + return true; +} + +/***********************************************************************/ +/*! + @brief Update/polling loop for the DS18X20 controller. +*/ +/***********************************************************************/ +void DS18X20Controller::update() { +#ifdef DEBUG_PROFILE + unsigned long total_start_time = millis(); +#endif + + // Bail out if there are no OneWire pins to poll + if (_DS18X20_pins.empty()) + return; + + // Iterate through the vector + for (uint8_t i = 0; i < _DS18X20_pins.size(); i++) { +#ifdef DEBUG_PROFILE + unsigned long sensor_start_time = millis(); +#endif + + // Create a reference to the DS18X20Hardware object + DS18X20Hardware &temp_dsx_driver = *(_DS18X20_pins[i]); + + // Check if the driver's timer has not expired yet + if (!temp_dsx_driver.IsTimerExpired()) { + continue; + } + +// Attempt to read the temperature in Celsius +#ifdef DEBUG_PROFILE + unsigned long temp_c_start_time = millis(); +#endif + + if (!temp_dsx_driver.ReadTemperatureC()) { + WS_DEBUG_PRINTLN( + "ERROR | DS18x20: Unable to read temperature in Celsius"); + continue; + } + +#ifdef DEBUG_PROFILE + unsigned long temp_c_end_time = millis(); + WS_DEBUG_PRINT("Read temperature Celsius time: "); + WS_DEBUG_PRINTLN(temp_c_end_time - temp_c_start_time); +#endif + + // We got a temperature value from the hardware, let's create a new + // sensor_event + _DS18X20_model->InitDS18x20EventMsg(temp_dsx_driver.getOneWirePinName()); + + // Are we reading the temperature in Celsius, Fahrenheit, or both? + if (temp_dsx_driver.is_read_temp_c) { + float temp_c = temp_dsx_driver.GetTemperatureC(); + _DS18X20_model->addSensorEvent( + wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE, + temp_c); + } + if (temp_dsx_driver.is_read_temp_f) { + float temp_f = temp_dsx_driver.GetTemperatureF(); + _DS18X20_model->addSensorEvent( + wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT, + temp_f); + } + + // Get the Ds18x20Event message + wippersnapper_ds18x20_Ds18x20Event *event_msg = + _DS18X20_model->GetDS18x20EventMsg(); + pb_size_t event_count = event_msg->sensor_events_count; + + if (!WsV2._sdCardV2->isModeOffline()) { + // Encode the Ds18x20Event message + if (!_DS18X20_model->EncodeDs18x20Event()) { + WS_DEBUG_PRINTLN( + "ERROR | DS18x20: Failed to encode Ds18x20Event message"); + continue; + } + // Publish the Ds18x20Event message to the broker + WS_DEBUG_PRINT("DS18x20: Publishing event to broker..."); + if (!WsV2.PublishSignal( + wippersnapper_signal_DeviceToBroker_ds18x20_event_tag, + _DS18X20_model->GetDS18x20EventMsg())) { + WS_DEBUG_PRINTLN( + "ERROR | DS18x20: Failed to publish Ds18x20Event message"); + continue; + } + WS_DEBUG_PRINTLN("Published!"); + } else { + if (!WsV2._sdCardV2->LogDS18xSensorEventToSD( + _DS18X20_model->GetDS18x20EventMsg())) { + WS_DEBUG_PRINTLN( + "ERROR | DS18x20: Failed to log DS18x20 event to SD card"); + continue; + } + } + +#ifdef DEBUG_PROFILE + unsigned long sensor_end_time = millis(); + WS_DEBUG_PRINT("Total sensor processing time: "); + WS_DEBUG_PRINTLN(sensor_end_time - sensor_start_time); +#endif + } + +#ifdef DEBUG_PROFILE + unsigned long total_end_time = millis(); + if (total_end_time - total_start_time != 0) { + WS_DEBUG_PRINT("Total update() execution time: "); + WS_DEBUG_PRINTLN(total_end_time - total_start_time); + } +#endif +} diff --git a/src/components/ds18x20/controller.h b/src/components/ds18x20/controller.h new file mode 100644 index 000000000..a77182f47 --- /dev/null +++ b/src/components/ds18x20/controller.h @@ -0,0 +1,46 @@ +/*! + * @file controller.h + * + * Controller for the DS18X20 API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_DS18X20_CONTROLLER_H +#define WS_DS18X20_CONTROLLER_H +#include "Wippersnapper_V2.h" +#include "hardware.h" +#include "model.h" +#include + +class Wippersnapper_V2; ///< Forward declaration +class DS18X20Model; ///< Forward declaration +class DS18X20Hardware; ///< Forward declaration + +/**************************************************************************/ +/*! + @brief Routes messages between the ds18x20.proto API and the hardware. +*/ +/**************************************************************************/ +class DS18X20Controller { +public: + DS18X20Controller(); + ~DS18X20Controller(); + // Routing + bool Handle_Ds18x20Add(pb_istream_t *stream); + bool Handle_Ds18x20Remove(pb_istream_t *stream); + // Polling + void update(); + +private: + DS18X20Model *_DS18X20_model; ///< ds18x20 model + std::vector> _DS18X20_pins; +}; +extern Wippersnapper_V2 WsV2; ///< Wippersnapper V2 instance +#endif // WS_DS18X20_CONTROLLER_H \ No newline at end of file diff --git a/src/components/ds18x20/hardware.cpp b/src/components/ds18x20/hardware.cpp new file mode 100644 index 000000000..4936d983f --- /dev/null +++ b/src/components/ds18x20/hardware.cpp @@ -0,0 +1,195 @@ +/*! + * @file hardware.cpp + * + * Hardware interface for the ds18x20.proto API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "hardware.h" + +/***********************************************************************/ +/*! + @brief DS18X20Hardware constructor + @param onewire_pin + The OneWire bus pin to use. +*/ +/***********************************************************************/ +DS18X20Hardware::DS18X20Hardware(uint8_t onewire_pin) : _drv_therm(_ow) { + is_read_temp_c = false; + is_read_temp_f = false; + // Initialize the OneWire bus object + _onewire_pin = onewire_pin; + new (&_ow) OneWireNg_CurrentPlatform(onewire_pin, false); +} + +/***********************************************************************/ +/*! + @brief DS18X20Hardware destructor +*/ +/***********************************************************************/ +DS18X20Hardware::~DS18X20Hardware() { + pinMode(_onewire_pin, + INPUT); // Set the pin to hi-z and release it for other uses +} + +/***********************************************************************/ +/*! + @brief Get the sensor's ID + @returns True if the sensor was successfully identified, False otherwise. +*/ +/***********************************************************************/ +bool DS18X20Hardware::GetSensor() { + OneWireNg::ErrorCode ec = _ow->readSingleId(_sensorId); + return ec == OneWireNg::EC_SUCCESS; +} + +/***********************************************************************/ +/*! + @brief Gets the pin used as a OneWire bus. + @returns The OneWire bus pin. +*/ +/***********************************************************************/ +uint8_t DS18X20Hardware::GetOneWirePin() { return _onewire_pin; } + +/***********************************************************************/ +/*! + @brief Sets the name of the OneWire bus pin. + @param prettyOWPinName + The name of the OneWire bus pin (non-logical pin name, + includes the "D" or "A" prefix). +*/ +/***********************************************************************/ +void DS18X20Hardware::setOneWirePinName(const char *prettyOWPinName) { + strncpy(_onewire_pin_name, prettyOWPinName, sizeof(_onewire_pin_name)); + _onewire_pin_name[sizeof(_onewire_pin_name) - 1] = '\0'; +} + +/***********************************************************************/ +/*! + @brief Gets the name of the OneWire bus pin. + @returns The name of the OneWire bus pin (non-logical pin name, + includes the "D" or "A" prefix). +*/ +/***********************************************************************/ +const char *DS18X20Hardware::getOneWirePinName() { return _onewire_pin_name; } + +/*************************************************************************/ +/*! + @brief Sets the DS18X20 sensor's resolution. + @param resolution + The desired resolution of the DS18X20 sensor, in bits (from + 9 to 12). +*/ +/*************************************************************************/ +void DS18X20Hardware::SetResolution(int resolution) { + // Set the resolution of the DS18X20 sensor driver + switch (resolution) { + case 9: + _resolution = DSTherm::Resolution::RES_9_BIT; + break; + case 10: + _resolution = DSTherm::Resolution::RES_10_BIT; + break; + case 11: + _resolution = DSTherm::Resolution::RES_11_BIT; + break; + case 12: + _resolution = DSTherm::Resolution::RES_12_BIT; + break; + default: + _resolution = + DSTherm::Resolution::RES_12_BIT; // Default to 12-bit resolution + break; + } + + // Set common resolution for all sensors. + // Th, Tl (high/low alarm triggers) are set to 0. + _drv_therm.writeScratchpadAll(0, 0, _resolution); + + // The configuration above is stored in volatile sensors scratchpad + // memory and will be lost after power unplug. Therefore store the + // configuration permanently in sensors EEPROM. + _drv_therm.copyScratchpadAll(false); +} + +/*************************************************************************/ +/*! + @brief Sets the timer to read from the sensor. + @param period + The desired period to read the sensor, in seconds. +*/ +/*************************************************************************/ +void DS18X20Hardware::SetPeriod(float period) { + _period = period * 1000; // Convert to milliseconds + _prv_period = 0; // Also reset the previous period whenever we set a + // new period +} + +/*************************************************************************/ +/*! + @brief Obtains the current time in milliseconds and compares it to + the last time the sensor was polled. + @returns True if the timer has expired, False otherwise. +*/ +/*************************************************************************/ +bool DS18X20Hardware::IsTimerExpired() { + return millis() - _prv_period > _period; +} + +/*************************************************************************/ +/*! + @brief Gets the temperature value last read by the sensor, in Celsius. + @returns The temperature in Celsius. +*/ +/*************************************************************************/ +float DS18X20Hardware::GetTemperatureC() { return _temp_c; } + +/*************************************************************************/ +/*! + @brief Gets the temperature value last read by the sensor, in Fahrenheit. + @returns The temperature in Fahrenheit. +*/ +/*************************************************************************/ +float DS18X20Hardware::GetTemperatureF() { + _temp_f = _temp_c * 9.0 / 5.0 + 32.0; + return _temp_f; +} + +/*************************************************************************/ +/*! + @brief Attempts to obtain the temperature from the sensor, in + degrees Celsius. + @returns True if the temperature was successfully read, False otherwise. +*/ +/*************************************************************************/ +bool DS18X20Hardware::ReadTemperatureC() { + // Start temperature conversion for the first identified sensor on the OneWire + // bus + OneWireNg::ErrorCode ec = + _drv_therm.convertTemp(_sensorId, DSTherm::MAX_CONV_TIME, false); + + if (ec != OneWireNg::EC_SUCCESS) + return false; + + // Scratchpad placeholder is static to allow reuse of the associated + // sensor id while reissuing readScratchpadSingle() calls. + // Note, due to its storage class the placeholder is zero initialized. + static Placeholder scrpd; + ec = _drv_therm.readScratchpad(_sensorId, scrpd); + if (ec != OneWireNg::EC_SUCCESS) + return false; + + // Read the temperature from the sensor + long temp = scrpd->getTemp2(); + _temp_c = temp / 16.0; // Convert from 16-bit int to float + + _prv_period = millis(); // Update the last time the sensor was polled + return true; +} \ No newline at end of file diff --git a/src/components/ds18x20/hardware.h b/src/components/ds18x20/hardware.h new file mode 100644 index 000000000..0fcb8288c --- /dev/null +++ b/src/components/ds18x20/hardware.h @@ -0,0 +1,61 @@ +/*! + * @file model.h + * + * Hardware implementation for the ds18x20.proto message. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_DS18X20_HARDWARE_H +#define WS_DS18X20_HARDWARE_H +#include "Wippersnapper_V2.h" + +#include "OneWireNg_CurrentPlatform.h" +#include "drivers/DSTherm.h" +#include "utils/Placeholder.h" + +/**************************************************************************/ +/*! + @brief Interface for interacting with the's DallasTemp + and OneWire APIs. +*/ +/**************************************************************************/ +class DS18X20Hardware { +public: + DS18X20Hardware(uint8_t onewire_pin); + ~DS18X20Hardware(); + uint8_t GetOneWirePin(); + void SetResolution(int resolution); + void SetPeriod(float period); + void setOneWirePinName(const char *prettyOWPinName); + const char *getOneWirePinName(); + bool IsTimerExpired(); + bool GetSensor(); + bool ReadTemperatureC(); + float GetTemperatureC(); + float GetTemperatureF(); + bool is_read_temp_c; ///< Flag telling the controller to read the temperature + ///< in degrees Celsius + bool is_read_temp_f; ///< Flag telling the controller to read the temperature + ///< in degrees Fahrenheit +private: + Placeholder _ow; ///< OneWire bus object + OneWireNg::Id _sensorId; ///< Sensor ID + DSTherm _drv_therm; ///< DS18X20 driver object + DSTherm::Resolution _resolution; ///< Resolution of the DS18X20 sensor + float _temp_c; ///< Temperature in Celsius + float _temp_f; ///< Temperature in Fahrenheit + // From the PB model + uint8_t + _onewire_pin; ///< Pin utilized by the OneWire bus, used for addressing + char _onewire_pin_name[5]; ///< Name of the OneWire bus pin + float _period; ///< The desired period to read the sensor, in seconds + float _prv_period; ///< Last time the sensor was polled, in seconds +}; +#endif // WS_DS18X20_HARDWARE_H \ No newline at end of file diff --git a/src/components/ds18x20/model.cpp b/src/components/ds18x20/model.cpp new file mode 100644 index 000000000..17dd039c0 --- /dev/null +++ b/src/components/ds18x20/model.cpp @@ -0,0 +1,188 @@ +/*! + * @file model.cpp + * + * Model for the ds18x20.proto message. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "model.h" + +/***********************************************************************/ +/*! + @brief DS18X20Model constructor +*/ +/***********************************************************************/ +DS18X20Model::DS18X20Model() { + // Initialize the DS18X20 messages + _msg_DS18x20Add = wippersnapper_ds18x20_Ds18x20Add_init_zero; + _msg_DS18x20Added = wippersnapper_ds18x20_Ds18x20Added_init_zero; + _msg_DS18x20Remove = wippersnapper_ds18x20_Ds18x20Remove_init_zero; +} + +/***********************************************************************/ +/*! + @brief DS18X20Model destructor +*/ +/***********************************************************************/ +DS18X20Model::~DS18X20Model() {} + +/***********************************************************************/ +/*! + @brief Attempts to decode a Ds18x20Add message from the broker. + @param stream + The nanopb input stream. + @return True if the message was successfully decoded, False otherwise. +*/ +/***********************************************************************/ +bool DS18X20Model::DecodeDS18x20Add(pb_istream_t *stream) { + _msg_DS18x20Add = wippersnapper_ds18x20_Ds18x20Add_init_zero; + // Attempt to decode the stream into a Ds18x20Add message + return pb_decode(stream, wippersnapper_ds18x20_Ds18x20Add_fields, + &_msg_DS18x20Add); +} + +/***********************************************************************/ +/*! + @brief Gets a pointer to the Ds18x20Add message. + @return Pointer to the Ds18x20Add message. +*/ +/***********************************************************************/ +wippersnapper_ds18x20_Ds18x20Add *DS18X20Model::GetDS18x20AddMsg() { + return &_msg_DS18x20Add; +} + +/***********************************************************************/ +/*! + @brief Returns a pointer to the Ds18x20Added message. + @return Pointer to the Ds18x20Added message. +*/ +/***********************************************************************/ +wippersnapper_ds18x20_Ds18x20Added *DS18X20Model::GetDS18x20AddedMsg() { + return &_msg_DS18x20Added; +} + +/***********************************************************************/ +/*! + @brief Encodes a Ds18x20Added message. + @param onewire_pin + The OneWire bus pin to add. + @param is_init + True if the sensor was successfully initialized, + False otherwise. + @return True if the message was successfully encoded, + False otherwise. +*/ +/***********************************************************************/ +bool DS18X20Model::EncodeDS18x20Added(char *onewire_pin, bool is_init) { + // Fill the Ds18x20Added message + _msg_DS18x20Added = wippersnapper_ds18x20_Ds18x20Added_init_zero; + _msg_DS18x20Added.is_initialized = is_init; + strcpy(_msg_DS18x20Added.onewire_pin, onewire_pin); + + // Encode the Ds18x20Added message + size_t sz_msg; + if (!pb_get_encoded_size(&sz_msg, wippersnapper_ds18x20_Ds18x20Added_fields, + &_msg_DS18x20Added)) + return false; + + uint8_t buf[sz_msg]; + pb_ostream_t msg_stream = pb_ostream_from_buffer(buf, sizeof(buf)); + return pb_encode(&msg_stream, wippersnapper_ds18x20_Ds18x20Added_fields, + &_msg_DS18x20Added); +} + +/*************************************************************************/ +/*! + @brief Attempts to decode a Ds18x20Remove message from the broker. + @param stream + The nanopb input stream. + @return True if the message was successfully decoded, False otherwise. +*/ +/*************************************************************************/ +bool DS18X20Model::DecodeDS18x20Remove(pb_istream_t *stream) { + _msg_DS18x20Remove = wippersnapper_ds18x20_Ds18x20Remove_init_zero; + return pb_decode(stream, wippersnapper_ds18x20_Ds18x20Remove_fields, + &_msg_DS18x20Remove); +} + +/*************************************************************************/ +/*! + @brief Gets a pointer to the Ds18x20Remove message. + @return Pointer to the Ds18x20Remove message. +*/ +/*************************************************************************/ +wippersnapper_ds18x20_Ds18x20Remove *DS18X20Model::GetDS18x20RemoveMsg() { + return &_msg_DS18x20Remove; +} + +/*************************************************************************/ +/*! + @brief Gets a pointer to the Ds18x20Event message. + @return Pointer to the Ds18x20Event message. +*/ +/*************************************************************************/ +wippersnapper_ds18x20_Ds18x20Event *DS18X20Model::GetDS18x20EventMsg() { + return &_msg_DS18x20Event; +} + +/*************************************************************************/ +/*! + @brief Encodes a Ds18x20Event message. + @return True if the message was successfully encoded, False otherwise. +*/ +/*************************************************************************/ +bool DS18X20Model::EncodeDs18x20Event() { + // take the filled _msg_DS18x20Event we built in the controller and encode it + size_t sz_msg; + if (!pb_get_encoded_size(&sz_msg, wippersnapper_ds18x20_Ds18x20Event_fields, + &_msg_DS18x20Event)) + return false; + + uint8_t buf[sz_msg]; + pb_ostream_t msg_stream = pb_ostream_from_buffer(buf, sizeof(buf)); + return pb_encode(&msg_stream, wippersnapper_ds18x20_Ds18x20Event_fields, + &_msg_DS18x20Event); +} + +/*************************************************************************/ +/*! + @brief Initializes the Ds18x20Event message. + @param ow_pin_name + The OneWire bus pin name. +*/ +/*************************************************************************/ +void DS18X20Model::InitDS18x20EventMsg(const char *ow_pin_name) { + _msg_DS18x20Event = wippersnapper_ds18x20_Ds18x20Event_init_zero; + _msg_DS18x20Event.sensor_events_count = 0; + strcpy(_msg_DS18x20Event.onewire_pin, ow_pin_name); +} + +/*************************************************************************/ +/*! + @brief Adds a "sensor event" to the Ds18x20Event message. + @param sensor_type + The event's SensorType. + @param sensor_value + The event's value. +*/ +/*************************************************************************/ +void DS18X20Model::addSensorEvent(wippersnapper_sensor_SensorType sensor_type, + float sensor_value) { + _msg_DS18x20Event.sensor_events[_msg_DS18x20Event.sensor_events_count].type = + sensor_type; + _msg_DS18x20Event.sensor_events[_msg_DS18x20Event.sensor_events_count] + .which_value = wippersnapper_sensor_SensorEvent_float_value_tag; + + // Convert the float to 2 decimal places + sensor_value = roundf(sensor_value * 100) / 100; + _msg_DS18x20Event.sensor_events[_msg_DS18x20Event.sensor_events_count] + .value.float_value = sensor_value; + _msg_DS18x20Event.sensor_events_count++; +} \ No newline at end of file diff --git a/src/components/ds18x20/model.h b/src/components/ds18x20/model.h new file mode 100644 index 000000000..c7efaac4b --- /dev/null +++ b/src/components/ds18x20/model.h @@ -0,0 +1,55 @@ +/*! + * @file model.h + * + * Model interface for the DS18X20.proto message. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_DS18X20_MODEL_H +#define WS_DS18X20_MODEL_H +#include "Wippersnapper_V2.h" + +/**************************************************************************/ +/*! + @brief Provides an interface for creating, encoding, and parsing + messages from DS18X20.proto. +*/ +/**************************************************************************/ +class DS18X20Model { +public: + DS18X20Model(); + ~DS18X20Model(); + // Ds18x20Add Message API + bool DecodeDS18x20Add(pb_istream_t *stream); + wippersnapper_ds18x20_Ds18x20Add *GetDS18x20AddMsg(); + // DS18x20Added Message API + bool EncodeDS18x20Added(char *onewire_pin, bool is_init); + wippersnapper_ds18x20_Ds18x20Added *GetDS18x20AddedMsg(); + // Ds18x20Remove Message API + bool DecodeDS18x20Remove(pb_istream_t *stream); + wippersnapper_ds18x20_Ds18x20Remove *GetDS18x20RemoveMsg(); + // Ds18x20Event Message API + bool EncodeDs18x20Event(); + wippersnapper_ds18x20_Ds18x20Event *GetDS18x20EventMsg(); + void InitDS18x20EventMsg(const char *ow_pin_name); + void addSensorEvent(wippersnapper_sensor_SensorType sensor_type, + float sensor_value); + +private: + wippersnapper_ds18x20_Ds18x20Add + _msg_DS18x20Add; ///< wippersnapper_ds18x20_Ds18x20Add message + wippersnapper_ds18x20_Ds18x20Added + _msg_DS18x20Added; ///< wippersnapper_ds18x20_Ds18x20Added message + wippersnapper_ds18x20_Ds18x20Remove + _msg_DS18x20Remove; ///< wippersnapper_ds18x20_Ds18x20Remove message + wippersnapper_ds18x20_Ds18x20Event + _msg_DS18x20Event; ///< wippersnapper_ds18x20_Ds18x20Event message +}; +#endif // WS_DIGITALIO_MODEL_H \ No newline at end of file diff --git a/src/components/ds18x20/ws_ds18x20.cpp b/src/components/ds18x20/ws_ds18x20.cpp deleted file mode 100644 index 0cfa6e0c5..000000000 --- a/src/components/ds18x20/ws_ds18x20.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/*! - * @file ws_ds18x20.cpp - * - * This component implements 1-wire communication - * for the DS18X20-line of Maxim Temperature ICs. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2022-2023 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ - -#include "ws_ds18x20.h" - -/*************************************************************/ -/*! - @brief Creates a new WipperSnapper Ds18x20 component. -*/ -/*************************************************************/ -ws_ds18x20::ws_ds18x20() {} - -/*************************************************************/ -/*! - @brief Destructor for a WipperSnapper DS18X20 component. -*/ -/*************************************************************/ -ws_ds18x20::~ws_ds18x20() { - // delete DallasTemp sensors and release onewire buses - for (size_t idx = 0; idx < _ds18xDrivers.size(); idx++) { - delete _ds18xDrivers[idx]->dallasTempObj; - delete _ds18xDrivers[idx]->oneWire; - } - // remove all elements - _ds18xDrivers.clear(); -} - -/********************************************************************/ -/*! - @brief Initializes a DS18x20 sensor using a - configuration sent by the broker and adds it to a - vector of ds18x20 sensor drivers. - @param msgDs18x20InitReq - Message containing configuration data for a - ds18x20 sensor. - @returns True if initialized successfully, False otherwise. -*/ -/********************************************************************/ -bool ws_ds18x20::addDS18x20( - wippersnapper_ds18x20_v1_Ds18x20InitRequest *msgDs18x20InitReq) { - bool is_success = false; - - // init. new ds18x20 object - ds18x20Obj *newObj = new ds18x20Obj(); - char *oneWirePin = msgDs18x20InitReq->onewire_pin + 1; - newObj->oneWire = new OneWire(atoi(oneWirePin)); - newObj->dallasTempObj = new DallasTemperature(newObj->oneWire); - newObj->dallasTempObj->begin(); - // attempt to obtain sensor address - if (newObj->dallasTempObj->getAddress(newObj->dallasTempAddr, 0)) { - // attempt to set sensor resolution - newObj->dallasTempObj->setResolution(msgDs18x20InitReq->sensor_resolution); - // copy the device's sensor properties - newObj->sensorPropertiesCount = - msgDs18x20InitReq->i2c_device_properties_count; - // TODO: Make sure this works, it's a new idea and untested :) - for (int i = 0; i < newObj->sensorPropertiesCount; i++) { - newObj->sensorProperties[i].sensor_type = - msgDs18x20InitReq->i2c_device_properties[i].sensor_type; - newObj->sensorProperties[i].sensor_period = - (long)msgDs18x20InitReq->i2c_device_properties[i].sensor_period * - 1000; - } - // set pin - strcpy(newObj->onewire_pin, msgDs18x20InitReq->onewire_pin); - // add the new ds18x20 driver to vec. - _ds18xDrivers.push_back(newObj); - is_success = true; - } else { - WS_DEBUG_PRINTLN("Failed to find DSx sensor on specified pin."); - } - - // fill and publish the initialization response back to the broker - size_t msgSz; // message's encoded size - wippersnapper_signal_v1_Ds18x20Response msgInitResp = - wippersnapper_signal_v1_Ds18x20Response_init_zero; - msgInitResp.which_payload = - wippersnapper_signal_v1_Ds18x20Response_resp_ds18x20_init_tag; - msgInitResp.payload.resp_ds18x20_init.is_initialized = is_success; - strcpy(msgInitResp.payload.resp_ds18x20_init.onewire_pin, - msgDs18x20InitReq->onewire_pin); - - WS_DEBUG_PRINT("Created OneWireBus on GPIO "); - WS_DEBUG_PRINT(msgDs18x20InitReq->onewire_pin); - WS_DEBUG_PRINTLN(" with DS18x20 attached!"); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[DS18x] Attached DS18x20 sensor to pin %s\n", - msgDs18x20InitReq->onewire_pin); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - // Encode and publish response back to broker - memset(WS._buffer_outgoing, 0, sizeof(WS._buffer_outgoing)); - pb_ostream_t ostream = - pb_ostream_from_buffer(WS._buffer_outgoing, sizeof(WS._buffer_outgoing)); - if (!ws_pb_encode(&ostream, wippersnapper_signal_v1_Ds18x20Response_fields, - &msgInitResp)) { - WS_DEBUG_PRINTLN("ERROR: Unable to encode msg_init response message!"); - return false; - } - pb_get_encoded_size(&msgSz, wippersnapper_signal_v1_Ds18x20Response_fields, - &msgInitResp); - WS_DEBUG_PRINT("-> DS18x Init Response..."); - WS._mqtt->publish(WS._topic_signal_ds18_device, WS._buffer_outgoing, msgSz, - 1); - WS_DEBUG_PRINTLN("Published!"); - - return is_success; -} - -/********************************************************************/ -/*! - @brief De-initializes a DS18x20 sensor and releases its - pin and resources. - @param msgDS18x20DeinitReq - Message containing configuration data for a - ds18x20 sensor. -*/ -/********************************************************************/ -void ws_ds18x20::deleteDS18x20( - wippersnapper_ds18x20_v1_Ds18x20DeInitRequest *msgDS18x20DeinitReq) { - // Loop thru vector of drivers to find the unique address - for (size_t idx = 0; idx < _ds18xDrivers.size(); idx++) { - if (strcmp(_ds18xDrivers[idx]->onewire_pin, - msgDS18x20DeinitReq->onewire_pin) == 0) { - WS_DEBUG_PRINT("Deleting OneWire instance on pin "); - WS_DEBUG_PRINTLN(msgDS18x20DeinitReq->onewire_pin); - delete _ds18xDrivers[idx] - ->dallasTempObj; // delete dallas temp instance on pin - delete _ds18xDrivers[idx] - ->oneWire; // delete OneWire instance on pin and release pin for reuse - _ds18xDrivers.erase(_ds18xDrivers.begin() + - idx); // erase vector and re-allocate - } - } - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[DS18x] Deleted DS18x20 sensor on pin %s\n", - msgDS18x20DeinitReq->onewire_pin); - WS._ui_helper->add_text_to_terminal(buffer); -#endif -} - -/*************************************************************/ -/*! - @brief Iterates through each ds18x20 sensor and - reports data (if period expired) to Adafruit IO. -*/ -/*************************************************************/ -void ws_ds18x20::update() { - // return immediately if no drivers have been initialized - if (_ds18xDrivers.size() == 0) - return; - - long curTime; // used for holding the millis() value - std::vector::iterator iter, end; - for (iter = _ds18xDrivers.begin(), end = _ds18xDrivers.end(); iter != end; - ++iter) { - - // Create an empty DS18x20 event signal message and configure - wippersnapper_signal_v1_Ds18x20Response msgDS18x20Response = - wippersnapper_signal_v1_Ds18x20Response_init_zero; - msgDS18x20Response.which_payload = - wippersnapper_signal_v1_Ds18x20Response_resp_ds18x20_event_tag; - - // take the current time for the driver (*iter) - curTime = millis(); - // Poll each sensor type, if period has elapsed - for (int i = 0; i < (*iter)->sensorPropertiesCount; i++) { - // has sensor_period elapsed? - if (curTime - (*iter)->sensorPeriodPrv > - (long)(*iter)->sensorProperties[i].sensor_period) { - // issue global temperature request to all DS sensors - WS_DEBUG_PRINTLN("Requesting temperature.."); - (*iter)->dallasTempObj->requestTemperatures(); - // poll the DS sensor driver - float tempC = (*iter)->dallasTempObj->getTempC((*iter)->dallasTempAddr); - if (tempC == DEVICE_DISCONNECTED_C) { - WS_DEBUG_PRINTLN("ERROR: Could not read temperature data, is the " - "sensor disconnected?"); -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal( - "[DS18x ERROR] Unable to read temperature, is the sensor " - "disconnected?\n"); -#endif - break; - } - - // check and pack based on sensorType - char buffer[100]; - if ((*iter)->sensorProperties[i].sensor_type == - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE) { - - WS_DEBUG_PRINT("(OneWireBus GPIO: "); - WS_DEBUG_PRINT((*iter)->onewire_pin); - WS_DEBUG_PRINT(") DS18x20 Value: "); - WS_DEBUG_PRINT(tempC); - WS_DEBUG_PRINTLN("*C") - snprintf(buffer, 100, "[DS18x] Read %0.2f*C on GPIO %s\n", tempC, - (*iter)->onewire_pin); - - msgDS18x20Response.payload.resp_ds18x20_event.sensor_event[i].type = - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE; - msgDS18x20Response.payload.resp_ds18x20_event.sensor_event[i].value = - tempC; - - msgDS18x20Response.payload.resp_ds18x20_event.sensor_event_count++; - } - - if ((*iter)->sensorProperties[i].sensor_type == - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT) { - msgDS18x20Response.payload.resp_ds18x20_event.sensor_event[i].type = - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT; - msgDS18x20Response.payload.resp_ds18x20_event.sensor_event[i].value = - (*iter)->dallasTempObj->toFahrenheit(tempC); - WS_DEBUG_PRINT("(OneWireBus GPIO: "); - WS_DEBUG_PRINT((*iter)->onewire_pin); - WS_DEBUG_PRINT(") DS18x20 Value: "); - WS_DEBUG_PRINT( - msgDS18x20Response.payload.resp_ds18x20_event.sensor_event[i] - .value); - WS_DEBUG_PRINTLN("*F") - snprintf(buffer, 100, "[DS18x] Read %0.2f*F on GPIO %s\n", - msgDS18x20Response.payload.resp_ds18x20_event.sensor_event[i] - .value, - (*iter)->onewire_pin); - - msgDS18x20Response.payload.resp_ds18x20_event.sensor_event_count++; - } - - // did we obtain the expected amount of sensor events for the - // `resp_ds18x20_event` message? - if (msgDS18x20Response.payload.resp_ds18x20_event.sensor_event_count == - (*iter)->sensorPropertiesCount) { - - // prep sensor event data for sending to IO - // use onewire_pin as the "address" - strcpy(msgDS18x20Response.payload.resp_ds18x20_event.onewire_pin, - (*iter)->onewire_pin); - // prep and encode buffer - memset(WS._buffer_outgoing, 0, sizeof(WS._buffer_outgoing)); - pb_ostream_t ostream = pb_ostream_from_buffer( - WS._buffer_outgoing, sizeof(WS._buffer_outgoing)); - if (!ws_pb_encode(&ostream, - wippersnapper_signal_v1_Ds18x20Response_fields, - &msgDS18x20Response)) { - WS_DEBUG_PRINTLN( - "ERROR: Unable to encode DS18x20 event responsemessage!"); - snprintf(buffer, 100, - "[DS18x ERROR] Unable to encode event message!"); - return; - } - - WS_DEBUG_PRINTLN( - "DEBUG: msgDS18x20Response sensor_event message contents:"); - for (int i = 0; - i < - msgDS18x20Response.payload.resp_ds18x20_event.sensor_event_count; - i++) { - WS_DEBUG_PRINT("sensor_event[#]: "); - WS_DEBUG_PRINTLN(i); - WS_DEBUG_PRINT("\tOneWire Bus: "); - WS_DEBUG_PRINTLN( - msgDS18x20Response.payload.resp_ds18x20_event.onewire_pin); - WS_DEBUG_PRINT("\tsensor_event type: "); - WS_DEBUG_PRINTLN( - msgDS18x20Response.payload.resp_ds18x20_event.sensor_event[i] - .type); - WS_DEBUG_PRINT("\tsensor_event value: "); - WS_DEBUG_PRINTLN( - msgDS18x20Response.payload.resp_ds18x20_event.sensor_event[i] - .value); - } - - // Publish I2CResponse msg - size_t msgSz; - pb_get_encoded_size(&msgSz, - wippersnapper_signal_v1_Ds18x20Response_fields, - &msgDS18x20Response); - WS_DEBUG_PRINT("PUBLISHING -> msgDS18x20Response Event Message..."); - if (!WS._mqtt->publish(WS._topic_signal_ds18_device, - WS._buffer_outgoing, msgSz, 1)) { - WS_DEBUG_PRINTLN("ERROR: Unable to publish DS18x20 event message - " - "MQTT Publish failed!"); - return; - }; - WS_DEBUG_PRINTLN("PUBLISHED!"); -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - (*iter)->sensorPeriodPrv = curTime; // set prv period - } - } - } - } -} \ No newline at end of file diff --git a/src/components/ds18x20/ws_ds18x20.h b/src/components/ds18x20/ws_ds18x20.h deleted file mode 100644 index 5398d4c4f..000000000 --- a/src/components/ds18x20/ws_ds18x20.h +++ /dev/null @@ -1,65 +0,0 @@ -/*! - * @file ws_ds18x20.h - * - * This component implements 1-wire communication - * for the DS18X20-line of Maxim Temperature ICs. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2022 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ -#ifndef WIPPERSNAPPER_DS18X20_H -#define WIPPERSNAPPER_DS18X20_H - -#include "Wippersnapper.h" - -#include -#include - -/** DS18x20 Object */ -struct ds18x20Obj { - OneWire * - oneWire; ///< Pointer to an OneWire bus used by a DallasTemperature object - char onewire_pin[5]; ///< Pin utilized by the OneWire bus, used for addressing - DallasTemperature - *dallasTempObj; ///< Pointer to a DallasTemperature sensor object - DeviceAddress dallasTempAddr; ///< Temperature sensor's address - int sensorPropertiesCount; ///< Tracks # of sensorProperties - wippersnapper_i2c_v1_I2CDeviceSensorProperties sensorProperties[2] = - wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero; ///< DS sensor - ///< type(s) - long sensorPeriodPrv; ///< Last time the sensor was polled, in millis -}; - -// forward decl. -class Wippersnapper; - -/**************************************************************************/ -/*! - @brief Class that provides an interface with DS18X20-compatible - sensors. -*/ -/**************************************************************************/ -class ws_ds18x20 { -public: - ws_ds18x20(); - ~ws_ds18x20(); - - bool - addDS18x20(wippersnapper_ds18x20_v1_Ds18x20InitRequest *msgDs18x20InitReq); - void deleteDS18x20( - wippersnapper_ds18x20_v1_Ds18x20DeInitRequest *msgDS18x20DeinitReq); - void update(); - -private: - std::vector - _ds18xDrivers; ///< Vec. of ptrs. to ds18x driver objects -}; -extern Wippersnapper WS; - -#endif // WIPPERSNAPPER_DS18X20_H \ No newline at end of file diff --git a/src/components/i2c/WipperSnapper_I2C.cpp b/src/components/i2c/WipperSnapper_I2C.cpp deleted file mode 100644 index 089d1e496..000000000 --- a/src/components/i2c/WipperSnapper_I2C.cpp +++ /dev/null @@ -1,1362 +0,0 @@ -/*! - * @file WipperSnapper_I2C.cpp - * - * This component initiates I2C operations - * using the Arduino generic TwoWire driver. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2021-2022 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ - -#include "WipperSnapper_I2C.h" - -#ifdef ARDUINO_ARCH_RP2040 -// Wire uses GPIO4 (SDA) and GPIO5 (SCL) automatically. -#define WIRE Wire -#endif - -/***************************************************************************************************************/ -/*! - @brief Creates a new WipperSnapper I2C component. - @param msgInitRequest - The I2C initialization request message. -*/ -/***************************************************************************************************************/ -WipperSnapper_Component_I2C::WipperSnapper_Component_I2C( - wippersnapper_i2c_v1_I2CBusInitRequest *msgInitRequest) { - WS_DEBUG_PRINTLN("EXEC: New I2C Port "); - WS_DEBUG_PRINT("\tPort #: "); - WS_DEBUG_PRINTLN(msgInitRequest->i2c_port_number); - WS_DEBUG_PRINT("\tSDA Pin: "); - WS_DEBUG_PRINTLN(msgInitRequest->i2c_pin_sda); - WS_DEBUG_PRINT("\tSCL Pin: "); - WS_DEBUG_PRINTLN(msgInitRequest->i2c_pin_scl); - WS_DEBUG_PRINT("\tFrequency (Hz): "); - WS_DEBUG_PRINTLN(msgInitRequest->i2c_frequency); - -#if defined(PIN_I2C_POWER) - // turn on the I2C power by setting pin to opposite of 'rest state' - pinMode(PIN_I2C_POWER, INPUT); - delay(1); - bool polarity = digitalRead(PIN_I2C_POWER); - pinMode(PIN_I2C_POWER, OUTPUT); - digitalWrite(PIN_I2C_POWER, !polarity); -#elif defined(TFT_I2C_POWER) - // ADAFRUIT_FEATHER_ESP32S2_TFT - pinMode(TFT_I2C_POWER, OUTPUT); - digitalWrite(TFT_I2C_POWER, HIGH); -#elif defined(NEOPIXEL_I2C_POWER) - // ADAFRUIT_FEATHER_ESP32_V2 - pinMode(NEOPIXEL_I2C_POWER, OUTPUT); - digitalWrite(NEOPIXEL_I2C_POWER, HIGH); -#endif - - // Enable pullups on SCL, SDA - pinMode(msgInitRequest->i2c_pin_scl, INPUT_PULLUP); - pinMode(msgInitRequest->i2c_pin_sda, INPUT_PULLUP); - delay(150); - - // Is SDA or SCL stuck low? - if ((digitalRead(msgInitRequest->i2c_pin_scl) == 0) || - (digitalRead(msgInitRequest->i2c_pin_sda) == 0)) { - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_ERROR_PULLUPS; - _isInit = false; - } else { - // Reset state of SCL/SDA pins - pinMode(msgInitRequest->i2c_pin_scl, INPUT); - pinMode(msgInitRequest->i2c_pin_sda, INPUT); - -// Initialize I2C bus -#if defined(ARDUINO_ARCH_ESP32) - _i2c = new TwoWire(msgInitRequest->i2c_port_number); - if (!_i2c->begin((int)msgInitRequest->i2c_pin_sda, - (int)msgInitRequest->i2c_pin_scl)) { - _isInit = false; // if the peripheral was configured incorrectly - } else { - _isInit = true; // if the peripheral was configured incorrectly - } - _i2c->setClock(50000); -#elif defined(ARDUINO_ARCH_ESP8266) - _i2c = new TwoWire(); - _i2c->begin(msgInitRequest->i2c_pin_sda, msgInitRequest->i2c_pin_scl); - _i2c->setClock(50000); - _isInit = true; -#elif defined(ARDUINO_ARCH_RP2040) - _i2c = &WIRE; - _i2c->begin(); - _isInit = true; -#else - // SAMD - _i2c = new TwoWire(&PERIPH_WIRE, msgInitRequest->i2c_pin_sda, - msgInitRequest->i2c_pin_scl); - _i2c->begin(); - _isInit = true; -#endif - - // set i2c obj. properties - _portNum = msgInitRequest->i2c_port_number; - _busStatusResponse = wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS; - } -} - -/*************************************************************/ -/*! - @brief Destructor for a WipperSnapper I2C component. -*/ -/*************************************************************/ -WipperSnapper_Component_I2C::~WipperSnapper_Component_I2C() { - _portNum = 100; // Invalid = 100 - _isInit = false; -} - -/*****************************************************/ -/*! - @brief Returns if i2c port is initialized. - @returns True if initialized, False otherwise. -*/ -/*****************************************************/ -bool WipperSnapper_Component_I2C::isInitialized() { return _isInit; } - -/*****************************************************/ -/*! - @brief Returns the state of the I2C bus. - @returns wippersnapper_i2c_v1_BusResponse. -*/ -/*****************************************************/ -wippersnapper_i2c_v1_BusResponse WipperSnapper_Component_I2C::getBusStatus() { - return _busStatusResponse; -} - -/************************************************************************/ -/*! - @brief Scans all I2C addresses on the bus between 0x08 and 0x7F - inclusive and returns an array of the devices found. - @returns wippersnapper_i2c_v1_I2CBusScanResponse -*/ -/************************************************************************/ -wippersnapper_i2c_v1_I2CBusScanResponse -WipperSnapper_Component_I2C::scanAddresses() { - uint8_t endTransmissionRC; - uint16_t address; - wippersnapper_i2c_v1_I2CBusScanResponse scanResp = - wippersnapper_i2c_v1_I2CBusScanResponse_init_zero; - -#ifndef ARDUINO_ARCH_ESP32 - // Set I2C WDT timeout to catch I2C hangs, SAMD-specific - WS.enableWDT(I2C_TIMEOUT_MS); - WS.feedWDT(); -#endif - - // Scan all I2C addresses between 0x08 and 0x7F inclusive and return a list of - // those that respond. - WS_DEBUG_PRINTLN("EXEC: I2C Scan"); - for (address = 0x08; address < 0x7F; address++) { - _i2c->beginTransmission(address); - endTransmissionRC = _i2c->endTransmission(); - -#if defined(ARDUINO_ARCH_ESP32) - // Check endTransmission()'s return code (Arduino-ESP32 ONLY) - // https://github.com/espressif/arduino-esp32/blob/master/libraries/Wire/src/Wire.cpp - if (endTransmissionRC == 5) { - WS_DEBUG_PRINTLN("ESP_ERR_TIMEOUT: I2C Bus Busy"); - scanResp.bus_response = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_ERROR_HANG; - // NOTE: ESP-IDF appears to handle this "behind the scenes" by - // resetting/clearing the bus. The user should be prompted to - // perform a bus scan again. - break; - } else if (endTransmissionRC == 7) { - WS_DEBUG_PRINT("I2C_ESP_ERR: SDA/SCL shorted, requests queued: "); - WS_DEBUG_PRINTLN(endTransmissionRC); - break; - } -#endif - - // Found device! - if (endTransmissionRC == 0) { - WS_DEBUG_PRINT("Found I2C Device at 0x"); - WS_DEBUG_PRINTLN(address); - scanResp.addresses_found[scanResp.addresses_found_count] = - (uint32_t)address; - scanResp.addresses_found_count++; - } - } - -#ifndef ARDUINO_ARCH_ESP32 - // re-enable WipperSnapper SAMD WDT global timeout - WS.enableWDT(WS_WDT_TIMEOUT); - WS.feedWDT(); -#endif - - WS_DEBUG_PRINT("I2C Devices Found: ") - WS_DEBUG_PRINTLN(scanResp.addresses_found_count); - - scanResp.bus_response = wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS; - return scanResp; -} - -/*******************************************************************************/ -/*! - @brief Initializes I2C device driver. - @param msgDeviceInitReq - A decoded I2CDevice initialization request message. - @returns True if I2C device is initialized and attached, False otherwise. -*/ -/*******************************************************************************/ -bool WipperSnapper_Component_I2C::initI2CDevice( - wippersnapper_i2c_v1_I2CDeviceInitRequest *msgDeviceInitReq) { - WS_DEBUG_PRINT("Attempting to initialize I2C device: "); - WS_DEBUG_PRINTLN(msgDeviceInitReq->i2c_device_name); - - uint16_t i2cAddress = (uint16_t)msgDeviceInitReq->i2c_device_address; - if ((strcmp("aht20", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("am2301b", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("am2315c", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("dht20", msgDeviceInitReq->i2c_device_name) == 0)) { - _ahtx0 = new WipperSnapper_I2C_Driver_AHTX0(this->_i2c, i2cAddress); - if (!_ahtx0->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize AHTX0 chip!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _ahtx0->configureDriver(msgDeviceInitReq); - drivers.push_back(_ahtx0); - } else if (strcmp("bh1750", msgDeviceInitReq->i2c_device_name) == 0) { - _bh1750 = new WipperSnapper_I2C_Driver_BH1750(this->_i2c, i2cAddress); - if (!_bh1750->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize BH1750 chip!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _bh1750->configureDriver(msgDeviceInitReq); - drivers.push_back(_bh1750); - } else if (strcmp("bme280", msgDeviceInitReq->i2c_device_name) == 0) { - _bme280 = new WipperSnapper_I2C_Driver_BME280(this->_i2c, i2cAddress); - if (!_bme280->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize BME280!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _bme280->configureDriver(msgDeviceInitReq); - drivers.push_back(_bme280); - WS_DEBUG_PRINTLN("BME280 Initialized Successfully!"); - } else if (strcmp("bmp280", msgDeviceInitReq->i2c_device_name) == 0) { - _bmp280 = new WipperSnapper_I2C_Driver_BMP280(this->_i2c, i2cAddress); - if (!_bmp280->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize BMP280!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _bmp280->configureDriver(msgDeviceInitReq); - drivers.push_back(_bmp280); - WS_DEBUG_PRINTLN("BMP280 Initialized Successfully!"); - } else if ((strcmp("bmp388", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("bmp390", msgDeviceInitReq->i2c_device_name) == 0)) { - _bmp3xx = new WipperSnapper_I2C_Driver_BMP3XX(this->_i2c, i2cAddress); - if (!_bmp3xx->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize BMP388!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _bmp3xx->configureDriver(msgDeviceInitReq); - drivers.push_back(_bmp3xx); - WS_DEBUG_PRINTLN("BMP388 Initialized Successfully!"); - } else if ((strcmp("bme680", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("bme688", msgDeviceInitReq->i2c_device_name) == 0)) { - _bme680 = new WipperSnapper_I2C_Driver_BME680(this->_i2c, i2cAddress); - if (!_bme680->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize BME680!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _bme680->configureDriver(msgDeviceInitReq); - drivers.push_back(_bme680); - WS_DEBUG_PRINTLN("BME680 Initialized Successfully!"); - } else if (strcmp("dps310", msgDeviceInitReq->i2c_device_name) == 0) { - _dps310 = new WipperSnapper_I2C_Driver_DPS310(this->_i2c, i2cAddress); - if (!_dps310->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize DPS310!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _dps310->configureDriver(msgDeviceInitReq); - drivers.push_back(_dps310); - WS_DEBUG_PRINTLN("DPS310 Initialized Successfully!"); - } else if (strcmp("ds2484", msgDeviceInitReq->i2c_device_name) == 0) { - _ds2484 = new WipperSnapper_I2C_Driver_DS2484(this->_i2c, i2cAddress); - if (!_ds2484->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize DS2484!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _ds2484->configureDriver(msgDeviceInitReq); - drivers.push_back(_ds2484); - WS_DEBUG_PRINTLN("DS2484 Initialized Successfully!"); - } else if (strcmp("ens160", msgDeviceInitReq->i2c_device_name) == 0) { - _ens160 = new WipperSnapper_I2C_Driver_ENS160(this->_i2c, i2cAddress); - if (!_ens160->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize ENS160!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _ens160->configureDriver(msgDeviceInitReq); - drivers.push_back(_ens160); - WS_DEBUG_PRINTLN("ENS160 Initialized Successfully!"); - } else if (strcmp("hts221", msgDeviceInitReq->i2c_device_name) == 0) { - _hts221 = new WipperSnapper_I2C_Driver_HTS221(this->_i2c, i2cAddress); - if (!_hts221->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize HTS221!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _hts221->configureDriver(msgDeviceInitReq); - drivers.push_back(_hts221); - WS_DEBUG_PRINTLN("HTS221 Initialized Successfully!"); - } else if (strcmp("htu21d", msgDeviceInitReq->i2c_device_name) == 0) { - _htu21d = new WipperSnapper_I2C_Driver_HTU21D(this->_i2c, i2cAddress); - if (!_htu21d->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize HTU21D!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _htu21d->configureDriver(msgDeviceInitReq); - drivers.push_back(_htu21d); - WS_DEBUG_PRINTLN("HTU21D Initialized Successfully!"); - } else if (strcmp("htu31d", msgDeviceInitReq->i2c_device_name) == 0) { - _htu31d = new WipperSnapper_I2C_Driver_HTU31D(this->_i2c, i2cAddress); - if (!_htu31d->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize HTU31D!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _htu31d->configureDriver(msgDeviceInitReq); - drivers.push_back(_htu31d); - WS_DEBUG_PRINTLN("HTU31D Initialized Successfully!"); - } else if (strcmp("scd30", msgDeviceInitReq->i2c_device_name) == 0) { - _scd30 = new WipperSnapper_I2C_Driver_SCD30(this->_i2c, i2cAddress); - if (!_scd30->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize SCD30!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _scd30->configureDriver(msgDeviceInitReq); - drivers.push_back(_scd30); - WS_DEBUG_PRINTLN("SCD30 Initialized Successfully!"); - } else if (strcmp("ina219", msgDeviceInitReq->i2c_device_name) == 0) { - _ina219 = new WipperSnapper_I2C_Driver_INA219(this->_i2c, i2cAddress); - if (!_ina219->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize INA219"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _ina219->configureDriver(msgDeviceInitReq); - drivers.push_back(_ina219); - WS_DEBUG_PRINTLN("INA219 Initialized Successfully!"); - } else if (strcmp("ltr390", msgDeviceInitReq->i2c_device_name) == 0) { - _ltr390 = new WipperSnapper_I2C_Driver_LTR390(this->_i2c, i2cAddress); - if (!_ltr390->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize LTR390"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _ltr390->configureDriver(msgDeviceInitReq); - drivers.push_back(_ltr390); - WS_DEBUG_PRINTLN("LTR390 Initialized Successfully!"); - } else if ((strcmp("ltr329", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("ltr303", msgDeviceInitReq->i2c_device_name) == 0)) { - _ltr329 = - new WipperSnapper_I2C_Driver_LTR329_LTR303(this->_i2c, i2cAddress); - if (!_ltr329->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize LTR329/303"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _ltr329->configureDriver(msgDeviceInitReq); - drivers.push_back(_ltr329); - WS_DEBUG_PRINTLN("LTR329/303 Initialized Successfully!"); - } else if (strcmp("nau7802", msgDeviceInitReq->i2c_device_name) == 0) { - _nau7802 = new WipperSnapper_I2C_Driver_NAU7802(this->_i2c, i2cAddress); - if (!_nau7802->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize NAU7802"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _nau7802->configureDriver(msgDeviceInitReq); - drivers.push_back(_nau7802); - WS_DEBUG_PRINTLN("NAU7802 Initialized Successfully!"); - } else if (strcmp("sgp30", msgDeviceInitReq->i2c_device_name) == 0) { - _sgp30 = new WipperSnapper_I2C_Driver_SGP30(this->_i2c, i2cAddress); - if (!_sgp30->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize SGP30!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _sgp30->configureDriver(msgDeviceInitReq); - drivers.push_back(_sgp30); - WS_DEBUG_PRINTLN("SGP30 Initialized Successfully!"); - } else if (strcmp("sgp40", msgDeviceInitReq->i2c_device_name) == 0) { - _sgp40 = new WipperSnapper_I2C_Driver_SGP40(this->_i2c, i2cAddress); - if (!_sgp40->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize SGP40!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _sgp40->configureDriver(msgDeviceInitReq); - drivers.push_back(_sgp40); - WS_DEBUG_PRINTLN("SGP40 Initialized Successfully!"); - } else if ((strcmp("sht20", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("si7021", msgDeviceInitReq->i2c_device_name) == 0)) { - _si7021 = new WipperSnapper_I2C_Driver_SI7021(this->_i2c, i2cAddress); - if (!_si7021->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize SI7021/SHT20!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _si7021->configureDriver(msgDeviceInitReq); - drivers.push_back(_si7021); - WS_DEBUG_PRINTLN("SI7021/SHT20 Initialized Successfully!"); - } else if (strcmp("mcp3421", msgDeviceInitReq->i2c_device_name) == 0) { - _mcp3421 = new WipperSnapper_I2C_Driver_MCP3421(this->_i2c, i2cAddress); - if (!_mcp3421->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize MCP3421!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _mcp3421->configureDriver(msgDeviceInitReq); - drivers.push_back(_mcp3421); - WS_DEBUG_PRINTLN("MCP3421 Initialized Successfully!"); - } else if (strcmp("mcp9808", msgDeviceInitReq->i2c_device_name) == 0) { - _mcp9808 = new WipperSnapper_I2C_Driver_MCP9808(this->_i2c, i2cAddress); - if (!_mcp9808->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize MCP9808!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _mcp9808->configureDriver(msgDeviceInitReq); - drivers.push_back(_mcp9808); - WS_DEBUG_PRINTLN("MCP9808 Initialized Successfully!"); - } else if (strcmp("mpl115a2", msgDeviceInitReq->i2c_device_name) == 0) { - _mpl115a2 = new WipperSnapper_I2C_Driver_MPL115A2(this->_i2c, i2cAddress); - if (!_mpl115a2->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize MPL115A2!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _mpl115a2->configureDriver(msgDeviceInitReq); - drivers.push_back(_mpl115a2); - WS_DEBUG_PRINTLN("MPL115A2 Initialized Successfully!"); - } else if (strcmp("mprls", msgDeviceInitReq->i2c_device_name) == 0) { - _mprls = new WipperSnapper_I2C_Driver_MPRLS(this->_i2c, i2cAddress); - if (!_mprls->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize MPRLS!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _mprls->configureDriver(msgDeviceInitReq); - drivers.push_back(_mprls); - WS_DEBUG_PRINTLN("MPRLS Initialized Successfully!"); - } else if (strcmp("ms8607", msgDeviceInitReq->i2c_device_name) == 0) { - _ms8607 = new WipperSnapper_I2C_Driver_MS8607(this->_i2c, i2cAddress); - if (!_ms8607->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize MS8607!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _ms8607->configureDriver(msgDeviceInitReq); - drivers.push_back(_ms8607); - WS_DEBUG_PRINTLN("MS8607 Initialized Successfully!"); - } else if (strcmp("tmp117", msgDeviceInitReq->i2c_device_name) == 0) { - _tmp117 = new WipperSnapper_I2C_Driver_TMP117(this->_i2c, i2cAddress); - if (!_tmp117->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize TMP117!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _tmp117->configureDriver(msgDeviceInitReq); - drivers.push_back(_tmp117); - WS_DEBUG_PRINTLN("TMP117 Initialized Successfully!"); - } else if (strcmp("tsl2591", msgDeviceInitReq->i2c_device_name) == 0) { - _tsl2591 = new WipperSnapper_I2C_Driver_TSL2591(this->_i2c, i2cAddress); - if (!_tsl2591->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize TSL2591!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _tsl2591->configureDriver(msgDeviceInitReq); - drivers.push_back(_tsl2591); - WS_DEBUG_PRINTLN("TSL2591 Initialized Successfully!"); - } else if (strcmp("vcnl4020", msgDeviceInitReq->i2c_device_name) == 0) { - _vcnl4020 = new WipperSnapper_I2C_Driver_VCNL4020(this->_i2c, i2cAddress); - if (!_vcnl4020->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize VCNL4020!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _vcnl4020->configureDriver(msgDeviceInitReq); - drivers.push_back(_vcnl4020); - WS_DEBUG_PRINTLN("VCNL4020 Initialized Successfully!"); - } else if (strcmp("vcnl4040", msgDeviceInitReq->i2c_device_name) == 0) { - _vcnl4040 = new WipperSnapper_I2C_Driver_VCNL4040(this->_i2c, i2cAddress); - if (!_vcnl4040->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize VCNL4040!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _vcnl4040->configureDriver(msgDeviceInitReq); - drivers.push_back(_vcnl4040); - WS_DEBUG_PRINTLN("VCNL4040 Initialized Successfully!"); - } else if (strcmp("veml7700", msgDeviceInitReq->i2c_device_name) == 0) { - _veml7700 = new WipperSnapper_I2C_Driver_VEML7700(this->_i2c, i2cAddress); - if (!_veml7700->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize VEML7700!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _veml7700->configureDriver(msgDeviceInitReq); - drivers.push_back(_veml7700); - WS_DEBUG_PRINTLN("VEML7700 Initialized Successfully!"); - } else if (strcmp("scd40", msgDeviceInitReq->i2c_device_name) == 0) { - _scd40 = new WipperSnapper_I2C_Driver_SCD4X(this->_i2c, i2cAddress); - if (!_scd40->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize SCD4x!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _scd40->configureDriver(msgDeviceInitReq); - drivers.push_back(_scd40); - WS_DEBUG_PRINTLN("SCD4x Initialized Successfully!"); - } else if ((strcmp("sen5x", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("sen55", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("sen54", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("sen50", msgDeviceInitReq->i2c_device_name) == 0)) { - _sen5x = new WipperSnapper_I2C_Driver_SEN5X(this->_i2c, i2cAddress); - if (!_sen5x->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize SEN5X!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _sen5x->configureDriver(msgDeviceInitReq); - drivers.push_back(_sen5x); - WS_DEBUG_PRINTLN("SEN5X Initialized Successfully!"); - } else if ((strcmp("sht40", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("sht41", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("sht45", msgDeviceInitReq->i2c_device_name) == 0)) { - _sht4x = new WipperSnapper_I2C_Driver_SHT4X(this->_i2c, i2cAddress); - if (!_sht4x->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize sht4x!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _sht4x->configureDriver(msgDeviceInitReq); - drivers.push_back(_sht4x); - WS_DEBUG_PRINTLN("SHT4X Initialized Successfully!"); - } else if ((strcmp("sht3x", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("sht30_shell", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("sht30_mesh", msgDeviceInitReq->i2c_device_name) == 0)) { - _sht3x = new WipperSnapper_I2C_Driver_SHT3X(this->_i2c, i2cAddress); - if (!_sht3x->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize sht3x!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _sht3x->configureDriver(msgDeviceInitReq); - drivers.push_back(_sht3x); - WS_DEBUG_PRINTLN("SHT3X Initialized Successfully!"); - } else if (strcmp("shtc3", msgDeviceInitReq->i2c_device_name) == 0) { - _shtc3 = new WipperSnapper_I2C_Driver_SHTC3(this->_i2c, i2cAddress); - if (!_shtc3->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize SHTC3!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _shtc3->configureDriver(msgDeviceInitReq); - drivers.push_back(_shtc3); - WS_DEBUG_PRINTLN("SHTC3 Initialized Successfully!"); - } else if ((strcmp("pct2075", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("tc74a0", msgDeviceInitReq->i2c_device_name) == 0)) { - _pct2075 = new WipperSnapper_I2C_Driver_PCT2075(this->_i2c, i2cAddress); - if (!_pct2075->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize PCT2075 Temp Sensor!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _pct2075->configureDriver(msgDeviceInitReq); - drivers.push_back(_pct2075); - WS_DEBUG_PRINTLN("PCT2075 Temp Sensor Initialized Successfully!"); - } else if (strcmp("pmsa003i", msgDeviceInitReq->i2c_device_name) == 0) { - _pm25 = new WipperSnapper_I2C_Driver_PM25(this->_i2c, i2cAddress); - if (!_pm25->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize PM2.5 AQI Sensor!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _pm25->configureDriver(msgDeviceInitReq); - drivers.push_back(_pm25); - WS_DEBUG_PRINTLN("PM2.5 AQI Sensor Initialized Successfully!"); - } else if (strcmp("lc709203f", msgDeviceInitReq->i2c_device_name) == 0) { - _lc = new WipperSnapper_I2C_Driver_LC709203F(this->_i2c, i2cAddress); - if (!_lc->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize LC709203F Sensor!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _lc->configureDriver(msgDeviceInitReq); - drivers.push_back(_lc); - WS_DEBUG_PRINTLN("LC709203F Sensor Initialized Successfully!"); - } else if (strcmp("lps22hb", msgDeviceInitReq->i2c_device_name) == 0) { - _lps22hb = new WipperSnapper_I2C_Driver_LPS22HB(this->_i2c, i2cAddress); - if (!_lps22hb->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize LPS22HB Sensor!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _lps22hb->configureDriver(msgDeviceInitReq); - drivers.push_back(_lps22hb); - WS_DEBUG_PRINTLN("LPS22HB Sensor Initialized Successfully!"); - } else if (strcmp("lps25hb", msgDeviceInitReq->i2c_device_name) == 0) { - _lps25hb = new WipperSnapper_I2C_Driver_LPS25HB(this->_i2c, i2cAddress); - if (!_lps25hb->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize LPS25HB Sensor!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _lps25hb->configureDriver(msgDeviceInitReq); - drivers.push_back(_lps25hb); - WS_DEBUG_PRINTLN("LPS25HB Sensor Initialized Successfully!"); - } else if ((strcmp("lps33hw", msgDeviceInitReq->i2c_device_name) == 0) || - (strcmp("lps35hw", msgDeviceInitReq->i2c_device_name)) == 0) { - _lps3xhw = new WipperSnapper_I2C_Driver_LPS3XHW(this->_i2c, i2cAddress); - if (!_lps3xhw->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize LPS3XHW Sensor!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _lps3xhw->configureDriver(msgDeviceInitReq); - drivers.push_back(_lps3xhw); - WS_DEBUG_PRINTLN("LPS3XHW Sensor Initialized Successfully!"); - } else if (strcmp("stemma_soil", msgDeviceInitReq->i2c_device_name) == 0) { - _ss = - new WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor(this->_i2c, i2cAddress); - if (!_ss->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize STEMMA Soil Sensor!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _ss->configureDriver(msgDeviceInitReq); - drivers.push_back(_ss); - WS_DEBUG_PRINTLN("STEMMA Soil Sensor Initialized Successfully!"); - } else if (strcmp("vl53l0x", msgDeviceInitReq->i2c_device_name) == 0) { - _vl53l0x = new WipperSnapper_I2C_Driver_VL53L0X(this->_i2c, i2cAddress); - if (!_vl53l0x->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize VL53L0X!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _vl53l0x->configureDriver(msgDeviceInitReq); - drivers.push_back(_vl53l0x); - WS_DEBUG_PRINTLN("VL53L0X Initialized Successfully!"); - } else if (strcmp("vl53l1x", msgDeviceInitReq->i2c_device_name) == 0) { - _vl53l1x = new WipperSnapper_I2C_Driver_VL53L1X(this->_i2c, i2cAddress); - if (!_vl53l1x->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize VL53L1X!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _vl53l1x->configureDriver(msgDeviceInitReq); - drivers.push_back(_vl53l1x); - WS_DEBUG_PRINTLN("VL53L1X Initialized Successfully!"); - } else if (strcmp("vl53l4cd", msgDeviceInitReq->i2c_device_name) == 0) { - _vl53l4cd = new WipperSnapper_I2C_Driver_VL53L4CD(this->_i2c, i2cAddress); - if (!_vl53l4cd->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize VL53L4CD!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _vl53l4cd->configureDriver(msgDeviceInitReq); - drivers.push_back(_vl53l4cd); - WS_DEBUG_PRINTLN("VL53L4CD Initialized Successfully!"); - } else if (strcmp("vl53l4cx", msgDeviceInitReq->i2c_device_name) == 0) { - _vl53l4cx = new WipperSnapper_I2C_Driver_VL53L4CX(this->_i2c, i2cAddress); - if (!_vl53l4cx->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize VL53L4CX!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _vl53l4cx->configureDriver(msgDeviceInitReq); - drivers.push_back(_vl53l4cx); - WS_DEBUG_PRINTLN("VL53L4CX Initialized Successfully!"); - } else if (strcmp("vl6180x", msgDeviceInitReq->i2c_device_name) == 0) { - _vl6180x = new WipperSnapper_I2C_Driver_VL6180X(this->_i2c, i2cAddress); - if (!_vl6180x->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize VL6180X!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _vl6180x->configureDriver(msgDeviceInitReq); - drivers.push_back(_vl6180x); - WS_DEBUG_PRINTLN("VL6180X Initialized Successfully!"); - } else if (strcmp("max17048", msgDeviceInitReq->i2c_device_name) == 0) { - _max17048 = new WipperSnapper_I2C_Driver_MAX17048(this->_i2c, i2cAddress); - if (!_max17048->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize MAX17048/MAX17049!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _max17048->configureDriver(msgDeviceInitReq); - drivers.push_back(_max17048); - WS_DEBUG_PRINTLN("MAX17048/MAX17049 Initialized Successfully!"); - } else if (strcmp("adt7410", msgDeviceInitReq->i2c_device_name) == 0) { - _adt7410 = new WipperSnapper_I2C_Driver_ADT7410(this->_i2c, i2cAddress); - if (!_adt7410->begin()) { - WS_DEBUG_PRINTLN("ERROR: Failed to initialize ADT7410!"); - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL; - return false; - } - _adt7410->configureDriver(msgDeviceInitReq); - drivers.push_back(_adt7410); - WS_DEBUG_PRINTLN("ADT7410 Initialized Successfully!"); - } else { - WS_DEBUG_PRINTLN("ERROR: I2C device type not found!") - _busStatusResponse = - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_UNSUPPORTED_SENSOR; - return false; - } - _busStatusResponse = wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS; - return true; -} - -/*********************************************************************************/ -/*! - @brief Updates the properties of an I2C device driver. - @param msgDeviceUpdateReq - A decoded I2CDeviceUpdateRequest. -*/ -/*********************************************************************************/ -void WipperSnapper_Component_I2C::updateI2CDeviceProperties( - wippersnapper_i2c_v1_I2CDeviceUpdateRequest *msgDeviceUpdateReq) { - uint16_t i2cAddress = (uint16_t)msgDeviceUpdateReq->i2c_device_address; - - // Loop thru vector of drivers to find the unique address - for (size_t i = 0; i < drivers.size(); i++) { - if (drivers[i]->getI2CAddress() == i2cAddress) { - // Update the properties of each driver - for (int j = 0; j < msgDeviceUpdateReq->i2c_device_properties_count; - j++) { - drivers[i]->setSensorPeriod( - msgDeviceUpdateReq->i2c_device_properties[j].sensor_period, - msgDeviceUpdateReq->i2c_device_properties[j].sensor_type); - } - } - } - - // set response OK - _busStatusResponse = wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS; -} - -/*******************************************************************************/ -/*! - @brief Deinitializes and deletes an I2C device driver object. - @param msgDeviceDeinitReq - A decoded I2CDeviceDeinitRequest. -*/ -/*******************************************************************************/ -void WipperSnapper_Component_I2C::deinitI2CDevice( - wippersnapper_i2c_v1_I2CDeviceDeinitRequest *msgDeviceDeinitReq) { - uint16_t deviceAddr = (uint16_t)msgDeviceDeinitReq->i2c_device_address; - std::vector::iterator iter, end; - - for (iter = drivers.begin(), end = drivers.end(); iter != end; ++iter) { - if ((*iter)->getI2CAddress() == deviceAddr) { - // Delete the object that iter points to - // delete *iter; - *iter = nullptr; -// ESP-IDF, Erase–remove iter ptr from driver vector -#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - *iter = nullptr; - drivers.erase(remove(drivers.begin(), drivers.end(), nullptr), - drivers.end()); -#else - // Arduino can not erase-remove, erase only - drivers.erase(iter); -#endif - WS_DEBUG_PRINTLN("I2C Device De-initialized!"); - } - } - _busStatusResponse = wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS; -} - -/*******************************************************************************/ -/*! - @brief Encodes an I2C sensor device's signal message. - @param msgi2cResponse - Pointer to an I2CResponse signal message. - @param sensorAddress - The unique I2C address of the sensor. - @returns True if message encoded successfully, False otherwise. -*/ -/*******************************************************************************/ -bool WipperSnapper_Component_I2C::encodePublishI2CDeviceEventMsg( - wippersnapper_signal_v1_I2CResponse *msgi2cResponse, - uint32_t sensorAddress) { - // Encode I2CResponse msg - msgi2cResponse->payload.resp_i2c_device_event.sensor_address = sensorAddress; - memset(WS._buffer_outgoing, 0, sizeof(WS._buffer_outgoing)); - pb_ostream_t ostream = - pb_ostream_from_buffer(WS._buffer_outgoing, sizeof(WS._buffer_outgoing)); - if (!ws_pb_encode(&ostream, wippersnapper_signal_v1_I2CResponse_fields, - msgi2cResponse)) { - WS_DEBUG_PRINTLN( - "ERROR: Unable to encode I2C device event response message!"); - return false; - } - - // Publish I2CResponse msg - size_t msgSz; - pb_get_encoded_size(&msgSz, wippersnapper_signal_v1_I2CResponse_fields, - msgi2cResponse); - WS_DEBUG_PRINT("PUBLISHING -> I2C Device Sensor Event Message..."); - if (!WS._mqtt->publish(WS._topic_signal_i2c_device, WS._buffer_outgoing, - msgSz, 1)) { - WS_DEBUG_PRINTLN("ERROR: MQTT Publish failed!"); - return false; - }; - WS_DEBUG_PRINTLN("PUBLISHED!"); - return true; -} - -/*******************************************************************************/ -/*! - @brief Fills a sensor_event message with the sensor's value and type. - @param msgi2cResponse - A pointer to the signal's I2CResponse message. - @param value - The value read by the sensor. - @param sensorType - The SI unit represented by the sensor's value. -*/ -/*******************************************************************************/ -void WipperSnapper_Component_I2C::fillEventMessage( - wippersnapper_signal_v1_I2CResponse *msgi2cResponse, float value, - wippersnapper_i2c_v1_SensorType sensorType) { - // fill sensor value - msgi2cResponse->payload.resp_i2c_device_event - .sensor_event[msgi2cResponse->payload.resp_i2c_device_event - .sensor_event_count] - .value = value; - // fill sensor type - msgi2cResponse->payload.resp_i2c_device_event - .sensor_event[msgi2cResponse->payload.resp_i2c_device_event - .sensor_event_count] - .type = sensorType; - msgi2cResponse->payload.resp_i2c_device_event.sensor_event_count++; -} - -/*******************************************************************************/ -/*! - @brief Displays a sensor event message on the TFT - @param msgi2cResponse - A pointer to an I2CResponse message. - @param sensorAddress - The unique I2C address of the sensor. -*/ -/*******************************************************************************/ -void WipperSnapper_Component_I2C::displayDeviceEventMessage( - wippersnapper_signal_v1_I2CResponse *msgi2cResponse, - uint32_t sensorAddress) { - - pb_size_t numEvents = - msgi2cResponse->payload.resp_i2c_device_event.sensor_event_count; - - char buffer[100]; - for (int i = 0; i < numEvents; i++) { - float value = - msgi2cResponse->payload.resp_i2c_device_event.sensor_event[i].value; - - switch ( - msgi2cResponse->payload.resp_i2c_device_event.sensor_event[i].type) { - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE: - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE: - snprintf(buffer, 100, "[I2C: %#x] Read: %0.3f *C\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT: - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT: - snprintf(buffer, 100, "[I2C: %#x] Read: %0.3f *F\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_RELATIVE_HUMIDITY: - snprintf(buffer, 100, "[I2C: %#x] Read: %0.3f %% rh\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PRESSURE: - snprintf(buffer, 100, "[I2C: %#x] Read: %0.3f hPA\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_ALTITUDE: - snprintf(buffer, 100, "[I2C: %x] Read: %0.3f m\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_LIGHT: - snprintf(buffer, 100, "[I2C: %x] Read: %0.3f lux\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_STD: - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_STD: - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_STD: - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_CO2: - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_ECO2: - snprintf(buffer, 100, "[I2C: %x] Read: %0.3f ppm\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_TVOC: - snprintf(buffer, 100, "[I2C: %x] Read: %0.3f ppb\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_UNITLESS_PERCENT: - snprintf(buffer, 100, "[I2C: %x] Read: %0.3f%%\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOLTAGE: - snprintf(buffer, 100, "[I2C: %x] Read: %0.3f V\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_CURRENT: - snprintf(buffer, 100, "[I2C: %x] Read: %0.3f mA\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_RAW: - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PROXIMITY: - snprintf(buffer, 100, "[I2C: %x] Read: %0.3f\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_GAS_RESISTANCE: - snprintf(buffer, 100, "[I2C: %x] Read: %0.3f Ohms\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_NOX_INDEX: - snprintf(buffer, 100, "[I2C: %x] Read: %0.3f NOX\n", - (unsigned int)sensorAddress, value); - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOC_INDEX: - snprintf(buffer, 100, "[I2C: %x] Read: %0.3f VOC\n", - (unsigned int)sensorAddress, value); - break; - default: - break; - } -#ifdef USE_DISPLAY - WS._ui_helper->add_text_to_terminal(buffer); -#endif - } -} - -/*******************************************************************************/ -/*! - @brief Queries all I2C device drivers for new values. Fills and sends an - I2CSensorEvent with the sensor event data. -*/ -/*******************************************************************************/ -void WipperSnapper_Component_I2C::update() { - - // Create response message - wippersnapper_signal_v1_I2CResponse msgi2cResponse = - wippersnapper_signal_v1_I2CResponse_init_zero; - msgi2cResponse.which_payload = - wippersnapper_signal_v1_I2CResponse_resp_i2c_device_event_tag; - - long curTime; - bool sensorsReturningFalse = true; - int retries = 3; - - while (sensorsReturningFalse && retries > 0) { - sensorsReturningFalse = false; - retries--; - - std::vector::iterator iter, end; - for (iter = drivers.begin(), end = drivers.end(); iter != end; ++iter) { - // Number of events which occured for this driver - msgi2cResponse.payload.resp_i2c_device_event.sensor_event_count = 0; - - // Event struct - sensors_event_t event; - - // AMBIENT_TEMPERATURE sensor (°C) - sensorEventRead( - iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventAmbientTemp, - &WipperSnapper_I2C_Driver::getSensorAmbientTempPeriod, - &WipperSnapper_I2C_Driver::getSensorAmbientTempPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorAmbientTempPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE, - "Ambient Temperature", " degrees C", event, - &sensors_event_t::temperature, sensorsReturningFalse, retries); - - // Ambient Temperature sensor (°F) - sensorEventRead( - iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventAmbientTempF, - &WipperSnapper_I2C_Driver::getSensorAmbientTempFPeriod, - &WipperSnapper_I2C_Driver::getSensorAmbientTempFPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorAmbientTempFPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT, - "Ambient Temperature", " degrees F", event, - &sensors_event_t::temperature, sensorsReturningFalse, retries); - - // OBJECT_TEMPERATURE sensor (°C) - sensorEventRead( - iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventObjectTemp, - &WipperSnapper_I2C_Driver::getSensorObjectTempPeriod, - &WipperSnapper_I2C_Driver::getSensorObjectTempPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorObjectTempPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE, - "Object Temperature", " degrees C", event, - &sensors_event_t::temperature, sensorsReturningFalse, retries); - - // OBJECT_TEMPERATURE sensor (°F) - sensorEventRead( - iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventObjectTempF, - &WipperSnapper_I2C_Driver::getSensorObjectTempFPeriod, - &WipperSnapper_I2C_Driver::getSensorObjectTempFPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorObjectTempFPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT, - "Object Temperature", " degrees F", event, - &sensors_event_t::temperature, sensorsReturningFalse, retries); - - // RELATIVE_HUMIDITY sensor - sensorEventRead( - iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventRelativeHumidity, - &WipperSnapper_I2C_Driver::getSensorRelativeHumidityPeriod, - &WipperSnapper_I2C_Driver::getSensorRelativeHumidityPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorRelativeHumidityPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_RELATIVE_HUMIDITY, - "Humidity", " %RH", event, &sensors_event_t::relative_humidity, - sensorsReturningFalse, retries); - - // PRESSURE sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventPressure, - &WipperSnapper_I2C_Driver::getSensorPressurePeriod, - &WipperSnapper_I2C_Driver::getSensorPressurePeriodPrv, - &WipperSnapper_I2C_Driver::setSensorPressurePeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PRESSURE, - "Pressure", " hPa", event, &sensors_event_t::pressure, - sensorsReturningFalse, retries); - - // CO2 sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventCO2, - &WipperSnapper_I2C_Driver::getSensorCO2Period, - &WipperSnapper_I2C_Driver::getSensorCO2PeriodPrv, - &WipperSnapper_I2C_Driver::setSensorCO2PeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_CO2, "CO2", - " ppm", event, &sensors_event_t::CO2, - sensorsReturningFalse, retries); - - // eCO2 sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventECO2, - &WipperSnapper_I2C_Driver::getSensorECO2Period, - &WipperSnapper_I2C_Driver::getSensorECO2PeriodPrv, - &WipperSnapper_I2C_Driver::setSensorECO2PeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_ECO2, "eCO2", - " ppm", event, &sensors_event_t::eCO2, - sensorsReturningFalse, retries); - - // TVOC sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventTVOC, - &WipperSnapper_I2C_Driver::getSensorTVOCPeriod, - &WipperSnapper_I2C_Driver::getSensorTVOCPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorTVOCPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_TVOC, "TVOC", - " ppb", event, &sensors_event_t::tvoc, - sensorsReturningFalse, retries); - - // Altitude sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventAltitude, - &WipperSnapper_I2C_Driver::getSensorAltitudePeriod, - &WipperSnapper_I2C_Driver::getSensorAltitudePeriodPrv, - &WipperSnapper_I2C_Driver::setSensorAltitudePeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_ALTITUDE, - "Altitude", " m", event, &sensors_event_t::altitude, - sensorsReturningFalse, retries); - - // Light sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventLight, - &WipperSnapper_I2C_Driver::getSensorLightPeriod, - &WipperSnapper_I2C_Driver::getSensorLightPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorLightPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_LIGHT, - "Light", " lux", event, &sensors_event_t::light, - sensorsReturningFalse, retries); - - // PM10_STD sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventPM10_STD, - &WipperSnapper_I2C_Driver::getSensorPM10_STDPeriod, - &WipperSnapper_I2C_Driver::getSensorPM10_STDPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorPM10_STDPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_STD, - "PM1.0", " ppm", event, &sensors_event_t::pm10_std, - sensorsReturningFalse, retries); - - // PM25_STD sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventPM25_STD, - &WipperSnapper_I2C_Driver::getSensorPM25_STDPeriod, - &WipperSnapper_I2C_Driver::getSensorPM25_STDPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorPM25_STDPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_STD, - "PM2.5", " ppm", event, &sensors_event_t::pm25_std, - sensorsReturningFalse, retries); - - // PM100_STD sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventPM100_STD, - &WipperSnapper_I2C_Driver::getSensorPM100_STDPeriod, - &WipperSnapper_I2C_Driver::getSensorPM100_STDPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorPM100_STDPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_STD, - "PM10.0", " ppm", event, &sensors_event_t::pm100_std, - sensorsReturningFalse, retries); - - // Voltage sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventVoltage, - &WipperSnapper_I2C_Driver::getSensorVoltagePeriod, - &WipperSnapper_I2C_Driver::getSensorVoltagePeriodPrv, - &WipperSnapper_I2C_Driver::setSensorVoltagePeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOLTAGE, - "Voltage", " V", event, &sensors_event_t::voltage, - sensorsReturningFalse, retries); - - // Current sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventCurrent, - &WipperSnapper_I2C_Driver::getSensorCurrentPeriod, - &WipperSnapper_I2C_Driver::getSensorCurrentPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorCurrentPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_CURRENT, - "Current", " mA", event, &sensors_event_t::current, - sensorsReturningFalse, retries); - - // Unitless % sensor - sensorEventRead( - iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventUnitlessPercent, - &WipperSnapper_I2C_Driver::getSensorUnitlessPercentPeriod, - &WipperSnapper_I2C_Driver::getSensorUnitlessPercentPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorUnitlessPercentPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_UNITLESS_PERCENT, - "Unitless Percent", " %", event, &sensors_event_t::unitless_percent, - sensorsReturningFalse, retries); - - // Raw sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventRaw, - &WipperSnapper_I2C_Driver::getSensorRawPeriod, - &WipperSnapper_I2C_Driver::getSensorRawPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorRawPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_RAW, "Raw", - "", event, nullptr, sensorsReturningFalse, retries); - - // Gas sensor - sensorEventRead( - iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventGasResistance, - &WipperSnapper_I2C_Driver::getSensorGasResistancePeriod, - &WipperSnapper_I2C_Driver::getSensorGasResistancePeriodPrv, - &WipperSnapper_I2C_Driver::setSensorGasResistancePeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_GAS_RESISTANCE, - "Gas Resistance", " Ohms", event, &sensors_event_t::gas_resistance, - sensorsReturningFalse, retries); - - // NOx-index sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventNOxIndex, - &WipperSnapper_I2C_Driver::getSensorNOxIndexPeriod, - &WipperSnapper_I2C_Driver::getSensorNOxIndexPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorNOxIndexPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_NOX_INDEX, - "NOx Index", "", event, &sensors_event_t::nox_index, - sensorsReturningFalse, retries); - - // VOC-index sensor - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventVOCIndex, - &WipperSnapper_I2C_Driver::getSensorVOCIndexPeriod, - &WipperSnapper_I2C_Driver::getSensorVOCIndexPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorVOCIndexPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOC_INDEX, - "VOC Index", "", event, &sensors_event_t::voc_index, - sensorsReturningFalse, retries); - - // Proximity sensor -- sends using event.data[0] same as raw sensor_type - sensorEventRead(iter, curTime, &msgi2cResponse, - &WipperSnapper_I2C_Driver::getEventProximity, - &WipperSnapper_I2C_Driver::sensorProximityPeriod, - &WipperSnapper_I2C_Driver::SensorProximityPeriodPrv, - &WipperSnapper_I2C_Driver::setSensorProximityPeriodPrv, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PROXIMITY, - "Proximity", "", event, nullptr, sensorsReturningFalse, - retries); - - // Did this driver obtain data from sensors? - if (msgi2cResponse.payload.resp_i2c_device_event.sensor_event_count == - 0) { - continue; - } - - displayDeviceEventMessage(&msgi2cResponse, (*iter)->getI2CAddress()); - - // Encode and publish I2CDeviceEvent message - if (!encodePublishI2CDeviceEventMsg(&msgi2cResponse, - (*iter)->getI2CAddress())) { - WS_DEBUG_PRINTLN("ERROR: Failed to encode and publish I2CDeviceEvent!"); - continue; - } - } // end of retry loop - } -} - -/*******************************************************************************/ -/*! - @brief Reads a sensor event from an I2C device driver. - @param iter - An iterator pointing to the current I2C device driver. - @param curTime - The current time in milliseconds. - @param msgi2cResponse - A pointer to the I2CResponse message. - @param getEventFunc - A pointer to the I2C device driver's getEvent function. - @param getPeriodFunc - A pointer to the I2C device driver's getPeriod function. - @param getPeriodPrvFunc - A pointer to the I2C device driver's getPeriodPrv function. - @param setPeriodPrvFunc - A pointer to the I2C device driver's setPeriodPrv function. - @param sensorType - The type of sensor being read. - @param sensorName - The name of the sensor being read. - @param unit - The unit of measurement for the sensor. - @param event - A sensors_event_t struct. - @param valueMember - Pointer to sensors_event_t struct's value member unless data[0]. - @param sensorsReturningFalse - A boolean indicating if the sensor is returning false. - @param retries - The number of retries left for the sensor. -*/ -void WipperSnapper_Component_I2C::sensorEventRead( - std::vector::iterator &iter, - unsigned long curTime, wippersnapper_signal_v1_I2CResponse *msgi2cResponse, - bool (WipperSnapper_I2C_Driver::*getEventFunc)(sensors_event_t *), - long (WipperSnapper_I2C_Driver::*getPeriodFunc)(), - long (WipperSnapper_I2C_Driver::*getPeriodPrvFunc)(), - void (WipperSnapper_I2C_Driver::*setPeriodPrvFunc)(long), - wippersnapper_i2c_v1_SensorType sensorType, const char *sensorName, - const char *unit, sensors_event_t event, - float sensors_event_t::*valueMember, bool &sensorsReturningFalse, - int &retries) { - // sensorName used for prefix + error message, units is value suffix - curTime = millis(); - if (((*iter)->*getPeriodFunc)() != 0L && - curTime - ((*iter)->*getPeriodPrvFunc)() > ((*iter)->*getPeriodFunc)()) { - // within the period, read the sensor - if (((*iter)->*getEventFunc)(&event)) { - float value; - if (sensorType == wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_RAW || - sensorType == wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PROXIMITY) { - value = event.data[0]; - } else { - value = event.*valueMember; - } - WS_DEBUG_PRINT("Sensor 0x"); - WS_DEBUG_PRINTHEX((*iter)->getI2CAddress()); - WS_DEBUG_PRINTLN(""); - WS_DEBUG_PRINT("\t"); - WS_DEBUG_PRINT(sensorName); - WS_DEBUG_PRINT(": "); - WS_DEBUG_PRINT(value); - WS_DEBUG_PRINTLN(unit); - - // pack event data into msg - fillEventMessage(msgi2cResponse, value, sensorType); - - ((*iter)->*setPeriodPrvFunc)(curTime); - } else { - WS_DEBUG_PRINT("ERROR: Failed to get "); - WS_DEBUG_PRINT(sensorName); - WS_DEBUG_PRINTLN(" reading!"); - sensorsReturningFalse = true; - if (retries == 1) { - ((*iter)->*setPeriodPrvFunc)(curTime); - } - } - } -} diff --git a/src/components/i2c/WipperSnapper_I2C.h b/src/components/i2c/WipperSnapper_I2C.h deleted file mode 100644 index 008397258..000000000 --- a/src/components/i2c/WipperSnapper_I2C.h +++ /dev/null @@ -1,186 +0,0 @@ -/*! - * @file WipperSnapper_I2C.h - * - * This component initiates I2C operations - * using the Arduino generic TwoWire driver. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2021 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ -#ifndef WipperSnapper_Component_I2C_H -#define WipperSnapper_Component_I2C_H - -#include "Wippersnapper.h" -#include - -#include "drivers/WipperSnapper_I2C_Driver.h" -#include "drivers/WipperSnapper_I2C_Driver_ADT7410.h" -#include "drivers/WipperSnapper_I2C_Driver_AHTX0.h" -#include "drivers/WipperSnapper_I2C_Driver_BH1750.h" -#include "drivers/WipperSnapper_I2C_Driver_BME280.h" -#include "drivers/WipperSnapper_I2C_Driver_BME680.h" -#include "drivers/WipperSnapper_I2C_Driver_BMP280.h" -#include "drivers/WipperSnapper_I2C_Driver_BMP3XX.h" -#include "drivers/WipperSnapper_I2C_Driver_DPS310.h" -#include "drivers/WipperSnapper_I2C_Driver_DS2484.h" -#include "drivers/WipperSnapper_I2C_Driver_ENS160.h" -#include "drivers/WipperSnapper_I2C_Driver_HTS221.h" -#include "drivers/WipperSnapper_I2C_Driver_HTU21D.h" -#include "drivers/WipperSnapper_I2C_Driver_HTU31D.h" -#include "drivers/WipperSnapper_I2C_Driver_INA219.h" -#include "drivers/WipperSnapper_I2C_Driver_LC709203F.h" -#include "drivers/WipperSnapper_I2C_Driver_LPS22HB.h" -#include "drivers/WipperSnapper_I2C_Driver_LPS25HB.h" -#include "drivers/WipperSnapper_I2C_Driver_LPS3XHW.h" -#include "drivers/WipperSnapper_I2C_Driver_LTR329_LTR303.h" -#include "drivers/WipperSnapper_I2C_Driver_LTR390.h" -#include "drivers/WipperSnapper_I2C_Driver_MAX17048.h" -#include "drivers/WipperSnapper_I2C_Driver_MCP3421.h" -#include "drivers/WipperSnapper_I2C_Driver_MCP9808.h" -#include "drivers/WipperSnapper_I2C_Driver_MPL115A2.h" -#include "drivers/WipperSnapper_I2C_Driver_MPRLS.h" -#include "drivers/WipperSnapper_I2C_Driver_MS8607.h" -#include "drivers/WipperSnapper_I2C_Driver_NAU7802.h" -#include "drivers/WipperSnapper_I2C_Driver_PCT2075.h" -#include "drivers/WipperSnapper_I2C_Driver_PM25.h" -#include "drivers/WipperSnapper_I2C_Driver_SCD30.h" -#include "drivers/WipperSnapper_I2C_Driver_SCD4X.h" -#include "drivers/WipperSnapper_I2C_Driver_SEN5X.h" -#include "drivers/WipperSnapper_I2C_Driver_SGP30.h" -#include "drivers/WipperSnapper_I2C_Driver_SGP40.h" -#include "drivers/WipperSnapper_I2C_Driver_SHT3X.h" -#include "drivers/WipperSnapper_I2C_Driver_SHT4X.h" -#include "drivers/WipperSnapper_I2C_Driver_SHTC3.h" -#include "drivers/WipperSnapper_I2C_Driver_SI7021.h" -#include "drivers/WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor.h" -#include "drivers/WipperSnapper_I2C_Driver_TMP117.h" -#include "drivers/WipperSnapper_I2C_Driver_TSL2591.h" -#include "drivers/WipperSnapper_I2C_Driver_VCNL4020.h" -#include "drivers/WipperSnapper_I2C_Driver_VCNL4040.h" -#include "drivers/WipperSnapper_I2C_Driver_VEML7700.h" -#include "drivers/WipperSnapper_I2C_Driver_VL53L0X.h" -#include "drivers/WipperSnapper_I2C_Driver_VL53L1X.h" -#include "drivers/WipperSnapper_I2C_Driver_VL53L4CD.h" -#include "drivers/WipperSnapper_I2C_Driver_VL53L4CX.h" -#include "drivers/WipperSnapper_I2C_Driver_VL6180X.h" - -#define I2C_TIMEOUT_MS 50 ///< Default I2C timeout, in milliseconds. - -// forward decl. -class Wippersnapper; - -/**************************************************************************/ -/*! - @brief Class that provides an interface with the I2C bus. -*/ -/**************************************************************************/ -class WipperSnapper_Component_I2C { -public: - WipperSnapper_Component_I2C( - wippersnapper_i2c_v1_I2CBusInitRequest *msgInitRequest); - ~WipperSnapper_Component_I2C(); - bool isInitialized(); - wippersnapper_i2c_v1_BusResponse getBusStatus(); - - wippersnapper_i2c_v1_I2CBusScanResponse scanAddresses(); - bool - initI2CDevice(wippersnapper_i2c_v1_I2CDeviceInitRequest *msgDeviceInitReq); - - void updateI2CDeviceProperties( - wippersnapper_i2c_v1_I2CDeviceUpdateRequest *msgDeviceUpdateReq); - void deinitI2CDevice( - wippersnapper_i2c_v1_I2CDeviceDeinitRequest *msgDeviceDeinitReq); - - void update(); - - void sensorEventRead( - std::vector::iterator &iter, - unsigned long curTime, - wippersnapper_signal_v1_I2CResponse *msgi2cResponse, - bool (WipperSnapper_I2C_Driver::*getEventFunc)(sensors_event_t *), - long (WipperSnapper_I2C_Driver::*getPeriodFunc)(), - long (WipperSnapper_I2C_Driver::*getPeriodPrvFunc)(), - void (WipperSnapper_I2C_Driver::*setPeriodPrvFunc)(long), - wippersnapper_i2c_v1_SensorType sensorType, const char *sensorName, - const char *unit, sensors_event_t event, - float sensors_event_t::*valueMember, bool &sensorsReturningFalse, - int &retries); - - void fillEventMessage(wippersnapper_signal_v1_I2CResponse *msgi2cResponse, - float value, - wippersnapper_i2c_v1_SensorType sensorType); - - void - displayDeviceEventMessage(wippersnapper_signal_v1_I2CResponse *msgi2cResponse, - uint32_t sensorAddress); - - bool encodePublishI2CDeviceEventMsg( - wippersnapper_signal_v1_I2CResponse *msgi2cResponse, - uint32_t sensorAddress); - -private: - bool _isInit = false; - int32_t _portNum; - TwoWire *_i2c = nullptr; - wippersnapper_i2c_v1_BusResponse _busStatusResponse; - std::vector drivers; ///< List of sensor drivers - // Sensor driver objects - WipperSnapper_I2C_Driver_AHTX0 *_ahtx0 = nullptr; - WipperSnapper_I2C_Driver_DPS310 *_dps310 = nullptr; - WipperSnapper_I2C_Driver_DS2484 *_ds2484 = nullptr; - WipperSnapper_I2C_Driver_ENS160 *_ens160 = nullptr; - WipperSnapper_I2C_Driver_SCD30 *_scd30 = nullptr; - WipperSnapper_I2C_Driver_BH1750 *_bh1750 = nullptr; - WipperSnapper_I2C_Driver_BME280 *_bme280 = nullptr; - WipperSnapper_I2C_Driver_BMP280 *_bmp280 = nullptr; - WipperSnapper_I2C_Driver_BMP3XX *_bmp3xx = nullptr; - WipperSnapper_I2C_Driver_BME680 *_bme680 = nullptr; - WipperSnapper_I2C_Driver_HTS221 *_hts221 = nullptr; - WipperSnapper_I2C_Driver_HTU21D *_htu21d = nullptr; - WipperSnapper_I2C_Driver_HTU31D *_htu31d = nullptr; - WipperSnapper_I2C_Driver_INA219 *_ina219 = nullptr; - WipperSnapper_I2C_Driver_LTR329_LTR303 *_ltr329 = nullptr; - WipperSnapper_I2C_Driver_LTR390 *_ltr390 = nullptr; - WipperSnapper_I2C_Driver_MCP3421 *_mcp3421 = nullptr; - WipperSnapper_I2C_Driver_MCP9808 *_mcp9808 = nullptr; - WipperSnapper_I2C_Driver_MPL115A2 *_mpl115a2 = nullptr; - WipperSnapper_I2C_Driver_MPRLS *_mprls = nullptr; - WipperSnapper_I2C_Driver_MS8607 *_ms8607 = nullptr; - WipperSnapper_I2C_Driver_NAU7802 *_nau7802 = nullptr; - WipperSnapper_I2C_Driver_TMP117 *_tmp117 = nullptr; - WipperSnapper_I2C_Driver_TSL2591 *_tsl2591 = nullptr; - WipperSnapper_I2C_Driver_VCNL4020 *_vcnl4020 = nullptr; - WipperSnapper_I2C_Driver_VCNL4040 *_vcnl4040 = nullptr; - WipperSnapper_I2C_Driver_VEML7700 *_veml7700 = nullptr; - WipperSnapper_I2C_Driver_SCD4X *_scd40 = nullptr; - WipperSnapper_I2C_Driver_SEN5X *_sen5x = nullptr; - WipperSnapper_I2C_Driver_SGP30 *_sgp30 = nullptr; - WipperSnapper_I2C_Driver_SGP40 *_sgp40 = nullptr; - WipperSnapper_I2C_Driver_PCT2075 *_pct2075 = nullptr; - WipperSnapper_I2C_Driver_PM25 *_pm25 = nullptr; - WipperSnapper_I2C_Driver_SI7021 *_si7021 = nullptr; - WipperSnapper_I2C_Driver_SHT4X *_sht4x = nullptr; - WipperSnapper_I2C_Driver_SHT3X *_sht3x = nullptr; - WipperSnapper_I2C_Driver_SHTC3 *_shtc3 = nullptr; - WipperSnapper_I2C_Driver_LC709203F *_lc = nullptr; - WipperSnapper_I2C_Driver_LPS22HB *_lps22hb = nullptr; - WipperSnapper_I2C_Driver_LPS25HB *_lps25hb = nullptr; - WipperSnapper_I2C_Driver_LPS3XHW *_lps3xhw = nullptr; - WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor *_ss = nullptr; - WipperSnapper_I2C_Driver_VL53L0X *_vl53l0x = nullptr; - WipperSnapper_I2C_Driver_VL53L1X *_vl53l1x = nullptr; - WipperSnapper_I2C_Driver_VL53L4CD *_vl53l4cd = nullptr; - WipperSnapper_I2C_Driver_VL53L4CX *_vl53l4cx = nullptr; - WipperSnapper_I2C_Driver_VL6180X *_vl6180x = nullptr; - WipperSnapper_I2C_Driver_MAX17048 *_max17048 = nullptr; - WipperSnapper_I2C_Driver_ADT7410 *_adt7410 = nullptr; -}; -extern Wippersnapper WS; - -#endif // WipperSnapper_Component_I2C_H diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp new file mode 100644 index 000000000..ebba20477 --- /dev/null +++ b/src/components/i2c/controller.cpp @@ -0,0 +1,758 @@ +/*! + * @file controller.cpp + * + * Controller for the i2c.proto API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2025 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "controller.h" + +/*******************************************************************************/ +/*! + @brief Lambda function to create a drvBase driver instance + @param i2c + The desired I2C interface. + @param addr + The desired i2c device address. + @param mux_channel + The desired I2C multiplexer channel. + @param driver_name + The i2c driver's name. +*/ +/*******************************************************************************/ +using FnCreateI2CDriver = + std::function; + +// Factory for creating a new I2C drivers +// NOTE: When you add a new driver, make sure to add it to the factory! +static const std::map I2cFactory = { + {"bme280", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvBme280(i2c, addr, mux_channel, driver_name); + }}, + {"adt7410", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvAdt7410(i2c, addr, mux_channel, driver_name); + }}, + {"aht20", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvAhtx0(i2c, addr, mux_channel, driver_name); + }}, + {"am2301b", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvAhtx0(i2c, addr, mux_channel, driver_name); + }}, + {"am2315c", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvAhtx0(i2c, addr, mux_channel, driver_name); + }}, + {"dht20", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvAhtx0(i2c, addr, mux_channel, driver_name); + }}, + {"bh1750", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvBh1750(i2c, addr, mux_channel, driver_name); + }}, + {"bme680", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvBme680(i2c, addr, mux_channel, driver_name); + }}, + {"bme688", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvBme680(i2c, addr, mux_channel, driver_name); + }}, + {"BMP280", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvBmp3xx(i2c, addr, mux_channel, driver_name); + }}, + {"bmp388", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvBmp3xx(i2c, addr, mux_channel, driver_name); + }}, + {"bmp390", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvBmp3xx(i2c, addr, mux_channel, driver_name); + }}, + {"bmp280", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvBmp280(i2c, addr, mux_channel, driver_name); + }}, + {"dps310", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvDps310(i2c, addr, mux_channel, driver_name); + }}, + {"ds2484", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvDs2484(i2c, addr, mux_channel, driver_name); + }}, + {"ens160", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvEns160(i2c, addr, mux_channel, driver_name); + }}, + {"hts221", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvHts221(i2c, addr, mux_channel, driver_name); + }}, + {"htu21d", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvHtu21d(i2c, addr, mux_channel, driver_name); + }}, + {"ina219", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvIna219(i2c, addr, mux_channel, driver_name); + }}, + {"lc709203f", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLc709203f(i2c, addr, mux_channel, driver_name); + }}, + {"lps3xhw", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLps3xhw(i2c, addr, mux_channel, driver_name); + }}, + {"lps22hb", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLps22hb(i2c, addr, mux_channel, driver_name); + }}, + {"lps25hb", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLps25hb(i2c, addr, mux_channel, driver_name); + }}, + {"ltr329", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLtr329_Ltr303(i2c, addr, mux_channel, driver_name); + }}, + {"ltr303", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLtr329_Ltr303(i2c, addr, mux_channel, driver_name); + }}, + {"ltr390", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLtr390(i2c, addr, mux_channel, driver_name); + }}, + {"max17048", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvMax1704x(i2c, addr, mux_channel, driver_name); + }}, + {"mcp3421", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvMax1704x(i2c, addr, mux_channel, driver_name); + }}, + {"mcp9808", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvMcp9808(i2c, addr, mux_channel, driver_name); + }}, + {"mpl115a2", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvMpl115a2(i2c, addr, mux_channel, driver_name); + }}, + {"mprls", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvMprls(i2c, addr, mux_channel, driver_name); + }}, + {"ms8607", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvMs8607(i2c, addr, mux_channel, driver_name); + }}, + {"nau7802", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvNau7802(i2c, addr, mux_channel, driver_name); + }}, + {"pct2075", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvPct2075(i2c, addr, mux_channel, driver_name); + }}, + {"pmsa003i", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvPm25(i2c, addr, mux_channel, driver_name); + }}, + {"scd40", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvScd4x(i2c, addr, mux_channel, driver_name); + }}, + {"scd41", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvScd4x(i2c, addr, mux_channel, driver_name); + }}, + {"scd30", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvScd30(i2c, addr, mux_channel, driver_name); + }}, + {"sgp40", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSgp40(i2c, addr, mux_channel, driver_name); + }}, + {"sht3x", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSht3x(i2c, addr, mux_channel, driver_name); + }}, + {"sht30_shell", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSht3x(i2c, addr, mux_channel, driver_name); + }}, + {"sht30_mesh", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSht3x(i2c, addr, mux_channel, driver_name); + }}, + {"sht40", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSht4x(i2c, addr, mux_channel, driver_name); + }}, + {"sht41", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSht4x(i2c, addr, mux_channel, driver_name); + }}, + {"sht45", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSht4x(i2c, addr, mux_channel, driver_name); + }}, + {"sen5x", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSen5x(i2c, addr, mux_channel, driver_name); + }}, + {"sen55", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSen5x(i2c, addr, mux_channel, driver_name); + }}, + {"sen54", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSen5x(i2c, addr, mux_channel, driver_name); + }}, + {"sen50", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSen5x(i2c, addr, mux_channel, driver_name); + }}, + {"shtc3", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvShtc3(i2c, addr, mux_channel, driver_name); + }}, + {"si7021", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSi7021(i2c, addr, mux_channel, driver_name); + }}, + {"stemma_soil", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvSen5x(i2c, addr, mux_channel, driver_name); + }}, + {"tmp117", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvTmp117(i2c, addr, mux_channel, driver_name); + }}, + {"tsl2591", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvTsl2591(i2c, addr, mux_channel, driver_name); + }}, + {"vncl4020", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvVncl4020(i2c, addr, mux_channel, driver_name); + }}, + {"veml7700", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvVeml7700(i2c, addr, mux_channel, driver_name); + }}, + {"vncl4040", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvVncl4040(i2c, addr, mux_channel, driver_name); + }}, + {"vl53l0x", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvVl53l0x(i2c, addr, mux_channel, driver_name); + }}, + {"vl53l1x", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvVl53l1x(i2c, addr, mux_channel, driver_name); + }}, + {"vl53l4cd", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvVl53l4cd(i2c, addr, mux_channel, driver_name); + }}, + {"vl53l4cx", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvVl53l4cx(i2c, addr, mux_channel, driver_name); + }}, + {"vl6180x", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvVl6180x(i2c, addr, mux_channel, driver_name); + }}}; ///< I2C driver factory + +/***********************************************************************/ +/*! + @brief Creates an I2C driver by name + @param driver_name + The name of the I2C driver. + @param i2c + The I2C bus. + @param addr + The I2C device address. + @param i2c_mux_channel + The I2C MUX channel. + @param status + The I2cDeviceStatus message. + @returns A pointer to the I2C driver. +*/ +/***********************************************************************/ +drvBase *CreateI2CDriverByName(const char *driver_name, TwoWire *i2c, + uint16_t addr, uint32_t i2c_mux_channel, + wippersnapper_i2c_I2cDeviceStatus &status) { + auto it = I2cFactory.find(driver_name); + if (it == I2cFactory.end()) { + status = + wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_FAIL_UNSUPPORTED_SENSOR; + return nullptr; + } + + status = wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_SUCCESS; + return it->second(i2c, addr, i2c_mux_channel, driver_name); +} + +/***********************************************************************/ +/*! + @brief I2cController constructor +*/ +/***********************************************************************/ +I2cController::I2cController() { + _i2c_bus_alt = nullptr; + _i2c_model = new I2cModel(); + // Initialize the default I2C bus + _i2c_bus_default = new I2cHardware(); + _i2c_bus_default->InitBus(true); +} + +/***********************************************************************/ +/*! + @brief I2cController destructor +*/ +/***********************************************************************/ +I2cController::~I2cController() { + if (_i2c_model) + delete _i2c_model; + + if (_i2c_bus_default) + delete _i2c_bus_default; +} + +/*************************************************************************/ +/*! + @brief Returns if the I2C bus has been created successfully. + @param is_alt_bus + True if the alt. I2C bus is being queried, False otherwise. + @returns True if the I2C bus has already been created, False otherwise. +*/ +/*************************************************************************/ +bool I2cController::IsBusStatusOK(bool is_alt_bus) { + bool is_ok = false; + if (is_alt_bus) { + is_ok = (_i2c_bus_alt->GetBusStatus() == + wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_SUCCESS); + } else { + is_ok = (_i2c_bus_default->GetBusStatus() == + wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_SUCCESS); + } + return is_ok; +} + +/***********************************************************************/ +/*! + @brief Publishes an I2cDeviceAddedorReplaced message to the broker + @param device_descriptor + The I2cDeviceDescriptor message. + @param device_status + The I2cDeviceStatus message. + @returns True if the I2cDeviceAddedorReplaced message was published + successfully, False otherwise. +*/ +/***********************************************************************/ +bool I2cController::PublishI2cDeviceAddedorReplaced( + const wippersnapper_i2c_I2cDeviceDescriptor &device_descriptor, + const wippersnapper_i2c_I2cDeviceStatus &device_status) { + if (!_i2c_model->encodeMsgI2cDeviceAddedorReplaced( + device_descriptor, _i2c_bus_default->GetBusStatus(), device_status)) { + WS_DEBUG_PRINTLN( + "[i2c] ERROR: Unable to encode I2cDeviceAddedorReplaced message!"); + return false; + } + + if (WsV2._sdCardV2->isModeOffline()) + return true; // Back out if we're in offline mode + + if (!WsV2.PublishSignal( + wippersnapper_signal_DeviceToBroker_i2c_device_added_replaced_tag, + _i2c_model->GetMsgI2cDeviceAddedOrReplaced())) { + WS_DEBUG_PRINTLN("[i2c] ERROR: Unable to publish I2cDeviceAddedorReplaced " + "message to IO!"); + return false; + } + return true; +} + +/***********************************************************************/ +/*! + @brief Implements handling for a I2cDeviceRemove message + @param stream + A pointer to the pb_istream_t stream. + @returns True if the I2cDeviceRemove message was handled, False + otherwise. +*/ +/***********************************************************************/ +bool I2cController::Handle_I2cDeviceRemove(pb_istream_t *stream) { + // Attempt to decode an I2cDeviceRemove message + WS_DEBUG_PRINTLN("[i2c] Decoding I2cDeviceRemove message..."); + if (!_i2c_model->DecodeI2cDeviceRemove(stream)) { + WS_DEBUG_PRINTLN("[i2c] ERROR: Unable to decode I2cDeviceRemove message!"); + return false; + } + + // TODO [Online]: Implement the rest of this function + WS_DEBUG_PRINTLN("[i2c] I2cDeviceRemove message not yet implemented!"); + + return true; +} + +/***********************************************************************/ +/*! + @brief Attempts to initialize a MUX on the bus. + @param name + The name of the MUX to initialize, used to set number + of channels. + @param address + The MUX's I2C address. + @param is_alt_bus + True if the alternative I2C bus is being used, False + otherwise. + @returns True if the MUX was successfully initialized, False + otherwise. +*/ +/***********************************************************************/ +bool I2cController::InitMux(const char *name, uint32_t address, + bool is_alt_bus) { + if (is_alt_bus) { + if (!_i2c_bus_alt->HasMux()) { + if (!_i2c_bus_alt->AddMuxToBus(address, name)) { + return false; + } + } + } else { + if (!_i2c_bus_default->HasMux()) { + if (!_i2c_bus_default->AddMuxToBus(address, name)) { + return false; + } + } + } + // TODO [Online]: Publish back out to IO here! + return true; +} + +/***********************************************************************/ +/*! + @brief Implements handling for a I2cDeviceAddOrReplace message + @param stream + A pointer to the pb_istream_t stream. + @returns True if the I2cDeviceAddOrReplace message was handled + (created or replaced), False otherwise. +*/ +/***********************************************************************/ +bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) { + bool use_alt_bus = false; + bool did_set_mux_ch = false; + // Attempt to decode an I2cDeviceAddOrReplace message + WS_DEBUG_PRINTLN("[i2c] Decoding I2cDeviceAddOrReplace message..."); + if (!_i2c_model->DecodeI2cDeviceAddReplace(stream)) { + WS_DEBUG_PRINTLN( + "[i2c] ERROR: Unable to decode I2cDeviceAddOrReplace message!"); + return false; + } + + wippersnapper_i2c_I2cDeviceStatus device_status = + wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_UNSPECIFIED; + // Parse out device name and descriptor + char device_name[15]; + strcpy(device_name, + _i2c_model->GetI2cDeviceAddOrReplaceMsg()->i2c_device_name); + wippersnapper_i2c_I2cDeviceDescriptor device_descriptor = + _i2c_model->GetI2cDeviceAddOrReplaceMsg()->i2c_device_description; + + // TODO [Online]: Handle Replace messages by implementing the Remove handler + // first...then proceed to adding a new device + + // Does the device's descriptor specify a different i2c bus? + if (strcmp(device_descriptor.i2c_bus_scl, "default") != 0) { + WS_DEBUG_PRINTLN("[i2c] Non-default I2C bus specified!"); + if (_i2c_bus_alt == nullptr) { + WS_DEBUG_PRINTLN("[i2c] Initializing alternative i2c bus..."); + _i2c_bus_alt = new I2cHardware(); + _i2c_bus_alt->InitBus(false, device_descriptor.i2c_bus_sda, + device_descriptor.i2c_bus_scl); + } + use_alt_bus = true; + } + + // Before we do anything on the bus - was the bus initialized correctly? + if (!IsBusStatusOK(use_alt_bus)) { + WS_DEBUG_PRINTLN( + "[i2c] I2C bus is stuck or not operational, reset the board!"); + if (WsV2._sdCardV2->isModeOffline()) { + WsV2.haltErrorV2(" ", WS_LED_STATUS_ERROR_RUNTIME, + false); // doesn't return, halts + } + if (!PublishI2cDeviceAddedorReplaced(device_descriptor, device_status)) { + WS_DEBUG_PRINTLN("[i2c] ERROR: Unable to publish message to IO!"); + return false; + } + return true; + } + + // I2C MUX (Case #1) - We are creating an I2C mux via the + // I2cDeviceAddorReplace message + if ((strcmp(device_name, "pca9546") == 0) || + (strcmp(device_name, "pca9548") == 0)) { + WS_DEBUG_PRINT("[i2c] Initializing MUX driver..."); + if (!InitMux(device_name, device_descriptor.i2c_mux_address, use_alt_bus)) { + // TODO [Online]: Publish back out to IO here! + WsV2.haltErrorV2("[i2c] Failed to initialize MUX driver!", + WS_LED_STATUS_ERROR_RUNTIME, false); + } + WS_DEBUG_PRINTLN("OK!"); + return true; + } + + // Mux case #2 - We are creating a new driver that USES THE MUX via + // I2cDeviceAddorReplace message + if (device_descriptor.i2c_mux_address != 0x00) { + if (_i2c_bus_alt->HasMux() || _i2c_bus_default->HasMux()) { + WS_DEBUG_PRINT("[i2c] Configuring MUX channel: "); + WS_DEBUG_PRINTLN(device_descriptor.i2c_mux_channel); + ConfigureMuxChannel(device_descriptor.i2c_mux_channel, use_alt_bus); + did_set_mux_ch = true; + } else { + WsV2.haltErrorV2("[i2c] Device requires a MUX but MUX not present " + "within config.json!", + WS_LED_STATUS_ERROR_RUNTIME, false); + } + } + + WS_DEBUG_PRINTLN("Creating a new I2C driver"); + // Assign I2C bus + TwoWire *bus = nullptr; + if (use_alt_bus) { + bus = _i2c_bus_alt->GetBus(); + } else { + bus = _i2c_bus_default->GetBus(); + } + + drvBase *drv = CreateI2CDriverByName( + device_name, bus, device_descriptor.i2c_device_address, + device_descriptor.i2c_mux_channel, device_status); + if (drv == nullptr) { + WS_DEBUG_PRINTLN("[i2c] ERROR: I2C driver type not found or unsupported!"); + if (WsV2._sdCardV2->isModeOffline()) { + WsV2.haltErrorV2("[i2c] Driver failed to initialize!\n\tDid you set " + "the correct value for i2cDeviceName?\n\tDid you set " + "the correct value for" + "i2cDeviceAddress?", + WS_LED_STATUS_ERROR_RUNTIME, false); + } + } + + // Attempt to initialize the driver + if (did_set_mux_ch) { + drv->SetMuxAddress(device_descriptor.i2c_mux_address); + WS_DEBUG_PRINTLN("[i2c] Set driver to use MUX"); + } + if (use_alt_bus) { + drv->EnableAltI2CBus(_i2c_model->GetI2cDeviceAddOrReplaceMsg() + ->i2c_device_description.i2c_bus_scl, + _i2c_model->GetI2cDeviceAddOrReplaceMsg() + ->i2c_device_description.i2c_bus_sda); + WS_DEBUG_PRINTLN("[i2c] Set driver to use Alt I2C bus"); + } + // Configure the driver + drv->EnableSensorReads( + _i2c_model->GetI2cDeviceAddOrReplaceMsg()->i2c_device_sensor_types, + _i2c_model->GetI2cDeviceAddOrReplaceMsg()->i2c_device_sensor_types_count); + drv->SetSensorPeriod( + _i2c_model->GetI2cDeviceAddOrReplaceMsg()->i2c_device_period); + if (!drv->begin()) { + if (WsV2._sdCardV2->isModeOffline()) { + WsV2.haltErrorV2("[i2c] Driver failed to initialize!\n\tDid you set " + "the correct value for i2cDeviceName?\n\tDid you set " + "the correct value for" + "i2cDeviceAddress?", + WS_LED_STATUS_ERROR_RUNTIME, false); + } + } + + _i2c_drivers.push_back(drv); + WS_DEBUG_PRINTLN("[i2c] Driver initialized and added to controller: "); + WS_DEBUG_PRINTLN(device_name); + + // If we're using a MUX, clear the channel for any subsequent bus + // operations that may not involve the MUX + if (did_set_mux_ch) { + if (use_alt_bus) { + _i2c_bus_alt->ClearMuxChannel(); + } else { + _i2c_bus_default->ClearMuxChannel(); + } + } + + if (WsV2._sdCardV2->isModeOffline() != true) { + // Create and publish the I2cDeviceAddedorReplaced message to the broker + WS_DEBUG_PRINTLN("[i2c] MQTT Publish I2cDeviceAddedorReplaced not yet " + "implemented!"); + /* if (!PublishI2cDeviceAddedorReplaced(device_descriptor, + device_status)) return false; */ + } + + return true; +} + +/********************************************************************************/ +/*! + @brief Enables a MUX channel on the appropriate I2C bus. + @param mux_channel + Desired MUX channel to enable + @param is_alt_bus + True if an alternative I2C bus is being used, False otherwise. +*/ +/********************************************************************************/ +void I2cController::ConfigureMuxChannel(uint32_t mux_channel, bool is_alt_bus) { + if (is_alt_bus) { + _i2c_bus_alt->ClearMuxChannel(); // sanity-check + _i2c_bus_alt->SelectMuxChannel(mux_channel); + return; + } + _i2c_bus_default->ClearMuxChannel(); // sanity-check + _i2c_bus_default->SelectMuxChannel(mux_channel); +} + +/***********************************************************************/ +/*! + @brief Handles polling, reading, and logger for i2c devices + attached to the I2C controller. +*/ +/***********************************************************************/ +void I2cController::update() { + if (_i2c_drivers.size() == 0) + return; // bail out if no drivers exist + + for (auto *drv : _i2c_drivers) { + // Does this driver have any enabled sensors? + size_t sensor_count = drv->GetEnabledSensorCnt(); + if (sensor_count == 0) + continue; // bail out if driver has no sensors enabled + + // Did driver's period elapse yet? + ulong cur_time = millis(); + if (cur_time - drv->GetSensorPeriodPrv() < drv->GetSensorPeriod()) + continue; // bail out if the period hasn't elapsed yet + + // Optionally configure the I2C MUX + uint32_t mux_channel = drv->GetMuxChannel(); + if (drv->HasMux()) + ConfigureMuxChannel(mux_channel, drv->HasAltI2CBus()); + + // Read the driver's sensors + _i2c_model->ClearI2cDeviceEvent(); + for (size_t i = 0; i < sensor_count; i++) { + sensors_event_t event = {0}; + // Attempt to call driver's read handler function + if (!drv->GetSensorEvent(drv->_sensors[i], &event)) { + WS_DEBUG_PRINTLN("[i2c] ERROR: Failed to read sensor!"); + continue; + } + // Fill the I2cDeviceEvent's sensor_event array submsg. + _i2c_model->AddI2cDeviceSensorEvent(event, drv->_sensors[i]); + } + + // Configure the DeviceEvent's DeviceDescription sub-msg + _i2c_model->SetI2cDeviceEventDeviceDescripton( + drv->GetPinSCL(), drv->GetPinSDA(), (uint32_t)drv->GetAddress(), + drv->GetMuxAddress(), mux_channel); + _i2c_model->EncodeI2cDeviceEvent(); + + // Handle the DeviceEvent message + if (WsV2._sdCardV2->isModeOffline()) { + if (!WsV2._sdCardV2->LogI2cDeviceEvent(_i2c_model->GetI2cDeviceEvent())) { + WS_DEBUG_PRINTLN( + "[i2c] ERROR: Unable to log the I2cDeviceEvent to SD!"); + statusLEDSolid(WS_LED_STATUS_FS_WRITE); + } + } else { + // TODO: This needs to be implemented for online mode + WS_DEBUG_PRINTLN( + "[i2c] MQTT Publish I2cDeviceEvent not yet implemented!"); + } + + cur_time = millis(); + drv->SetSensorPeriodPrv(cur_time); + } +} \ No newline at end of file diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h new file mode 100644 index 000000000..ac317d5a2 --- /dev/null +++ b/src/components/i2c/controller.h @@ -0,0 +1,106 @@ +/*! + * @file controller.h + * + * Routing controller for WipperSnapper's I2C component. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2025 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_I2C_CONTROLLER_H +#define WS_I2C_CONTROLLER_H +#include "Wippersnapper_V2.h" +#include "hardware.h" +#include "model.h" +// I2C Drivers +#include "drivers/drvAdt7410.h" +#include "drivers/drvAhtx0.h" +#include "drivers/drvBase.h" ///< Base driver class +#include "drivers/drvBh1750.h" +#include "drivers/drvBme280.h" +#include "drivers/drvBme680.h" +#include "drivers/drvBmp280.h" +#include "drivers/drvBmp3xx.h" +#include "drivers/drvDps310.h" +#include "drivers/drvDs2484.h" +#include "drivers/drvEns160.h" +#include "drivers/drvHts221.h" +#include "drivers/drvHtu21d.h" +#include "drivers/drvIna219.h" +#include "drivers/drvLc709203f.h" +#include "drivers/drvLps22hb.h" +#include "drivers/drvLps25hb.h" +#include "drivers/drvLps3xhw.h" +#include "drivers/drvLtr329_Ltr303.h" +#include "drivers/drvLtr390.h" +#include "drivers/drvMCP9808.h" +#include "drivers/drvMax1704x.h" +#include "drivers/drvMcp3421.h" +#include "drivers/drvMpl115a2.h" +#include "drivers/drvMprls.h" +#include "drivers/drvMs8607.h" +#include "drivers/drvNau7802.h" +#include "drivers/drvPct2075.h" +#include "drivers/drvPm25.h" +#include "drivers/drvScd30.h" +#include "drivers/drvScd4x.h" +#include "drivers/drvSen5x.h" +#include "drivers/drvSgp40.h" +#include "drivers/drvSht3x.h" +#include "drivers/drvSht4x.h" +#include "drivers/drvShtc3.h" +#include "drivers/drvSi7021.h" +#include "drivers/drvStemmaSoil.h" +#include "drivers/drvTmp117.h" +#include "drivers/drvTsl2591.h" +#include "drivers/drvVeml7700.h" +#include "drivers/drvVl53l0x.h" +#include "drivers/drvVl53l1x.h" +#include "drivers/drvVl53l4cd.h" +#include "drivers/drvVl53l4cx.h" +#include "drivers/drvVl6180x.h" +#include "drivers/drvVncl4020.h" +#include "drivers/drvVncl4040.h" + +class Wippersnapper_V2; ///< Forward declaration +class I2cModel; ///< Forward declaration +class I2cHardware; ///< Forward declaration + +/**************************************************************************/ +/*! + @brief Routes messages using the i2c.proto API to the + appropriate hardware, model, and device driver classes. +*/ +/**************************************************************************/ +class I2cController { +public: + I2cController(); + ~I2cController(); + void update(); + // Routing // + bool Handle_I2cDeviceAddOrReplace(pb_istream_t *stream); + // TODO [Online]: These are for Online mode and not yet implemented + bool Handle_I2cDeviceRemove(pb_istream_t *stream); + // bool Handle_I2cBusScan(pb_istream_t *stream); + // Publishing // + bool PublishI2cDeviceAddedorReplaced( + const wippersnapper_i2c_I2cDeviceDescriptor &device_descriptor, + const wippersnapper_i2c_I2cDeviceStatus &device_status); + // Helpers // + bool IsBusStatusOK(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); + +private: + I2cModel *_i2c_model; ///< Pointer to an I2C model object + I2cHardware *_i2c_bus_default; ///< Pointer to the default I2C bus + I2cHardware *_i2c_bus_alt; ///< Pointer to an alternative I2C bus + std::vector _i2c_drivers; ///< Vector of ptrs to I2C device drivers +}; +extern Wippersnapper_V2 WsV2; ///< Wippersnapper V2 instance +#endif // WS_I2C_CONTROLLER_H \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver.h b/src/components/i2c/drivers/WipperSnapper_I2C_Driver.h deleted file mode 100644 index 809b03b56..000000000 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver.h +++ /dev/null @@ -1,1429 +0,0 @@ -/*! - * @file WipperSnapper_I2C_Driver.h - * - * Base implementation for I2C device drivers. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2021-2022 for Adafruit Industries. - * - * MIT license, all text here must be included in any redistribution. - * - */ - -#ifndef WipperSnapper_I2C_Driver_H -#define WipperSnapper_I2C_Driver_H - -#include -#include - -#define PERIOD_24HRS_AGO_MILLIS (millis() - (24 * 60 * 60 * 1000)) -///< Used for last sensor read time, initially set 24hrs ago (max period) - -/**************************************************************************/ -/*! - @brief Base class for I2C Drivers. -*/ -/**************************************************************************/ -class WipperSnapper_I2C_Driver { - -public: - /*******************************************************************************/ - /*! - @brief Instanciates an I2C sensor. - @param i2c - The I2C hardware interface, default is Wire. - @param sensorAddress - The I2C sensor's unique address. - */ - /*******************************************************************************/ - WipperSnapper_I2C_Driver(TwoWire *i2c, uint16_t sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; - } - - /*******************************************************************************/ - /*! - @brief Destructor for an I2C sensor. - */ - /*******************************************************************************/ - virtual ~WipperSnapper_I2C_Driver() {} - - /*******************************************************************************/ - /*! - @brief Initializes the I2C sensor and begins I2C. - @returns True if initialized successfully, False otherwise. - */ - /*******************************************************************************/ - bool begin() { return false; } - - /*******************************************************************************/ - /*! - @brief Sets the sensor's period, provided a - wippersnapper_i2c_v1_SensorType. - @param period The period for the sensor to return values within, in - seconds. - @param sensorType The type of sensor device. - */ - /*******************************************************************************/ - void setSensorPeriod(float period, - wippersnapper_i2c_v1_SensorType sensorType) { - long sensorPeriod = (long)period * 1000; - - switch (sensorType) { - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE: - _tempSensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_RELATIVE_HUMIDITY: - _humidSensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PRESSURE: - _pressureSensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_CO2: - _CO2SensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_ECO2: - _ECO2SensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_TVOC: - _TVOCSensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_ALTITUDE: - _altitudeSensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE: - _objectTempSensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_LIGHT: - _lightSensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_STD: - _PM10SensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_STD: - _PM25SensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_STD: - _PM100SensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_UNITLESS_PERCENT: - _unitlessPercentPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOLTAGE: - _voltagePeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_CURRENT: - _currentPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PROXIMITY: - _proximitySensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_RAW: - _rawSensorPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT: - _ambientTempFPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT: - _objectTempFPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_GAS_RESISTANCE: - _gasResistancePeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_NOX_INDEX: - _NOxIndexPeriod = sensorPeriod; - break; - case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOC_INDEX: - _VOCIndexPeriod = sensorPeriod; - break; - default: - break; - } - } - - /*******************************************************************************/ - /*! - @brief Uses an I2CDeviceInitRequest message to configure the sensors - belonging to the driver. - @param msgDeviceInitReq - I2CDeviceInitRequest containing a list of I2C device properties. - */ - /*******************************************************************************/ - void - configureDriver(wippersnapper_i2c_v1_I2CDeviceInitRequest *msgDeviceInitReq) { - int propertyIdx = 0; // contains the amount of i2c sensors in the - // msgDeviceInitReq to configure - while (propertyIdx < msgDeviceInitReq->i2c_device_properties_count) { - setSensorPeriod( - msgDeviceInitReq->i2c_device_properties[propertyIdx].sensor_period, - msgDeviceInitReq->i2c_device_properties[propertyIdx].sensor_type); - ++propertyIdx; - } - } - - /*******************************************************************************/ - /*! - @brief Gets the I2C device's address. - @returns The I2C device's unique i2c address. - */ - /*******************************************************************************/ - uint16_t getI2CAddress() { return _sensorAddress; } - - /****************************** SENSOR_TYPE: CO2 - * *******************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the co2 sensor's period, if - set. - @returns Time when the co2 sensor should be polled, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorCO2Period() { return _CO2SensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the co2 sensor was queried last. - @returns Time when the co2 sensor was last queried, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorCO2PeriodPrv() { return _CO2SensorPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the co2 sensor was queried. - @param period - The time when the co2 sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorCO2PeriodPrv(long period) { - _CO2SensorPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Gets a sensor's CO2 value. - @param co2Event - The CO2 value, in ppm. - @returns True if the sensor value was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventCO2(sensors_event_t *co2Event) { - (void) - co2Event; // Parameter is intentionally unused in this virtual function. - return false; - } - - /****************************** SENSOR_TYPE: ECO2 - * *******************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the eCO2 sensor's period, if - set. - @returns Time when the eCO2 sensor should be polled, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorECO2Period() { return _ECO2SensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the eCO2 sensor was queried last. - @returns Time when the eCO2 sensor was last queried, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorECO2PeriodPrv() { return _ECO2SensorPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the eCO2 sensor was queried. - @param period - The time when the CO2 sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorECO2PeriodPrv(long period) { - _ECO2SensorPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Gets a sensor's eCO2 value. - @param eco2Event - The equivalent CO2 value, in ppm. - @returns True if the sensor value was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventECO2(sensors_event_t *eco2Event) { - (void)eco2Event; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /****************************** SENSOR_TYPE: TVOC - * *******************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the TVOC sensor's period, if - set. - @returns Time when the TVOC sensor should be polled, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorTVOCPeriod() { return _TVOCSensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the TVOC sensor was queried last. - @returns Time when the TVOC sensor was last queried, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorTVOCPeriodPrv() { return _TVOCSensorPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the TVOC sensor was queried. - @param period - The time when the TVOC sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorTVOCPeriodPrv(long period) { - _TVOCSensorPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Gets a sensor's TVOC value. - @param tvocEvent - The Total Volatile Organic Compounds value, in ppb. - @returns True if the sensor value was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventTVOC(sensors_event_t *tvocEvent) { - (void)tvocEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /********************** SENSOR_TYPE: AMBIENT TEMPERATURE (°C) - * ***********************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the ambient temperature (°C) - sensor's period, if set. - @returns Time when the temperature sensor should be polled, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorAmbientTempPeriod() { return _tempSensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the ambient temperature sensor (°C) was queried last. - @returns Time when the ambient temperature sensor (°C) was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorAmbientTempPeriodPrv() { return _tempSensorPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the ambient temperature sensor (°C) - was queried. - @param periodPrv - The time when the ambient temperature sensor (°C) was queried - last. - */ - /*******************************************************************************/ - virtual void setSensorAmbientTempPeriodPrv(long periodPrv) { - _tempSensorPeriodPrv = periodPrv; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads an ambient temperature sensor (°C). - Expects value to return in the proper SI unit. - @param tempEvent - Pointer to an Adafruit_Sensor event. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventAmbientTemp(sensors_event_t *tempEvent) { - (void)tempEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /************************* SENSOR_TYPE: RELATIVE_HUMIDITY - * ***********************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the humidity sensor's period, if - set. - @returns Time when the humidity sensor should be polled, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorRelativeHumidityPeriod() { return _humidSensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the humidity sensor was queried last. - @returns Time when the humidity sensor was last queried, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorRelativeHumidityPeriodPrv() { - return _humidSensorPeriodPrv; - } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the temperature sensor was queried. - @param periodPrv - The time when the temperature sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorRelativeHumidityPeriodPrv(long periodPrv) { - _humidSensorPeriodPrv = periodPrv; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a humidity sensor and converts - the reading into the expected SI unit. - @param humidEvent - Pointer to an Adafruit_Sensor event. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventRelativeHumidity(sensors_event_t *humidEvent) { - (void)humidEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /**************************** SENSOR_TYPE: PRESSURE - * ****************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the pressure sensor's period, if - set. - @returns Time when the pressure sensor should be polled, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorPressurePeriod() { return _pressureSensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the pressure sensor was queried last. - @returns Time when the pressure sensor was last queried, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorPressurePeriodPrv() { return _pressureSensorPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the pressure sensor was queried. - @param period - The time when the pressure sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorPressurePeriodPrv(long period) { - _pressureSensorPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a pressure sensor and converts - the reading into the expected SI unit. - @param pressureEvent - Pointer to an Adafruit_Sensor event. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventPressure(sensors_event_t *pressureEvent) { - (void)pressureEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /**************************** SENSOR_TYPE: Altitude - * ****************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the Altitude sensor's period, if - set. - @returns Time when the Altitude sensor should be polled, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorAltitudePeriod() { return _altitudeSensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the Altitude sensor was queried last. - @returns Time when the Altitude sensor was last queried, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorAltitudePeriodPrv() { return _altitudeSensorPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the Altitude sensor was queried. - @param period - The time when the Altitude sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorAltitudePeriodPrv(long period) { - _altitudeSensorPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a Altitude sensor and converts - the reading into the expected SI unit. - @param altitudeEvent - Altitude reading, in meters. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventAltitude(sensors_event_t *altitudeEvent) { - (void)altitudeEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /**************************** SENSOR_TYPE: Object_Temperature - * ****************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the object temperature sensor's - period, if set. - @returns Time when the object temperature sensor should be polled, in - seconds. - */ - /*********************************************************************************/ - virtual long getSensorObjectTempPeriod() { return _objectTempSensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the object temperature sensor was queried last. - @returns Time when the object temperature sensor was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorObjectTempPeriodPrv() { - return _objectTempSensorPeriodPrv; - } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the object temperature sensor - was queried. - @param period - The time when the object temperature sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorObjectTempPeriodPrv(long period) { - _objectTempSensorPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a object temperature sensor and - converts the reading into the expected SI unit. - @param objectTempEvent - object temperature sensor reading, in meters. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventObjectTemp(sensors_event_t *objectTempEvent) { - (void)objectTempEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /**************************** SENSOR_TYPE: LIGHT - * ****************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the object light sensor's - period, if set. - @returns Time when the object light sensor should be polled, in - seconds. - */ - /*********************************************************************************/ - virtual long getSensorLightPeriod() { return _lightSensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the light sensor was queried last. - @returns Time when the light sensor was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorLightPeriodPrv() { return _lightSensorPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the light sensor - was queried. - @param period - The time when the light sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorLightPeriodPrv(long period) { - _lightSensorPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a object light sensor and - converts the reading into the expected SI unit. - @param lightEvent - Light sensor reading, in meters. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventLight(sensors_event_t *lightEvent) { - (void)lightEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /**************************** SENSOR_TYPE: PM10_STD - * ****************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the object pm10 standard sensors' - period, if set. - @returns Time when the object pm10 standard sensor should be polled, in - seconds. - */ - /*********************************************************************************/ - virtual long getSensorPM10_STDPeriod() { return _PM10SensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the pm10 std. sensor was queried last. - @returns Time when the pm10 std. sensor was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorPM10_STDPeriodPrv() { return _PM10SensorPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the light sensor - was queried. - @param period - The time when the light sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorPM10_STDPeriodPrv(long period) { - _PM10SensorPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a object pm10 std. sensor and - converts the reading into the expected SI unit. - @param pm10StdEvent - pm10 std. sensor reading, in ppm. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventPM10_STD(sensors_event_t *pm10StdEvent) { - (void)pm10StdEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /**************************** SENSOR_TYPE: PM25_STD - * ****************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the object pm25 standard sensors' - period, if set. - @returns Time when the object pm25 standard sensor should be polled, in - seconds. - */ - /*********************************************************************************/ - virtual long getSensorPM25_STDPeriod() { return _PM25SensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the pm25 std. sensor was queried last. - @returns Time when the pm25 std. sensor was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorPM25_STDPeriodPrv() { return _PM25SensorPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the light sensor - was queried. - @param period - The time when the light sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorPM25_STDPeriodPrv(long period) { - _PM25SensorPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a object pm25 std. sensor and - converts the reading into the expected SI unit. - @param pm25StdEvent - pm25 std. sensor reading, in ppm. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventPM25_STD(sensors_event_t *pm25StdEvent) { - (void)pm25StdEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /**************************** SENSOR_TYPE: PM100_STD - * ****************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the object pm100 standard sensors' - period, if set. - @returns Time when the object pm100 standard sensor should be polled, in - seconds. - */ - /*********************************************************************************/ - virtual long getSensorPM100_STDPeriod() { return _PM100SensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the pm100 std. sensor was queried last. - @returns Time when the pm100 std. sensor was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorPM100_STDPeriodPrv() { return _PM100SensorPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the light sensor - was queried. - @param period - The time when the light sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorPM100_STDPeriodPrv(long period) { - _PM100SensorPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a object pm100 std. sensor and - converts the reading into the expected SI unit. - @param pm100StdEvent - pm100 std. sensor reading, in ppm. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventPM100_STD(sensors_event_t *pm100StdEvent) { - (void)pm100StdEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /**************************** SENSOR_TYPE: UNITLESS_PERCENT - * ****************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the object unitless % sensor - period, if set. - @returns Time when the object unitless % sensor should be polled, in - seconds. - */ - /*********************************************************************************/ - virtual long getSensorUnitlessPercentPeriod() { - return _unitlessPercentPeriod; - } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the unitless % sensor was queried last. - @returns Time when the unitless % sensor was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorUnitlessPercentPeriodPrv() { - return _unitlessPercentPeriodPrv; - } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the unitless % sensor - was queried. - @param period - The time when the unitless % sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorUnitlessPercentPeriodPrv(long period) { - _unitlessPercentPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a object unitless % std. sensor and - converts the reading into the expected SI unit. - @param unitlessPercentEvent - unitless % sensor reading. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventUnitlessPercent(sensors_event_t *unitlessPercentEvent) { - (void)unitlessPercentEvent; // Parameter is intentionally unused in this - // virtual function. - return false; - } - - /**************************** SENSOR_TYPE: VOLTAGE - * ****************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the voltage sensor's period. - @returns Time when the object voltage sensor should be polled, in - seconds. - */ - /*********************************************************************************/ - virtual long getSensorVoltagePeriod() { return _voltagePeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the voltage sensor was queried last. - @returns Time when the voltage sensor was last queried, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorVoltagePeriodPrv() { return _voltagePeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the voltage sensor was queried. - @param period - The time when the voltage sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorVoltagePeriodPrv(long period) { - _voltagePeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - 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. - */ - /*******************************************************************************/ - virtual bool getEventVoltage(sensors_event_t *voltageEvent) { - (void)voltageEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /**************************** SENSOR_TYPE: CURRENT - * ****************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the current sensor's period. - @returns Time when the object current sensor should be polled, in - seconds. - */ - /*********************************************************************************/ - virtual long getSensorCurrentPeriod() { return _currentPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the current sensor was queried last. - @returns Time when the current sensor was last queried, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorCurrentPeriodPrv() { return _currentPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the current sensor was queried. - @param period - The time when the current sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorCurrentPeriodPrv(long period) { - _currentPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a current sensor and converts the - reading into the expected SI unit. - @param currentEvent - current sensor reading, in volts. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventCurrent(sensors_event_t *currentEvent) { - (void)currentEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /****************************** SENSOR_TYPE: Raw - * *******************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the raw sensor's period, if - set. - @returns Time when the raw sensor should be polled, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorRawPeriod() { return _rawSensorPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the raw sensor was queried last. - @returns Time when the raw sensor was last queried, in seconds. - */ - /*********************************************************************************/ - virtual long getSensorRawPeriodPrv() { return _rawSensorPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the raw sensor was queried. - @param period - The time when the raw sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorRawPeriodPrv(long period) { - _rawSensorPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Gets a sensor's Raw value. - @param rawEvent - The Raw value. - @returns True if the sensor value was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventRaw(sensors_event_t *rawEvent) { - (void) - rawEvent; // Parameter is intentionally unused in this virtual function. - return false; - } - - /****************************** SENSOR_TYPE: Ambient Temp (°F) - * *******************************/ - - /*******************************************************************************/ - /*! - @brief Disables the device's ambient temperature (°F) sensor, if it - exists. - */ - /*******************************************************************************/ - virtual void disableAmbientTempF() { _ambientTempFPeriod = 0.0L; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the ambient temperature (°F) - sensor's period, if set. - @returns Time when the ambient temperature sensor should be polled, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorAmbientTempFPeriod() { return _ambientTempFPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the ambient temperature sensor (°F) was queried last. - @returns Time when the ambient temperature sensor was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorAmbientTempFPeriodPrv() { - return _ambientTempFPeriodPrv; - } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the ambient temperature sensor (°F) - was queried. - @param period - The time when the ambient temperature sensor (°F) was queried - last. - */ - /*******************************************************************************/ - virtual void setSensorAmbientTempFPeriodPrv(long period) { - _ambientTempFPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Helper function to obtain a sensor's ambient temperature value - in °F. Requires `getEventAmbientTemp()` to be fully - implemented by a driver. - @param AmbientTempFEvent - The ambient temperature value, in °F. - @returns True if the sensor value was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventAmbientTempF(sensors_event_t *AmbientTempFEvent) { - // obtain ambient temp. in °C - if (!getEventAmbientTemp(AmbientTempFEvent)) - return false; - // convert event from °C to °F - AmbientTempFEvent->temperature = - (AmbientTempFEvent->temperature * 9.0) / 5.0 + 32; - return true; - } - - /****************************** SENSOR_TYPE: Object Temp (°F) - * *******************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the object temperature (°F) - sensor's period, if set. - @returns Time when the object temperature sensor should be polled, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorObjectTempFPeriod() { return _objectTempFPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the object temperature sensor (°F) was queried last. - @returns Time when the object temperature sensor was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorObjectTempFPeriodPrv() { return _objectTempFPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the object temperature sensor (°F) - was queried. - @param period - The time when the object temperature sensor (°F) was queried - last. - */ - /*******************************************************************************/ - virtual void setSensorObjectTempFPeriodPrv(long period) { - _objectTempFPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Helper function to obtain a sensor's object temperature value - in °F. Requires `getEventObjectTemp()` to be fully - implemented by a driver. - @param objectTempFEvent - The object temperature value, in °F. - @returns True if the sensor value was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventObjectTempF(sensors_event_t *objectTempFEvent) { - // obtain ambient temp. in °C - if (!getEventObjectTemp(objectTempFEvent)) - return false; - // convert event from °C to °F - objectTempFEvent->temperature = - (objectTempFEvent->temperature * 9.0) / 5.0 + 32.0; - return true; - } - - /****************************** SENSOR_TYPE: Gas Resistance (ohms) - * *******************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the gas resistance (ohms) - sensor's period, if set. - @returns Time when the gas resistance sensor should be polled, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorGasResistancePeriod() { return _gasResistancePeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the gas resistance sensor (ohms) was queried last. - @returns Time when the gas resistance sensor was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorGasResistancePeriodPrv() { - return _gasResistancePeriodPrv; - } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the object gas resistance sensor - was queried. - @param period - The time when the gas resistance sensor was queried - last. - */ - /*******************************************************************************/ - virtual void setSensorGasResistancePeriodPrv(long period) { - _gasResistancePeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a gas resistance sensor and converts - the reading into the expected SI unit. - @param gasEvent - gas resistance sensor reading, in ohms. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventGasResistance(sensors_event_t *gasEvent) { - (void) - gasEvent; // Parameter is intentionally unused in this virtual function. - return false; - } - - /****************************** SENSOR_TYPE: NOx Index (index) - * *******************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the NOx Index - sensor's period, if set. - @returns Time when the NOx Index sensor should be polled, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorNOxIndexPeriod() { return _NOxIndexPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the NOx Index sensor was queried last. - @returns Time when the NOx Index sensor was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorNOxIndexPeriodPrv() { return _NOxIndexPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the object NOx Index sensor - was queried. - @param period - The time when the NOx Index sensor was queried - last. - */ - /*******************************************************************************/ - virtual void setSensorNOxIndexPeriodPrv(long period) { - _NOxIndexPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a NOx Index sensor and converts - the reading into the expected SI unit. - @param gasEvent - NOx Index sensor reading, unitless. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventNOxIndex(sensors_event_t *gasEvent) { - (void) - gasEvent; // Parameter is intentionally unused in this virtual function. - return false; - } - - /****************************** SENSOR_TYPE: VOC Index (index) - * *******************************/ - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the VOC Index - sensor's period, if set. - @returns Time when the VOC Index sensor should be polled, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorVOCIndexPeriod() { return _VOCIndexPeriod; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the VOC Index sensor was queried last. - @returns Time when the VOC Index sensor was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long getSensorVOCIndexPeriodPrv() { return _VOCIndexPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the object VOC Index sensor - was queried. - @param period - The time when the VOC Index sensor was queried - last. - */ - /*******************************************************************************/ - virtual void setSensorVOCIndexPeriodPrv(long period) { - _VOCIndexPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a VOC Index sensor and converts - the reading into the expected SI unit. - @param gasEvent - VOC Index sensor reading, unitless. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventVOCIndex(sensors_event_t *gasEvent) { - (void) - gasEvent; // Parameter is intentionally unused in this virtual function. - return false; - } - - /**************************** SENSOR_TYPE: PROXIMITY - * ****************************/ - /*******************************************************************************/ - /*! - @brief Enables the device's proximity sensor, if it exists. - */ - /*******************************************************************************/ - virtual void enableSensorProximity(){}; - - /*******************************************************************************/ - /*! - @brief Disables the device's object proximity sensor, if it exists. - */ - /*******************************************************************************/ - virtual void disableSensorProximity() { _proximitySensorPeriod = 0.0L; } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the proximity sensor's - period, if set. - @returns Time when the roximity sensor should be polled, in - seconds. - */ - /*********************************************************************************/ - virtual long sensorProximityPeriod() { return _proximitySensorPeriod; } - - /*******************************************************************************/ - /*! - @brief Set the proximity sensor's return frequency. - @param period - The time interval at which to return new data from the - proximity sensor. - */ - /*******************************************************************************/ - virtual void setSensorProximityPeriod(long period) { - if (period == 0) - disableSensorProximity(); - _proximitySensorPeriod = period; - } - - /*********************************************************************************/ - /*! - @brief Base implementation - Returns the previous time interval at - which the proximity sensor was queried last. - @returns Time when the proximity sensor was last queried, - in seconds. - */ - /*********************************************************************************/ - virtual long SensorProximityPeriodPrv() { return _proximitySensorPeriodPrv; } - - /*******************************************************************************/ - /*! - @brief Sets a timestamp for when the proximity sensor - was queried. - @param period - The time when the proximity sensor was queried last. - */ - /*******************************************************************************/ - virtual void setSensorProximityPeriodPrv(long period) { - _proximitySensorPeriodPrv = period; - } - - /*******************************************************************************/ - /*! - @brief Base implementation - Reads a proximity sensor and - converts the reading into the expected SI unit. - @param proximityEvent - Proximity sensor reading, in millimeters. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool getEventProximity(sensors_event_t *proximityEvent) { - (void)proximityEvent; // Parameter is intentionally unused in this virtual - // function. - return false; - } - - /*******************************************************************************/ - /*! - @brief Updates the properties of a proximity sensor. - @param period - The time interval at which to return new data from the - proimity sensor. - */ - /*******************************************************************************/ - virtual void updateSensorProximity(float period) { - setSensorProximityPeriod(period); - } - -protected: - TwoWire *_i2c; ///< Pointer to the I2C driver's Wire object - uint16_t _sensorAddress; ///< The I2C driver's unique I2C address. - long _tempSensorPeriod = - 0L; ///< The time period between reading the temperature sensor's value. - long _tempSensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the temperature sensor was - ///< last read - long _humidSensorPeriod = - 0L; ///< The time period between reading the humidity sensor's value. - long _humidSensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the humidity sensor was last - ///< read. - long _pressureSensorPeriod = - 0L; ///< The time period between reading the pressure sensor's value. - long _pressureSensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the pressure sensor was last - ///< read. - long _CO2SensorPeriod = - 0L; ///< The time period between reading the CO2 sensor's value. - long _CO2SensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the CO2 sensor was last read. - long _ECO2SensorPeriod = - 0L; ///< The time period between reading the eCO2 sensor's value. - long _ECO2SensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the eCO2 sensor was last read. - long _TVOCSensorPeriod = - 0L; ///< The time period between reading the TVOC sensor's value. - long _TVOCSensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the TVOC sensor was last read. - long _altitudeSensorPeriod = - 0L; ///< The time period between reading the altitude sensor's value. - long _altitudeSensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the altitude sensor was last - ///< read. - long _objectTempSensorPeriod = 0L; ///< The time period between reading the - ///< object temperature sensor's value. - long _objectTempSensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the object temperature sensor - ///< was last read. - long _lightSensorPeriod = - 0L; ///< The time period between reading the light sensor's value. - long _lightSensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the light sensor was last - ///< read. - long _PM10SensorPeriod = - 0L; ///< The time period between reading the pm25 sensor's value. - long _PM10SensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the pm25 sensor was last read. - long _PM25SensorPeriod = - 0L; ///< The time period between reading the pm25 sensor's value. - long _PM25SensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the pm25 sensor was last read. - long _PM100SensorPeriod = - 0L; ///< The time period between reading the pm100_std sensor's value. - long _PM100SensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the pm100_std sensor was last - ///< read. - long _unitlessPercentPeriod = - 0L; ///< The time period between reading the unitless % sensor's value. - long _unitlessPercentPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the unitless % sensor was last - ///< read. - long _voltagePeriod = - 0L; ///< The time period between reading the voltage sensor's value. - long _voltagePeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the voltage sensor was last - ///< read. - long _currentPeriod = - 0L; ///< The time period between reading the current sensor's value. - long _currentPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the current sensor was last - ///< read. - long _rawSensorPeriod = - 0L; ///< The time period between reading the Raw sensor's value. - long _rawSensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the Raw sensor was last read. - long _ambientTempFPeriod = 0L; ///< The time period between reading the - ///< ambient temp. (°F) sensor's value. - long _ambientTempFPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the ambient temp. (°F) sensor - ///< was last read. - long _objectTempFPeriod = 0L; ///< The time period between reading the object - ///< temp. (°F) sensor's value. - long _objectTempFPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the object temp. (°F) sensor - ///< was last read. - long _gasResistancePeriod = 0L; ///< The time period between reading the gas - ///< resistance sensor's value. - long _gasResistancePeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the gas resistance sensor was - ///< last read. - long _NOxIndexPeriod = - 0L; ///< The time period between reading the NOx Index sensor's value. - long _NOxIndexPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the NOx Index sensor was last - ///< read. - long _VOCIndexPeriod = - 0L; ///< The time period between reading the VOC Index sensor's value. - long _VOCIndexPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the VOC Index sensor was last - ///< read. - long _proximitySensorPeriod = - 0L; ///< The time period between reading the proximity sensor's value. - long _proximitySensorPeriodPrv = - PERIOD_24HRS_AGO_MILLIS; ///< The time when the proximity sensor was last - ///< read. -}; - -#endif // WipperSnapper_I2C_Driver_H diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_HTU31D.h b/src/components/i2c/drivers/WipperSnapper_I2C_Driver_HTU31D.h deleted file mode 100644 index aace146b0..000000000 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_HTU31D.h +++ /dev/null @@ -1,87 +0,0 @@ -/*! - * @file WipperSnapper_I2C_Driver_HTU31D.h - * - * Device driver for an HTU31D Humidity and Temperature sensor. - */ - -#ifndef WipperSnapper_I2C_Driver_HTU31D_H -#define WipperSnapper_I2C_Driver_HTU31D_H - -#include "WipperSnapper_I2C_Driver.h" -#include - -/**************************************************************************/ -/*! - @brief Class that provides a sensor driver for the HTU31D humidity and - temperature sensor. -*/ -/**************************************************************************/ -class WipperSnapper_I2C_Driver_HTU31D : public WipperSnapper_I2C_Driver { - -public: - /*******************************************************************************/ - /*! - @brief Constructor for an HTU31D sensor. - @param i2c - The I2C interface. - @param sensorAddress - 7-bit device address. - */ - /*******************************************************************************/ - WipperSnapper_I2C_Driver_HTU31D(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; - } - - /*******************************************************************************/ - /*! - @brief Destructor for an HTU31D sensor. - */ - /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_HTU31D() { delete _htu31d; } - - /*******************************************************************************/ - /*! - @brief Initializes the HTU31D sensor and begins I2C. - @returns True if initialized successfully, False otherwise. - - */ - /*******************************************************************************/ - bool begin() { - // attempt to initialize the HTU31D using the I2C interface - _htu31d = new Adafruit_HTU31D(); - return _htu31d->begin(_sensorAddress, _i2c); - } - - /*******************************************************************************/ - /*! - @brief Gets the HTU31D's current 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) { - return _htu31d->getEvent(nullptr, tempEvent); - } - - /*******************************************************************************/ - /*! - @brief Gets the HTU31D's current humidity. - @param humidEvent - Pointer to an Adafruit_Sensor event. - @returns True if the humidity was obtained successfully, False - otherwise. - */ - /*******************************************************************************/ - bool getEventRelativeHumidity(sensors_event_t *humidEvent) { - return _htu31d->getEvent(humidEvent, nullptr); - } - -protected: - Adafruit_HTU31D *_htu31d; ///< Pointer to an HTU31D object -}; - -#endif // WipperSnapper_I2C_Driver_HTU31D \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SGP30.h b/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SGP30.h deleted file mode 100644 index 32da8a53a..000000000 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SGP30.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef WipperSnapper_I2C_Driver_SGP30_H -#define WipperSnapper_I2C_Driver_SGP30_H - -#include "WipperSnapper_I2C_Driver.h" -#include - -/**************************************************************************/ -/*! - @brief Class that provides a driver interface for a SGP30 sensor. -*/ -/**************************************************************************/ -class WipperSnapper_I2C_Driver_SGP30 : public WipperSnapper_I2C_Driver { -public: - /*******************************************************************************/ - /*! - @brief Constructor for a SGP30 sensor. - @param i2c - The I2C interface. - @param sensorAddress - 7-bit device address. - */ - /*******************************************************************************/ - WipperSnapper_I2C_Driver_SGP30(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; - } - - /*******************************************************************************/ - /*! - @brief Destructor for an SGP30 sensor. - */ - /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_SGP30() { - // Called when a SGP30 component is deleted. - delete _sgp30; - } - - /*******************************************************************************/ - /*! - @brief Initializes the SGP30 sensor and begins I2C. - @returns True if initialized successfully, False otherwise. - */ - /*******************************************************************************/ - bool begin() { - _sgp30 = new Adafruit_SGP30(); - bool isInit = _sgp30->begin(_i2c); - if (isInit) { - _sgp30->IAQinit(); - } - return isInit; - } - - bool getEventECO2(sensors_event_t *senseEvent) { - bool result = _sgp30->IAQmeasure(); - if (result) { - senseEvent->eCO2 = _sgp30->eCO2; - } - return result; - } - - bool getEventTVOC(sensors_event_t *senseEvent) { - bool result = _sgp30->IAQmeasure(); - if (result) { - senseEvent->tvoc = _sgp30->TVOC; - } - return result; - } - -protected: - Adafruit_SGP30 *_sgp30; ///< Pointer to SGP30 temperature sensor object -}; - -#endif // WipperSnapper_I2C_Driver_SGP30 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_ADT7410.h b/src/components/i2c/drivers/drvAdt7410.h similarity index 79% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_ADT7410.h rename to src/components/i2c/drivers/drvAdt7410.h index d5be6d989..3e6c33bfa 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_ADT7410.h +++ b/src/components/i2c/drivers/drvAdt7410.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_ADT7410.h + * @file drvAdt7410.h * * Device driver for the ADT7410 Temperature sensor. * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_ADT7410_H -#define WipperSnapper_I2C_Driver_ADT7410_H +#ifndef DRV_ADT7410_H +#define DRV_ADT7410_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -23,7 +23,7 @@ @brief Class that provides a driver interface for a ADT7410 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_ADT7410 : public WipperSnapper_I2C_Driver { +class drvAdt7410 : public drvBase { public: /*******************************************************************************/ /*! @@ -32,12 +32,16 @@ class WipperSnapper_I2C_Driver_ADT7410 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_ADT7410(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvAdt7410(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 } /*******************************************************************************/ @@ -45,7 +49,7 @@ class WipperSnapper_I2C_Driver_ADT7410 : public WipperSnapper_I2C_Driver { @brief Destructor for an ADT7410 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_ADT7410() { + ~drvAdt7410() { // Called when a ADT7410 component is deleted. delete _ADT7410; } @@ -56,9 +60,9 @@ class WipperSnapper_I2C_Driver_ADT7410 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _ADT7410 = new Adafruit_ADT7410(); - return _ADT7410->begin((uint8_t)_sensorAddress, _i2c); + return _ADT7410->begin((uint8_t)_address, _i2c); } /*******************************************************************************/ @@ -79,4 +83,4 @@ class WipperSnapper_I2C_Driver_ADT7410 : public WipperSnapper_I2C_Driver { Adafruit_ADT7410 *_ADT7410; ///< Pointer to ADT7410 temperature sensor object }; -#endif // WipperSnapper_I2C_Driver_ADT7410 \ No newline at end of file +#endif // drvAdt7410 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_AHTX0.h b/src/components/i2c/drivers/drvAhtx0.h similarity index 81% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_AHTX0.h rename to src/components/i2c/drivers/drvAhtx0.h index dfcdd039e..e08226815 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_AHTX0.h +++ b/src/components/i2c/drivers/drvAhtx0.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_AHTX0.h + * @file drvAhtx0.h * * Device driver for an AHT Humidity and Temperature sensor. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_AHTX0_H -#define WipperSnapper_I2C_Driver_AHTX0_H +#ifndef DRV_AHTX0_H +#define DRV_AHTX0_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -25,7 +25,7 @@ and humidity sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_AHTX0 : public WipperSnapper_I2C_Driver { +class drvAhtx0 : public drvBase { public: /*******************************************************************************/ @@ -35,12 +35,16 @@ class WipperSnapper_I2C_Driver_AHTX0 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_AHTX0(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvAhtx0(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 } /*******************************************************************************/ @@ -48,7 +52,7 @@ class WipperSnapper_I2C_Driver_AHTX0 : public WipperSnapper_I2C_Driver { @brief Destructor for an AHTX0 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_AHTX0() { delete _aht; } + ~drvAhtx0() { delete _aht; } /*******************************************************************************/ /*! @@ -57,15 +61,19 @@ class WipperSnapper_I2C_Driver_AHTX0 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ - bool begin() { - // attempt + bool begin() override { + // attempt to initialize the driver _aht = new Adafruit_AHTX0(); - if (!_aht->begin(_i2c, (int32_t)_sensorAddress)) + if (!_aht->begin(_i2c, (int32_t)_address)) return false; - // get temperature and humidity sensor + // initialize sensors _aht_temp = _aht->getTemperatureSensor(); + if (_aht_temp == NULL) + return false; _aht_humidity = _aht->getHumiditySensor(); + if (_aht_humidity == NULL) + return false; return true; } @@ -80,10 +88,6 @@ class WipperSnapper_I2C_Driver_AHTX0 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventAmbientTemp(sensors_event_t *tempEvent) { - // is sensor enabled correctly? - if (_aht_temp == NULL) - return false; - // get event _aht_temp->getEvent(tempEvent); return true; } @@ -98,10 +102,6 @@ class WipperSnapper_I2C_Driver_AHTX0 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventRelativeHumidity(sensors_event_t *humidEvent) { - // is sensor enabled correctly? - if (_aht_humidity == NULL) - return false; - // get humidity _aht_humidity->getEvent(humidEvent); return true; } @@ -114,4 +114,4 @@ class WipperSnapper_I2C_Driver_AHTX0 : public WipperSnapper_I2C_Driver { NULL; ///< Holds data for the AHTX0's humidity sensor }; -#endif // WipperSnapper_I2C_Driver_AHTX0 \ No newline at end of file +#endif // drvAhtx0 \ No newline at end of file diff --git a/src/components/i2c/drivers/drvBase.h b/src/components/i2c/drivers/drvBase.h new file mode 100644 index 000000000..c528730f9 --- /dev/null +++ b/src/components/i2c/drivers/drvBase.h @@ -0,0 +1,727 @@ +/*! + * @file drvBase.h + * + * Base implementation for I2C device drivers. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2025 for Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + * + */ + +#ifndef DRV_BASE_H +#define DRV_BASE_H +#include +#include +#include + +#define NO_MUX_CH 0xFFFF; ///< No MUX channel specified + +/**************************************************************************/ +/*! + @brief Base class for I2C Drivers. +*/ +/**************************************************************************/ +class drvBase { + +public: + /*******************************************************************************/ + /*! + @brief Instanciates an I2C sensor. + @param i2c + The I2C hardware interface, default is Wire. + @param address + The I2C sensor's unique address. + @param mux_channel + An optional channel number used to address a device on a I2C + MUX. + @param driver_name + The name of the driver. + */ + /*******************************************************************************/ + drvBase(TwoWire *i2c, uint16_t address, uint32_t mux_channel, + const char *driver_name) { + _i2c = i2c; + _address = address; + _i2c_mux_addr = 0x0; + _i2c_mux_channel = mux_channel; + strncpy(_name, driver_name, sizeof(_name) - 1); + _name[sizeof(_name) - 1] = '\0'; + _has_alt_i2c_bus = false; + strcpy(_pin_scl, "default"); + strcpy(_pin_sda, "default"); + } + + /*******************************************************************************/ + /*! + @brief Destructor for an I2C sensor. + */ + /*******************************************************************************/ + virtual ~drvBase() {} + + /*******************************************************************************/ + /*! + @brief Gets the name of the driver. + @returns The driver's name. + */ + /*******************************************************************************/ + const char *GetDrvName() { return _name; } + + /*******************************************************************************/ + /*! + @brief Gets the I2C device's address. + @returns The I2C device's unique i2c address. + */ + /*******************************************************************************/ + uint16_t GetAddress() { return _address; } + + /*******************************************************************************/ + /*! + @brief Gets the I2C MUX address. + @returns The I2C MUX address. + */ + /*******************************************************************************/ + uint32_t GetMuxAddress() { return _i2c_mux_addr; } + + /*******************************************************************************/ + /*! + @brief Sets the I2C MUX address. + @param mux_address + The I2C MUX address. + */ + /*******************************************************************************/ + void SetMuxAddress(uint32_t mux_address) { _i2c_mux_addr = mux_address; } + + /*******************************************************************************/ + /*! + @brief Set if the I2C driver has an alternative I2C bus. + @param scl_pin + The SCL pin for the alternative I2C bus. + @param sda_pin + The SDA pin for the alternative I2C bus. + */ + /*******************************************************************************/ + void EnableAltI2CBus(char *scl_pin, char *sda_pin) { + strcpy(_pin_scl, scl_pin); + strcpy(_pin_sda, sda_pin); + _has_alt_i2c_bus = true; + } + + /*******************************************************************************/ + /*! + @brief Gets the SCL pin for the alternative I2C bus. + @returns The SCL pin for the alternative I2C bus. + */ + /*******************************************************************************/ + const char *GetPinSCL() { return _pin_scl; } + + /*******************************************************************************/ + /*! + @brief Gets the SDA pin for the alternative I2C bus. + @returns The SDA pin for the alternative I2C bus. + */ + /*******************************************************************************/ + const char *GetPinSDA() { return _pin_sda; } + + /*******************************************************************************/ + /*! + @brief Checks if the I2C driver uses an alternative I2C bus. + @returns True if the I2C driver uses an alternative I2C bus, False + otherwise. + */ + /*******************************************************************************/ + bool HasAltI2CBus() { return _has_alt_i2c_bus; } + + /*******************************************************************************/ + /*! + @brief Gets the I2C MUX channel connected to the I2C device. + @returns The desired MUX channel. + */ + /*******************************************************************************/ + uint32_t GetMuxChannel() { return _i2c_mux_channel; } + + /*******************************************************************************/ + /*! + @brief Checks if the I2C driver is attached to an I2C MUX. + @returns True if the I2C driver uses an I2C MUX, False otherwise. + */ + /*******************************************************************************/ + bool HasMux() { return _i2c_mux_channel != NO_MUX_CH; } + + /*******************************************************************************/ + /*! + @brief Configures an i2c device's sensors. + @param sensor_types + Pointer to an array of SensorType objects. + @param sensor_types_count + The number of active sensors to read from the device. + */ + /*******************************************************************************/ + void EnableSensorReads(wippersnapper_sensor_SensorType *sensor_types, + size_t sensor_types_count) { + _sensors_count = sensor_types_count; + for (size_t i = 0; i < _sensors_count; i++) { + _sensors[i] = sensor_types[i]; + } + } + + /*******************************************************************************/ + /*! + @brief Gets the number of enabled sensors. + @returns The number of enabled sensors. + */ + /*******************************************************************************/ + size_t GetEnabledSensorCnt() { return _sensors_count; } + + /*******************************************************************************/ + /*! + @brief Initializes the I2C sensor and begins I2C. + @returns True if initialized successfully, False otherwise. + */ + /*******************************************************************************/ + virtual bool begin() = 0; + + /*******************************************************************************/ + /*! + @brief Sets the sensor's period and converts from seconds to + milliseconds. + @param period The period for the sensor to return values within, in + seconds. + */ + /*******************************************************************************/ + void SetSensorPeriod(float period) { + if (period < 0) { + _sensor_period = 0; + return; + } + _sensor_period = (unsigned long)(period * 1000.0f); + } + + /*******************************************************************************/ + /*! + @brief Sets the sensor's previous period and converts from seconds + to milliseconds. + @param period The period for the sensor to return values within, in + seconds. + */ + /*******************************************************************************/ + void SetSensorPeriodPrv(ulong period) { _sensor_period_prv = period; } + + /*******************************************************************************/ + /*! + @brief Gets the sensor's period. + @returns The sensor's period, in milliseconds. + */ + /*******************************************************************************/ + ulong GetSensorPeriod() { return _sensor_period; } + + /*******************************************************************************/ + /*! + @brief Gets the sensor's previous period. + @returns The sensor's previous period, in milliseconds. + */ + /*******************************************************************************/ + ulong GetSensorPeriodPrv() { return _sensor_period_prv; } + + /*******************************************************************************/ + /*! + @brief Gets a sensor's CO2 value. + @param co2Event + The CO2 value, in ppm. + @returns True if the sensor value was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventCO2(sensors_event_t *co2Event) { return false; }; + + /*******************************************************************************/ + /*! + @brief Gets a sensor's eCO2 value. + @param eco2Event + The equivalent CO2 value, in ppm. + @returns True if the sensor value was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventECO2(sensors_event_t *eco2Event) { return false; } + + /*******************************************************************************/ + /*! + @brief Gets a sensor's TVOC value. + @param tvocEvent + The Total Volatile Organic Compounds value, in ppb. + @returns True if the sensor value was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventTVOC(sensors_event_t *tvocEvent) { return false; } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads an ambient temperature sensor (°C). + Expects value to return in the proper SI unit. + @param tempEvent + Pointer to an Adafruit_Sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventAmbientTemp(sensors_event_t *tempEvent) { return false; } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a humidity sensor and converts + the reading into the expected SI unit. + @param humidEvent + Pointer to an Adafruit_Sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventRelativeHumidity(sensors_event_t *humidEvent) { + return false; + } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a pressure sensor and converts + the reading into the expected SI unit. + @param pressureEvent + Pointer to an Adafruit_Sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventPressure(sensors_event_t *pressureEvent) { + return false; + } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a Altitude sensor and converts + the reading into the expected SI unit. + @param altitudeEvent + Altitude reading, in meters. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventAltitude(sensors_event_t *altitudeEvent) { + return false; + } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a object temperature sensor and + converts the reading into the expected SI unit. + @param objectTempEvent + object temperature sensor reading, in meters. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventObjectTemp(sensors_event_t *objectTempEvent) { + return false; + } + + /*******************************************************************************/ + /*! + @brief Base implementation - Selects a MUX channel for use with the + I2C device. + @param channel + The MUX channel to select. + */ + virtual void SelectMUXChannel(uint8_t channel) { return; } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a object light sensor and + converts the reading into the expected SI unit. + @param lightEvent + Light sensor reading, in meters. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventLight(sensors_event_t *lightEvent) { return false; } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a object pm10 std. sensor and + converts the reading into the expected SI unit. + @param pm10StdEvent + pm10 std. sensor reading, in ppm. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventPM10_STD(sensors_event_t *pm10StdEvent) { return false; } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a object pm10 env. sensor and + converts the reading into the expected SI unit. + @param pm10EnvEvent + pm10 env. sensor reading, in ppm. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventPM10_Env(sensors_event_t *pm10EnvEvent) { return false; } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a object pm25 std. sensor and + converts the reading into the expected SI unit. + @param pm25StdEvent + pm25 std. sensor reading, in ppm. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventPM25_STD(sensors_event_t *pm25StdEvent) { return false; } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a object pm25 env. sensor and + converts the reading into the expected SI unit. + @param pm25EnvEvent + pm25 env. sensor reading, in ppm. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventPM25_Env(sensors_event_t *pm25EnvEvent) { return false; } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a object pm100 std. sensor and + converts the reading into the expected SI unit. + @param pm100StdEvent + pm100 std. sensor reading, in ppm. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventPM100_STD(sensors_event_t *pm100StdEvent) { + return false; + } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a object pm100 env. sensor and + converts the reading into the expected SI unit. + @param pm100EnvEvent + pm100 env. sensor reading, in ppm. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventPM100_Env(sensors_event_t *pm100EnvEvent) { + return false; + } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a object unitless % std. sensor and + converts the reading into the expected SI unit. + @param unitlessPercentEvent + unitless % sensor reading. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventUnitlessPercent(sensors_event_t *unitlessPercentEvent) { + return false; + } + + /*******************************************************************************/ + /*! + @brief Base implementation - 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. + */ + /*******************************************************************************/ + virtual bool getEventVoltage(sensors_event_t *voltageEvent) { return false; } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a current sensor and converts the + reading into the expected SI unit. + @param currentEvent + current sensor reading, in volts. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventCurrent(sensors_event_t *currentEvent) { return false; } + + /*******************************************************************************/ + /*! + @brief Gets a sensor's Raw value. + @param rawEvent + The Raw value. + @returns True if the sensor value was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventRaw(sensors_event_t *rawEvent) { return false; } + + /*******************************************************************************/ + /*! + @brief Helper function to obtain a sensor's ambient temperature value + in °F. Requires `getEventAmbientTemp()` to be fully + implemented by a driver. + @param AmbientTempFEvent + The ambient temperature value, in °F. + @returns True if the sensor value was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventAmbientTempF(sensors_event_t *AmbientTempFEvent) { + // obtain ambient temp. in °C + if (!getEventAmbientTemp(AmbientTempFEvent)) { + return false; + } + // convert event from °C to °F + AmbientTempFEvent->temperature = + (AmbientTempFEvent->temperature * 9.0) / 5.0 + 32; + return true; + } + + /*******************************************************************************/ + /*! + @brief Helper function to obtain a sensor's object temperature value + in °F. Requires `getEventObjectTemp()` to be fully + implemented by a driver. + @param objectTempFEvent + The object temperature value, in °F. + @returns True if the sensor value was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventObjectTempF(sensors_event_t *objectTempFEvent) { + // obtain ambient temp. in °C + if (!getEventObjectTemp(objectTempFEvent)) + return false; + // convert event from °C to °F + objectTempFEvent->temperature = + (objectTempFEvent->temperature * 9.0) / 5.0 + 32.0; + return true; + } + + /****************************** SENSOR_TYPE: Gas Resistance (ohms) + * *******************************/ + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a gas resistance sensor and converts + the reading into the expected SI unit. + @param gasEvent + gas resistance sensor reading, in ohms. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventGasResistance(sensors_event_t *gasEvent) { + return false; + } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a NOx Index sensor and converts + the reading into the expected SI unit. + @param gasEvent + NOx Index sensor reading, unitless. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventNOxIndex(sensors_event_t *gasEvent) { return false; } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a VOC Index sensor and converts + the reading into the expected SI unit. + @param gasEvent + VOC Index sensor reading, unitless. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventVOCIndex(sensors_event_t *gasEvent) { return false; } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a proximity sensor and + converts the reading into the expected SI unit. + @param proximityEvent + Proximity sensor reading, in millimeters. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventProximity(sensors_event_t *proximityEvent) { + return false; + } + + /*******************************************************************************/ + /*! + @brief Reads a sensor's event from the i2c driver. + @param sensor_type + The sensor type to read. + @param sensors_event + Pointer to an Adafruit_Sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + bool GetSensorEvent(wippersnapper_sensor_SensorType sensor_type, + sensors_event_t *sensors_event) { + auto it = SensorEventHandlers.find(sensor_type); + if (it == SensorEventHandlers.end()) + return false; // Could not find sensor_type + return it->second(sensors_event); + } + + /*******************************************************************************/ + /*! + @brief Function type for sensor event handlers + @param sensors_event_t* + Pointer to the sensor event structure to be filled + @returns True if event was successfully read, False otherwise + */ + /*******************************************************************************/ + using fnGetEvent = std::function; + + // Maps SensorType to function calls + std::map SensorEventHandlers = { + {wippersnapper_sensor_SensorType_SENSOR_TYPE_UNSPECIFIED, + [this](sensors_event_t *event) -> bool { + return this->getEventRaw(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_LIGHT, + [this](sensors_event_t *event) -> bool { + return this->getEventLight(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_PRESSURE, + [this](sensors_event_t *event) -> bool { + return this->getEventPressure(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_PROXIMITY, + [this](sensors_event_t *event) -> bool { + return this->getEventProximity(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_RELATIVE_HUMIDITY, + [this](sensors_event_t *event) -> bool { + return this->getEventRelativeHumidity(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE, + [this](sensors_event_t *event) -> bool { + return this->getEventAmbientTemp(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE, + [this](sensors_event_t *event) -> bool { + return this->getEventObjectTemp(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE, + [this](sensors_event_t *event) -> bool { + return this->getEventVoltage(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_CURRENT, + [this](sensors_event_t *event) -> bool { + return this->getEventCurrent(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW, + [this](sensors_event_t *event) -> bool { + return this->getEventRaw(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_PM10_STD, + [this](sensors_event_t *event) -> bool { + return this->getEventPM10_STD(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_PM25_STD, + [this](sensors_event_t *event) -> bool { + return this->getEventPM25_STD(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_PM100_STD, + [this](sensors_event_t *event) -> bool { + return this->getEventPM100_STD(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_PM10_ENV, + [this](sensors_event_t *event) -> bool { + return this->getEventPM10_Env(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_PM25_ENV, + [this](sensors_event_t *event) -> bool { + return this->getEventPM25_Env(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_PM100_ENV, + [this](sensors_event_t *event) -> bool { + return this->getEventPM100_Env(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_CO2, + [this](sensors_event_t *event) -> bool { + return this->getEventCO2(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_GAS_RESISTANCE, + [this](sensors_event_t *event) -> bool { + return this->getEventGasResistance(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_ALTITUDE, + [this](sensors_event_t *event) -> bool { + return this->getEventAltitude(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_ECO2, + [this](sensors_event_t *event) -> bool { + return this->getEventECO2(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_UNITLESS_PERCENT, + [this](sensors_event_t *event) -> bool { + return this->getEventUnitlessPercent(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT, + [this](sensors_event_t *event) -> bool { + return this->getEventAmbientTempF(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT, + [this](sensors_event_t *event) -> bool { + return this->getEventObjectTempF(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_VOC_INDEX, + [this](sensors_event_t *event) -> bool { + return this->getEventVOCIndex(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_NOX_INDEX, + [this](sensors_event_t *event) -> bool { + return this->getEventNOxIndex(event); + }}, + {wippersnapper_sensor_SensorType_SENSOR_TYPE_TVOC, + [this](sensors_event_t *event) -> bool { + return this->getEventTVOC(event); + }}}; ///< SensorType to function call map + + wippersnapper_sensor_SensorType + _sensors[15]; ///< Sensors attached to the device. + +protected: + TwoWire *_i2c; ///< Pointer to the I2C bus + bool _has_alt_i2c_bus; ///< True if the device is on an alternate I2C bus + uint16_t _address; ///< The device's I2C address. + uint32_t _i2c_mux_addr; ///< The I2C MUX address, if applicable. + uint32_t _i2c_mux_channel; ///< The I2C MUX channel, if applicable. + char _name[15]; ///< The device's name. + char _pin_scl[8]; ///< The device's SCL pin. + char _pin_sda[8]; ///< The device's SDA pin. + ulong _sensor_period; ///< The sensor's period, in milliseconds. + ulong _sensor_period_prv; ///< The sensor's previous period, in milliseconds. + size_t _sensors_count; ///< Number of sensors on the device. +}; +#endif // DRV_BASE_H \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_BH1750.h b/src/components/i2c/drivers/drvBh1750.h similarity index 74% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_BH1750.h rename to src/components/i2c/drivers/drvBh1750.h index fb06dcab0..2c2096dcc 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_BH1750.h +++ b/src/components/i2c/drivers/drvBh1750.h @@ -1,7 +1,21 @@ -#ifndef WipperSnapper_I2C_Driver_BH1750_H -#define WipperSnapper_I2C_Driver_BH1750_H +/*! + * @file drvBh1750.h + * + * Device driver for a BH1750 Light 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) Scott Perkins, 2022 + * + * MIT license, all text here must be included in any redistribution. + * + */ +#ifndef DRV_1750_H +#define DRV_1750_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include //include the library for the BH1750 sensor /**************************************************************************/ @@ -17,7 +31,7 @@ sensor returns to Power Down mode after each reading. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_BH1750 : public WipperSnapper_I2C_Driver { +class drvBh1750 : public drvBase { public: /*******************************************************************************/ /*! @@ -26,12 +40,16 @@ class WipperSnapper_I2C_Driver_BH1750 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_BH1750(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvBh1750(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 } /*******************************************************************************/ @@ -39,7 +57,7 @@ class WipperSnapper_I2C_Driver_BH1750 : public WipperSnapper_I2C_Driver { @brief Destructor for a BH1750 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_BH1750() { + ~drvBh1750() { // Called when a BH1750 component is deleted. delete _bh1750; } @@ -51,10 +69,10 @@ class WipperSnapper_I2C_Driver_BH1750 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _bh1750 = new hp_BH1750(); // attempt to initialize BH1750 - if (!_bh1750->begin(_sensorAddress, _i2c)) + if (!_bh1750->begin(_address, _i2c)) return false; // Set to the recommended quality setting _bh1750->setQuality(BH1750_QUALITY_HIGH); @@ -82,4 +100,4 @@ class WipperSnapper_I2C_Driver_BH1750 : public WipperSnapper_I2C_Driver { hp_BH1750 *_bh1750; ///< Pointer to BH1750 light sensor object }; -#endif // WipperSnapper_I2C_Driver_BH1750 \ No newline at end of file +#endif // drvBh1750 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_BME280.h b/src/components/i2c/drivers/drvBme280.h similarity index 84% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_BME280.h rename to src/components/i2c/drivers/drvBme280.h index 7d3c261f5..d6b8f74f4 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_BME280.h +++ b/src/components/i2c/drivers/drvBme280.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_BME280.h + * @file drvBme280.h * * Device driver for a BME280 Pressure Humidity and Temperature sensor. * @@ -7,16 +7,16 @@ * please support Adafruit and open-source hardware by purchasing * products from Adafruit! * - * Copyright (c) Brent Rubell 2021 for Adafruit Industries. + * Copyright (c) Brent Rubell 2025 for Adafruit Industries. * * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_BME280_H -#define WipperSnapper_I2C_Driver_BME280_H +#ifndef DRV_BME_280_H +#define DRV_BME_280_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #define SEALEVELPRESSURE_HPA (1013.25) ///< Default sea level pressure, in hPa @@ -27,7 +27,7 @@ and humidity sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_BME280 : public WipperSnapper_I2C_Driver { +class drvBme280 : public drvBase { public: /*******************************************************************************/ @@ -37,12 +37,16 @@ class WipperSnapper_I2C_Driver_BME280 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C MUX channel, if applicable. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_BME280(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvBme280(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 } /*******************************************************************************/ @@ -50,7 +54,7 @@ class WipperSnapper_I2C_Driver_BME280 : public WipperSnapper_I2C_Driver { @brief Destructor for an BME280 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_BME280() { delete _bme; } + ~drvBme280() { delete _bme; } /*******************************************************************************/ /*! @@ -58,15 +62,24 @@ class WipperSnapper_I2C_Driver_BME280 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _bme = new Adafruit_BME280(); // attempt to initialize BME280 - if (!_bme->begin(_sensorAddress, _i2c)) + if (!_bme->begin(_address, _i2c)) return false; - // configure BME280 device + + // Configure sensors _bme_temp = _bme->getTemperatureSensor(); + if (_bme_temp == NULL) + return false; + _bme_humidity = _bme->getHumiditySensor(); + if (_bme_humidity == NULL) + return false; + _bme_pressure = _bme->getPressureSensor(); + if (_bme_pressure == NULL) + return false; return true; } @@ -80,10 +93,7 @@ class WipperSnapper_I2C_Driver_BME280 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventAmbientTemp(sensors_event_t *tempEvent) { - if (_bme_temp == NULL) - return false; - _bme_temp->getEvent(tempEvent); - return true; + return _bme_temp->getEvent(tempEvent); } /*******************************************************************************/ @@ -96,10 +106,7 @@ class WipperSnapper_I2C_Driver_BME280 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventRelativeHumidity(sensors_event_t *humidEvent) { - if (_bme_humidity == NULL) - return false; - _bme_humidity->getEvent(humidEvent); - return true; + return _bme_humidity->getEvent(humidEvent); } /*******************************************************************************/ @@ -113,10 +120,7 @@ class WipperSnapper_I2C_Driver_BME280 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventPressure(sensors_event_t *pressureEvent) { - if (_bme_pressure == NULL) - return false; - _bme_pressure->getEvent(pressureEvent); - return true; + return _bme_pressure->getEvent(pressureEvent); } /*******************************************************************************/ @@ -143,4 +147,4 @@ class WipperSnapper_I2C_Driver_BME280 : public WipperSnapper_I2C_Driver { NULL; ///< Ptr to an adafruit_sensor representing the humidity }; -#endif // WipperSnapper_I2C_Driver_BME280 \ No newline at end of file +#endif // drvBme280 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_BME680.h b/src/components/i2c/drivers/drvBme680.h similarity index 84% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_BME680.h rename to src/components/i2c/drivers/drvBme680.h index 276f181dc..64c44793b 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_BME680.h +++ b/src/components/i2c/drivers/drvBme680.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_BME680.h + * @file drvBme680.h * * Device driver for a BME680 Pressure Humidity and Temperature sensor. * @@ -7,16 +7,16 @@ * please support Adafruit and open-source hardware by purchasing * products from Adafruit! * - * Copyright (c) Brent Rubell 2021 for Adafruit Industries. + * Copyright (c) Brent Rubell 2021-2025 for Adafruit Industries. * * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_BME680_H -#define WipperSnapper_I2C_Driver_BME680_H +#ifndef DRV_BME680_H +#define DRV_BME680_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #define SEALEVELPRESSURE_HPA (1013.25) ///< Default sea level pressure, in hPa @@ -27,7 +27,7 @@ and humidity sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_BME680 : public WipperSnapper_I2C_Driver { +class drvBme680 : public drvBase { public: /*******************************************************************************/ @@ -37,12 +37,16 @@ class WipperSnapper_I2C_Driver_BME680 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_BME680(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvBme680(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 } /*******************************************************************************/ @@ -50,7 +54,7 @@ class WipperSnapper_I2C_Driver_BME680 : public WipperSnapper_I2C_Driver { @brief Destructor for an BME680 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_BME680() { delete _bme; } + ~drvBme680() { delete _bme; } /*******************************************************************************/ /*! @@ -58,21 +62,27 @@ class WipperSnapper_I2C_Driver_BME680 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _bme = new Adafruit_BME680(_i2c); // attempt to initialize BME680 - if (!_bme->begin(_sensorAddress)) + if (!_bme->begin(_address)) return false; // Set up oversampling and filter initialization // defaults from // https://github.com/adafruit/Adafruit_BME680/blob/master/examples/bme680test/bme680test.ino - _bme->setTemperatureOversampling(BME680_OS_8X); - _bme->setHumidityOversampling(BME680_OS_2X); - _bme->setPressureOversampling(BME680_OS_4X); - _bme->setIIRFilterSize(BME680_FILTER_SIZE_3); - _bme->setGasHeater(320, 150); // 320*C for 150 ms + if (!_bme->setTemperatureOversampling(BME680_OS_8X)) + return false; + if (!_bme->setHumidityOversampling(BME680_OS_2X)) + return false; + if (!_bme->setPressureOversampling(BME680_OS_4X)) + return false; + if (!_bme->setIIRFilterSize(BME680_FILTER_SIZE_3)) + return false; + // 320*C for 150 ms + if ((!_bme->setGasHeater(320, 150))) + return false; return true; } @@ -172,4 +182,4 @@ class WipperSnapper_I2C_Driver_BME680 : public WipperSnapper_I2C_Driver { Adafruit_BME680 *_bme; ///< BME680 object }; -#endif // WipperSnapper_I2C_Driver_BME680 \ No newline at end of file +#endif // drvBme680 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_BMP280.h b/src/components/i2c/drivers/drvBmp280.h similarity index 85% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_BMP280.h rename to src/components/i2c/drivers/drvBmp280.h index 0a3e8ad4f..212f17029 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_BMP280.h +++ b/src/components/i2c/drivers/drvBmp280.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_BMP280.h + * @file drvBmp280.h * * Device driver for a BMP280 Pressure and Temperature sensor. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_BMP280_H -#define WipperSnapper_I2C_Driver_BMP280_H +#ifndef DRV_BMP280_H +#define DRV_BMP280_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #define SEALEVELPRESSURE_HPA (1013.25) ///< Default sea level pressure, in hPa @@ -27,7 +27,7 @@ and pressure sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_BMP280 : public WipperSnapper_I2C_Driver { +class drvBmp280 : public drvBase { public: /*******************************************************************************/ @@ -37,12 +37,16 @@ class WipperSnapper_I2C_Driver_BMP280 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_BMP280(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvBmp280(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 } /*******************************************************************************/ @@ -50,7 +54,7 @@ class WipperSnapper_I2C_Driver_BMP280 : public WipperSnapper_I2C_Driver { @brief Destructor for an BMP280 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_BMP280() { delete _bmp; } + ~drvBmp280() { delete _bmp; } /*******************************************************************************/ /*! @@ -58,10 +62,10 @@ class WipperSnapper_I2C_Driver_BMP280 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _bmp = new Adafruit_BMP280(_i2c); // attempt to initialize BMP280 - if (!_bmp->begin(_sensorAddress)) + if (!_bmp->begin(_address)) return false; // set up sampling as recommended in Adafruit library @@ -71,9 +75,14 @@ class WipperSnapper_I2C_Driver_BMP280 : public WipperSnapper_I2C_Driver { Adafruit_BMP280::FILTER_X16, /* Filtering. */ Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */ - // configure BMP280 device + // attempt to get sensors _bmp_temp = _bmp->getTemperatureSensor(); + if (_bmp_temp == NULL) + return false; _bmp_pressure = _bmp->getPressureSensor(); + if (_bmp_pressure == NULL) + return false; + return true; } @@ -87,10 +96,7 @@ class WipperSnapper_I2C_Driver_BMP280 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventAmbientTemp(sensors_event_t *tempEvent) { - if (_bmp_temp == NULL) - return false; - _bmp_temp->getEvent(tempEvent); - return true; + return _bmp_temp->getEvent(tempEvent); } /*******************************************************************************/ @@ -104,10 +110,7 @@ class WipperSnapper_I2C_Driver_BMP280 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventPressure(sensors_event_t *pressureEvent) { - if (_bmp_pressure == NULL) - return false; - _bmp_pressure->getEvent(pressureEvent); - return true; + return _bmp_pressure->getEvent(pressureEvent); } /*******************************************************************************/ @@ -134,4 +137,4 @@ class WipperSnapper_I2C_Driver_BMP280 : public WipperSnapper_I2C_Driver { NULL; ///< Ptr to an adafruit_sensor representing the humidity }; -#endif // WipperSnapper_I2C_Driver_BMP280 \ No newline at end of file +#endif // drvBmp280 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_BMP3XX.h b/src/components/i2c/drivers/drvBmp3xx.h similarity index 80% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_BMP3XX.h rename to src/components/i2c/drivers/drvBmp3xx.h index 9609cd087..b23f436e7 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_BMP3XX.h +++ b/src/components/i2c/drivers/drvBmp3xx.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_BMP3XX.h + * @file drvBmp3xx.h * * Device driver for a BMP3XX precision pressure sensor breakout. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_BMP3XX_H -#define WipperSnapper_I2C_Driver_BMP3XX_H +#ifndef DRV_BMP3XX_H +#define DRV_BMP3XX_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #define SEALEVELPRESSURE_HPA (1013.25) ///< Default sea level pressure, in hPa @@ -27,8 +27,7 @@ and pressure sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_BMP3XX : public WipperSnapper_I2C_Driver { - +class drvBmp3xx : public drvBase { public: /*******************************************************************************/ /*! @@ -37,12 +36,16 @@ class WipperSnapper_I2C_Driver_BMP3XX : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_BMP3XX(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvBmp3xx(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 } /*******************************************************************************/ @@ -50,7 +53,7 @@ class WipperSnapper_I2C_Driver_BMP3XX : public WipperSnapper_I2C_Driver { @brief Destructor for an BMP3XX sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_BMP3XX() { delete _bmp3xx; } + ~drvBmp3xx() { delete _bmp3xx; } /*******************************************************************************/ /*! @@ -58,17 +61,21 @@ class WipperSnapper_I2C_Driver_BMP3XX : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _bmp3xx = new Adafruit_BMP3XX(); // attempt to initialize BMP3XX - if (!_bmp3xx->begin_I2C(_sensorAddress, _i2c)) + if (!_bmp3xx->begin_I2C(_address, _i2c)) return false; // Set up oversampling and filter initialization - _bmp3xx->setTemperatureOversampling(BMP3_OVERSAMPLING_8X); - _bmp3xx->setPressureOversampling(BMP3_OVERSAMPLING_4X); - _bmp3xx->setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3); - _bmp3xx->setOutputDataRate(BMP3_ODR_50_HZ); + if (!_bmp3xx->setTemperatureOversampling(BMP3_OVERSAMPLING_8X)) + return false; + if (!_bmp3xx->setPressureOversampling(BMP3_OVERSAMPLING_4X)) + return false; + if (!_bmp3xx->setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3)) + return false; + if (!_bmp3xx->setOutputDataRate(BMP3_ODR_50_HZ)) + return false; return true; } @@ -125,5 +132,4 @@ class WipperSnapper_I2C_Driver_BMP3XX : public WipperSnapper_I2C_Driver { protected: Adafruit_BMP3XX *_bmp3xx; ///< BMP3XX object }; - -#endif // WipperSnapper_I2C_Driver_BMP3XX \ No newline at end of file +#endif // drvBmp3xx \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_DPS310.h b/src/components/i2c/drivers/drvDps310.h similarity index 57% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_DPS310.h rename to src/components/i2c/drivers/drvDps310.h index 46ee548dc..0406d69b6 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_DPS310.h +++ b/src/components/i2c/drivers/drvDps310.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_DPS310.h + * @file drvDps310.h * * Device driver the DPS310 barometric pressure sensor. * @@ -7,16 +7,15 @@ * please support Adafruit and open-source hardware by purchasing * products from Adafruit! * - * Copyright (c) Brent Rubell 2021 for Adafruit Industries. + * Copyright (c) Brent Rubell 2021-2025 for Adafruit Industries. * * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_DPS310_H -#define WipperSnapper_I2C_Driver_DPS310_H - -#include "WipperSnapper_I2C_Driver.h" +#ifndef DRV_DPS310_H +#define DRV_DPS310_H +#include "drvBase.h" #include /**************************************************************************/ @@ -25,7 +24,7 @@ pressure sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_DPS310 : public WipperSnapper_I2C_Driver { +class drvDps310 : public drvBase { public: /*******************************************************************************/ @@ -35,12 +34,21 @@ class WipperSnapper_I2C_Driver_DPS310 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_DPS310(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { + drvDps310(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) { _i2c = i2c; - _sensorAddress = sensorAddress; + _address = sensorAddress; + _i2c_mux_channel = mux_channel; + strncpy(_name, driver_name, sizeof(_name) - 1); + _name[sizeof(_name) - 1] = '\0'; + _last_read = 0; } /*******************************************************************************/ @@ -48,7 +56,7 @@ class WipperSnapper_I2C_Driver_DPS310 : public WipperSnapper_I2C_Driver { @brief Destructor for an DPS310 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_DPS310() { delete _dps310; } + ~drvDps310() { delete _dps310; } /*******************************************************************************/ /*! @@ -56,21 +64,56 @@ class WipperSnapper_I2C_Driver_DPS310 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { // initialize DPS310 _dps310 = new Adafruit_DPS310(); - if (!_dps310->begin_I2C((uint8_t)_sensorAddress, _i2c)) + if (!_dps310->begin_I2C((uint8_t)_address, _i2c)) { return false; + } // init OK, perform sensor configuration _dps310->configureTemperature(DPS310_64HZ, DPS310_64SAMPLES); _dps310->configurePressure(DPS310_64HZ, DPS310_64SAMPLES); _dps_temp = _dps310->getTemperatureSensor(); + if (_dps_temp == NULL) { + return false; + } _dps_pressure = _dps310->getPressureSensor(); - // check if sensors are configured properly - if (_dps_temp == NULL || _dps_pressure == NULL) + if (_dps_pressure == NULL) { return false; + } + return true; + } + /*******************************************************************************/ + /*! + @brief Reads the DPS310's temperature and pressure. + @returns True if the measurements were read successfully, False + otherwise. + */ + /*******************************************************************************/ + bool alreadyRecentlyRead() { + return (_last_read != 0 && (millis() - _last_read < 1000)); + } + + /*******************************************************************************/ + /*! + @brief Reads the DPS310's temperature and pressure. + @returns True if the measurements were read successfully, False + otherwise. + */ + /*******************************************************************************/ + bool ReadMeasurements() { + if (alreadyRecentlyRead()) + return true; + + while (!_dps310->temperatureAvailable() || !_dps310->pressureAvailable()) + return false; + + if (!_dps310->getEvents(&_temp_event, &_pressure_event)) + return false; + + _last_read = millis(); return true; } @@ -84,10 +127,10 @@ class WipperSnapper_I2C_Driver_DPS310 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventAmbientTemp(sensors_event_t *tempEvent) { - if (!_dps310->temperatureAvailable()) + if (!ReadMeasurements()) { return false; - - _dps_temp->getEvent(tempEvent); + } + tempEvent->temperature = _temp_event.temperature; return true; } @@ -101,14 +144,19 @@ class WipperSnapper_I2C_Driver_DPS310 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventPressure(sensors_event_t *pressureEvent) { - if (!_dps310->pressureAvailable()) + if (!ReadMeasurements()) { return false; - - _dps_pressure->getEvent(pressureEvent); + } + pressureEvent->pressure = _pressure_event.pressure; return true; } protected: + sensors_event_t _temp_event = { + 0}; ///< DPS310 sensor event for temperature readings + sensors_event_t + _pressure_event; ///< DPS310 sensor event for pressure readings + ulong _last_read; ///< Last time the sensor was read Adafruit_DPS310 *_dps310; ///< DPS310 driver object Adafruit_Sensor *_dps_temp = NULL; ///< Holds data for the DPS310's temperature sensor @@ -116,4 +164,4 @@ class WipperSnapper_I2C_Driver_DPS310 : public WipperSnapper_I2C_Driver { NULL; ///< Holds data for the DPS310's pressure sensor }; -#endif // WipperSnapper_I2C_Driver_DPS310 \ No newline at end of file +#endif // drvDps310 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_DS2484.h b/src/components/i2c/drivers/drvDs2484.h similarity index 72% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_DS2484.h rename to src/components/i2c/drivers/drvDs2484.h index ed276ab9d..25fc26d21 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_DS2484.h +++ b/src/components/i2c/drivers/drvDs2484.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_DS2484.h + * @file drvDs2484.h * * Device driver the DS2484 I2C OneWire converter (hosting a DS18b20). * @@ -13,15 +13,15 @@ * */ -#ifndef WipperSnapper_I2C_Driver_DS2484_H -#define WipperSnapper_I2C_Driver_DS2484_H +#ifndef DRV_DS2484_H +#define DRV_DS2484_H #define DS18B20_FAMILY_CODE 0x28 ///< DS18B20 family code #define DS18B20_CMD_CONVERT_T 0x44 ///< Convert T command #define DS18B20_CMD_MATCH_ROM 0x55 ///< Match ROM command #define DS18B20_CMD_READ_SCRATCHPAD 0xBE ///< Read Scratchpad command -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -30,7 +30,7 @@ converter hosting a DS18b20 temperature sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_DS2484 : public WipperSnapper_I2C_Driver { +class drvDs2484 : public drvBase { public: /*******************************************************************************/ @@ -40,12 +40,16 @@ class WipperSnapper_I2C_Driver_DS2484 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_DS2484(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvDs2484(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 } /*******************************************************************************/ @@ -53,7 +57,7 @@ class WipperSnapper_I2C_Driver_DS2484 : public WipperSnapper_I2C_Driver { @brief Destructor for an DS2484 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_DS2484() { delete _ds2484; } + ~drvDs2484() { delete _ds2484; } /*******************************************************************************/ /*! @@ -61,25 +65,15 @@ class WipperSnapper_I2C_Driver_DS2484 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { // initialize DS2484 _ds2484 = new Adafruit_DS248x(); - if (!_ds2484->begin(_i2c, (uint8_t)_sensorAddress)) { - WS_DEBUG_PRINTLN("Could not find DS2484"); + if (!_ds2484->begin(_i2c, (uint8_t)_address)) return false; - } // check bus is okay - if (!_ds2484->OneWireReset()) { - WS_DEBUG_PRINTLN("Failed to do a OneWire bus reset"); - if (_ds2484->shortDetected()) { - WS_DEBUG_PRINTLN("\tShort detected"); - } - if (!_ds2484->presencePulseDetected()) { - WS_DEBUG_PRINTLN("\tNo presense pulse"); - } + if (!_ds2484->OneWireReset()) return false; - } // locate first DS18B20 bool found_device = false; @@ -88,19 +82,12 @@ class WipperSnapper_I2C_Driver_DS2484 : public WipperSnapper_I2C_Driver { while (!found_device && _ds2484->OneWireSearch(_rom)) { if (_rom[0] == DS18B20_FAMILY_CODE) { found_device = true; - } else { - WS_DEBUG_PRINT("Found unwanted device with family code: 0x"); - WS_DEBUG_PRINTHEX(_rom[0]); - WS_DEBUG_PRINTLN(" expected 0x28"); // DS18B20_FAMILY_CODE } } - if (!found_device) { - WS_DEBUG_PRINTLN("Could not find DS18B20 attached to DS2484"); + if (!found_device) return false; - } - WS_DEBUG_PRINTLN("DS2484 found"); return true; } @@ -113,10 +100,9 @@ class WipperSnapper_I2C_Driver_DS2484 : public WipperSnapper_I2C_Driver { otherwise. */ bool processTemperatureEvent(sensors_event_t *tempEvent) { - if (!_ds2484->OneWireReset()) { - WS_DEBUG_PRINTLN("Failed to do a OneWire bus reset"); + if (!_ds2484->OneWireReset()) return false; - } + if (!_ds2484->presencePulseDetected()) { tempEvent->temperature = NAN; return true; @@ -133,8 +119,6 @@ class WipperSnapper_I2C_Driver_DS2484 : public WipperSnapper_I2C_Driver { // Read scratchpad if (!_ds2484->OneWireReset()) { - WS_DEBUG_PRINTLN( - "Failed to do a OneWire bus reset after starting temp conversion"); return false; } _ds2484->OneWireWriteByte(DS18B20_CMD_MATCH_ROM); // Match ROM command @@ -173,4 +157,4 @@ class WipperSnapper_I2C_Driver_DS2484 : public WipperSnapper_I2C_Driver { uint8_t _rom[8]; ///< DS18B20 ROM }; -#endif // WipperSnapper_I2C_Driver_DS2484 \ No newline at end of file +#endif // drvDs2484 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_ENS160.h b/src/components/i2c/drivers/drvEns160.h similarity index 84% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_ENS160.h rename to src/components/i2c/drivers/drvEns160.h index 49015b745..556031ad0 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_ENS160.h +++ b/src/components/i2c/drivers/drvEns160.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_ENS160.h + * @file drvEns160.h * * Device driver for a ENS160 MOX Gas Sensor. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_ENS160_H -#define WipperSnapper_I2C_Driver_ENS160_H +#ifndef DRV_ENS160_H +#define DRV_ENS160_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #define SEALEVELPRESSURE_HPA (1013.25) ///< Default sea level pressure, in hPa @@ -27,7 +27,7 @@ and humidity sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_ENS160 : public WipperSnapper_I2C_Driver { +class drvEns160 : public drvBase { public: /*******************************************************************************/ @@ -37,12 +37,16 @@ class WipperSnapper_I2C_Driver_ENS160 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_ENS160(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvEns160(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 } /*******************************************************************************/ @@ -50,7 +54,7 @@ class WipperSnapper_I2C_Driver_ENS160 : public WipperSnapper_I2C_Driver { @brief Destructor for an ENS160 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_ENS160() { delete _ens160; } + ~drvEns160() { delete _ens160; } /*******************************************************************************/ /*! @@ -58,15 +62,17 @@ class WipperSnapper_I2C_Driver_ENS160 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { - _ens160 = new ScioSense_ENS160((TwoWire *)_i2c, (uint8_t)_sensorAddress); + bool begin() override { + _ens160 = new ScioSense_ENS160((TwoWire *)_i2c, (uint8_t)_address); // attempt to initialize ENS160 if (!_ens160->begin()) return false; // Set the mode to standard - return _ens160->setMode(ENS160_OPMODE_STD); + if (!_ens160->setMode(ENS160_OPMODE_STD)) + return false; + return true; } /*******************************************************************************/ @@ -131,4 +137,4 @@ class WipperSnapper_I2C_Driver_ENS160 : public WipperSnapper_I2C_Driver { ScioSense_ENS160 *_ens160; ///< ENS160 object }; -#endif // WipperSnapper_I2C_Driver_ENS160 \ No newline at end of file +#endif // drvEns160 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_HTS221.h b/src/components/i2c/drivers/drvHts221.h similarity index 80% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_HTS221.h rename to src/components/i2c/drivers/drvHts221.h index 017b44686..d4a8c783e 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_HTS221.h +++ b/src/components/i2c/drivers/drvHts221.h @@ -1,13 +1,13 @@ /*! - * @file WipperSnapper_I2C_Driver_HTS221.h + * @file drvHts221.h * * Device driver for an HTS221 Humidity and Temperature sensor. */ -#ifndef WipperSnapper_I2C_Driver_HTS221_H -#define WipperSnapper_I2C_Driver_HTS221_H +#ifndef DRV_HTS221_H +#define DRV_HTS221_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -16,7 +16,7 @@ temperature sensor. This implementation uses the 1 Hz data rate. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_HTS221 : public WipperSnapper_I2C_Driver { +class drvHts221 : public drvBase { public: /*******************************************************************************/ @@ -26,12 +26,16 @@ class WipperSnapper_I2C_Driver_HTS221 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_HTS221(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvHts221(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 } /*******************************************************************************/ @@ -39,7 +43,7 @@ class WipperSnapper_I2C_Driver_HTS221 : public WipperSnapper_I2C_Driver { @brief Destructor for an HTS221 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_HTS221() { delete _hts221; } + ~drvHts221() { delete _hts221; } /*******************************************************************************/ /*! @@ -48,10 +52,10 @@ class WipperSnapper_I2C_Driver_HTS221 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ - bool begin() { + bool begin() override { // attempt to initialize the HTS221 using the I2C interface _hts221 = new Adafruit_HTS221(); - if (!_hts221->begin_I2C(_sensorAddress, _i2c)) + if (!_hts221->begin_I2C(_address, _i2c)) return false; // set the HTS221's data rate to 1 Hz @@ -59,7 +63,12 @@ class WipperSnapper_I2C_Driver_HTS221 : public WipperSnapper_I2C_Driver { // get temperature and humidity sensor _hts221_temp = _hts221->getTemperatureSensor(); + if (_hts221_temp == NULL) + return false; + _hts221_humidity = _hts221->getHumiditySensor(); + if (_hts221_humidity == NULL) + return false; return true; } @@ -74,10 +83,6 @@ class WipperSnapper_I2C_Driver_HTS221 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventAmbientTemp(sensors_event_t *tempEvent) { - // is sensor enabled correctly? - if (_hts221_temp == NULL) - return false; - // get temperature and return status return _hts221_temp->getEvent(tempEvent); } @@ -91,10 +96,6 @@ class WipperSnapper_I2C_Driver_HTS221 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventRelativeHumidity(sensors_event_t *humidEvent) { - // is sensor enabled correctly? - if (_hts221_humidity == NULL) - return false; - // get humidity and return status return _hts221_humidity->getEvent(humidEvent); } @@ -106,4 +107,4 @@ class WipperSnapper_I2C_Driver_HTS221 : public WipperSnapper_I2C_Driver { NULL; ///< Holds data for the HTS221's humidity sensor }; -#endif // WipperSnapper_I2C_Driver_HTS221 \ No newline at end of file +#endif // drvHts221 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_HTU21D.h b/src/components/i2c/drivers/drvHtu21d.h similarity index 82% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_HTU21D.h rename to src/components/i2c/drivers/drvHtu21d.h index bfc689216..12134f6ad 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_HTU21D.h +++ b/src/components/i2c/drivers/drvHtu21d.h @@ -1,13 +1,13 @@ /*! - * @file WipperSnapper_I2C_Driver_HTU21D.h + * @file drvHtu21d.h * * Device driver for an HTU21D Humidity and Temperature sensor. */ -#ifndef WipperSnapper_I2C_Driver_HTU21D_H -#define WipperSnapper_I2C_Driver_HTU21D_H +#ifndef DRV_HTU21D_H +#define DRV_HTU21D_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -16,7 +16,7 @@ temperature sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_HTU21D : public WipperSnapper_I2C_Driver { +class drvHtu21d : public drvBase { public: /*******************************************************************************/ @@ -26,12 +26,16 @@ class WipperSnapper_I2C_Driver_HTU21D : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_HTU21D(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvHtu21d(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 } /*******************************************************************************/ @@ -39,7 +43,7 @@ class WipperSnapper_I2C_Driver_HTU21D : public WipperSnapper_I2C_Driver { @brief Destructor for an HTU21D sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_HTU21D() { delete _htu21d; } + ~drvHtu21d() { delete _htu21d; } /*******************************************************************************/ /*! @@ -85,5 +89,4 @@ class WipperSnapper_I2C_Driver_HTU21D : public WipperSnapper_I2C_Driver { protected: Adafruit_HTU21DF *_htu21d; ///< Pointer to an HTU21D object }; - -#endif // WipperSnapper_I2C_Driver_HTU21D \ No newline at end of file +#endif // drvHtu21d \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA219.h b/src/components/i2c/drivers/drvIna219.h similarity index 83% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA219.h rename to src/components/i2c/drivers/drvIna219.h index 3cb93b04d..cf25a6be9 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA219.h +++ b/src/components/i2c/drivers/drvIna219.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_INA219.h + * @file drvIna219.h * * Device driver for the INA219 High-side DC Current and Voltage Monitor * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_INA219_H -#define WipperSnapper_I2C_Driver_INA219_H +#ifndef DRV_INA219_H +#define DRV_INA219_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -23,7 +23,7 @@ @brief Class that provides a driver interface for a INA219 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_INA219 : public WipperSnapper_I2C_Driver { +class drvIna219 : public drvBase { public: /*******************************************************************************/ /*! @@ -32,12 +32,16 @@ class WipperSnapper_I2C_Driver_INA219 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress The 7-bit I2C address of the sensor. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_INA219(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvIna219(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 } /*******************************************************************************/ @@ -45,7 +49,7 @@ class WipperSnapper_I2C_Driver_INA219 : public WipperSnapper_I2C_Driver { @brief Destructor for an INA219 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_INA219() { delete _ina219; } + ~drvIna219() { delete _ina219; } /*******************************************************************************/ /*! @@ -54,7 +58,7 @@ class WipperSnapper_I2C_Driver_INA219 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool begin() { - _ina219 = new Adafruit_INA219(_sensorAddress); + _ina219 = new Adafruit_INA219(_address); if (!_ina219->begin(_i2c)) return false; @@ -101,4 +105,4 @@ class WipperSnapper_I2C_Driver_INA219 : public WipperSnapper_I2C_Driver { Adafruit_INA219 *_ina219; ///< Pointer to INA219 sensor object }; -#endif // WipperSnapper_I2C_Driver_INA219 \ No newline at end of file +#endif // drvIna219 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_LC709203F.h b/src/components/i2c/drivers/drvLc709203f.h similarity index 80% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_LC709203F.h rename to src/components/i2c/drivers/drvLc709203f.h index aa713165b..22286d35b 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_LC709203F.h +++ b/src/components/i2c/drivers/drvLc709203f.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_LC709203F.h + * @file drvLc709203f.h * * Device driver for the LC709203F LiPoly / LiIon Fuel Gauge and * Battery Monitor. @@ -13,10 +13,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_LC709203F_H -#define WipperSnapper_I2C_Driver_LC709203F_H +#ifndef DRV_LC709203F_H +#define DRV_LC709203F_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -24,7 +24,7 @@ @brief Class that provides a driver interface for a LC709203F sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_LC709203F : public WipperSnapper_I2C_Driver { +class drvLc709203f : public drvBase { public: /*******************************************************************************/ /*! @@ -33,12 +33,16 @@ class WipperSnapper_I2C_Driver_LC709203F : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress The 7-bit I2C address of the sensor. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_LC709203F(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvLc709203f(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 } /*******************************************************************************/ @@ -46,7 +50,7 @@ class WipperSnapper_I2C_Driver_LC709203F : public WipperSnapper_I2C_Driver { @brief Destructor for an LC709203F sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_LC709203F() { delete _lc; } + ~drvLc709203f() { delete _lc; } /*******************************************************************************/ /*! @@ -54,7 +58,7 @@ class WipperSnapper_I2C_Driver_LC709203F : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _lc = new Adafruit_LC709203F(); if (!_lc->begin(_i2c)) return false; @@ -62,9 +66,13 @@ class WipperSnapper_I2C_Driver_LC709203F : public WipperSnapper_I2C_Driver { // Default settings from LC709203F demo: // https://github.com/adafruit/Adafruit_LC709203F/blob/master/examples/LC709203F_demo/LC709203F_demo.ino // NOTE: in the future, it would be nice if these able to be user-defined! - _lc->setThermistorB(3950); - _lc->setPackSize(LC709203F_APA_500MAH); - _lc->setAlarmVoltage(3.8); + if (!_lc->setThermistorB(3950)) + return false; + if (!_lc->setPackSize(LC709203F_APA_500MAH)) + return false; + if (!_lc->setAlarmVoltage(3.8)) + return false; + return true; } @@ -102,4 +110,4 @@ class WipperSnapper_I2C_Driver_LC709203F : public WipperSnapper_I2C_Driver { Adafruit_LC709203F *_lc; ///< Pointer to LC709203F sensor object }; -#endif // WipperSnapper_I2C_Driver_LC709203F \ No newline at end of file +#endif // drvLc709203f \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_LPS22HB.h b/src/components/i2c/drivers/drvLps22hb.h similarity index 82% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_LPS22HB.h rename to src/components/i2c/drivers/drvLps22hb.h index bb5858669..984843d06 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_LPS22HB.h +++ b/src/components/i2c/drivers/drvLps22hb.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_LPS22HB.h + * @file drvLps22hb.h * * Device driver for a LPS22HB precision pressure sensor breakout. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_LPS22HB_H -#define WipperSnapper_I2C_Driver_LPS22HB_H +#ifndef DRV_LPS22HB_H +#define DRV_LPS22HB_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -25,7 +25,7 @@ and pressure sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_LPS22HB : public WipperSnapper_I2C_Driver { +class drvLps22hb : public drvBase { public: /*******************************************************************************/ @@ -35,12 +35,16 @@ class WipperSnapper_I2C_Driver_LPS22HB : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_LPS22HB(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvLps22hb(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 } /*******************************************************************************/ @@ -48,7 +52,7 @@ class WipperSnapper_I2C_Driver_LPS22HB : public WipperSnapper_I2C_Driver { @brief Destructor for an LPS22HB sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_LPS22HB() { delete _lps22; } + ~drvLps22hb() { delete _lps22; } /*******************************************************************************/ /*! @@ -56,16 +60,20 @@ class WipperSnapper_I2C_Driver_LPS22HB : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _lps22 = new Adafruit_LPS22(); // attempt to initialize LPS22HB - if (!_lps22->begin_I2C(_sensorAddress, _i2c)) + if (!_lps22->begin_I2C(_address, _i2c)) return false; // Set up sample rate and filter initialization _lps22->setDataRate(LPS22_RATE_ONE_SHOT); _temp = _lps22->getTemperatureSensor(); + if (_temp == NULL) + return false; _pressure = _lps22->getPressureSensor(); + if (_pressure == NULL) + return false; return true; } @@ -79,10 +87,7 @@ class WipperSnapper_I2C_Driver_LPS22HB : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventAmbientTemp(sensors_event_t *tempEvent) { - if (_temp == NULL) - return false; - _temp->getEvent(tempEvent); - return true; + return _temp->getEvent(tempEvent); } /*******************************************************************************/ @@ -96,10 +101,7 @@ class WipperSnapper_I2C_Driver_LPS22HB : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventPressure(sensors_event_t *pressureEvent) { - if (_pressure == NULL) - return false; - _pressure->getEvent(pressureEvent); - return true; + return _pressure->getEvent(pressureEvent); } protected: @@ -109,5 +111,4 @@ class WipperSnapper_I2C_Driver_LPS22HB : public WipperSnapper_I2C_Driver { Adafruit_Sensor *_pressure = NULL; ///< Ptr to an adafruit_sensor representing the pressure }; - -#endif // WipperSnapper_I2C_Driver_LPS22HB \ No newline at end of file +#endif // drvLps22hb \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_LPS25HB.h b/src/components/i2c/drivers/drvLps25hb.h similarity index 82% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_LPS25HB.h rename to src/components/i2c/drivers/drvLps25hb.h index cdcc173f7..54e77be9f 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_LPS25HB.h +++ b/src/components/i2c/drivers/drvLps25hb.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_LPS25HB.h + * @file drvLps25hb.h * * Device driver for a LPS25HB precision pressure sensor breakout. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_LPS25HB_H -#define WipperSnapper_I2C_Driver_LPS25HB_H +#ifndef DRV_LPS25HB_H +#define DRV_LPS25HB_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -25,7 +25,7 @@ and pressure sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_LPS25HB : public WipperSnapper_I2C_Driver { +class drvLps25hb : public drvBase { public: /*******************************************************************************/ @@ -35,12 +35,16 @@ class WipperSnapper_I2C_Driver_LPS25HB : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_LPS25HB(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvLps25hb(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 } /*******************************************************************************/ @@ -48,7 +52,7 @@ class WipperSnapper_I2C_Driver_LPS25HB : public WipperSnapper_I2C_Driver { @brief Destructor for an LPS25HB sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_LPS25HB() { delete _lps25; } + ~drvLps25hb() { delete _lps25; } /*******************************************************************************/ /*! @@ -56,16 +60,20 @@ class WipperSnapper_I2C_Driver_LPS25HB : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _lps25 = new Adafruit_LPS25(); // attempt to initialize LPS25HB - if (!_lps25->begin_I2C(_sensorAddress, _i2c)) + if (!_lps25->begin_I2C(_address, _i2c)) return false; // Set up sample rate and filter initialization _lps25->setDataRate(LPS25_RATE_ONE_SHOT); _temp = _lps25->getTemperatureSensor(); + if (_temp == NULL) + return false; _pressure = _lps25->getPressureSensor(); + if (_pressure == NULL) + return false; return true; } @@ -79,10 +87,7 @@ class WipperSnapper_I2C_Driver_LPS25HB : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventAmbientTemp(sensors_event_t *tempEvent) { - if (_temp == NULL) - return false; - _temp->getEvent(tempEvent); - return true; + return _temp->getEvent(tempEvent); } /*******************************************************************************/ @@ -96,10 +101,7 @@ class WipperSnapper_I2C_Driver_LPS25HB : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventPressure(sensors_event_t *pressureEvent) { - if (_pressure == NULL) - return false; - _pressure->getEvent(pressureEvent); - return true; + return _pressure->getEvent(pressureEvent); } protected: @@ -110,4 +112,4 @@ class WipperSnapper_I2C_Driver_LPS25HB : public WipperSnapper_I2C_Driver { NULL; ///< Ptr to an adafruit_sensor representing the pressure }; -#endif // WipperSnapper_I2C_Driver_LPS25HB \ No newline at end of file +#endif // drvLps25hb \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_LPS3XHW.h b/src/components/i2c/drivers/drvLps3xhw.h similarity index 83% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_LPS3XHW.h rename to src/components/i2c/drivers/drvLps3xhw.h index fcc99b3e1..a27b8cecc 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_LPS3XHW.h +++ b/src/components/i2c/drivers/drvLps3xhw.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_LPS3XHW.h + * @file drvLps3xhw.h * * Device driver for a LPS3XHW precision pressure sensor breakout. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_LPS3XHW_H -#define WipperSnapper_I2C_Driver_LPS3XHW_H +#ifndef DRV_LPS3XHW_H +#define DRV_LPS3XHW_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -25,7 +25,7 @@ and pressure sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_LPS3XHW : public WipperSnapper_I2C_Driver { +class drvLps3xhw : public drvBase { public: /*******************************************************************************/ @@ -35,12 +35,16 @@ class WipperSnapper_I2C_Driver_LPS3XHW : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_LPS3XHW(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvLps3xhw(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 } /*******************************************************************************/ @@ -48,7 +52,7 @@ class WipperSnapper_I2C_Driver_LPS3XHW : public WipperSnapper_I2C_Driver { @brief Destructor for an LPS3XHW sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_LPS3XHW() { delete _lps3xhw; } + ~drvLps3xhw() { delete _lps3xhw; } /*******************************************************************************/ /*! @@ -56,10 +60,10 @@ class WipperSnapper_I2C_Driver_LPS3XHW : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _lps3xhw = new Adafruit_LPS35HW(); // attempt to initialize LPS3XHW - if (!_lps3xhw->begin_I2C(_sensorAddress, _i2c)) + if (!_lps3xhw->begin_I2C(_address, _i2c)) return false; // Set up sample rate and filter initialization @@ -104,4 +108,4 @@ class WipperSnapper_I2C_Driver_LPS3XHW : public WipperSnapper_I2C_Driver { Adafruit_LPS35HW *_lps3xhw; ///< LPS3XHW object }; -#endif // WipperSnapper_I2C_Driver_LPS3XHW \ No newline at end of file +#endif // drvLps3xhw \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_LTR329_LTR303.h b/src/components/i2c/drivers/drvLtr329_Ltr303.h similarity index 86% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_LTR329_LTR303.h rename to src/components/i2c/drivers/drvLtr329_Ltr303.h index c9df454d3..14711ef79 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_LTR329_LTR303.h +++ b/src/components/i2c/drivers/drvLtr329_Ltr303.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_LTR329_LTR303.h + * @file drvLtr329_Ltr303.h * * Device driver for the LTR329 + LTR303 (329+interrupt) light sensors. * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_LTR329_LTR303_H -#define WipperSnapper_I2C_Driver_LTR329_LTR303_H +#ifndef DRV_LTR329_LTR303_H +#define DRV_LTR329_LTR303_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -23,7 +23,7 @@ @brief Class that provides a driver interface for a LTR329/303 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_LTR329_LTR303 : public WipperSnapper_I2C_Driver { +class drvLtr329_Ltr303 : public drvBase { public: /*******************************************************************************/ /*! @@ -32,12 +32,16 @@ class WipperSnapper_I2C_Driver_LTR329_LTR303 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress The 7-bit I2C address of the sensor. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_LTR329_LTR303(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvLtr329_Ltr303(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 } /*******************************************************************************/ @@ -45,7 +49,7 @@ class WipperSnapper_I2C_Driver_LTR329_LTR303 : public WipperSnapper_I2C_Driver { @brief Destructor for an LTR329/303 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_LTR329_LTR303() { delete _LTR329; } + ~drvLtr329_Ltr303() { delete _LTR329; } /*******************************************************************************/ /*! @@ -53,7 +57,7 @@ class WipperSnapper_I2C_Driver_LTR329_LTR303 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _LTR329 = new Adafruit_LTR329(); // Attempt to initialize LTR329 if (!_LTR329->begin(_i2c)) @@ -120,4 +124,4 @@ class WipperSnapper_I2C_Driver_LTR329_LTR303 : public WipperSnapper_I2C_Driver { uint16_t _delayBetweenReads; }; -#endif // WipperSnapper_I2C_Driver_LTR329_LTR303 \ No newline at end of file +#endif // drvLtr329_Ltr303 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_LTR390.h b/src/components/i2c/drivers/drvLtr390.h similarity index 86% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_LTR390.h rename to src/components/i2c/drivers/drvLtr390.h index f416953d9..cdfa08eab 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_LTR390.h +++ b/src/components/i2c/drivers/drvLtr390.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_LTR390.h + * @file drvLtr390.h * * Device driver for the LTR390 light sensor. * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_LTR390_H -#define WipperSnapper_I2C_Driver_LTR390_H +#ifndef DRV_LTR390_H +#define DRV_LTR390_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -23,7 +23,7 @@ @brief Class that provides a driver interface for a LTR390 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_LTR390 : public WipperSnapper_I2C_Driver { +class drvLtr390 : public drvBase { public: /*******************************************************************************/ /*! @@ -32,12 +32,16 @@ class WipperSnapper_I2C_Driver_LTR390 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress The 7-bit I2C address of the sensor. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_LTR390(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvLtr390(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 } /*******************************************************************************/ @@ -45,7 +49,7 @@ class WipperSnapper_I2C_Driver_LTR390 : public WipperSnapper_I2C_Driver { @brief Destructor for an LTR390 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_LTR390() { delete _ltr390; } + ~drvLtr390() { delete _ltr390; } /*******************************************************************************/ /*! @@ -53,7 +57,7 @@ class WipperSnapper_I2C_Driver_LTR390 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _ltr390 = new Adafruit_LTR390(); // Attempt to initialize LTR390 if (!_ltr390->begin(_i2c)) @@ -117,4 +121,4 @@ class WipperSnapper_I2C_Driver_LTR390 : public WipperSnapper_I2C_Driver { Adafruit_LTR390 *_ltr390; ///< Pointer to LTR390 light sensor object }; -#endif // WipperSnapper_I2C_Driver_LTR390 \ No newline at end of file +#endif // drvLtr390 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_MCP9808.h b/src/components/i2c/drivers/drvMCP9808.h similarity index 79% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_MCP9808.h rename to src/components/i2c/drivers/drvMCP9808.h index 896bac210..4b9d76ff7 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_MCP9808.h +++ b/src/components/i2c/drivers/drvMCP9808.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_MCP9808.h + * @file drvMcp9808.h * * Device driver for the MCP9808 Temperature sensor. * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_MCP9808_H -#define WipperSnapper_I2C_Driver_MCP9808_H +#ifndef DRV_MCP9808_H +#define DRV_MCP9808_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -23,7 +23,7 @@ @brief Class that provides a driver interface for a MCP9808 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_MCP9808 : public WipperSnapper_I2C_Driver { +class drvMcp9808 : public drvBase { public: /*******************************************************************************/ /*! @@ -32,12 +32,16 @@ class WipperSnapper_I2C_Driver_MCP9808 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_MCP9808(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvMcp9808(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 } /*******************************************************************************/ @@ -45,7 +49,7 @@ class WipperSnapper_I2C_Driver_MCP9808 : public WipperSnapper_I2C_Driver { @brief Destructor for an MCP9808 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_MCP9808() { + ~drvMcp9808() { // Called when a MCP9808 component is deleted. delete _mcp9808; } @@ -56,9 +60,9 @@ class WipperSnapper_I2C_Driver_MCP9808 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _mcp9808 = new Adafruit_MCP9808(); - return _mcp9808->begin((uint8_t)_sensorAddress, _i2c); + return _mcp9808->begin((uint8_t)_address, _i2c); } /*******************************************************************************/ @@ -79,4 +83,4 @@ class WipperSnapper_I2C_Driver_MCP9808 : public WipperSnapper_I2C_Driver { Adafruit_MCP9808 *_mcp9808; ///< Pointer to MCP9808 temperature sensor object }; -#endif // WipperSnapper_I2C_Driver_MCP9808 \ No newline at end of file +#endif // drvMcp9808 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_MAX17048.h b/src/components/i2c/drivers/drvMax1704x.h similarity index 82% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_MAX17048.h rename to src/components/i2c/drivers/drvMax1704x.h index 33280c2bc..7bdb93879 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_MAX17048.h +++ b/src/components/i2c/drivers/drvMax1704x.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_MAX17048.h + * @file drvMax1704x.h * * Device driver for the MAX17048/MAX17049 LiPoly / LiIon Fuel Gauge and Battery * Monitor @@ -13,10 +13,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_MAX17048_H -#define WipperSnapper_I2C_Driver_MAX17048_H +#ifndef DRV_MAX1704x_H +#define DRV_MAX1704x_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -24,7 +24,7 @@ @brief Class that provides a driver interface for a MAX17048 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_MAX17048 : public WipperSnapper_I2C_Driver { +class drvMax1704x : public drvBase { public: /*******************************************************************************/ /*! @@ -33,12 +33,16 @@ class WipperSnapper_I2C_Driver_MAX17048 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress The 7-bit I2C address of the sensor. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_MAX17048(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvMax1704x(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 } /*******************************************************************************/ @@ -46,7 +50,7 @@ class WipperSnapper_I2C_Driver_MAX17048 : public WipperSnapper_I2C_Driver { @brief Destructor for an MAX17048 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_MAX17048() { delete _maxlipo; } + ~drvMax1704x() { delete _maxlipo; } /*******************************************************************************/ /*! @@ -54,11 +58,9 @@ class WipperSnapper_I2C_Driver_MAX17048 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _maxlipo = new Adafruit_MAX17048(); - if (!_maxlipo->begin(_i2c)) - return false; - return true; + return _maxlipo->begin(_i2c); } /*******************************************************************************/ @@ -95,4 +97,4 @@ class WipperSnapper_I2C_Driver_MAX17048 : public WipperSnapper_I2C_Driver { Adafruit_MAX17048 *_maxlipo; ///< Pointer to MAX17048 sensor object }; -#endif // WipperSnapper_I2C_Driver_MAX17048 \ No newline at end of file +#endif // drvMax1704x \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_MCP3421.h b/src/components/i2c/drivers/drvMcp3421.h similarity index 79% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_MCP3421.h rename to src/components/i2c/drivers/drvMcp3421.h index 6ad1641cf..a83921ae3 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_MCP3421.h +++ b/src/components/i2c/drivers/drvMcp3421.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_MCP3421.h + * @file drvMcp3421.h * * Device driver for the MCP3421 18-bit ADC sensor. * @@ -12,11 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_MCP3421_H -#define WipperSnapper_I2C_Driver_MCP3421_H +#ifndef DRV_MCP3421_H +#define DRV_MCP3421_H -#include "WipperSnapper_I2C_Driver.h" -#include "Wippersnapper.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -24,7 +23,7 @@ @brief Class that provides a driver interface for a MCP3421 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_MCP3421 : public WipperSnapper_I2C_Driver { +class drvMcp3421 : public drvBase { public: /*******************************************************************************/ /*! @@ -33,12 +32,16 @@ class WipperSnapper_I2C_Driver_MCP3421 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_MCP3421(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvMcp3421(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 } /*******************************************************************************/ @@ -46,7 +49,7 @@ class WipperSnapper_I2C_Driver_MCP3421 : public WipperSnapper_I2C_Driver { @brief Destructor for an MCP3421 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_MCP3421() { delete _mcp3421; } + ~drvMcp3421() { delete _mcp3421; } /*******************************************************************************/ /*! @@ -54,18 +57,12 @@ class WipperSnapper_I2C_Driver_MCP3421 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _mcp3421 = new Adafruit_MCP3421(); - if (!_mcp3421->begin((uint8_t)_sensorAddress, _i2c)) { - WS_DEBUG_PRINTLN("Failed to find MCP3421 chip"); + if (!_mcp3421->begin((uint8_t)_address, _i2c)) return false; - } - if (!configureSensor()) { - WS_DEBUG_PRINTLN("Failed to configure MCP3421 sensor"); - return false; - } - return true; + return configureSensor(); } /*******************************************************************************/ @@ -130,4 +127,4 @@ class WipperSnapper_I2C_Driver_MCP3421 : public WipperSnapper_I2C_Driver { Adafruit_MCP3421 *_mcp3421; ///< Pointer to MCP3421 sensor object }; -#endif // WipperSnapper_I2C_Driver_MCP3421 \ No newline at end of file +#endif // drvMcp3421 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_MPL115A2.h b/src/components/i2c/drivers/drvMpl115a2.h similarity index 81% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_MPL115A2.h rename to src/components/i2c/drivers/drvMpl115a2.h index 4c0026b87..6ada5ff9c 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_MPL115A2.h +++ b/src/components/i2c/drivers/drvMpl115a2.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_MPL115A2.h + * @file drvMpl115a2.h * * Device driver for a MPL115A2 pressure sensor breakout. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_MPL115A2_H -#define WipperSnapper_I2C_Driver_MPL115A2_H +#ifndef DRV_MPL115A2_H +#define DRV_MPL115A2_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -25,7 +25,7 @@ and pressure sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_MPL115A2 : public WipperSnapper_I2C_Driver { +class drvMpl115a2 : public drvBase { public: /*******************************************************************************/ @@ -35,12 +35,16 @@ class WipperSnapper_I2C_Driver_MPL115A2 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_MPL115A2(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvMpl115a2(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 } /*******************************************************************************/ @@ -48,7 +52,7 @@ class WipperSnapper_I2C_Driver_MPL115A2 : public WipperSnapper_I2C_Driver { @brief Destructor for an MPL115A2 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_MPL115A2() { delete _mpl115a2; } + ~drvMpl115a2() { delete _mpl115a2; } /*******************************************************************************/ /*! @@ -56,12 +60,9 @@ class WipperSnapper_I2C_Driver_MPL115A2 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _mpl115a2 = new Adafruit_MPL115A2(); - // attempt to initialize MPL115A2 - if (!_mpl115a2->begin(_sensorAddress, _i2c)) - return false; - return true; + return _mpl115a2->begin(_address, _i2c); } /*******************************************************************************/ @@ -97,4 +98,4 @@ class WipperSnapper_I2C_Driver_MPL115A2 : public WipperSnapper_I2C_Driver { Adafruit_MPL115A2 *_mpl115a2; ///< MPL115A2 object }; -#endif // WipperSnapper_I2C_Driver_MPL115A2 \ No newline at end of file +#endif // drvMpl115a2 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_MPRLS.h b/src/components/i2c/drivers/drvMprls.h similarity index 79% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_MPRLS.h rename to src/components/i2c/drivers/drvMprls.h index 9dbf665d1..5bc38be4f 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_MPRLS.h +++ b/src/components/i2c/drivers/drvMprls.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_MPRLS.h + * @file drvMprls.h * * Device driver for a MPRLS precision pressure sensor breakout. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_MPRLS_H -#define WipperSnapper_I2C_Driver_MPRLS_H +#ifndef DRV_MPRLS_H +#define DRV_MPRLS_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -24,7 +24,7 @@ @brief Class that provides a sensor driver for the MPRLS sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_MPRLS : public WipperSnapper_I2C_Driver { +class drvMprls : public drvBase { public: /*******************************************************************************/ @@ -34,12 +34,16 @@ class WipperSnapper_I2C_Driver_MPRLS : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_MPRLS(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvMprls(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 } /*******************************************************************************/ @@ -47,7 +51,7 @@ class WipperSnapper_I2C_Driver_MPRLS : public WipperSnapper_I2C_Driver { @brief Destructor for an MPRLS sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_MPRLS() { delete _mprls; } + ~drvMprls() { delete _mprls; } /*******************************************************************************/ /*! @@ -55,13 +59,10 @@ class WipperSnapper_I2C_Driver_MPRLS : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _mprls = new Adafruit_MPRLS(); // attempt to initialize MPRLS - if (!_mprls->begin(_sensorAddress, _i2c)) - return false; - - return true; + return _mprls->begin(_address, _i2c); } /*******************************************************************************/ @@ -83,4 +84,4 @@ class WipperSnapper_I2C_Driver_MPRLS : public WipperSnapper_I2C_Driver { Adafruit_MPRLS *_mprls; ///< MPRLS object }; -#endif // WipperSnapper_I2C_Driver_MPRLS \ No newline at end of file +#endif // drvMprls \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_MS8607.h b/src/components/i2c/drivers/drvMs8607.h similarity index 87% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_MS8607.h rename to src/components/i2c/drivers/drvMs8607.h index a024304a3..708baf33a 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_MS8607.h +++ b/src/components/i2c/drivers/drvMs8607.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_MS8607.h + * @file drvMs8607.h * * Device driver for an MS8607 Pressure Humidity and Temperature sensor. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_MS8607_H -#define WipperSnapper_I2C_Driver_MS8607_H +#ifndef DRV_MS8607 +#define DRV_MS8607 -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -24,7 +24,7 @@ @brief Class that provides a sensor driver for the MS8607 PHT sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_MS8607 : public WipperSnapper_I2C_Driver { +class drvMs8607 : public drvBase { public: /*******************************************************************************/ @@ -34,12 +34,16 @@ class WipperSnapper_I2C_Driver_MS8607 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_MS8607(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvMs8607(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 } /*******************************************************************************/ @@ -47,7 +51,7 @@ class WipperSnapper_I2C_Driver_MS8607 : public WipperSnapper_I2C_Driver { @brief Destructor for an MS8607 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_MS8607() { delete _ms8607; } + ~drvMs8607() { delete _ms8607; } /*******************************************************************************/ /*! @@ -55,15 +59,22 @@ class WipperSnapper_I2C_Driver_MS8607 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _ms8607 = new Adafruit_MS8607(); // attempt to initialize MS8607 if (!_ms8607->begin(_i2c)) return false; _ms8607_temp = _ms8607->getTemperatureSensor(); + if (_ms8607_temp == NULL) + return false; _ms8607_humidity = _ms8607->getHumiditySensor(); + if (_ms8607_humidity == NULL) + return false; _ms8607_pressure = _ms8607->getPressureSensor(); + if (_ms8607_pressure == NULL) + return false; + return true; } @@ -77,8 +88,6 @@ class WipperSnapper_I2C_Driver_MS8607 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventAmbientTemp(sensors_event_t *tempEvent) { - if (_ms8607_temp == NULL) - return false; _ms8607_temp->getEvent(tempEvent); return true; } @@ -93,8 +102,6 @@ class WipperSnapper_I2C_Driver_MS8607 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventRelativeHumidity(sensors_event_t *humidEvent) { - if (_ms8607_humidity == NULL) - return false; _ms8607_humidity->getEvent(humidEvent); return true; } @@ -110,8 +117,6 @@ class WipperSnapper_I2C_Driver_MS8607 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool getEventPressure(sensors_event_t *pressureEvent) { - if (_ms8607_pressure == NULL) - return false; _ms8607_pressure->getEvent(pressureEvent); return true; } @@ -126,4 +131,4 @@ class WipperSnapper_I2C_Driver_MS8607 : public WipperSnapper_I2C_Driver { NULL; ///< Ptr to an adafruit_sensor representing the humidity }; -#endif // WipperSnapper_I2C_Driver_MS8607 \ No newline at end of file +#endif // drvMs8607 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_NAU7802.h b/src/components/i2c/drivers/drvNau7802.h similarity index 75% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_NAU7802.h rename to src/components/i2c/drivers/drvNau7802.h index 85a6ffae5..c08c526bc 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_NAU7802.h +++ b/src/components/i2c/drivers/drvNau7802.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_NAU7802.h + * @file drvNau7802.h * * Device driver for the NAU7802 24bit ADC / load cell breakout * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_NAU7802_H -#define WipperSnapper_I2C_Driver_NAU7802_H +#ifndef DRV_NAU7802_H +#define DRV_NAU7802_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #define NAU7802_TIMEOUT_MS 250 ///< Timeout waiting for data from NAU7802 @@ -26,7 +26,7 @@ @brief Class that provides a driver interface for the NAU7802. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_NAU7802 : public WipperSnapper_I2C_Driver { +class drvNau7802 : public drvBase { public: /*******************************************************************************/ /*! @@ -35,13 +35,16 @@ class WipperSnapper_I2C_Driver_NAU7802 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_NAU7802(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; - _nau7802 = new Adafruit_NAU7802(); + drvNau7802(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 } /*******************************************************************************/ @@ -49,7 +52,7 @@ class WipperSnapper_I2C_Driver_NAU7802 : public WipperSnapper_I2C_Driver { @brief Destructor for an NAU7802. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_NAU7802() { _nau7802 = nullptr; } + ~drvNau7802() { _nau7802 = nullptr; } /*******************************************************************************/ /*! @@ -57,7 +60,7 @@ class WipperSnapper_I2C_Driver_NAU7802 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { return _nau7802->begin(_i2c) && configure_nau7802(); } + bool begin() override { return _nau7802->begin(_i2c) && configure_nau7802(); } /*******************************************************************************/ /*! @@ -67,18 +70,18 @@ class WipperSnapper_I2C_Driver_NAU7802 : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool configure_nau7802() { if (!_nau7802->setLDO(NAU7802_3V0)) { - WS_DEBUG_PRINTLN("Failed to set LDO to 3V0"); + // WS_DEBUG_PRINTLN("Failed to set LDO to 3V0"); return false; } if (!_nau7802->setGain(NAU7802_GAIN_128)) { - WS_DEBUG_PRINTLN("Failed to set gain to 128"); + // WS_DEBUG_PRINTLN("Failed to set gain to 128"); return false; } if (!_nau7802->setRate(NAU7802_RATE_10SPS) && !_nau7802->setRate(NAU7802_RATE_10SPS)) { - WS_DEBUG_PRINTLN("Failed to set sample rate to 10SPS"); + // WS_DEBUG_PRINTLN("Failed to set sample rate to 10SPS"); return false; } @@ -87,13 +90,14 @@ class WipperSnapper_I2C_Driver_NAU7802 : public WipperSnapper_I2C_Driver { for (int retries = 0; retries < 3; retries++) { if (_nau7802->calibrate(NAU7802_CALMOD_INTERNAL)) { - WS_DEBUG_PRINTLN("Calibrated internal offset"); + // WS_DEBUG_PRINTLN("Calibrated internal offset"); return true; } - WS_DEBUG_PRINTLN("Failed to calibrate internal offset, retrying!"); + // WS_DEBUG_PRINTLN("Failed to calibrate internal offset, retrying!"); delay(1000); } - WS_DEBUG_PRINTLN("ERROR: Failed to calibrate internal offset of NAU7802."); + // WS_DEBUG_PRINTLN("ERROR: Failed to calibrate internal offset of + // NAU7802."); return false; } @@ -126,7 +130,7 @@ class WipperSnapper_I2C_Driver_NAU7802 : public WipperSnapper_I2C_Driver { // Wait for the sensor to be ready while (!_nau7802->available()) { if (millis() - start > NAU7802_TIMEOUT_MS) { - WS_DEBUG_PRINTLN("NAU7802 data not available"); + // WS_DEBUG_PRINTLN("NAU7802 data not available"); return false; } } @@ -138,4 +142,4 @@ class WipperSnapper_I2C_Driver_NAU7802 : public WipperSnapper_I2C_Driver { Adafruit_NAU7802 *_nau7802 = nullptr; ///< NAU7802 object }; -#endif // WipperSnapper_I2C_Driver_NAU7802_H \ No newline at end of file +#endif // DRV_NAU7802_H \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_PCT2075.h b/src/components/i2c/drivers/drvPct2075.h similarity index 79% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_PCT2075.h rename to src/components/i2c/drivers/drvPct2075.h index 557c1e358..1eb11435a 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_PCT2075.h +++ b/src/components/i2c/drivers/drvPct2075.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_PCT2075.h + * @file drvPct2075.h * * Device driver for the PCT2075 Temperature sensor. * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_PCT2075_H -#define WipperSnapper_I2C_Driver_PCT2075_H +#ifndef DRV_PCT2075_H +#define DRV_PCT2075_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -23,7 +23,7 @@ @brief Class that provides a driver interface for a PCT2075 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_PCT2075 : public WipperSnapper_I2C_Driver { +class drvPct2075 : public drvBase { public: /*******************************************************************************/ /*! @@ -32,12 +32,16 @@ class WipperSnapper_I2C_Driver_PCT2075 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_PCT2075(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvPct2075(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 } /*******************************************************************************/ @@ -45,7 +49,7 @@ class WipperSnapper_I2C_Driver_PCT2075 : public WipperSnapper_I2C_Driver { @brief Destructor for an PCT2075 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_PCT2075() { + ~drvPct2075() { // Called when a PCT2075 component is deleted. delete _pct2075; } @@ -56,9 +60,9 @@ class WipperSnapper_I2C_Driver_PCT2075 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _pct2075 = new Adafruit_PCT2075(); - return _pct2075->begin((uint8_t)_sensorAddress, _i2c); + return _pct2075->begin((uint8_t)_address, _i2c); } /*******************************************************************************/ @@ -79,4 +83,4 @@ class WipperSnapper_I2C_Driver_PCT2075 : public WipperSnapper_I2C_Driver { Adafruit_PCT2075 *_pct2075; ///< Pointer to PCT2075 temperature sensor object }; -#endif // WipperSnapper_I2C_Driver_PCT2075 \ No newline at end of file +#endif // drvPct2075 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_PM25.h b/src/components/i2c/drivers/drvPm25.h similarity index 74% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_PM25.h rename to src/components/i2c/drivers/drvPm25.h index 47b311fa0..70bacab0c 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_PM25.h +++ b/src/components/i2c/drivers/drvPm25.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_PM25.h + * @file drvPm25.h * * Device driver for the Adafruit PM2.5 Air Quality Sensor. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_PM25_H -#define WipperSnapper_I2C_Driver_PM25_h +#ifndef DRV_PM25_H +#define DRV_PM25_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #include @@ -25,7 +25,7 @@ @brief Class that provides a driver interface for the PM25 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_PM25 : public WipperSnapper_I2C_Driver { +class drvPm25 : public drvBase { public: /*******************************************************************************/ @@ -35,12 +35,16 @@ class WipperSnapper_I2C_Driver_PM25 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_PM25(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvPm25(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 } /*******************************************************************************/ @@ -49,16 +53,11 @@ class WipperSnapper_I2C_Driver_PM25 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _pm25 = new Adafruit_PM25AQI(); - - // Wait one second for sensor to boot up! - delay(1000); - - if (!_pm25->begin_I2C(_i2c)) - return false; - - return true; + // Wait three seconds for the sensor to boot up! + delay(3000); + return _pm25->begin_I2C(_i2c); } /*******************************************************************************/ @@ -72,10 +71,14 @@ class WipperSnapper_I2C_Driver_PM25 : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool getEventPM10_STD(sensors_event_t *pm10StdEvent) { PM25_AQI_Data data; - if (!_pm25->read(&data)) + if (!_pm25->read(&data)) { + WS_DEBUG_PRINTLN("Failed to read PM10STD data"); return false; // couldn't read data + } pm10StdEvent->pm10_std = (float)data.pm10_standard; + WS_DEBUG_PRINT("PM10STD: "); + WS_DEBUG_PRINTLN(pm10StdEvent->pm10_std); return true; } @@ -90,10 +93,13 @@ class WipperSnapper_I2C_Driver_PM25 : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool getEventPM25_STD(sensors_event_t *pm25StdEvent) { PM25_AQI_Data data; - if (!_pm25->read(&data)) + if (!_pm25->read(&data)) { + WS_DEBUG_PRINTLN("Failed to read PM25STD data"); return false; // couldn't read data - + } pm25StdEvent->pm25_std = (float)data.pm25_standard; + WS_DEBUG_PRINT("PM25STD: "); + WS_DEBUG_PRINTLN(pm25StdEvent->pm25_std); return true; } @@ -108,10 +114,14 @@ class WipperSnapper_I2C_Driver_PM25 : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool getEventPM100_STD(sensors_event_t *pm100StdEvent) { PM25_AQI_Data data; - if (!_pm25->read(&data)) + if (!_pm25->read(&data)) { + WS_DEBUG_PRINTLN("Failed to read PM100STD data"); return false; // couldn't read data + } pm100StdEvent->pm100_std = (float)data.pm100_standard; + WS_DEBUG_PRINT("PM100STD: "); + WS_DEBUG_PRINTLN(pm100StdEvent->pm100_std); return true; } @@ -119,4 +129,4 @@ class WipperSnapper_I2C_Driver_PM25 : public WipperSnapper_I2C_Driver { Adafruit_PM25AQI *_pm25; ///< PM25 driver object }; -#endif // WipperSnapper_I2C_Driver_PM25 \ No newline at end of file +#endif // drvPm25 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h b/src/components/i2c/drivers/drvScd30.h similarity index 54% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h rename to src/components/i2c/drivers/drvScd30.h index cb7c409b5..977d11025 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h +++ b/src/components/i2c/drivers/drvScd30.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_SCD30.h + * @file drvScd30.h * * Device driver for the SCD30 CO2, Temperature, and Humidity sensor. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_SCD30_H -#define WipperSnapper_I2C_Driver_SCD30_H +#ifndef DRV_SCD30_H +#define DRV_SCD30_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -24,7 +24,7 @@ @brief Class that provides a driver interface for the SCD30 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { +class drvScd30 : public drvBase { public: /*******************************************************************************/ @@ -34,12 +34,16 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_SCD30(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvScd30(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 } /*******************************************************************************/ @@ -48,9 +52,61 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _scd = new Adafruit_SCD30(); - return _scd->begin((uint8_t)_sensorAddress, _i2c); + return _scd->begin((uint8_t)_address, _i2c); + } + + /*******************************************************************************/ + /*! + @brief Checks if sensor was read within last 1s, or is the first read. + @returns True if the sensor was recently read, False otherwise. + */ + bool hasBeenReadInLastSecond() { + return _lastRead != 0 && millis() - _lastRead < 1000; + } + + /*******************************************************************************/ + /*! + @brief Checks if the sensor is ready to be read + @returns True if the sensor is ready, False otherwise. + */ + /*******************************************************************************/ + bool isSensorReady() { + if (!_scd->dataReady()) { + // failed, one more quick attempt + delay(100); + if (!_scd->dataReady()) { + return false; + } + } + return true; + } + + /*******************************************************************************/ + /*! + @brief Reads the SCD30 sensor. + @returns True if the sensor was read successfully, False otherwise. + */ + /*******************************************************************************/ + bool readSensorData() { + // dont read sensor more than once per second + if (hasBeenReadInLastSecond()) { + return true; + } + + if (!isSensorReady()) { + return false; + } + + if (!_scd->read()) { + return false; + } + _CO2 = _scd->CO2; + _humidity = _scd->relative_humidity; + _temperature = _scd->temperature; + _lastRead = millis(); + return true; } /*******************************************************************************/ @@ -64,14 +120,11 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool getEventAmbientTemp(sensors_event_t *tempEvent) { // check if sensor is enabled and data is available - if (_tempSensorPeriod != 0 && (!_scd->dataReady())) - return false; - - // attempt to get temperature data - sensors_event_t humidEvent; - if (!_scd->getEvent(&humidEvent, tempEvent)) + if (!readSensorData()) { return false; + } + tempEvent->temperature = _temperature; return true; } @@ -86,14 +139,11 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool getEventRelativeHumidity(sensors_event_t *humidEvent) { // check if sensor is enabled and data is available - if (_humidSensorPeriod != 0 && (!_scd->dataReady())) - return false; - - // attempt to get temperature data - sensors_event_t tempEvent; - if (!_scd->getEvent(humidEvent, &tempEvent)) + if (!readSensorData()) { return false; + } + humidEvent->relative_humidity = _humidity; return true; } @@ -108,15 +158,20 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool getEventCO2(sensors_event_t *co2Event) { // check if sensor is enabled and data is available - if (_CO2SensorPeriod != 0 && (!_scd->dataReady())) + if (!readSensorData()) { return false; + } - co2Event->CO2 = _scd->CO2; + co2Event->CO2 = _CO2; return true; } protected: - Adafruit_SCD30 *_scd; ///< SCD30 driver object + Adafruit_SCD30 *_scd = nullptr; ///< SCD30 driver object + ulong _lastRead = 0; ///< Last time the sensor was read + float _temperature; ///< Temperature + float _humidity; ///< Relative Humidity + float _CO2; ///< CO2 }; -#endif // WipperSnapper_I2C_Driver_SCD30 \ No newline at end of file +#endif // drvScd30 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD4X.h b/src/components/i2c/drivers/drvScd4x.h similarity index 79% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD4X.h rename to src/components/i2c/drivers/drvScd4x.h index dfe2c1de3..c23bccadf 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD4X.h +++ b/src/components/i2c/drivers/drvScd4x.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_SCD4x.h + * @file drvScd4x.h * * Device driver for the SCD4X CO2, Temperature, and Humidity sensor. * @@ -14,11 +14,11 @@ * */ -#ifndef WipperSnapper_I2C_Driver_SCD4X_H -#define WipperSnapper_I2C_Driver_SCD4X_H +#ifndef DRV_SCD4X_H +#define DRV_SCD4X_H -#include "WipperSnapper_I2C_Driver.h" -#include +#include "drvBase.h" +#include #include /**************************************************************************/ @@ -26,7 +26,7 @@ @brief Class that provides a driver interface for the SCD40 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_SCD4X : public WipperSnapper_I2C_Driver { +class drvScd4x : public drvBase { public: /*******************************************************************************/ @@ -36,12 +36,16 @@ class WipperSnapper_I2C_Driver_SCD4X : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_SCD4X(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvScd4x(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 } /*******************************************************************************/ @@ -50,17 +54,21 @@ class WipperSnapper_I2C_Driver_SCD4X : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { - _scd = new SensirionI2CScd4x(); - _scd->begin(*_i2c); + bool begin() override { + _scd = new SensirionI2cScd4x(); + _scd->begin(*_i2c, _address); // stop previously started measurement - if (_scd->stopPeriodicMeasurement()) + if (_scd->stopPeriodicMeasurement()) { + WS_DEBUG_PRINTLN("Unable to L63"); return false; + } // start measurements - if (_scd->startPeriodicMeasurement()) + if (_scd->startPeriodicMeasurement()) { + WS_DEBUG_PRINTLN("Unable to L69"); return false; + } return true; } @@ -78,14 +86,16 @@ class WipperSnapper_I2C_Driver_SCD4X : public WipperSnapper_I2C_Driver { delay(100); // Check if data is ready - error = _scd->getDataReadyFlag(isDataReady); - if (error || !isDataReady) + error = _scd->getDataReadyStatus(isDataReady); + if (error || !isDataReady) { return false; + } // Read SCD4x measurement error = _scd->readMeasurement(_co2, _temperature, _humidity); - if (error || _co2 == 0) + if (error || _co2 == 0) { return false; + } return true; } @@ -101,9 +111,7 @@ class WipperSnapper_I2C_Driver_SCD4X : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool getEventAmbientTemp(sensors_event_t *tempEvent) { // read all sensor measurements - if (!readSensorMeasurements()) - return false; - + readSensorMeasurements(); tempEvent->temperature = _temperature; return true; } @@ -119,9 +127,7 @@ class WipperSnapper_I2C_Driver_SCD4X : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool getEventRelativeHumidity(sensors_event_t *humidEvent) { // read all sensor measurements - if (!readSensorMeasurements()) - return false; - + readSensorMeasurements(); humidEvent->relative_humidity = _humidity; return true; } @@ -137,18 +143,16 @@ class WipperSnapper_I2C_Driver_SCD4X : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool getEventCO2(sensors_event_t *co2Event) { // read all sensor measurements - if (!readSensorMeasurements()) - return false; - + readSensorMeasurements(); co2Event->CO2 = (float)_co2; return true; } protected: - SensirionI2CScd4x *_scd; ///< SCD4x driver object + SensirionI2cScd4x *_scd; ///< SCD4x driver object uint16_t _co2; ///< SCD4x co2 reading float _temperature; ///< SCD4x temperature reading float _humidity; ///< SCD4x humidity reading }; -#endif // WipperSnapper_I2C_Driver_SCD4X \ No newline at end of file +#endif // drvScd4x \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SEN5X.h b/src/components/i2c/drivers/drvSen5x.h similarity index 90% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_SEN5X.h rename to src/components/i2c/drivers/drvSen5x.h index 3ad5d45f5..c96a60604 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SEN5X.h +++ b/src/components/i2c/drivers/drvSen5x.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_SEN5X.h + * @file drvSen5x.h * * Device driver for the SEN5X CO2, Temperature, and Humidity sensor. * TEMPORARY HACK @@ -14,10 +14,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_SEN5X_H -#define WipperSnapper_I2C_Driver_SEN5X_H +#ifndef DRV_SEN5X_H +#define DRV_SEN5X_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #include @@ -26,7 +26,7 @@ @brief Class that provides a driver interface for the SEN5X sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { +class drvSen5x : public drvBase { const float OVERFLOW_SEN55 = (0xFFFF / 10); // maxes out at u_int16 / 10 @@ -38,12 +38,16 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_SEN5X(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvSen5x(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 } /*******************************************************************************/ @@ -52,7 +56,7 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _sen = new SensirionI2CSen5x(); _sen->begin(*_i2c); u_int16_t error_stop = _sen->deviceReset(); @@ -88,7 +92,7 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, noxIndex); - if ((_tempSensorPeriod != 0 && error != 0) || ambientTemperature == NAN) { + if (error != 0 || ambientTemperature == NAN) { return false; } @@ -115,7 +119,7 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, noxIndex); - if ((_humidSensorPeriod != 0 && error != 0) || ambientHumidity == NAN) { + if (error != 0 || ambientHumidity == NAN) { return false; } @@ -145,7 +149,7 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, noxIndex); - if ((_NOxIndexPeriod != 0 && error != 0) || noxIndex == NAN) { + if (error != 0 || noxIndex == NAN) { return false; } @@ -172,7 +176,7 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, noxIndex); - if ((_VOCIndexPeriod != 0 && error != 0) || vocIndex == NAN) { + if (error != 0 || vocIndex == NAN) { return false; } @@ -199,8 +203,7 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, noxIndex); - if ((_PM10SensorPeriod != 0 && error != 0) || - massConcentrationPm1p0 == NAN || + if (error != 0 || massConcentrationPm1p0 == NAN || massConcentrationPm1p0 == OVERFLOW_SEN55) { return false; } @@ -228,8 +231,7 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, noxIndex); - if ((_PM25SensorPeriod != 0 && error != 0) || - massConcentrationPm2p5 == NAN || + if (error != 0 || massConcentrationPm2p5 == NAN || massConcentrationPm2p5 == OVERFLOW_SEN55) { return false; } @@ -257,8 +259,7 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, noxIndex); - if ((_PM25SensorPeriod != 0 && error != 0) || - massConcentrationPm4p0 == NAN || + if (error != 0 || massConcentrationPm4p0 == NAN || massConcentrationPm4p0 == OVERFLOW_SEN55) { return false; } @@ -286,8 +287,7 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, noxIndex); - if ((_PM100SensorPeriod != 0 && error != 0) || - massConcentrationPm10p0 == NAN || + if (error != 0 || massConcentrationPm10p0 == NAN || massConcentrationPm10p0 == OVERFLOW_SEN55) { return false; } @@ -300,4 +300,4 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { SensirionI2CSen5x *_sen; ///< SEN5X driver object }; -#endif // WipperSnapper_I2C_Driver_SEN5X +#endif // drvSen5x diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SGP40.h b/src/components/i2c/drivers/drvSgp40.h similarity index 84% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_SGP40.h rename to src/components/i2c/drivers/drvSgp40.h index 3e201b106..cae4c9de6 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SGP40.h +++ b/src/components/i2c/drivers/drvSgp40.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_SGP40.h + * @file drvSgp40.h * * Device driver for the SGP40 VOC/gas sensor. * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_SGP40_H -#define WipperSnapper_I2C_Driver_SGP40_H +#ifndef DRV_SGP40_H +#define DRV_SGP40_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #include @@ -25,7 +25,7 @@ @brief Class that provides a driver interface for the SGP40 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_SGP40 : public WipperSnapper_I2C_Driver { +class drvSgp40 : public drvBase { public: /*******************************************************************************/ /*! @@ -34,12 +34,16 @@ class WipperSnapper_I2C_Driver_SGP40 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_SGP40(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvSgp40(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 } /*******************************************************************************/ @@ -48,7 +52,7 @@ class WipperSnapper_I2C_Driver_SGP40 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _sgp40 = new Adafruit_SGP40(); if (!_sgp40->begin(_i2c)) { return false; diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SHT3X.h b/src/components/i2c/drivers/drvSht3x.h similarity index 83% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_SHT3X.h rename to src/components/i2c/drivers/drvSht3x.h index db233cd44..d2486a2f9 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SHT3X.h +++ b/src/components/i2c/drivers/drvSht3x.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_SHT3X.h + * @file drvSht3x.h * * Device driver for the SHT3X Temperature and Humidity Sensor * @@ -15,10 +15,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_SHT3X_H -#define WipperSnapper_I2C_Driver_SHT3X_H +#ifndef DRV_SHT3X_H +#define DRV_SHT3X_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #include @@ -27,7 +27,7 @@ @brief Class that provides a driver interface for the SHT3X sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_SHT3X : public WipperSnapper_I2C_Driver { +class drvSht3x : public drvBase { public: /*******************************************************************************/ @@ -37,12 +37,16 @@ class WipperSnapper_I2C_Driver_SHT3X : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_SHT3X(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvSht3x(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 } /*******************************************************************************/ @@ -51,8 +55,8 @@ class WipperSnapper_I2C_Driver_SHT3X : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { - if (_sensorAddress == 0x44) // if address 0x44 (dec:68), alternative = 0x45 + bool begin() override { + if (_address == 0x44) // if address 0x44 (dec:68), alternative = 0x45 _sht3x = new SHTSensor(SHTSensor::SHT3X); else _sht3x = new SHTSensor(SHTSensor::SHT3X_ALT); @@ -102,4 +106,4 @@ class WipperSnapper_I2C_Driver_SHT3X : public WipperSnapper_I2C_Driver { SHTSensor *_sht3x; ///< SHT3X object }; -#endif // WipperSnapper_I2C_Driver_SHT3X \ No newline at end of file +#endif // drvSht3x \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SHT4X.h b/src/components/i2c/drivers/drvSht4x.h similarity index 85% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_SHT4X.h rename to src/components/i2c/drivers/drvSht4x.h index c95a408a9..243744b56 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SHT4X.h +++ b/src/components/i2c/drivers/drvSht4x.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_SHT4X.h + * @file drvSht4x.h * * Device driver for the SHT4X Temperature and Humidity Sensor * @@ -15,10 +15,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_SHT4X_H -#define WipperSnapper_I2C_Driver_SHT4X_H +#ifndef DRV_SHT4X_H +#define DRV_SHT4X_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #include @@ -27,7 +27,7 @@ @brief Class that provides a driver interface for the SHT4X sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_SHT4X : public WipperSnapper_I2C_Driver { +class drvSht4x : public drvBase { public: /*******************************************************************************/ @@ -37,12 +37,16 @@ class WipperSnapper_I2C_Driver_SHT4X : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_SHT4X(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvSht4x(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 } /*******************************************************************************/ @@ -51,7 +55,7 @@ class WipperSnapper_I2C_Driver_SHT4X : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _sht4x = new SHTSensor(SHTSensor::SHT4X); if (!_sht4x->init(*_i2c)) return false; @@ -100,4 +104,4 @@ class WipperSnapper_I2C_Driver_SHT4X : public WipperSnapper_I2C_Driver { SHTSensor *_sht4x; ///< SHT4X object }; -#endif // WipperSnapper_I2C_Driver_SHT4X \ No newline at end of file +#endif // drvSht4x \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SHTC3.h b/src/components/i2c/drivers/drvShtc3.h similarity index 84% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_SHTC3.h rename to src/components/i2c/drivers/drvShtc3.h index c68a383a7..ec633d7ea 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SHTC3.h +++ b/src/components/i2c/drivers/drvShtc3.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_SHTC3.h + * @file drvShtc3.h * * Device driver for the SHTC3 Temperature and Humidity Sensor * @@ -15,10 +15,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_SHTC3_H -#define WipperSnapper_I2C_Driver_SHTC3_H +#ifndef DRV_SHTC3_H +#define DRV_SHTC3_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #include @@ -27,7 +27,7 @@ @brief Class that provides a driver interface for the SHTC3 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_SHTC3 : public WipperSnapper_I2C_Driver { +class drvShtc3 : public drvBase { public: /*******************************************************************************/ @@ -37,12 +37,16 @@ class WipperSnapper_I2C_Driver_SHTC3 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_SHTC3(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvShtc3(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 } /*******************************************************************************/ @@ -51,7 +55,7 @@ class WipperSnapper_I2C_Driver_SHTC3 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _shtc3 = new SHTSensor(SHTSensor::SHTC3); return _shtc3->init(*_i2c); } @@ -94,4 +98,4 @@ class WipperSnapper_I2C_Driver_SHTC3 : public WipperSnapper_I2C_Driver { SHTSensor *_shtc3; ///< SHTC3 object }; -#endif // WipperSnapper_I2C_Driver_SHTC3 \ No newline at end of file +#endif // drvShtc3 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SI7021.h b/src/components/i2c/drivers/drvSi7021.h similarity index 84% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_SI7021.h rename to src/components/i2c/drivers/drvSi7021.h index 705baca2a..d9737e354 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SI7021.h +++ b/src/components/i2c/drivers/drvSi7021.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_SI7021.h + * @file drvSi7021.h * * Device driver for the SI7021 Temperature, and Humidity sensor. * @@ -14,10 +14,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_SI7021_H -#define WipperSnapper_I2C_Driver_SI7021_H +#ifndef DRV_SI7021_H +#define DRV_SI7021_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #include @@ -26,7 +26,7 @@ @brief Class that provides a driver interface for the SI7021 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_SI7021 : public WipperSnapper_I2C_Driver { +class drvSi7021 : public drvBase { public: /*******************************************************************************/ @@ -36,12 +36,16 @@ class WipperSnapper_I2C_Driver_SI7021 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_SI7021(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvSi7021(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 } /*******************************************************************************/ @@ -49,7 +53,7 @@ class WipperSnapper_I2C_Driver_SI7021 : public WipperSnapper_I2C_Driver { @brief Destructor for an SI7021 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_SI7021() { + ~drvSi7021() { // Called when a Si7021 component is deleted. delete _si7021; } @@ -60,7 +64,7 @@ class WipperSnapper_I2C_Driver_SI7021 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _si7021 = new Adafruit_Si7021(_i2c); return _si7021->begin(); } @@ -99,4 +103,4 @@ class WipperSnapper_I2C_Driver_SI7021 : public WipperSnapper_I2C_Driver { Adafruit_Si7021 *_si7021; ///< SI7021 driver object }; -#endif // WipperSnapper_I2C_Driver_SI7021 \ No newline at end of file +#endif // drvSi7021 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor.h b/src/components/i2c/drivers/drvStemmaSoil.h similarity index 80% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor.h rename to src/components/i2c/drivers/drvStemmaSoil.h index dd29b5fa9..bda0dd9f4 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor.h +++ b/src/components/i2c/drivers/drvStemmaSoil.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor.h + * @file drvStemmaSoil.h * * Device driver for the STEMMA Soil Sensor * @@ -13,10 +13,10 @@ * */ -#ifndef WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor_H -#define WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor_H +#ifndef DRV_STEMMA_SOIL_H +#define DRV_STEMMA_SOIL_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -24,8 +24,7 @@ @brief Class that provides a driver interface for the STEMMA soil sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor - : public WipperSnapper_I2C_Driver { +class drvStemmaSoil : public drvBase { public: /*******************************************************************************/ /*! @@ -34,13 +33,20 @@ class WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor(TwoWire *i2c, - uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { + drvStemmaSoil(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) { _i2c = i2c; - _sensorAddress = sensorAddress; + _address = sensorAddress; + _i2c_mux_channel = mux_channel; + strncpy(_name, driver_name, sizeof(_name) - 1); + _name[sizeof(_name) - 1] = '\0'; _seesaw = new Adafruit_seesaw(_i2c); } @@ -49,7 +55,7 @@ class WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor @brief Destructor for a STEMMA soil sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor() { _seesaw = nullptr; } + ~drvStemmaSoil() { _seesaw = nullptr; } /*******************************************************************************/ /*! @@ -57,7 +63,7 @@ class WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { return _seesaw->begin(_sensorAddress); } + bool begin() override { return _seesaw->begin(_address); } /*******************************************************************************/ /*! @@ -101,4 +107,4 @@ class WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor Adafruit_seesaw *_seesaw = nullptr; ///< Seesaw object }; -#endif // WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor_H \ No newline at end of file +#endif // DRV_STEMMA_SOIL_H \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_TMP117.h b/src/components/i2c/drivers/drvTmp117.h similarity index 79% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_TMP117.h rename to src/components/i2c/drivers/drvTmp117.h index 4dae3d749..38db6d6b6 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_TMP117.h +++ b/src/components/i2c/drivers/drvTmp117.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_TMP117.h + * @file drvTmp117.h * * Device driver for the TMP117 Temperature sensor. * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_TMP117_H -#define WipperSnapper_I2C_Driver_TMP117_H +#ifndef DRV_TMP117_H +#define DRV_TMP117_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -23,7 +23,7 @@ @brief Class that provides a driver interface for a TMP117 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_TMP117 : public WipperSnapper_I2C_Driver { +class drvTmp117 : public drvBase { public: /*******************************************************************************/ /*! @@ -32,12 +32,16 @@ class WipperSnapper_I2C_Driver_TMP117 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_TMP117(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvTmp117(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 } /*******************************************************************************/ @@ -45,7 +49,7 @@ class WipperSnapper_I2C_Driver_TMP117 : public WipperSnapper_I2C_Driver { @brief Destructor for an TMP117 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_TMP117() { + ~drvTmp117() { // Called when a TMP117 component is deleted. delete _tmp117; } @@ -56,9 +60,9 @@ class WipperSnapper_I2C_Driver_TMP117 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _tmp117 = new Adafruit_TMP117(); - return _tmp117->begin((uint8_t)_sensorAddress, _i2c); + return _tmp117->begin((uint8_t)_address, _i2c); } /*******************************************************************************/ @@ -78,4 +82,4 @@ class WipperSnapper_I2C_Driver_TMP117 : public WipperSnapper_I2C_Driver { Adafruit_TMP117 *_tmp117; ///< Pointer to TMP117 temperature sensor object }; -#endif // WipperSnapper_I2C_Driver_TMP117 \ No newline at end of file +#endif // drvTmp117 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_TSL2591.h b/src/components/i2c/drivers/drvTsl2591.h similarity index 84% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_TSL2591.h rename to src/components/i2c/drivers/drvTsl2591.h index fbb1d10b3..0aea6c4c6 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_TSL2591.h +++ b/src/components/i2c/drivers/drvTsl2591.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_TSL2591.h + * @file drvTsl2591.h * * Device driver for the TSL2591 digital luminosity (light) sensor. * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_TSL2591_H -#define WipperSnapper_I2C_Driver_TSL2591_H +#ifndef DRV_TSL2591_H +#define DRV_TSL2591_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -23,7 +23,7 @@ @brief Class that provides a driver interface for a TSL2591 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_TSL2591 : public WipperSnapper_I2C_Driver { +class drvTsl2591 : public drvBase { public: /*******************************************************************************/ /*! @@ -32,12 +32,16 @@ class WipperSnapper_I2C_Driver_TSL2591 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress The 7-bit I2C address of the sensor. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_TSL2591(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvTsl2591(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 } /*******************************************************************************/ @@ -45,7 +49,7 @@ class WipperSnapper_I2C_Driver_TSL2591 : public WipperSnapper_I2C_Driver { @brief Destructor for an TSL2591 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_TSL2591() { delete _tsl; } + ~drvTsl2591() { delete _tsl; } /*******************************************************************************/ /*! @@ -53,7 +57,7 @@ class WipperSnapper_I2C_Driver_TSL2591 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _tsl = new Adafruit_TSL2591(2591); // Attempt to initialize TSL2591 if (!_tsl->begin(_i2c, TSL2591_ADDR)) @@ -95,4 +99,4 @@ class WipperSnapper_I2C_Driver_TSL2591 : public WipperSnapper_I2C_Driver { Adafruit_TSL2591 *_tsl; ///< Pointer to TSL2591 light sensor object }; -#endif // WipperSnapper_I2C_Driver_TSL2591 \ No newline at end of file +#endif // drvTsl2591 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VEML7700.h b/src/components/i2c/drivers/drvVeml7700.h similarity index 81% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_VEML7700.h rename to src/components/i2c/drivers/drvVeml7700.h index a3a753177..6262a9744 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VEML7700.h +++ b/src/components/i2c/drivers/drvVeml7700.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_VEML7700.h + * @file drvVeml7700.h * * Device driver for the VEML7700 digital luminosity (light) sensor. * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_VEML7700_H -#define WipperSnapper_I2C_Driver_VEML7700_H +#ifndef DRV_VEML770_H +#define DRV_VEML770_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -23,7 +23,7 @@ @brief Class that provides a driver interface for a VEML7700 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_VEML7700 : public WipperSnapper_I2C_Driver { +class drvVeml7700 : public drvBase { public: /*******************************************************************************/ /*! @@ -32,12 +32,16 @@ class WipperSnapper_I2C_Driver_VEML7700 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress The 7-bit I2C address of the sensor. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_VEML7700(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvVeml7700(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 } /*******************************************************************************/ @@ -45,7 +49,7 @@ class WipperSnapper_I2C_Driver_VEML7700 : public WipperSnapper_I2C_Driver { @brief Destructor for an VEML7700 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_VEML7700() { delete _veml; } + ~drvVeml7700() { delete _veml; } /*******************************************************************************/ /*! @@ -53,7 +57,7 @@ class WipperSnapper_I2C_Driver_VEML7700 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _veml = new Adafruit_VEML7700(); // Attempt to initialize and configure VEML7700 return _veml->begin(_i2c); @@ -81,4 +85,4 @@ class WipperSnapper_I2C_Driver_VEML7700 : public WipperSnapper_I2C_Driver { Adafruit_VEML7700 *_veml; ///< Pointer to VEML7700 light sensor object }; -#endif // WipperSnapper_I2C_Driver_VEML7700 \ No newline at end of file +#endif // drvVeml7700 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL53L0X.h b/src/components/i2c/drivers/drvVl53l0x.h similarity index 81% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL53L0X.h rename to src/components/i2c/drivers/drvVl53l0x.h index 03fda3325..70e32c876 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL53L0X.h +++ b/src/components/i2c/drivers/drvVl53l0x.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_VL53L0X.h + * @file drvVl53l0x.h * * Device driver for the VL53L0X ToF sensor. * @@ -13,10 +13,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_VL53L0X_H -#define WipperSnapper_I2C_Driver_VL53L0X_H +#ifndef DRV_VL53L0X_H +#define DRV_VL53L0X_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -24,7 +24,7 @@ @brief Class that provides a driver interface for a VL53L0X sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_VL53L0X : public WipperSnapper_I2C_Driver { +class drvVl53l0x : public drvBase { public: /*******************************************************************************/ /*! @@ -33,12 +33,16 @@ class WipperSnapper_I2C_Driver_VL53L0X : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_VL53L0X(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvVl53l0x(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 } /*******************************************************************************/ @@ -46,7 +50,7 @@ class WipperSnapper_I2C_Driver_VL53L0X : public WipperSnapper_I2C_Driver { @brief Destructor for an VL53L0X sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_VL53L0X() { + ~drvVl53l0x() { // Called when a VL53L0X component is deleted. delete _vl53l0x; } @@ -60,7 +64,7 @@ class WipperSnapper_I2C_Driver_VL53L0X : public WipperSnapper_I2C_Driver { bool begin() { _vl53l0x = new Adafruit_VL53L0X(); bool isInit = - _vl53l0x->begin((uint8_t)_sensorAddress, false, _i2c, + _vl53l0x->begin((uint8_t)_address, false, _i2c, Adafruit_VL53L0X::VL53L0X_SENSE_HIGH_ACCURACY); return isInit; } @@ -88,4 +92,4 @@ class WipperSnapper_I2C_Driver_VL53L0X : public WipperSnapper_I2C_Driver { Adafruit_VL53L0X *_vl53l0x; ///< Pointer to VL53L0X temperature sensor object }; -#endif // WipperSnapper_I2C_Driver_VL53L0X \ No newline at end of file +#endif // drvVl53l0x \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL53L1X.h b/src/components/i2c/drivers/drvVl53l1x.h similarity index 78% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL53L1X.h rename to src/components/i2c/drivers/drvVl53l1x.h index 00c20bbbb..1c4357c68 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL53L1X.h +++ b/src/components/i2c/drivers/drvVl53l1x.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_VL53L1X.h + * @file drvVl53l1x.h * * Device driver for the VL53L1X ToF sensor. * @@ -13,10 +13,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_VL53L1X_H -#define WipperSnapper_I2C_Driver_VL53L1X_H +#ifndef DRV_VL53L1X_H +#define DRV_VL53L1X_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -24,7 +24,7 @@ @brief Class that provides a driver interface for a VL53L1X sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_VL53L1X : public WipperSnapper_I2C_Driver { +class drvVl53l1x : public drvBase { public: /*******************************************************************************/ /*! @@ -33,12 +33,16 @@ class WipperSnapper_I2C_Driver_VL53L1X : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_VL53L1X(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvVl53l1x(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 } /*******************************************************************************/ @@ -46,7 +50,7 @@ class WipperSnapper_I2C_Driver_VL53L1X : public WipperSnapper_I2C_Driver { @brief Destructor for an VL53L1X sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_VL53L1X() { + ~drvVl53l1x() { // Called when a VL53L1X component is deleted. delete _VL53L1X; } @@ -59,7 +63,7 @@ class WipperSnapper_I2C_Driver_VL53L1X : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool begin() { _VL53L1X = new Adafruit_VL53L1X(); - if (_VL53L1X->begin((uint8_t)_sensorAddress, _i2c, false)) { + if (_VL53L1X->begin((uint8_t)_address, _i2c, false)) { _VL53L1X->startRanging(); _VL53L1X->setTimingBudget(500); // distance mode is long(2) by default return true; @@ -82,10 +86,6 @@ class WipperSnapper_I2C_Driver_VL53L1X : public WipperSnapper_I2C_Driver { } int16_t proximityMM = _VL53L1X->distance(); if (proximityMM == -1) { - WS_DEBUG_PRINT("VL53L1X: Invalid proximity value:"); - WS_DEBUG_PRINTLN(proximityMM); - WS_DEBUG_PRINT("VL53L1X status: "); - WS_DEBUG_PRINTLN(_VL53L1X->vl_status); proximityEvent->data[0] = NAN; } else { proximityEvent->data[0] = proximityMM; @@ -98,4 +98,4 @@ class WipperSnapper_I2C_Driver_VL53L1X : public WipperSnapper_I2C_Driver { Adafruit_VL53L1X *_VL53L1X; ///< Pointer to VL53L1X temperature sensor object }; -#endif // WipperSnapper_I2C_Driver_VL53L1X \ No newline at end of file +#endif // drvVl53l1x \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL53L4CD.h b/src/components/i2c/drivers/drvVl53l4cd.h similarity index 69% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL53L4CD.h rename to src/components/i2c/drivers/drvVl53l4cd.h index 95c18d701..b324eeae5 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL53L4CD.h +++ b/src/components/i2c/drivers/drvVl53l4cd.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_VL53L4CD.h + * @file drvVl53l4cd.h * * Device driver for the VL53L4CD ToF sensor. * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_VL53L4CD_H -#define WipperSnapper_I2C_Driver_VL53L4CD_H +#ifndef DRV_VL53L4CD +#define DRV_VL53L4CD -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -23,7 +23,7 @@ @brief Class that provides a driver interface for a VL53L4CD sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_VL53L4CD : public WipperSnapper_I2C_Driver { +class drvVl53l4cd : public drvBase { public: /*******************************************************************************/ /*! @@ -32,12 +32,16 @@ class WipperSnapper_I2C_Driver_VL53L4CD : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_VL53L4CD(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvVl53l4cd(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 } /*******************************************************************************/ @@ -45,7 +49,7 @@ class WipperSnapper_I2C_Driver_VL53L4CD : public WipperSnapper_I2C_Driver { @brief Destructor for an VL53L4CD sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_VL53L4CD() { + ~drvVl53l4cd() { // Called when a VL53L4CD component is deleted. delete _VL53L4CD; } @@ -59,43 +63,43 @@ class WipperSnapper_I2C_Driver_VL53L4CD : public WipperSnapper_I2C_Driver { bool begin() { _VL53L4CD = new VL53L4CD(_i2c, -1); - if (_VL53L4CD->InitSensor((uint8_t)_sensorAddress) != VL53L4CD_ERROR_NONE) { - WS_DEBUG_PRINTLN("Failed to initialize VL53L4CD sensor!"); + if (_VL53L4CD->InitSensor((uint8_t)_address) != VL53L4CD_ERROR_NONE) { + // WS_DEBUG_PRINTLN("Failed to initialize VL53L4CD sensor!"); return false; } // Program the highest possible TimingBudget, no interval time if (_VL53L4CD->VL53L4CD_SetRangeTiming(200, 0) != VL53L4CD_ERROR_NONE) { - WS_DEBUG_PRINTLN("Failed to set VL53L4CD timing!"); + // WS_DEBUG_PRINTLN("Failed to set VL53L4CD timing!"); return false; } if (uint16_t signalThreshold; _VL53L4CD->VL53L4CD_GetSignalThreshold(&signalThreshold) == VL53L4CD_ERROR_NONE) { - WS_DEBUG_PRINT("VL53L4CD old signal threshold: "); - WS_DEBUG_PRINTLN(signalThreshold); - WS_DEBUG_PRINTLN("Setting VL53L4CD signal threshold to 50"); + // WS_DEBUG_PRINT("VL53L4CD old signal threshold: "); + // WS_DEBUG_PRINTLN(signalThreshold); + // WS_DEBUG_PRINTLN("Setting VL53L4CD signal threshold to 50"); if (_VL53L4CD->VL53L4CD_SetSignalThreshold(50) != VL53L4CD_ERROR_NONE) { - WS_DEBUG_PRINTLN("Failed to set new VL53L4CD signal threshold!"); + // WS_DEBUG_PRINTLN("Failed to set new VL53L4CD signal threshold!"); } } else { - WS_DEBUG_PRINTLN("Failed to get VL53L4CD signal threshold!"); + // WS_DEBUG_PRINTLN("Failed to get VL53L4CD signal threshold!"); } if (uint16_t sigmaThreshold; _VL53L4CD->VL53L4CD_GetSigmaThreshold( &sigmaThreshold) == VL53L4CD_ERROR_NONE) { - WS_DEBUG_PRINT("VL53L4CD old sigma threshold: "); - WS_DEBUG_PRINTLN(sigmaThreshold); - WS_DEBUG_PRINTLN("Setting VL53L4CD sigma threshold to 100"); + // WS_DEBUG_PRINT("VL53L4CD old sigma threshold: "); + // WS_DEBUG_PRINTLN(sigmaThreshold); + // WS_DEBUG_PRINTLN("Setting VL53L4CD sigma threshold to 100"); if (_VL53L4CD->VL53L4CD_SetSigmaThreshold(100) != VL53L4CD_ERROR_NONE) { - WS_DEBUG_PRINTLN("Failed to set VL53L4CD sigma threshold!"); + // WS_DEBUG_PRINTLN("Failed to set VL53L4CD sigma threshold!"); } } else { - WS_DEBUG_PRINTLN("Failed to get VL53L4CD sigma threshold!"); + // WS_DEBUG_PRINTLN("Failed to get VL53L4CD sigma threshold!"); } if (_VL53L4CD->VL53L4CD_StartRanging() != VL53L4CD_ERROR_NONE) { - WS_DEBUG_PRINTLN("Failed to start VL53L4CD ranging!"); + // WS_DEBUG_PRINTLN("Failed to start VL53L4CD ranging!"); return false; } return true; @@ -116,7 +120,7 @@ class WipperSnapper_I2C_Driver_VL53L4CD : public WipperSnapper_I2C_Driver { uint8_t status; // Start fresh reading, seemed to be accepting stale value _VL53L4CD->VL53L4CD_ClearInterrupt(); - WS_DEBUG_PRINT("Waiting for VL53L4CD data ready..."); + // WS_DEBUG_PRINT("Waiting for VL53L4CD data ready..."); delay(250); for (uint8_t retries = 0; @@ -124,9 +128,9 @@ class WipperSnapper_I2C_Driver_VL53L4CD : public WipperSnapper_I2C_Driver { !NewDataReady && retries < 3; retries++) { delay(300); - WS_DEBUG_PRINT(" ."); + // WS_DEBUG_PRINT(" ."); } - WS_DEBUG_PRINTLN(); + // WS_DEBUG_PRINTLN(); if ((status == VL53L4CD_ERROR_NONE) && (NewDataReady != 0)) { // (Mandatory) Clear HW interrupt to restart measurements _VL53L4CD->VL53L4CD_ClearInterrupt(); @@ -134,8 +138,8 @@ class WipperSnapper_I2C_Driver_VL53L4CD : public WipperSnapper_I2C_Driver { // Read measured distance. RangeStatus = 0 means valid data if (_VL53L4CD->VL53L4CD_GetResult(&results) == VL53L4CD_ERROR_NONE) { if (results.range_status != 0) { - WS_DEBUG_PRINT("VL53L4CD range status: "); - WS_DEBUG_PRINTLN(results.range_status); + // WS_DEBUG_PRINT("VL53L4CD range status: "); + // WS_DEBUG_PRINTLN(results.range_status); return false; } proximityEvent->data[0] = (float)results.distance_mm; @@ -146,11 +150,12 @@ class WipperSnapper_I2C_Driver_VL53L4CD : public WipperSnapper_I2C_Driver { // https://github.com/stm32duino/VL53L4CD/blob/066664f983bcf70819133c7fcf43101035b09bab/src/vl53l4cd_api.h#L130-L131 } else { if (status == VL53L4CD_ERROR_INVALID_ARGUMENT) { - WS_DEBUG_PRINTLN("VL53L4CD: Invalid argument to CheckForDataReady()"); + // WS_DEBUG_PRINTLN("VL53L4CD: Invalid argument to + // CheckForDataReady()"); } else if (status == VL53L4CD_ERROR_TIMEOUT) { - WS_DEBUG_PRINTLN("VL53L4CD: Timeout waiting for data ready"); + // WS_DEBUG_PRINTLN("VL53L4CD: Timeout waiting for data ready"); } else { - WS_DEBUG_PRINTLN("VL53L4CD: data not ready yet"); + // WS_DEBUG_PRINTLN("VL53L4CD: data not ready yet"); } } return false; @@ -160,4 +165,4 @@ class WipperSnapper_I2C_Driver_VL53L4CD : public WipperSnapper_I2C_Driver { VL53L4CD *_VL53L4CD; ///< Pointer to VL53L4CD temperature sensor object }; -#endif // WipperSnapper_I2C_Driver_VL53L4CD \ No newline at end of file +#endif // drvVl53l4cd \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL53L4CX.h b/src/components/i2c/drivers/drvVl53l4cx.h similarity index 81% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL53L4CX.h rename to src/components/i2c/drivers/drvVl53l4cx.h index ef8307256..79707d3bb 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL53L4CX.h +++ b/src/components/i2c/drivers/drvVl53l4cx.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_VL53L4CX.h + * @file drvVl53l4cx.h * * Device driver for the VL53L4CX ToF sensor. * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_VL53L4CX_H -#define WipperSnapper_I2C_Driver_VL53L4CX_H +#ifndef DRV_VL53L4CX_H +#define DRV_VL53L4CX_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include #include @@ -28,7 +28,7 @@ @brief Class that provides a driver interface for a VL53L4CX sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_VL53L4CX : public WipperSnapper_I2C_Driver { +class drvVl53l4cx : public drvBase { public: /*******************************************************************************/ /*! @@ -37,12 +37,16 @@ class WipperSnapper_I2C_Driver_VL53L4CX : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_VL53L4CX(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvVl53l4cx(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 } /*******************************************************************************/ @@ -50,7 +54,7 @@ class WipperSnapper_I2C_Driver_VL53L4CX : public WipperSnapper_I2C_Driver { @brief Destructor for an VL53L4CX sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_VL53L4CX() { + ~drvVl53l4cx() { // Called when a VL53L4CX component is deleted. delete _VL53L4CX; } @@ -64,26 +68,26 @@ class WipperSnapper_I2C_Driver_VL53L4CX : public WipperSnapper_I2C_Driver { bool begin() { _VL53L4CX = new VL53L4CX(_i2c, VL53_SHUTDOWN_PIN); - if (_VL53L4CX->InitSensor((uint8_t)_sensorAddress) != VL53L4CX_ERROR_NONE) { - WS_DEBUG_PRINTLN("Failed to initialize VL53L4CX sensor!"); + if (_VL53L4CX->InitSensor((uint8_t)_address) != VL53L4CX_ERROR_NONE) { + // WS_DEBUG_PRINTLN("Failed to initialize VL53L4CX sensor!"); return false; } if (_VL53L4CX->VL53L4CX_SetDistanceMode(VL53L4CX_DISTANCEMODE_LONG) != VL53L4CX_ERROR_NONE) { - WS_DEBUG_PRINTLN("Failed to set VL53L4CX distance mode to long!"); + // WS_DEBUG_PRINTLN("Failed to set VL53L4CX distance mode to long!"); return false; } // Set 200ms measurement time, the possible TimingBudget is 8-200ms if (_VL53L4CX->VL53L4CX_SetMeasurementTimingBudgetMicroSeconds( VL53_TIMING_BUDGET_NS) != VL53L4CX_ERROR_NONE) { - WS_DEBUG_PRINTLN("Failed to set VL53L4CX timing budget!"); + // WS_DEBUG_PRINTLN("Failed to set VL53L4CX timing budget!"); return false; } if (_VL53L4CX->VL53L4CX_StartMeasurement() != VL53L4CX_ERROR_NONE) { - WS_DEBUG_PRINTLN("Failed to start VL53L4CX ranging!"); + // WS_DEBUG_PRINTLN("Failed to start VL53L4CX ranging!"); return false; } return true; @@ -137,37 +141,36 @@ class WipperSnapper_I2C_Driver_VL53L4CX : public WipperSnapper_I2C_Driver { // Start fresh reading, seemed to be accepting stale value status = _VL53L4CX->VL53L4CX_ClearInterruptAndStartMeasurement(); if (status != VL53L4CX_ERROR_NONE) { - WS_DEBUG_PRINT( - "VL53L4CX Error clearing interrupt and starting measurement: "); - WS_DEBUG_PRINTLN(status); + // WS_DEBUG_PRINT("VL53L4CX Error clearing interrupt and starting + // measurement: "); WS_DEBUG_PRINTLN(status); return false; } // Wait for data read period then update data ready status - WS_DEBUG_PRINT("Waiting for VL53L4CX data ready..."); + // WS_DEBUG_PRINT("Waiting for VL53L4CX data ready..."); delay(VL53_READING_DELAY); status = _VL53L4CX->VL53L4CX_GetMeasurementDataReady(&NewDataReady); if ((status != VL53L4CX_ERROR_NONE) || (NewDataReady == 0)) { // error or no data ready - WS_DEBUG_PRINT("VL53L4CX Error checking for data ready: "); - WS_DEBUG_PRINTLN(status); + // WS_DEBUG_PRINT("VL53L4CX Error checking for data ready: "); + // WS_DEBUG_PRINTLN(status); return false; } // get data - still to verify which of one or two objects found status = _VL53L4CX->VL53L4CX_GetMultiRangingData(pMultiRangingData); if (status != VL53L4CX_ERROR_NONE) { - WS_DEBUG_PRINT("VL53L4CX Error getting multi ranging data: "); - WS_DEBUG_PRINTLN(status); + // WS_DEBUG_PRINT("VL53L4CX Error getting multi ranging data: "); + // WS_DEBUG_PRINTLN(status); return false; } // whichObject: 0-based index, return NaN(Object not found) if too few found if (pMultiRangingData->NumberOfObjectsFound - 1 < whichObject) { - WS_DEBUG_PRINT("Object not found at index #"); - WS_DEBUG_PRINT(whichObject + 1); // human readable 1-based index - WS_DEBUG_PRINTLN(", returning NaN"); + // WS_DEBUG_PRINT("Object not found at index #"); + // WS_DEBUG_PRINT(whichObject + 1); // human readable 1-based index + // WS_DEBUG_PRINTLN(", returning NaN"); proximityEvent->data[0] = NAN; return true; } @@ -203,4 +206,4 @@ class WipperSnapper_I2C_Driver_VL53L4CX : public WipperSnapper_I2C_Driver { VL53L4CX *_VL53L4CX; ///< Pointer to VL53L4CX temperature sensor object }; -#endif // WipperSnapper_I2C_Driver_VL53L4CX \ No newline at end of file +#endif // drvVl53l4cx \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL6180X.h b/src/components/i2c/drivers/drvVl6180x.h similarity index 88% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL6180X.h rename to src/components/i2c/drivers/drvVl6180x.h index f6b41b92e..325a70377 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VL6180X.h +++ b/src/components/i2c/drivers/drvVl6180x.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_VL6180X.h + * @file drvVl6180x.h * * Device driver for the VL6180X ToF sensor. * @@ -12,11 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_VL6180X_H -#define WipperSnapper_I2C_Driver_VL6180X_H +#ifndef DRV_VL6180X_H +#define DRV_VL6180X_H -#include "WipperSnapper_I2C_Driver.h" -#include "Wippersnapper.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -24,7 +23,7 @@ @brief Class that provides a driver interface for a VL6180X sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_VL6180X : public WipperSnapper_I2C_Driver { +class drvVl6180x : public drvBase { public: /*******************************************************************************/ /*! @@ -33,12 +32,16 @@ class WipperSnapper_I2C_Driver_VL6180X : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_VL6180X(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvVl6180x(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 } /*******************************************************************************/ @@ -46,7 +49,7 @@ class WipperSnapper_I2C_Driver_VL6180X : public WipperSnapper_I2C_Driver { @brief Destructor for an VL6180X sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_VL6180X() { + ~drvVl6180x() { // Called when a VL6180X component is deleted. delete _vl6180x; } @@ -58,7 +61,7 @@ class WipperSnapper_I2C_Driver_VL6180X : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ bool begin() { - _vl6180x = new Adafruit_VL6180X(_sensorAddress); + _vl6180x = new Adafruit_VL6180X(_address); return _vl6180x->begin(_i2c); } @@ -128,4 +131,4 @@ class WipperSnapper_I2C_Driver_VL6180X : public WipperSnapper_I2C_Driver { Adafruit_VL6180X *_vl6180x; ///< Pointer to VL6180X temperature sensor object }; -#endif // WipperSnapper_I2C_Driver_VL6180X \ No newline at end of file +#endif // drvVl6180x \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VCNL4020.h b/src/components/i2c/drivers/drvVncl4020.h similarity index 82% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_VCNL4020.h rename to src/components/i2c/drivers/drvVncl4020.h index 42aef953e..5b8183f96 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VCNL4020.h +++ b/src/components/i2c/drivers/drvVncl4020.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_VCNL4020.h + * @file drvVncl4020.h * * Device driver for the VCNL4020 light + proximity sensor. * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_VCNL4020_H -#define WipperSnapper_I2C_Driver_VCNL4020_H +#ifndef DRV_VNCL4020_H +#define DRV_VNCL4020_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -23,7 +23,7 @@ @brief Class that provides a driver interface for a VCNL4020 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_VCNL4020 : public WipperSnapper_I2C_Driver { +class drvVncl4020 : public drvBase { public: /*******************************************************************************/ /*! @@ -32,12 +32,16 @@ class WipperSnapper_I2C_Driver_VCNL4020 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress The 7-bit I2C address of the sensor. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_VCNL4020(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvVncl4020(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 } /*******************************************************************************/ @@ -45,7 +49,7 @@ class WipperSnapper_I2C_Driver_VCNL4020 : public WipperSnapper_I2C_Driver { @brief Destructor for an VCNL4020 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_VCNL4020() { delete _vcnl4020; } + ~drvVncl4020() { delete _vcnl4020; } /*******************************************************************************/ /*! @@ -53,10 +57,10 @@ class WipperSnapper_I2C_Driver_VCNL4020 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _vcnl4020 = new Adafruit_VCNL4020(); // Attempt to initialize and configure VCNL4020 - return _vcnl4020->begin(_i2c, _sensorAddress); + return _vcnl4020->begin(_i2c, _address); } /*******************************************************************************/ @@ -93,4 +97,4 @@ class WipperSnapper_I2C_Driver_VCNL4020 : public WipperSnapper_I2C_Driver { Adafruit_VCNL4020 *_vcnl4020; ///< Pointer to VCNL4020 light sensor object }; -#endif // WipperSnapper_I2C_Driver_VCNL4020 \ No newline at end of file +#endif // drvVncl4020 \ No newline at end of file diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VCNL4040.h b/src/components/i2c/drivers/drvVncl4040.h similarity index 85% rename from src/components/i2c/drivers/WipperSnapper_I2C_Driver_VCNL4040.h rename to src/components/i2c/drivers/drvVncl4040.h index d1eb994b1..2d83f2931 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_VCNL4040.h +++ b/src/components/i2c/drivers/drvVncl4040.h @@ -1,5 +1,5 @@ /*! - * @file WipperSnapper_I2C_Driver_VCNL4040.h + * @file drvVncl4040.h * * Device driver for the VCNL4040 light + proximity sensor. * @@ -12,10 +12,10 @@ * MIT license, all text here must be included in any redistribution. * */ -#ifndef WipperSnapper_I2C_Driver_VCNL4040_H -#define WipperSnapper_I2C_Driver_VCNL4040_H +#ifndef DRV_VNCL4040_H +#define DRV_VNCL4040_H -#include "WipperSnapper_I2C_Driver.h" +#include "drvBase.h" #include /**************************************************************************/ @@ -23,7 +23,7 @@ @brief Class that provides a driver interface for a VCNL4040 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_VCNL4040 : public WipperSnapper_I2C_Driver { +class drvVncl4040 : public drvBase { public: /*******************************************************************************/ /*! @@ -32,12 +32,16 @@ class WipperSnapper_I2C_Driver_VCNL4040 : public WipperSnapper_I2C_Driver { The I2C interface. @param sensorAddress The 7-bit I2C address of the sensor. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. */ /*******************************************************************************/ - WipperSnapper_I2C_Driver_VCNL4040(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { - _i2c = i2c; - _sensorAddress = sensorAddress; + drvVncl4040(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 } /*******************************************************************************/ @@ -45,7 +49,7 @@ class WipperSnapper_I2C_Driver_VCNL4040 : public WipperSnapper_I2C_Driver { @brief Destructor for an VCNL4040 sensor. */ /*******************************************************************************/ - ~WipperSnapper_I2C_Driver_VCNL4040() { delete _vcnl4040; } + ~drvVncl4040() { delete _vcnl4040; } /*******************************************************************************/ /*! @@ -53,10 +57,10 @@ class WipperSnapper_I2C_Driver_VCNL4040 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() override { _vcnl4040 = new Adafruit_VCNL4040(); // Attempt to initialize and configure VCNL4040 - if (!_vcnl4040->begin(_sensorAddress, _i2c)) + if (!_vcnl4040->begin(_address, _i2c)) return false; // Power saving: this could be lower, but for reliability 200mA(max, 50mA @@ -107,4 +111,4 @@ class WipperSnapper_I2C_Driver_VCNL4040 : public WipperSnapper_I2C_Driver { Adafruit_VCNL4040 *_vcnl4040; ///< Pointer to VCNL4040 light sensor object }; -#endif // WipperSnapper_I2C_Driver_VCNL4040 \ No newline at end of file +#endif // drvVncl4040 \ No newline at end of file diff --git a/src/components/i2c/hardware.cpp b/src/components/i2c/hardware.cpp new file mode 100644 index 000000000..d3bd8901c --- /dev/null +++ b/src/components/i2c/hardware.cpp @@ -0,0 +1,213 @@ +#include "hardware.h" + +/***********************************************************************/ +/*! + @brief I2C hardware class constructor +*/ +/***********************************************************************/ +I2cHardware::I2cHardware() { _has_mux = false; } + +/***********************************************************************/ +/*! + @brief I2C hardware class destructor +*/ +/***********************************************************************/ +I2cHardware::~I2cHardware() { _has_mux = false; } + +/***********************************************************************/ +/*! + @brief Returns the I2C bus' status. + @returns The I2C bus status, as a wippersnapper_i2c_I2cBusStatus. +*/ +/***********************************************************************/ +wippersnapper_i2c_I2cBusStatus I2cHardware::GetBusStatus() { + return _bus_status; +} + +/***********************************************************************/ +/*! + @brief Optionally turns on the I2C bus, used for hardware with + a power control pin for the I2C bus. +*/ +/***********************************************************************/ +void I2cHardware::TogglePowerPin() { +#if defined(PIN_I2C_POWER) + // turn on the I2C power by setting pin to opposite of 'rest state' + pinMode(PIN_I2C_POWER, INPUT); + delay(1); + bool polarity = digitalRead(PIN_I2C_POWER); + pinMode(PIN_I2C_POWER, OUTPUT); + digitalWrite(PIN_I2C_POWER, !polarity); +#elif defined(TFT_I2C_POWER) + // ADAFRUIT_FEATHER_ESP32S2_TFT + pinMode(TFT_I2C_POWER, OUTPUT); + digitalWrite(TFT_I2C_POWER, HIGH); +#elif defined(NEOPIXEL_I2C_POWER) + // ADAFRUIT_FEATHER_ESP32_V2 + pinMode(NEOPIXEL_I2C_POWER, OUTPUT); + digitalWrite(NEOPIXEL_I2C_POWER, HIGH); +#endif +} + +/***********************************************************************/ +/*! + @brief Initializes an I2C bus. + @param is_default + True if the default I2C bus is being used, + False if an alternative I2C bus is being used. + @param sda + The desired SDA pin. + @param scl + The desired SCL pin. +*/ +/***********************************************************************/ +void I2cHardware::InitBus(bool is_default, const char *sda, const char *scl) { + uint8_t pin_sda, pin_scl; + if (!is_default && (sda == nullptr || scl == nullptr)) { + _bus_status = wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_UNSPECIFIED; + return; + } +// Some development boards define a pin that controls power +// to the i2c bus. If the pin is defined, turn the power to the i2c bus on. +#if defined(PIN_I2C_POWER) || defined(TFT_I2C_POWER) || \ + defined(NEOPIXEL_I2C_POWER) + TogglePowerPin(); +#endif + + // Assign I2C bus pins + if (is_default) { +#ifndef ARDUINO_ARCH_RP2040 + pin_sda = SDA; + pin_scl = SCL; +#else + // RP2040 BSP uses a different naming scheme than Espressif for I2C pins + pin_sda = PIN_WIRE0_SDA; + pin_scl = PIN_WIRE0_SCL; +#endif + } else { + pin_sda = atoi(sda); + pin_scl = atoi(scl); + } + + // Enable pullups + pinMode(pin_scl, INPUT_PULLUP); + pinMode(pin_sda, INPUT_PULLUP); + delay(150); + + // Is the bus stuck LOW? + if (digitalRead(pin_scl) == 0 || digitalRead(pin_sda) == 0) { + _bus_status = wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_ERROR_PULLUPS; + return; + } + + // Reset bus to a high-impedance state + pinMode(pin_scl, INPUT); + pinMode(pin_sda, INPUT); + +// Initialize bus +// NOTE: Each platform has a slightly different bus initialization routine +#ifdef ARDUINO_ARCH_ESP32 + if (is_default) { + _bus = new TwoWire(0); + } else { + _bus = new TwoWire(1); + _bus->setPins(pin_sda, pin_scl); + } + if (!_bus->begin(pin_sda, pin_scl)) { + _bus_status = wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_ERROR_HANG; + return; + } + _bus->setClock(50000); +#elif defined(ARDUINO_ARCH_ESP8266) + _bus = new TwoWire(); + _bus->begin(pin_sda, pin_scl); + _bus->setClock(50000); +#elif defined(ARDUINO_ARCH_RP2040) + _bus = &WIRE; + _bus->setSDA(pin_sda); + _bus->setSCL(pin_scl); + _bus->begin(); +#elif defined(ARDUINO_ARCH_SAM) + _bus = new TwoWire(&PERIPH_WIRE, pin_sda, pin_scl); + _bus->begin(); +#else +#error "I2C bus implementation not supported by this platform!" +#endif + + _bus_status = wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_SUCCESS; +} + +/***********************************************************************/ +/*! + @brief Returns a pointer to the I2C bus. + @returns Pointer to the I2C bus. +*/ +/***********************************************************************/ +TwoWire *I2cHardware::GetBus() { return _bus; } + +/***********************************************************************/ +/*! + @brief Adds a MUX to the I2C bus. + @param address_register + The MUX's address register. + @param name + The MUX's name. + @returns True if the MUX was successfully added to the bus, + False otherwise. +*/ +/***********************************************************************/ +bool I2cHardware::AddMuxToBus(uint32_t address_register, const char *name) { + if (strcmp(name, "pca9546") == 0) { + _mux_max_channels = 4; // PCA9546 supports 4 channels + } else if (strcmp(name, "pca9548") == 0 || strcmp(name, "tca9548a") == 0) { + _mux_max_channels = 8; // PCA9548 supports 8 channels + } else { + return false; + } + + _mux_address_register = address_register; + _has_mux = true; + // Put MUX in back into its default state cuz we don't know if we're about to + // use it again + ClearMuxChannel(); + return true; +} + +/***********************************************************************/ +/*! + @brief Clears the enabled MUX channel. +*/ +/***********************************************************************/ +void I2cHardware::ClearMuxChannel() { + if (!_has_mux) + return; + _bus->beginTransmission(_mux_address_register); + if (_mux_max_channels == 4) + _bus->write(0b0000); + else if (_mux_max_channels == 8) + _bus->write(0b00000000); + _bus->endTransmission(); +} + +/***********************************************************************/ +/*! + @brief Enables a specific channel on a MUX. + @param channel + The desired MUX channel to enable. +*/ +/***********************************************************************/ +void I2cHardware::SelectMuxChannel(uint32_t channel) { + if (channel > _mux_max_channels - 1) + return; + _bus->beginTransmission(_mux_address_register); + _bus->write(1 << channel); + _bus->endTransmission(); +} + +/***********************************************************************/ +/*! + @brief Returns if a MUX is present on the I2C bus. + @returns True if a MUX is present on the bus, False otherwise. +*/ +/***********************************************************************/ +bool I2cHardware::HasMux() { return _has_mux; } \ No newline at end of file diff --git a/src/components/i2c/hardware.h b/src/components/i2c/hardware.h new file mode 100644 index 000000000..ea5c063cd --- /dev/null +++ b/src/components/i2c/hardware.h @@ -0,0 +1,52 @@ +/*! + * @file hardware.cpp + * + * Hardware driver for the i2c API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2025 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_I2C_HARDWARE_H +#define WS_I2C_HARDWARE_H +#include "Wippersnapper_V2.h" +#include "drivers/drvBase.h" ///< Base driver class + +#ifdef ARDUINO_ARCH_RP2040 +// Wire uses GPIO4 (SDA) and GPIO5 (SCL) automatically. +#define WIRE Wire +#endif + +/**************************************************************************/ +/*! + @brief Interfaces with the I2C bus via the Arduino "Wire" API. +*/ +/**************************************************************************/ +class I2cHardware { +public: + I2cHardware(); + ~I2cHardware(); + void InitBus(bool is_default, const char *sda = nullptr, + const char *scl = nullptr); + TwoWire *GetBus(); + wippersnapper_i2c_I2cBusStatus GetBusStatus(); + // MUX + bool AddMuxToBus(uint32_t address_register, const char *name); + void SelectMuxChannel(uint32_t channel); + bool HasMux(); + void ClearMuxChannel(); + +private: + void TogglePowerPin(); + wippersnapper_i2c_I2cBusStatus _bus_status; ///< I2C bus status + TwoWire *_bus = nullptr; ///< I2C bus + bool _has_mux; ///< Is a MUX present on the bus? + uint32_t _mux_address_register; ///< I2C address for the MUX + int _mux_max_channels; ///< Maximum possible number of MUX channels +}; +#endif // WS_I2C_HARDWARE_H \ No newline at end of file diff --git a/src/components/i2c/model.cpp b/src/components/i2c/model.cpp new file mode 100644 index 000000000..9f7837577 --- /dev/null +++ b/src/components/i2c/model.cpp @@ -0,0 +1,319 @@ +/*! + * @file model.cpp + * + * Model for the i2c.proto message. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2025 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "model.h" + +/***********************************************************************/ +/*! + @brief I2C constructor +*/ +/***********************************************************************/ +I2cModel::I2cModel() { + _msg_i2c_bus_scan = wippersnapper_i2c_I2cBusScan_init_default; + _msg_i2c_bus_scanned = wippersnapper_i2c_I2cBusScan_init_default; + _msg_i2c_device_add_replace = + wippersnapper_i2c_I2cDeviceAddOrReplace_init_default; + _msg_i2c_device_added_replaced = + wippersnapper_i2c_I2cDeviceAddedOrReplaced_init_default; + _msg_i2c_device_remove = wippersnapper_i2c_I2cDeviceRemove_init_default; + _msg_i2c_device_removed = wippersnapper_i2c_I2cDeviceRemoved_init_default; + _msg_i2c_device_event = wippersnapper_i2c_I2cDeviceEvent_init_default; +} + +/***********************************************************************/ +/*! + @brief I2C destructor +*/ +/***********************************************************************/ +I2cModel::~I2cModel() { + // nothing to add here! +} + +/***************************************************************************/ +/*! + @brief Returns the numeric event value mapped to a sensor event. + @param sensor_type + The SensorType. + @param event + The sensors_event_t event. + @returns The value of the SensorType. +*/ +/***************************************************************************/ +float GetValueFromSensorsEvent(wippersnapper_sensor_SensorType sensor_type, + sensors_event_t *event) { + float value = 0.0; + switch (sensor_type) { + case wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE: + value = event->temperature; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT: + value = event->temperature; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE: + value = event->temperature; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT: + value = event->temperature; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW: + value = event->data[0]; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_RELATIVE_HUMIDITY: + value = event->relative_humidity; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_PRESSURE: + value = event->pressure; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE: + value = event->voltage; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_CURRENT: + value = event->current; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_CO2: + value = event->CO2; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_ECO2: + value = event->eCO2; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_TVOC: + value = event->tvoc; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_VOC_INDEX: + value = event->voc_index; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_NOX_INDEX: + value = event->nox_index; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_PM10_STD: + value = event->pm10_std; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_PM25_STD: + value = event->pm25_std; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_PM100_STD: + value = event->pm100_std; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_GAS_RESISTANCE: + value = event->gas_resistance; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_ALTITUDE: + value = event->altitude; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_UNITLESS_PERCENT: + value = event->unitless_percent; + break; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_LIGHT: + value = event->light; + break; + default: + value = 0.0; + break; + } + return value; +} + +/****************************************************************************/ +/*! + @brief Decodes a I2cDeviceRemove message from an input stream. + @param stream + A pointer to the pb_istream_t stream. + @returns True if the I2cDeviceRemove message was decoded successfully, + False otherwise. +*/ +/****************************************************************************/ +bool I2cModel::DecodeI2cDeviceRemove(pb_istream_t *stream) { + _msg_i2c_device_remove = wippersnapper_i2c_I2cDeviceRemove_init_default; + return pb_decode(stream, wippersnapper_i2c_I2cDeviceRemove_fields, + &_msg_i2c_device_remove); +} + +/**********************************************************************/ +/*! + @brief Returns a pointer to the I2cDeviceRemove message. + @returns Pointer to the I2cDeviceRemove message. +*/ +/**********************************************************************/ +wippersnapper_i2c_I2cDeviceRemove *I2cModel::GetI2cDeviceRemoveMsg() { + return &_msg_i2c_device_remove; +} + +/***************************************************************************/ +/*! + @brief Decodes a I2cDeviceAddReplace message from an input stream. + @param stream + A pointer to the pb_istream_t stream. + @returns True if the stream was decoded successfully, False otherwise. +*/ +/***************************************************************************/ +bool I2cModel::DecodeI2cDeviceAddReplace(pb_istream_t *stream) { + _msg_i2c_device_add_replace = + wippersnapper_i2c_I2cDeviceAddOrReplace_init_default; + return pb_decode(stream, wippersnapper_i2c_I2cDeviceAddOrReplace_fields, + &_msg_i2c_device_add_replace); +} + +/**********************************************************************/ +/*! + @brief Returns a pointer to the I2cDeviceAddOrReplace message. + @returns Pointer to the I2cDeviceAddOrReplace message. +*/ +/**********************************************************************/ +wippersnapper_i2c_I2cDeviceAddOrReplace * +I2cModel::GetI2cDeviceAddOrReplaceMsg() { + return &_msg_i2c_device_add_replace; +} + +/***************************************************************************/ +/*! + @brief Encodes a I2cDeviceAddedOrReplaced message. + @param device_descriptor + The I2cDeviceDescriptor message. + @param bus_status + The I2cBusStatus message. + @param device_status + The I2cDeviceStatus message. + @returns True if the message was encoded successfully, False otherwise. +*/ +/***************************************************************************/ +bool I2cModel::encodeMsgI2cDeviceAddedorReplaced( + wippersnapper_i2c_I2cDeviceDescriptor device_descriptor, + wippersnapper_i2c_I2cBusStatus bus_status, + wippersnapper_i2c_I2cDeviceStatus device_status) { + size_t sz_msg; + + // Fill I2cDeviceAddedOrReplaced message + _msg_i2c_device_added_replaced = + wippersnapper_i2c_I2cDeviceAddedOrReplaced_init_zero; + _msg_i2c_device_added_replaced.has_i2c_device_description = true; + _msg_i2c_device_added_replaced.i2c_device_description = device_descriptor; + _msg_i2c_device_added_replaced.i2c_bus_status = bus_status; + _msg_i2c_device_added_replaced.i2c_device_status = device_status; + + // Encode message + if (!pb_get_encoded_size(&sz_msg, + wippersnapper_i2c_I2cDeviceAddedOrReplaced_fields, + &_msg_i2c_device_added_replaced)) + return false; + + uint8_t buf[sz_msg]; + pb_ostream_t msg_stream = pb_ostream_from_buffer(buf, sizeof(buf)); + return pb_encode(&msg_stream, + wippersnapper_i2c_I2cDeviceAddedOrReplaced_fields, + &_msg_i2c_device_added_replaced); +} + +/**********************************************************************/ +/*! + @brief Returns a pointer to the I2cDeviceAddedOrReplaced message. + @returns Pointer to the I2cDeviceAddedOrReplaced message. +*/ +/**********************************************************************/ +wippersnapper_i2c_I2cDeviceAddedOrReplaced * +I2cModel::GetMsgI2cDeviceAddedOrReplaced() { + return &_msg_i2c_device_added_replaced; +} + +/**********************************************************************/ +/*! + @brief Clears the I2cDeviceEvent message. +*/ +/**********************************************************************/ +void I2cModel::ClearI2cDeviceEvent() { + _msg_i2c_device_event = wippersnapper_i2c_I2cDeviceEvent_init_zero; + _msg_i2c_device_event.i2c_device_events_count = 0; +} + +/**********************************************************************/ +/*! + @brief Sets the I2cDeviceEvent message's device description. + @param bus_scl + The SCL bus. + @param bus_sda + The SDA bus. + @param addr_device + The device address. + @param addr_mux + The MUX address. + @param mux_channel + The MUX channel. +*/ +/**********************************************************************/ +void I2cModel::SetI2cDeviceEventDeviceDescripton(const char *bus_scl, + const char *bus_sda, + uint32_t addr_device, + uint32_t addr_mux, + uint32_t mux_channel) { + _msg_i2c_device_event.has_i2c_device_description = true; + strcpy(_msg_i2c_device_event.i2c_device_description.i2c_bus_scl, bus_scl); + strcpy(_msg_i2c_device_event.i2c_device_description.i2c_bus_sda, bus_sda); + _msg_i2c_device_event.i2c_device_description.i2c_device_address = addr_device; + _msg_i2c_device_event.i2c_device_description.i2c_mux_address = addr_mux; + _msg_i2c_device_event.i2c_device_description.i2c_mux_channel = mux_channel; +} + +/***************************************************************************/ +/*! + @brief Adds a SensorEvent to the I2cDeviceEvent message. + @param event + The sensors_event_t event. + @param sensor_type + The SensorType. + @returns True if the SensorEvent was added successfully, False otherwise. +*/ +/***************************************************************************/ +bool I2cModel::AddI2cDeviceSensorEvent( + sensors_event_t &event, wippersnapper_sensor_SensorType sensor_type) { + if (_msg_i2c_device_event.i2c_device_events_count >= MAX_DEVICE_EVENTS) + return false; // Maximum amount of events reached + + _msg_i2c_device_event + .i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] + .type = sensor_type; + float value = GetValueFromSensorsEvent(sensor_type, &event); + _msg_i2c_device_event + .i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] + .value.float_value = value; + + _msg_i2c_device_event.i2c_device_events_count++; + return true; +} + +/***************************************************************************/ +/*! + @brief Encodes an I2cDeviceEvent message. + @returns True if the message was encoded successfully, False otherwise. +*/ +/***************************************************************************/ +bool I2cModel::EncodeI2cDeviceEvent() { + size_t sz_msg; + if (!pb_get_encoded_size(&sz_msg, wippersnapper_i2c_I2cDeviceEvent_fields, + &_msg_i2c_device_event)) + return false; + + uint8_t buf[sz_msg]; + pb_ostream_t msg_stream = pb_ostream_from_buffer(buf, sizeof(buf)); + return pb_encode(&msg_stream, wippersnapper_i2c_I2cDeviceEvent_fields, + &_msg_i2c_device_event); +} + +/**********************************************************************/ +/*! + @brief Returns a pointer to the I2cDeviceEvent message. + @returns Pointer to the I2cDeviceEvent message. +*/ +/**********************************************************************/ +wippersnapper_i2c_I2cDeviceEvent *I2cModel::GetI2cDeviceEvent() { + return &_msg_i2c_device_event; +} \ No newline at end of file diff --git a/src/components/i2c/model.h b/src/components/i2c/model.h new file mode 100644 index 000000000..c1d3de35f --- /dev/null +++ b/src/components/i2c/model.h @@ -0,0 +1,62 @@ +/*! + * @file model.h + * + * Provides high-level interfaces for messages within i2c.proto. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2025 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_I2C_MODEL_H +#define WS_I2C_MODEL_H +#include "Wippersnapper_V2.h" +#include +#define MAX_DEVICE_EVENTS \ + 15 ///< Maximum number of SensorEvents within I2cDeviceEvent + +/**************************************************************************/ +/*! + @brief Provides an interface for creating, encoding, and parsing + messages from i2c.proto. +*/ +/**************************************************************************/ +class I2cModel { +public: + I2cModel(); + ~I2cModel(); + bool DecodeI2cDeviceAddReplace(pb_istream_t *stream); + wippersnapper_i2c_I2cDeviceRemove *GetI2cDeviceRemoveMsg(); + bool DecodeI2cDeviceRemove(pb_istream_t *stream); + wippersnapper_i2c_I2cDeviceAddOrReplace *GetI2cDeviceAddOrReplaceMsg(); + bool encodeMsgI2cDeviceAddedorReplaced( + wippersnapper_i2c_I2cDeviceDescriptor i2c_device_description, + wippersnapper_i2c_I2cBusStatus i2c_bus_status, + wippersnapper_i2c_I2cDeviceStatus i2c_device_status); + wippersnapper_i2c_I2cDeviceAddedOrReplaced *GetMsgI2cDeviceAddedOrReplaced(); + // Device Event Message API + void ClearI2cDeviceEvent(); + void SetI2cDeviceEventDeviceDescripton(const char *bus_scl, + const char *bus_sda, + uint32_t addr_device, + uint32_t addr_mux, + uint32_t mux_channel); + bool AddI2cDeviceSensorEvent(sensors_event_t &event, + wippersnapper_sensor_SensorType sensor_type); + bool EncodeI2cDeviceEvent(); + wippersnapper_i2c_I2cDeviceEvent *GetI2cDeviceEvent(); + +private: + wippersnapper_i2c_I2cBusScan _msg_i2c_bus_scan; + wippersnapper_i2c_I2cBusScanned _msg_i2c_bus_scanned; + wippersnapper_i2c_I2cDeviceAddOrReplace _msg_i2c_device_add_replace; + wippersnapper_i2c_I2cDeviceAddedOrReplaced _msg_i2c_device_added_replaced; + wippersnapper_i2c_I2cDeviceRemove _msg_i2c_device_remove; + wippersnapper_i2c_I2cDeviceRemoved _msg_i2c_device_removed; + wippersnapper_i2c_I2cDeviceEvent _msg_i2c_device_event; +}; +#endif // WS_I2C_MODEL_H \ No newline at end of file diff --git a/src/components/ledc/drivers/README.txt b/src/components/ledc/drivers/README.txt deleted file mode 100644 index 2fe33d948..000000000 --- a/src/components/ledc/drivers/README.txt +++ /dev/null @@ -1 +0,0 @@ -These files are drivers that interface directly with WipperSnapper's ESP32 LEDC peripheral manager, `ws_ledc`. \ No newline at end of file diff --git a/src/components/ledc/drivers/servo/ws_ledc_servo.cpp b/src/components/ledc/drivers/servo/ws_ledc_servo.cpp deleted file mode 100644 index e4095aa22..000000000 --- a/src/components/ledc/drivers/servo/ws_ledc_servo.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/*! - * @file ws_ledc_servo.cpp - * - * Driver for ESP32 servo control using the WipperSnapper - * LEDC peripheral manager API. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Written by Brent Rubell for Adafruit Industries, 2022. - * - * writeMicroseconds calculation from ESP32Servo - * https://github.com/madhephaestus/ESP32Servo/blob/master/src/ESP32Servo.cpp - * Copyright (c) 2017 John K. Bennett. - * - * - * GNU Lesser General Public License, all text here must be included in any - * redistribution. - * - */ -#if defined(ARDUINO_ARCH_ESP32) -#include "ws_ledc_servo.h" - -/**************************************************************************/ -/*! - @brief Constructor. -*/ -/**************************************************************************/ -ws_ledc_servo::ws_ledc_servo() {} - -/**************************************************************************/ -/*! - @brief Destructor -*/ -/**************************************************************************/ -ws_ledc_servo::~ws_ledc_servo() { - detach(); // detach the active pin -} - -/**************************************************************************/ -/*! - @brief Sets a LEDC driver for use with servo objects. - @param ledcManager Pointer to LEDC driver. -*/ -/**************************************************************************/ -void ws_ledc_servo::setLEDCDriver(ws_ledc *ledcManager) { - _ledcMgr = ledcManager; -} - -/**************************************************************************/ -/*! - @brief Attaches a servo object to a pin. - @param pin Desired GPIO pin. - @param minPulseWidth Minimum pulsewidth, in uS. - @param maxPulseWidth Maximum pulsewidth, in uS. - @param servoFreq Desired servo frequency, in Hz. - @returns Channel number if a servo is successfully attached to a pin, - otherwise 255. -*/ -/**************************************************************************/ -uint8_t ws_ledc_servo::attach(int pin, int minPulseWidth, int maxPulseWidth, - int servoFreq) { - // Attempt to attach a pin to ledc channel - if (!_ledcMgr->attachPin((uint8_t)pin, (uint32_t)servoFreq, LEDC_TIMER_WIDTH)) - return 255; - // configure the servo object and assign it to a pin - _servo.Pin.nbr = pin; - _servo.Pin.isActive = true; - _minPulseWidth = minPulseWidth; - _maxPulseWidth = maxPulseWidth; - return 1; -} - -/**************************************************************************/ -/*! - @brief Detaches the servo (ledc timer) and de-allocates a servo - object. -*/ -/**************************************************************************/ -void ws_ledc_servo::detach() { - _ledcMgr->detachPin(_servo.Pin.nbr); - _servo.Pin.isActive = false; -} - -/**************************************************************************/ -/*! - @brief Returns if the servo is attached to a ledc timer - @returns True if the servo is attached to a timer, False otherwise. -*/ -/**************************************************************************/ -bool ws_ledc_servo::attached() { return _servo.Pin.isActive; } - -/**************************************************************************/ -/*! - @brief Writes the pulse width to the connected servo pin. - @param value Desired pulse width, in microseconds. -*/ -/**************************************************************************/ -void ws_ledc_servo::writeMicroseconds(int value) { - // are we attached to a pin? - if (!attached()) { - return; - } - - // out-of-bounds check, scale value - if (value < _minPulseWidth) - value = _minPulseWidth; - if (value > _maxPulseWidth) - value = _maxPulseWidth; - - // formula from ESP32Servo library - // https://github.com/madhephaestus/ESP32Servo/blob/master/src/ESP32Servo.cpp - // count = (pulse_high_width / (pulse_period/2**timer_width)) - // 50Hz servo = 20ms pulse_period - uint32_t count = - ((double)value / ((double)20000 / (double)pow(2, LEDC_TIMER_WIDTH))); - _ledcMgr->setDuty(_servo.Pin.nbr, count); -} -#endif // ARDUINO_ARCH_ESP32 \ No newline at end of file diff --git a/src/components/ledc/drivers/servo/ws_ledc_servo.h b/src/components/ledc/drivers/servo/ws_ledc_servo.h deleted file mode 100644 index c3bdfc389..000000000 --- a/src/components/ledc/drivers/servo/ws_ledc_servo.h +++ /dev/null @@ -1,75 +0,0 @@ -/*! - * @file ws_ledc_servo.h - * - * Driver for ESP32 servo control using the WipperSnapper - * LEDC peripheral manager API. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * - * Brent Rubell for Adafruit Industries 2022 - * - * - * MIT license, all text here must be included in any redistribution. - * - */ -#ifndef WS_ESP32_SERVO -#define WS_ESP32_SERVO - -#include "components/ledc/ws_ledc.h" - -// from https://github.com/arduino-libraries/Servo/blob/master/src/Servo.h -#define MIN_PULSE_WIDTH 544 ///< The shortest pulse sent to a servo -#define MAX_PULSE_WIDTH 2400 ///< The longest pulse sent to a servo -#define INVALID_SERVO 255 ///< Flag indicating an invalid servo index - -#define DEFAULT_SERVO_FREQ 50 ///< default servo frequency -#define LEDC_TIMER_WIDTH \ - 12 ///< timer width to request from LEDC manager component, in bits (NOTE: - ///< While ESP32x can go up to 16 bit timer width, ESP32-S2 does not work - ///< at this resolution. So, for the purposes of keeping this library - ///< compatible with multiple ESP32x platforms, the timer width has been - ///< scaled down to 10 bits and the calculation adjusted accordingly) - -/** Defines a servo attached to a pin */ -typedef struct { - uint8_t nbr; ///< Servo's pin number - uint8_t isActive; ///< True if the servo is enabled -} ServoPin_t; - -/** Defines a ws_ledc_servo object */ -typedef struct { - ServoPin_t Pin; ///< Servo properties -} servo_t; - -class ws_ledc; - -/************************************************************************************************/ -/*! - @brief High-level driver for servos for ESP32/ESP32-Sx/ESP32-Cx. This - driver implements a subset of the functions within the Arduino - servo library, - (https://github.com/arduino-libraries/Servo/blob/master/src/Servo.h). -*/ -/************************************************************************************************/ -class ws_ledc_servo { -public: - ws_ledc_servo(); - ~ws_ledc_servo(); - void setLEDCDriver(ws_ledc *ledcManager); - // The functions below are compatible with - // https://github.com/arduino-libraries/Servo/blob/master/src/Servo.h - uint8_t attach(int pin, int minPulseWidth, int maxPulseWidth, int servoFreq); - bool attached(); - void detach(); - void writeMicroseconds(int value); - -private: - servo_t _servo; ///< ws_ledc_servo object - int _minPulseWidth; ///< Servo's minimum pulse width, in uS. - int _maxPulseWidth; ///< Servo's maximum pulse width, in uS. - ws_ledc *_ledcMgr; -}; -#endif // WS_ESP32_SERVO \ No newline at end of file diff --git a/src/components/ledc/ws_ledc.cpp b/src/components/ledc/ws_ledc.cpp deleted file mode 100644 index 7416077bc..000000000 --- a/src/components/ledc/ws_ledc.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/*! - * @file ws_ledc.cpp - * - * This is the documentation for WipperSnapper's LEDC peripheral - * management API. It is used by drivers like ledc_servo. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Written by Brent Rubell for Adafruit Industries, 2022-2023 - * - * MIT license, all text here must be included in any redistribution. - * - */ -#if defined(ARDUINO_ARCH_ESP32) - -#include "ws_ledc.h" - -/**************************************************************************/ -/*! - @brief Sets up a LEDC pin with given frequency and resolution. - @param pin Desired GPIO pin number. - @param freq Desired timer frequency, in Hz. - @param resolution Desired timer resolution, in bits. - @return True if configuration is successful. False is returned if error - occurs and LEDC channel was not configured. -*/ -/**************************************************************************/ -bool ws_ledc::attachPin(uint8_t pin, uint32_t freq, uint8_t resolution) { - return ledcAttach(pin, freq, resolution); -} - -/**************************************************************************/ -/*! - @brief Detaches a pin from LEDC. - @param pin Desired GPIO pin number. - @return True if successfully detached, False otherwise. -*/ -/**************************************************************************/ -bool ws_ledc::detachPin(uint8_t pin) { return ledcDetach(pin); } - -/**************************************************************************/ -/*! - @brief Arduino AnalogWrite function, but for ESP32's LEDC. - @param pin The desired pin to write to. - @param value The duty cycle. - @return True if PWM value written to LEDC pin, False otherwise. -*/ -/**************************************************************************/ -bool ws_ledc::analogWrite(uint8_t pin, int value) { - if (value > 255 || value < 0) - return false; - - // Calculate duty cycle for the `value` passed in - // (assumes 12-bit resolution, 2^12) - uint32_t dutyCycle = (4095 / 255) * min(value, 255); - - // Call duty cycle write - return setDuty(pin, dutyCycle); -} - -/**************************************************************************/ -/*! - @brief Sets the duty cycle of a LEDC pin. - @param pin Desired GPIO pin to write to. - @param duty Desired duty cycle. - @return True if duty cycle was set, False otherwise. -*/ -/**************************************************************************/ -bool ws_ledc::setDuty(uint8_t pin, uint32_t duty) { - return ledcWrite(pin, duty); -} - -/**************************************************************************/ -/*! - @brief Writes a square wave with a fixed duty cycle and variable - frequency to a pin. Used by piezo buzzers and speakers. - @param pin The desired pin to write to. - @param freq The frequency of the tone, in Hz. - @return The frequency of the LEDC pin. 0 if error occurs and LEDC pin was - not configured. -*/ -/**************************************************************************/ -uint32_t ws_ledc::tone(uint8_t pin, uint32_t freq) { - return ledcWriteTone(pin, freq); -} - -#endif // ARDUINO_ARCH_ESP32 \ No newline at end of file diff --git a/src/components/ledc/ws_ledc.h b/src/components/ledc/ws_ledc.h deleted file mode 100644 index d206767a6..000000000 --- a/src/components/ledc/ws_ledc.h +++ /dev/null @@ -1,60 +0,0 @@ -/*! - * @file ws_ledc.h - * - * High-level interface for ESP32's LED Control (LEDC) peripheral, - * to be used by PWM and Servo drivers. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2022-2023 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ -#ifndef WS_LEDC_H -#define WS_LEDC_H - -#include "Wippersnapper.h" - -#include "esp32-hal-ledc.h" -#include "esp_err.h" - -// forward decl. -class Wippersnapper; - -/**************************************************************************/ -/*! - @brief High-level interface for the ESP32/ESP32-Sx/ESP32-Cx LED - Control (LEDC) peripheral. Instead of specifying a timer or - channel, this class automatically allocates a channel and - associates it with a pin. Underlying esp32-hal-ledc performs - timer management and handles the low-level LEDC peripheral API - calls. -*/ -/**************************************************************************/ -class ws_ledc { -public: - /**************************************************************************/ - /*! - @brief Ctor - */ - /**************************************************************************/ - ws_ledc(){}; - /**************************************************************************/ - /*! - @brief Dtor - */ - /**************************************************************************/ - ~ws_ledc(){}; - bool attachPin(uint8_t pin, uint32_t freq, uint8_t resolution); - bool detachPin(uint8_t pin); - // LEDC-API - bool setDuty(uint8_t pin, uint32_t duty); - bool analogWrite(uint8_t pin, int value); - uint32_t tone(uint8_t pin, uint32_t freq); -}; -extern Wippersnapper WS; - -#endif // ws_ledc_H \ No newline at end of file diff --git a/src/components/pixels/ws_pixels.cpp b/src/components/pixels/ws_pixels.cpp deleted file mode 100644 index a35eb6e42..000000000 --- a/src/components/pixels/ws_pixels.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/*! - * @file ws_pixels.cpp - * - * High-level interface for wippersnapper to manage addressable RGB pixel - * strands - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * - * Written by Brent Rubell for Adafruit Industries, 2022-2023 - * - * MIT license, all text here must be included in any redistribution. - * - */ -#include "ws_pixels.h" - -strand_s strands[MAX_PIXEL_STRANDS]{ - nullptr, - nullptr, - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_UNSPECIFIED, - 0, - 0, - wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_UNSPECIFIED, - -1, - -1, - -1}; ///< Contains all pixel strands used by WipperSnapper - -/**************************************************************************/ -/*! - @brief Destructor -*/ -/**************************************************************************/ -ws_pixels::~ws_pixels() { - // de-allocate all strands - for (size_t i = 0; i < sizeof(strands) / sizeof(strands[0]); i++) - deallocateStrand(i); -} - -/******************************************************************************/ -/*! - @brief Allocates an index of a free strand_t within the strand array. - @returns Index of a free strand_t, ERR_INVALID_STRAND if strand array is - full. -*/ -/******************************************************************************/ -int16_t ws_pixels::allocateStrand() { - for (size_t strandIdx = 0; strandIdx < sizeof(strands) / sizeof(strands[0]); - strandIdx++) { - if (strands[strandIdx].type == - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_UNSPECIFIED) { - return strandIdx; - } - } - return ERR_INVALID_STRAND; -} - -/**************************************************************************/ -/*! - @brief Deallocates a `strand_t` within `strands`, provided an index. - @param strandIdx - The desired index of a `strand_t` within `strands`. -*/ -/**************************************************************************/ -void ws_pixels::deallocateStrand(int16_t strandIdx) { - - // delete the pixel object - if (strands[strandIdx].neoPixelPtr != nullptr) - delete strands[strandIdx].neoPixelPtr; - if ((strands[strandIdx].dotStarPtr != nullptr)) - delete strands[strandIdx].dotStarPtr; - - // re-initialize status pixel (if pixel was prvsly used) - if (strands[strandIdx].pinNeoPixel == getStatusNeoPixelPin() || - strands[strandIdx].pinDotStarData == getStatusDotStarDataPin()) { - initStatusLED(); - } - - // reset the strand - strands[strandIdx] = { - nullptr, - nullptr, - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_UNSPECIFIED, - 0, - 0, - wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_UNSPECIFIED, - -1, - -1, - -1}; -} - -/**************************************************************************/ -/*! - @brief Returns the `neoPixelType` provided the strand's pixelOrder - @param pixelOrder - Desired pixel order, from init. message. - @returns Type of NeoPixel strand, usable by Adafruit_NeoPixel - constructor -*/ -/**************************************************************************/ -neoPixelType ws_pixels::getNeoPixelStrandOrder( - wippersnapper_pixels_v1_PixelsOrder pixelOrder) { - switch (pixelOrder) { - case wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_GRB: - return NEO_GRB + NEO_KHZ800; - case wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_GRBW: - return NEO_GRBW + NEO_KHZ800; - case wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_RGB: - return NEO_RGB + NEO_KHZ800; - case wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_RGBW: - return NEO_RGBW + NEO_KHZ800; - case wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_BRG: - return NEO_BRG + NEO_KHZ800; - default: - return NEO_GRB + NEO_KHZ800; - } -} - -/**************************************************************************/ -/*! - @brief Returns the color order of the DotStar strand. - @param pixelOrder - Desired pixel order, from init. message. - @returns Type of DotStar strand. -*/ -/**************************************************************************/ -uint8_t ws_pixels::getDotStarStrandOrder( - wippersnapper_pixels_v1_PixelsOrder pixelOrder) { - switch (pixelOrder) { - case wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_GRB: - return DOTSTAR_GRB; - case wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_RGB: - return DOTSTAR_RGB; - case wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_BRG: - return DOTSTAR_BRG; - case wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_RBG: - return DOTSTAR_RBG; - case wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_GBR: - return DOTSTAR_GBR; - case wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_BGR: - return DOTSTAR_BGR; - default: - return DOTSTAR_BRG; - } -} - -/**************************************************************************/ -/*! - @brief Creates a PixelsResponse message and publishes it to IO. - @param is_success - True if `addStrand()` succeeded, False otherwise. - @param pixels_pin_data - The strand's data pin.. -*/ -/**************************************************************************/ -void ws_pixels::publishAddStrandResponse(bool is_success, - char *pixels_pin_data) { - // Create response message - wippersnapper_signal_v1_PixelsResponse msgInitResp = - wippersnapper_signal_v1_PixelsResponse_init_zero; - msgInitResp.which_payload = - wippersnapper_signal_v1_PixelsResponse_resp_pixels_create_tag; - // Fill response message - msgInitResp.payload.resp_pixels_create.is_success = is_success; - memcpy(msgInitResp.payload.resp_pixels_create.pixels_pin_data, - pixels_pin_data, sizeof(char) * 6); - - // Encode `wippersnapper_pixels_v1_PixelsCreateResponse` message - memset(WS._buffer_outgoing, 0, sizeof(WS._buffer_outgoing)); - pb_ostream_t ostream = - pb_ostream_from_buffer(WS._buffer_outgoing, sizeof(WS._buffer_outgoing)); - if (!ws_pb_encode(&ostream, wippersnapper_signal_v1_PixelsResponse_fields, - &msgInitResp)) { - WS_DEBUG_PRINTLN("ERROR: Unable to encode " - "wippersnapper_signal_v1_PixelsResponse message!"); - return; - } - - // Publish message to broker - size_t msgSz; - pb_get_encoded_size(&msgSz, wippersnapper_signal_v1_PixelsResponse_fields, - &msgInitResp); - WS_DEBUG_PRINT("-> wippersnapper_signal_v1_PixelsResponse..."); - WS._mqtt->publish(WS._topic_signal_pixels_device, WS._buffer_outgoing, msgSz, - 1); - WS_DEBUG_PRINTLN("Published!"); -} - -/**************************************************************************/ -/*! - @brief Initializes a strand of addressable RGB Pixels. - @param pixelsCreateReqMsg - Pointer to strand init. request message - @returns True if successfully initialized, False otherwise. -*/ -/**************************************************************************/ -bool ws_pixels::addStrand( - wippersnapper_pixels_v1_PixelsCreateRequest *pixelsCreateReqMsg) { - // attempt to allocate a free strand from array of strands - int16_t strandIdx = allocateStrand(); - if (strandIdx == ERR_INVALID_STRAND) { // unable to allocate a strand - if (pixelsCreateReqMsg->pixels_type == - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_NEOPIXEL) - publishAddStrandResponse(false, pixelsCreateReqMsg->pixels_pin_neopixel); - else if (pixelsCreateReqMsg->pixels_type == - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_DOTSTAR) - publishAddStrandResponse(false, - pixelsCreateReqMsg->pixels_pin_dotstar_data); - return false; - } - - // fill generic members of the strand obj. - strands[strandIdx].type = pixelsCreateReqMsg->pixels_type; - strands[strandIdx].brightness = pixelsCreateReqMsg->pixels_brightness; - strands[strandIdx].numPixels = pixelsCreateReqMsg->pixels_num; - strands[strandIdx].ordering = pixelsCreateReqMsg->pixels_ordering; - - // fill strand pins - if (pixelsCreateReqMsg->pixels_type == - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_NEOPIXEL) { - strands[strandIdx].pinNeoPixel = - atoi(pixelsCreateReqMsg->pixels_pin_neopixel + 1); - } else if (pixelsCreateReqMsg->pixels_type == - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_DOTSTAR) { - strands[strandIdx].pinDotStarData = - atoi(pixelsCreateReqMsg->pixels_pin_dotstar_data + 1); - strands[strandIdx].pinDotStarClock = - atoi(pixelsCreateReqMsg->pixels_pin_dotstar_clock + 1); - } else { - WS_DEBUG_PRINTLN("ERROR: Invalid strand type provided!"); - publishAddStrandResponse(false, pixelsCreateReqMsg->pixels_pin_neopixel); - return false; - } - - // Fill specific members of strand obj. - if (pixelsCreateReqMsg->pixels_type == - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_NEOPIXEL) { - // Release status LED - // is requested pin in-use by the status pixel? - if (getStatusNeoPixelPin() == strands[strandIdx].pinNeoPixel && - WS.lockStatusNeoPixel) - releaseStatusLED(); // release it! - - // Create a new strand of NeoPixels - strands[strandIdx].neoPixelPtr = new Adafruit_NeoPixel( - pixelsCreateReqMsg->pixels_num, strands[strandIdx].pinNeoPixel, - getNeoPixelStrandOrder(pixelsCreateReqMsg->pixels_ordering)); - - // Initialize strand - strands[strandIdx].neoPixelPtr->begin(); - strands[strandIdx].neoPixelPtr->setBrightness( - strands[strandIdx].brightness); - strands[strandIdx].neoPixelPtr->clear(); - strands[strandIdx].neoPixelPtr->show(); - - // Check that we've correctly initialized the strand - if (strands[strandIdx].neoPixelPtr->numPixels() == 0) { - publishAddStrandResponse(false, pixelsCreateReqMsg->pixels_pin_neopixel); - return false; - } - - WS_DEBUG_PRINT("Created NeoPixel strand of length "); - WS_DEBUG_PRINT(pixelsCreateReqMsg->pixels_num); - WS_DEBUG_PRINT(" on GPIO #"); - WS_DEBUG_PRINTLN(pixelsCreateReqMsg->pixels_pin_neopixel); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Pixel] Added NeoPixel strand on Pin %s\n.", - pixelsCreateReqMsg->pixels_pin_neopixel); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - publishAddStrandResponse(true, pixelsCreateReqMsg->pixels_pin_neopixel); - } else if (pixelsCreateReqMsg->pixels_type == - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_DOTSTAR) { - - // release the status dotstar, if it is both in-use and the pin within - // `pixelsCreateReqMsg` - if ((strands[strandIdx].pinDotStarData == getStatusDotStarDataPin()) && - WS.lockStatusDotStar) { - releaseStatusLED(); - } - - // Create Dotstar strand - strands[strandIdx].dotStarPtr = new Adafruit_DotStar( - strands[strandIdx].numPixels, strands[strandIdx].pinDotStarData, - strands[strandIdx].pinDotStarClock, - getDotStarStrandOrder(strands[strandIdx].ordering)); - - // initialize strand - strands[strandIdx].dotStarPtr->begin(); - strands[strandIdx].dotStarPtr->setBrightness(strands[strandIdx].brightness); - strands[strandIdx].dotStarPtr->clear(); - strands[strandIdx].dotStarPtr->show(); - - // post-init sanity check - if (strands[strandIdx].dotStarPtr->numPixels() == 0) { - publishAddStrandResponse(false, - pixelsCreateReqMsg->pixels_pin_dotstar_data); - return false; - } - - WS_DEBUG_PRINT("Created DotStar strand of length "); - WS_DEBUG_PRINT(strands[strandIdx].numPixels); - WS_DEBUG_PRINT(" on Data GPIO #"); - WS_DEBUG_PRINTLN(strands[strandIdx].pinDotStarData); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Pixel] Added NeoPixel strand on Pin %s\n.", - pixelsCreateReqMsg->pixels_pin_neopixel); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - publishAddStrandResponse(true, pixelsCreateReqMsg->pixels_pin_dotstar_data); - } else { - WS_DEBUG_PRINTLN("ERROR: Invalid strand type provided!"); - publishAddStrandResponse(false, - pixelsCreateReqMsg->pixels_pin_dotstar_data); - return false; - } - - return true; -} - -/**************************************************************************/ -/*! - @brief Obtains the index of a `strand_t` within array of `strands`. - @param dataPin - strand_t's data dataPin - @param type - Type of strand_t, NeoPixel or DotStar. - @returns The index of a strand_t if within strands[], - ERR_INVALID_STRAND otherwise. -*/ -/**************************************************************************/ -int ws_pixels::getStrandIdx(int16_t dataPin, - wippersnapper_pixels_v1_PixelsType type) { - for (size_t strandIdx = 0; strandIdx < sizeof(strands) / sizeof(strands[0]); - strandIdx++) { - if (type == wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_NEOPIXEL && - strands[strandIdx].pinNeoPixel == dataPin) - return strandIdx; - if (type == wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_DOTSTAR && - strands[strandIdx].pinDotStarData == dataPin) - return strandIdx; - } - return ERR_INVALID_STRAND; -} - -/**************************************************************************/ -/*! - @brief Deletes a `strand_t` from `strands`, deinitializes a strand, - and frees its resources. - @param pixelsDeleteMsg - Protobuf message from Adafruit IO containing a - `wippersnapper_pixels_v1_PixelsDeleteRequest`. -*/ -/**************************************************************************/ -void ws_pixels::deleteStrand( - wippersnapper_pixels_v1_PixelsDeleteRequest *pixelsDeleteMsg) { - int strandIdx = getStrandIdx(atoi(pixelsDeleteMsg->pixels_pin_data + 1), - pixelsDeleteMsg->pixels_type); - if (strandIdx == ERR_INVALID_STRAND) { - WS_DEBUG_PRINTLN("ERROR: Strand not found, unable to delete strand!"); - return; - } - // deallocate and release resources of strand object - deallocateStrand(strandIdx); - - WS_DEBUG_PRINT("Deleted strand on data pin "); - WS_DEBUG_PRINTLN(pixelsDeleteMsg->pixels_pin_data); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Pixel] Deleted strand on pin %s\n.", - pixelsDeleteMsg->pixels_pin_data); - WS._ui_helper->add_text_to_terminal(buffer); -#endif -} - -/**************************************************************************/ -/*! - @brief Gets the gamma-corrected color, provided a pixel_color - @param pixel_color - Strand's color from Adafruit IO. - @param strand - Desired strand struct. to access. - @returns A gamma-corrected strand color -*/ -/**************************************************************************/ -uint32_t ws_pixels::getGammaCorrectedColor(uint32_t pixel_color, - strand_s strand) { - if (strand.neoPixelPtr != nullptr) { - return strand.neoPixelPtr->gamma32(pixel_color); - } else if (strand.dotStarPtr != nullptr) { - return strand.dotStarPtr->gamma32(pixel_color); - } else { - WS_DEBUG_PRINTLN( - "ERROR: Unable to perform gamma correction, unknown strand type!"); - return 0; - } -} - -/**************************************************************************/ -/*! - @brief Writes a color from Adafruit IO to a strand of - addressable pixels - @param pixelsWriteMsg - Protobuf message from Adafruit IO containing a - `wippersnapper_pixels_v1_PixelsWriteRequest`. -*/ -/**************************************************************************/ -void ws_pixels::fillStrand( - wippersnapper_pixels_v1_PixelsWriteRequest *pixelsWriteMsg) { - - // Get index of pixel strand - int strandIdx = getStrandIdx(atoi(pixelsWriteMsg->pixels_pin_data + 1), - pixelsWriteMsg->pixels_type); - if (strandIdx == ERR_INVALID_STRAND) { - WS_DEBUG_PRINTLN( - "ERROR: Pixel strand not found, can not write a color to the strand!"); - return; - } - - uint32_t rgbColorGamma = - getGammaCorrectedColor(pixelsWriteMsg->pixels_color, strands[strandIdx]); - - WS_DEBUG_PRINT("Filling color: "); - WS_DEBUG_PRINTLN(pixelsWriteMsg->pixels_color); - -#ifdef USE_DISPLAY - char buffer[100]; - snprintf(buffer, 100, "[Pixel] Filling strand on pin %s with color %u\n", - pixelsWriteMsg->pixels_pin_data, - (unsigned int)pixelsWriteMsg->pixels_color); - WS._ui_helper->add_text_to_terminal(buffer); -#endif - - if (pixelsWriteMsg->pixels_type == - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_NEOPIXEL) { - strands[strandIdx].neoPixelPtr->fill(rgbColorGamma); - strands[strandIdx].neoPixelPtr->show(); - } else if (pixelsWriteMsg->pixels_type == - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_DOTSTAR) { - strands[strandIdx].dotStarPtr->fill(rgbColorGamma); - strands[strandIdx].dotStarPtr->show(); - } else { - WS_DEBUG_PRINTLN("ERROR: Unable to determine pixel type to write to!"); - } -} \ No newline at end of file diff --git a/src/components/pixels/ws_pixels.h b/src/components/pixels/ws_pixels.h deleted file mode 100644 index 9fbe98618..000000000 --- a/src/components/pixels/ws_pixels.h +++ /dev/null @@ -1,72 +0,0 @@ -/*! - * @file ws_pixels.h - * - * High-level interface for wippersnapper to manage addressable RGB pixel - * strands - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * - * Brent Rubell for Adafruit Industries, 2022-2023 - * - * - * MIT license, all text here must be included in any redistribution. - * - */ -#ifndef WS_PIXELS -#define WS_PIXELS - -#include "Wippersnapper.h" - -#define MAX_PIXEL_STRANDS \ - 5 ///< Maximum number of pixel strands connected to a WipperSnapper device - -#define ERR_INVALID_STRAND -1 ///< Invalid strand index - -/** Object representation of a strand of pixels */ -struct strand_s { - Adafruit_NeoPixel *neoPixelPtr; ///< Ptr to a NeoPixel object - Adafruit_DotStar *dotStarPtr; ///< Ptr to a DotStar object - wippersnapper_pixels_v1_PixelsType - type; ///< Type of strand (DotStar, NeoPixel) - uint8_t brightness; ///< Strand brightness (0 to 255) - uint16_t numPixels; ///< Number of pixels on strand - wippersnapper_pixels_v1_PixelsOrder ordering; ///< Color order of strand - int16_t pinNeoPixel; ///< NeoPixel strand data pin - int16_t pinDotStarData; ///< DotStar strand data pin - int16_t pinDotStarClock; ///< DotStar strand clock pin -}; - -class Wippersnapper; ///< friend class -/**************************************************************************/ -/*! - @brief Class for managing and interfacing with strands of addressable - RGB LED pixels. -*/ -/**************************************************************************/ -class ws_pixels { -public: - ws_pixels(); - ~ws_pixels(); - - // Protobuf RPC - bool - addStrand(wippersnapper_pixels_v1_PixelsCreateRequest *pixelsCreateReqMsg); - void - deleteStrand(wippersnapper_pixels_v1_PixelsDeleteRequest *pixelsDeleteMsg); - void fillStrand(wippersnapper_pixels_v1_PixelsWriteRequest *pixelsWriteMsg); - - // Helpers - int16_t allocateStrand(); - void deallocateStrand(int16_t strandIdx); - int getStrandIdx(int16_t pin, wippersnapper_pixels_v1_PixelsType type); - neoPixelType - getNeoPixelStrandOrder(wippersnapper_pixels_v1_PixelsOrder pixelOrder); - uint8_t getDotStarStrandOrder(wippersnapper_pixels_v1_PixelsOrder pixelOrder); - void publishAddStrandResponse(bool is_success, char *pixels_pin_data); - uint32_t getGammaCorrectedColor(uint32_t pixel_color, strand_s strand); -}; -extern Wippersnapper WS; -#endif // WS_PIXELS \ No newline at end of file diff --git a/src/components/pwm/ws_pwm.cpp b/src/components/pwm/ws_pwm.cpp deleted file mode 100644 index 2e3ba0dc2..000000000 --- a/src/components/pwm/ws_pwm.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/*! - * @file ws_pwm.cpp - * - * PWM component for WipperSnapper. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * - * Written by Brent Rubell for Adafruit Industries, 2022. - * - * MIT license, all text here must be included in any redistribution. - * - */ -#include "ws_pwm.h" - -/**************************************************************************/ -/*! - @brief Constructor for non-ESP32 platforms. -*/ -/**************************************************************************/ -ws_pwm::ws_pwm() {} - -/**************************************************************************/ -/*! - @brief Constructor for ESP32 platforms. - @param ledcManager Pointer to LEDC driver. -*/ -/**************************************************************************/ -ws_pwm::ws_pwm(ws_ledc *ledcManager) { _ledcMgr = ledcManager; } - -/**************************************************************************/ -/*! - @brief Destructor -*/ -/**************************************************************************/ -ws_pwm::~ws_pwm() { _ledcMgr = nullptr; } - -/******************************************************************/ -/*! - @brief Attaches a PWM pin. - @param pin GPIO pin. - @param freq PWM frequency, in Hz. - @param resolution PWM resolution, in bytes. - @return True if PWM pin is successfully attached to a timer, - otherwise False. -*/ -/******************************************************************/ -bool ws_pwm::attach(uint8_t pin, double freq, uint8_t resolution) { - // Future TODO: Maybe this function should be within #ifdef for ARCH_ESP32 - bool is_attached = true; -#if defined(ARDUINO_ARCH_ESP32) - bool rc = _ledcMgr->attachPin(pin, (uint32_t)freq, resolution); - if (!rc) - return false; -#else - (void)pin; // marking as unused parameter to avoid compiler warning - (void)freq; // marking as unused parameter to avoid compiler warning - (void)resolution; // marking as unused parameter to avoid compiler warning -#endif - return is_attached; // always true on non-esp32 -} - -/************************************************/ -/*! - @brief Detaches a PWM pin. - @param pin Desired GPIO pin. -*/ -/************************************************/ -void ws_pwm::detach(uint8_t pin) { -#if defined(ARDUINO_ARCH_ESP32) - // detach pin from LEDC manager - _ledcMgr->detachPin(pin); -#endif - - // "disable" pin's PWM - digitalWrite(pin, LOW); -} - -/******************************************************************/ -/*! - @brief Writes a duty cycle to a pin with a fixed freq of 5kHz - @param pin GPIO pin to write to. - @param dutyCycle Desired duty cycle to write to a pin. -*/ -/******************************************************************/ -void ws_pwm::writeDutyCycle(uint8_t pin, int dutyCycle) { -#if defined(ARDUINO_ARCH_ESP32) - _ledcMgr->analogWrite(pin, dutyCycle); -#elif defined(ARDUINO_ESP8266_ADAFRUIT_HUZZAH) && defined(STATUS_LED_PIN) - // Adafruit Feather ESP8266's analogWrite() is inverted because its LED pin is - // reverse-wired - analogWrite(pin, 255 - dutyCycle); -#else - analogWrite(pin, dutyCycle); -#endif -} - -/******************************************************************/ -/*! - @brief Writes a frequency to a pin with a fixed duty cycle. - @param pin GPIO pin to write to. - @param freq Desired frequency to write to a pin, in Hz. -*/ -/******************************************************************/ -void ws_pwm::writeTone(uint8_t pin, uint32_t freq) { -#if defined(ARDUINO_ARCH_ESP32) - _ledcMgr->tone(pin, freq); -#else - tone(pin, freq); -#endif -} - -/******************************************************************/ -/*! - @brief Stops a square wave generated by writeTone(). - @param pin GPIO pin to stop generating the tone on. -*/ -/******************************************************************/ -void ws_pwm::noTone(uint8_t pin) { -#if defined(ARDUINO_ARCH_ESP32) - _ledcMgr->tone(pin, 0); -#else - noTone(pin); -#endif -} \ No newline at end of file diff --git a/src/components/pwm/ws_pwm.h b/src/components/pwm/ws_pwm.h deleted file mode 100644 index 6a201b2ce..000000000 --- a/src/components/pwm/ws_pwm.h +++ /dev/null @@ -1,50 +0,0 @@ -/*! - * @file ws_servo.h - * - * High-level interface for wippersnapper to manage servo objects - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * - * Brent Rubell for Adafruit Industries 2022 - * - * - * MIT license, all text here must be included in any redistribution. - * - */ -#ifndef WS_PWM -#define WS_PWM - -#include "Wippersnapper.h" - -#ifdef ARDUINO_ARCH_ESP32 -#include "components/ledc/ws_ledc.h" -#endif - -class Wippersnapper; -class ws_ledc; - -/**************************************************************************/ -/*! - @brief Interface for WipperSnapper PWM -*/ -/**************************************************************************/ -class ws_pwm { -public: - ws_pwm(); - ws_pwm(ws_ledc *ledcManager); - ~ws_pwm(); - bool attach(uint8_t pin, double freq, uint8_t resolution); - void detach(uint8_t pin); - void writeDutyCycle(uint8_t pin, int dutyCycle); - void writeTone(uint8_t pin, uint32_t freq); - void noTone(uint8_t pin); - -private: - ws_ledc *_ledcMgr = nullptr; ///< pointer to ws_ledc -}; -extern Wippersnapper WS; - -#endif // WS_PWM \ No newline at end of file diff --git a/src/components/register/Wippersnapper_Register.cpp b/src/components/register/Wippersnapper_Register.cpp deleted file mode 100644 index 522818997..000000000 --- a/src/components/register/Wippersnapper_Register.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/*! - * @file Wippersnapper_Register.cpp - * - * API for registering hardware with the Adafruit.io - * WipperSnapper broker. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2021 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ -#include "Wippersnapper.h" - -extern Wippersnapper WS; - -/****************************************************************************/ -/*! - @brief Encodes hardware registration request message and publishes - the message to the Adafruit IO broker. - @returns True if encoded and/or published successfully, False otherwise. -*/ -/****************************************************************************/ -bool Wippersnapper::encodePubRegistrationReq() { - bool _status; - - WS_DEBUG_PRINT("Encoding registration msg..."); - // Create message object - wippersnapper_description_v1_CreateDescriptionRequest _message = - wippersnapper_description_v1_CreateDescriptionRequest_init_zero; - - // Set machine_name - strcpy(_message.machine_name, WS._boardId); - - // Set MAC address - _message.mac_addr = atoi(WS.sUID); - - // Set version - strcpy(_message.str_version, WS_VERSION); - - // encode registration request message - uint8_t _message_buffer[256]; - pb_ostream_t _msg_stream = - pb_ostream_from_buffer(_message_buffer, sizeof(_message_buffer)); - - _status = ws_pb_encode( - &_msg_stream, - wippersnapper_description_v1_CreateDescriptionRequest_fields, &_message); - size_t _message_len = _msg_stream.bytes_written; - - // verify message - if (!_status) - return _status; - - // pubish message - WS.publish(WS._topic_description, _message_buffer, _message_len, 1); - WS_DEBUG_PRINTLN("Published!"); - WS._boardStatus = WS_BOARD_DEF_SENT; - - return _status; -} - -/****************************************************************************/ -/*! - @brief Polls the broker for the hardware registration response message. - - NOTE: This function is BLOCKING and will trigger a WDT reset - if the message has not arrived. - - NOTE: The registration response msg will arrive - async. at the `cbRegistrationStatus` function - and set the `boardStatus` -*/ -/****************************************************************************/ -void Wippersnapper::pollRegistrationResp() { - // Blocking loop, WDT reset upon failure. - while (WS._boardStatus != WS_BOARD_DEF_OK) { - WS_DEBUG_PRINT("Polling for registration message response..."); - WS_DEBUG_PRINTLN(WS._boardStatus); - statusLEDBlink(WS_LED_STATUS_WAITING_FOR_REG_MSG); - WS._mqtt->processPackets(20); // long-poll - } -} - -/****************************************************************************/ -/*! - @brief Decodes hardware registration response message from the - Adafruit IO MQTT broker and initializes hardware components. - @param data - MQTT message from the Adafruit IO MQTT broker. - @param len - Length of data from the Adafruit IO MQTT broker. -*/ -/****************************************************************************/ -void Wippersnapper::decodeRegistrationResp(char *data, uint16_t len) { - WS_DEBUG_PRINTLN("GOT Registration Response Message:"); - uint8_t buffer[len]; - memcpy(buffer, data, len); - - // init. CreateDescriptionResponse message - wippersnapper_description_v1_CreateDescriptionResponse message = - wippersnapper_description_v1_CreateDescriptionResponse_init_zero; - - // create input stream for buffer - pb_istream_t stream = pb_istream_from_buffer(buffer, len); - // decode the stream - if (!ws_pb_decode( - &stream, - wippersnapper_description_v1_CreateDescriptionResponse_fields, - &message)) { - WS.haltError("Could not decode registration response"); - } - // Decode registration response message - if (message.response == - wippersnapper_description_v1_CreateDescriptionResponse_Response_RESPONSE_OK) { - WS_DEBUG_PRINTLN("Hardware Response Msg:") - WS_DEBUG_PRINT("\tGPIO Pins: "); - WS_DEBUG_PRINTLN(message.total_gpio_pins); - WS_DEBUG_PRINT("\tAnalog Pins: "); - WS_DEBUG_PRINTLN(message.total_analog_pins); - WS_DEBUG_PRINT("\tReference voltage: "); - WS_DEBUG_PRINT(message.reference_voltage); - WS_DEBUG_PRINTLN("v"); - // Initialize Digital IO class - WS._digitalGPIO = new Wippersnapper_DigitalGPIO(message.total_gpio_pins); - // Initialize Analog IO class - WS._analogIO = new Wippersnapper_AnalogIO(message.total_analog_pins, - message.reference_voltage); - WS._boardStatus = WS_BOARD_DEF_OK; - - // Publish RegistrationComplete message to broker - wippersnapper_description_v1_RegistrationComplete msg = - wippersnapper_description_v1_RegistrationComplete_init_zero; - msg.is_complete = true; - - // encode registration request message - uint8_t _message_buffer[128]; - pb_ostream_t _msg_stream = - pb_ostream_from_buffer(_message_buffer, sizeof(_message_buffer)); - - bool _status = ws_pb_encode( - &_msg_stream, wippersnapper_description_v1_RegistrationComplete_fields, - &msg); - size_t _message_len = _msg_stream.bytes_written; - - // verify message encoded correctly - if (!_status) { - WS._boardStatus = WS_BOARD_DEF_INVALID; - return; - } - - // Publish message - WS.publish(_topic_description_status_complete, _message_buffer, - _message_len, 1); - WS_DEBUG_PRINTLN("Completed registration process, configuration next!"); - - } else { - WS._boardStatus = WS_BOARD_DEF_INVALID; - } -} \ No newline at end of file diff --git a/src/components/sensor/model.cpp b/src/components/sensor/model.cpp new file mode 100644 index 000000000..85f1cb3d3 --- /dev/null +++ b/src/components/sensor/model.cpp @@ -0,0 +1,34 @@ +/*! + * @file model.cpp + * + * Model for the sensor.proto message. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "model.h" + +/***********************************************************************/ +/*! + @brief SensorModel constructor +*/ +/***********************************************************************/ +SensorModel::SensorModel() { + _msg_sensor_event = wippersnapper_sensor_SensorEvent_init_zero; +} + +/***********************************************************************/ +/*! + @brief SensorModel destructor +*/ +/***********************************************************************/ +SensorModel::~SensorModel() { + // Zero-out the SensorEvent message + _msg_sensor_event = wippersnapper_sensor_SensorEvent_init_zero; +} \ No newline at end of file diff --git a/src/components/sensor/model.h b/src/components/sensor/model.h new file mode 100644 index 000000000..aa014c48c --- /dev/null +++ b/src/components/sensor/model.h @@ -0,0 +1,34 @@ +/*! + * @file model.h + * + * Model for the sensor.proto message. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_SENSOR_MODEL_H +#define WS_SENSOR_MODEL_H +#include "Wippersnapper_V2.h" +#include "protos/sensor.pb.h" + +/**************************************************************************/ +/*! + @brief Provides an interface for creating, encoding, and parsing + messages from sensor.proto. +*/ +/**************************************************************************/ +class SensorModel { +public: + SensorModel(); + ~SensorModel(); + +private: + wippersnapper_sensor_SensorEvent _msg_sensor_event; ///< SensorEvent message +}; +#endif // WS_SENSOR_MODEL_H \ No newline at end of file diff --git a/src/components/servo/ws_servo.cpp b/src/components/servo/ws_servo.cpp deleted file mode 100644 index 23db82a97..000000000 --- a/src/components/servo/ws_servo.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/*! - * @file ws_servo.cpp - * - * High-level servo manager interface for WipperSnapper. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * - * Written by Brent Rubell for Adafruit Industries, 2022. - * - * MIT license, all text here must be included in any redistribution. - * - */ -#include "ws_servo.h" - -/**************************************************************************/ -/*! - @brief Destructor -*/ -/**************************************************************************/ -ws_servo::~ws_servo() { - for (int i = 0; i < MAX_SERVO_NUM; i++) { - // de-allocate servo pins, if attached - if (_servos[i].servoObj->attached()) - _servos[i].servoObj->detach(); - } -} - -/**************************************************************************/ -/*! - @brief Attempts to get the servoComponent for the desired pin. - @param pin Desired GPIO pin. - @returns servoComponent within _servos[] if found, nullptr otherwise. -*/ -/**************************************************************************/ -servoComponent *ws_servo::getServoComponent(uint8_t pin) { - for (size_t i = 0; i < sizeof(_servos) / sizeof(_servos[0]); i++) { - WS_DEBUG_PRINTLN(_servos[i].pin); - if (_servos[i].pin == pin) - return &_servos[i]; - } - WS_DEBUG_PRINT("ERROR: Can not find servo on pin #"); - WS_DEBUG_PRINTLN(pin); - return nullptr; -} - -/**************************************************************************/ -/*! - @brief Attaches a servo object to a pin. - @param pin Desired GPIO pin. - @param minPulseWidth Minimum pulsewidth, in uS. - @param maxPulseWidth Maximum pulsewidth, in uS. - @param freq Servo Frequency, default is 50Hz - @returns True if a servo is successfully attached to a pin, - False otherwise -*/ -/**************************************************************************/ -bool ws_servo::servo_attach(int pin, int minPulseWidth, int maxPulseWidth, - int freq) { -#ifdef ARDUINO_ARCH_ESP32 - // ESP32/x specific implementation - ws_ledc_servo *servo = new ws_ledc_servo(); - servo->setLEDCDriver(WS._ledc); -#else - // generic Servo.h - Servo *servo = new Servo(); -#endif - - uint16_t rc = ERR_SERVO_ATTACH; -#ifdef ARDUINO_ARCH_ESP32 - rc = servo->attach(pin, minPulseWidth, maxPulseWidth, freq); -#else - (void)freq; // supress warning when we don't use the frequency parameter - rc = servo->attach(pin, minPulseWidth, maxPulseWidth); -#endif - if (rc == ERR_SERVO_ATTACH) - return false; // allocation or pin error - - // Attempt to allocate an unused servo - int servoIdx = -1; - for (int i = 0; i < MAX_SERVO_NUM; i++) { - if (_servos[i].pin == 0) { - servoIdx = i; - break; - } - } - - // create a new servo component storage struct - _servos[servoIdx].servoObj = servo; - _servos[servoIdx].pin = pin; - - // Write the default minimum to a servo - servo_write(_servos[servoIdx].pin, MIN_SERVO_PULSE_WIDTH); - return true; -} - -/**************************************************************************/ -/*! - @brief Detaches a servo from a pin and re-allocates the GPIO pin. - @param pin Desired GPIO pin. -*/ -/**************************************************************************/ -void ws_servo::servo_detach(int pin) { - // attempt to get servoComponent for desired `pin` - servoComponent *servoComponentPtr = getServoComponent(pin); - if (servoComponentPtr == nullptr) - return; - - // reset pin to default value - servoComponentPtr->pin = 0; - // release pin from use by servo object - servoComponentPtr->servoObj->detach(); - // de-init servo object - delete servoComponentPtr->servoObj; -} - -/**************************************************************************/ -/*! - @brief Writes a pulse width to a servo pin. - @param pin Desired GPIO pin. - @param value Desired pulse width, in uS. -*/ -/**************************************************************************/ -void ws_servo::servo_write(int pin, int value) { - // attempt to get servoComponent for desired `pin` - servoComponent *servoComponentPtr = getServoComponent(pin); - if (servoComponentPtr != nullptr) - servoComponentPtr->servoObj->writeMicroseconds(value); -} \ No newline at end of file diff --git a/src/components/servo/ws_servo.h b/src/components/servo/ws_servo.h deleted file mode 100644 index f0c8062a1..000000000 --- a/src/components/servo/ws_servo.h +++ /dev/null @@ -1,76 +0,0 @@ -/*! - * @file ws_servo.h - * - * High-level interface for wippersnapper to manage servo objects - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * - * Brent Rubell for Adafruit Industries 2022 - * - * - * MIT license, all text here must be included in any redistribution. - * - */ -#ifndef WS_SERVO -#define WS_SERVO - -#include "Wippersnapper.h" - -#if defined(ARDUINO_ARCH_ESP32) -#include "components/ledc/drivers/servo/ws_ledc_servo.h" -#else -#include -#endif - -#ifdef ARDUINO_ARCH_RP2040 -#define MAX_SERVO_NUM \ - 8 ///< Maximum number of servo objects for Pico, - ///< https://arduino-pico.readthedocs.io/en/latest/servo.html -#else -#define MAX_SERVO_NUM 16 ///< Maximum number of servo objects -#endif - -#define MIN_SERVO_PULSE_WIDTH 500 ///< Default min. servo pulse width of 500uS -#define ERR_SERVO_ATTACH 255 ///< Error when attempting to attach servo - -#if defined(ARDUINO_ARCH_ESP32) -class ws_ledc_servo; -/** Servo object for ESP32-servo implementation */ -struct servoComponent { - ws_ledc_servo *servoObj = nullptr; ///< Servo object - uint8_t pin = 0; ///< Servo's pin number -}; -#else -/** Servo object for Generic servo implementation */ -struct servoComponent { - Servo *servoObj = nullptr; ///< Servo object - uint8_t pin = 0; ///< Servo's pin number -}; -#endif - -class Wippersnapper; - -/**************************************************************************/ -/*! - @brief Interface for WipperSnapper servo control -*/ -/**************************************************************************/ -class ws_servo { -public: - ws_servo(){}; - ~ws_servo(); - bool servo_attach(int pin, int minPulseWidth, int maxPulseWidth, int freq); - void servo_detach(int pin); - void servo_write(int pin, int value); - servoComponent *getServoComponent(uint8_t pin); - -private: - servoComponent _servos[MAX_SERVO_NUM]; ///< Container of servo objects and - ///< their associated pin #s -}; -extern Wippersnapper WS; - -#endif // WS_SERVO \ No newline at end of file diff --git a/src/components/statusLED/Wippersnapper_StatusLED.cpp b/src/components/statusLED/Wippersnapper_StatusLED.cpp index 47b170462..06d6251bf 100644 --- a/src/components/statusLED/Wippersnapper_StatusLED.cpp +++ b/src/components/statusLED/Wippersnapper_StatusLED.cpp @@ -14,9 +14,9 @@ * */ #include "Wippersnapper_StatusLED.h" -#include "Wippersnapper.h" +#include "Wippersnapper_V2.h" -extern Wippersnapper WS; +extern Wippersnapper_V2 WsV2; #ifdef USE_STATUS_NEOPIXEL Adafruit_NeoPixel *statusPixel = new Adafruit_NeoPixel( STATUS_NEOPIXEL_NUM, STATUS_NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); @@ -35,7 +35,7 @@ Adafruit_DotStar *statusPixelDotStar = /****************************************************************************/ void initStatusLED() { #ifdef USE_STATUS_NEOPIXEL - if (WS.lockStatusNeoPixel == false) { + if (WsV2.lockStatusNeoPixelV2 == false) { #if defined(NEOPIXEL_I2C_POWER) pinMode(NEOPIXEL_I2C_POWER, OUTPUT); digitalWrite(NEOPIXEL_I2C_POWER, HIGH); @@ -52,12 +52,12 @@ void initStatusLED() { STATUS_NEOPIXEL_NUM, STATUS_NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); statusPixel->begin(); statusPixel->show(); // turn OFF all pixels - WS.lockStatusNeoPixel = true; + WsV2.lockStatusNeoPixelV2 = true; } #endif #ifdef USE_STATUS_DOTSTAR - if (WS.lockStatusDotStar == false) { + if (WsV2.lockStatusDotStarV2 == false) { #ifdef STATUS_DOTSTAR_COLOR_ORDER // Board requires a non-default color order in the constructor statusPixelDotStar = new Adafruit_DotStar( @@ -70,7 +70,7 @@ void initStatusLED() { #endif statusPixelDotStar->begin(); statusPixelDotStar->show(); // turn OFF all pixels - WS.lockStatusDotStar = true; + WsV2.lockStatusDotStarV2 = true; } #endif @@ -81,15 +81,16 @@ void initStatusLED() { #if defined(ARDUINO_ESP8266_ADAFRUIT_HUZZAH) analogWrite(STATUS_LED_PIN, 255); #elif defined(ARDUINO_ARCH_ESP32) - WS._pwmComponent->attach(STATUS_LED_PIN, LEDC_BASE_FREQ, LEDC_TIMER_12_BIT); - WS._pwmComponent->writeDutyCycle(STATUS_LED_PIN, 0); // turn OFF + // WsV2._pwmComponent->attach(STATUS_LED_PIN, LEDC_BASE_FREQ, + // LEDC_TIMER_12_BIT); WsV2._pwmComponent->writeDutyCycle(STATUS_LED_PIN, 0); + // // turn OFF #elif defined(ARDUINO_RASPBERRY_PI_PICO_W) digitalWrite(STATUS_LED_PIN, 0); #else analogWrite(STATUS_LED_PIN, 0); #endif - WS.lockStatusLED = true; // set global pin "lock" flag + WsV2.lockStatusLEDV2 = true; // set global pin "lock" flag #endif } @@ -102,20 +103,20 @@ void releaseStatusLED() { #ifdef USE_STATUS_NEOPIXEL delete statusPixel; // Deallocate Adafruit_NeoPixel object, set data pin back // to INPUT. - WS.lockStatusNeoPixel = false; // unlock + WsV2.lockStatusNeoPixelV2 = false; // unlock #endif #ifdef USE_STATUS_DOTSTAR delete statusPixelDotStar; // Deallocate Adafruit_DotStar object, set data pin // back to INPUT. - WS.lockStatusDotStar = false; // unlock + WsV2.lockStatusDotStarV2 = false; // unlock #endif #ifdef USE_STATUS_LED digitalWrite(STATUS_LED_PIN, 0); // turn off pinMode(STATUS_LED_PIN, - INPUT); // "release" for use by setting to input (hi-z) - WS.lockStatusLED = false; // un-set global pin "lock" flag + INPUT); // "release" for use by setting to input (hi-z) + WsV2.lockStatusLEDV2 = false; // un-set global pin "lock" flag #endif } @@ -127,7 +128,12 @@ void releaseStatusLED() { */ /****************************************************************************/ void setStatusLEDBrightness(float brightness) { - WS.status_pixel_brightness = brightness; + // Clamp brightness between 0.0-1.0 (0% to 100%) + if (brightness > 1.0) + brightness = 1.0; + if (brightness < 0.0) + brightness = 0.0; + WsV2.status_pixel_brightnessV2 = brightness; } /****************************************************************************/ @@ -139,14 +145,14 @@ void setStatusLEDBrightness(float brightness) { /****************************************************************************/ void setStatusLEDColor(uint32_t color) { #ifdef USE_STATUS_NEOPIXEL - if (!WS.lockStatusNeoPixel) + if (!WsV2.lockStatusNeoPixelV2) return; // status pixel is in-use elsewhere uint8_t red = (color >> 16) & 0xff; // red uint8_t green = (color >> 8) & 0xff; // green uint8_t blue = color & 0xff; // blue - // map() the WS.status_pixel_brightness - int brightness = WS.status_pixel_brightness * 255.0; + // map() the WsV2.status_pixel_brightnessV2 + int brightness = WsV2.status_pixel_brightnessV2 * 255.0; // flood all neopixels for (int i = 0; i < STATUS_NEOPIXEL_NUM; i++) { statusPixel->setPixelColor(i, brightness * red / 255, @@ -157,14 +163,14 @@ void setStatusLEDColor(uint32_t color) { #endif #ifdef USE_STATUS_DOTSTAR - if (!WS.lockStatusDotStar) + if (!WsV2.lockStatusDotStarV2) return; // status pixel is in-use elsewhere uint8_t red = (color >> 16) & 0xff; // red uint8_t green = (color >> 8) & 0xff; // green uint8_t blue = color & 0xff; // blue - // map() the WS.status_pixel_brightness - int brightness = WS.status_pixel_brightness * 255.0; + // map() the WsV2.status_pixel_brightnessV2 + int brightness = WsV2.status_pixel_brightnessV2 * 255.0; // flood all dotstar pixels for (int i = 0; i < STATUS_DOTSTAR_NUM; i++) { statusPixelDotStar->setPixelColor(i, brightness * red / 255, @@ -175,16 +181,16 @@ void setStatusLEDColor(uint32_t color) { #endif #ifdef USE_STATUS_LED - if (!WS.lockStatusLED) + if (!WsV2.lockStatusLEDV2) return; // status pixel is in-use elsewhere #ifdef ARDUINO_RASPBERRY_PI_PICO_W digitalWrite(STATUS_LED_PIN, color > 0); #else - if (color != BLACK) - WS._pwmComponent->writeDutyCycle( - STATUS_LED_PIN, map(WS.status_pixel_brightness, 0.0, 1.0, 0, 1023)); +/* if (color != BLACK) + WsV2._pwmComponent->writeDutyCycle( + STATUS_LED_PIN, map(WsV2.status_pixel_brightnessV2, 0.0, 1.0, 0, 1023)); else - WS._pwmComponent->writeDutyCycle(STATUS_LED_PIN, 0); + WsV2._pwmComponent->writeDutyCycle(STATUS_LED_PIN, 0); */ #endif #endif } @@ -200,7 +206,7 @@ void setStatusLEDColor(uint32_t color) { /****************************************************************************/ void setStatusLEDColor(uint32_t color, int brightness) { #ifdef USE_STATUS_NEOPIXEL - if (!WS.lockStatusNeoPixel) + if (!WsV2.lockStatusNeoPixelV2) return; // status pixel is in-use elsewhere // parse out the color elements @@ -217,7 +223,7 @@ void setStatusLEDColor(uint32_t color, int brightness) { #endif #ifdef USE_STATUS_DOTSTAR - if (!WS.lockStatusDotStar) + if (!WsV2.lockStatusDotStarV2) return; // status pixel is in-use elsewhere uint8_t red = (color >> 16) & 0xff; // red @@ -233,7 +239,7 @@ void setStatusLEDColor(uint32_t color, int brightness) { #endif #ifdef USE_STATUS_LED - if (!WS.lockStatusLED) + if (!WsV2.lockStatusLEDV2) return; #ifdef ARDUINO_RASPBERRY_PI_PICO_W @@ -242,9 +248,9 @@ void setStatusLEDColor(uint32_t color, int brightness) { if (color != BLACK) { // re-map for pixel as a LED int pulseWidth = map(brightness, 0, 255, 0, 1023); - WS._pwmComponent->writeDutyCycle(STATUS_LED_PIN, pulseWidth); + // WsV2._pwmComponent->writeDutyCycle(STATUS_LED_PIN, pulseWidth); } else { - WS._pwmComponent->writeDutyCycle(STATUS_LED_PIN, 0); + // WsV2._pwmComponent->writeDutyCycle(STATUS_LED_PIN, 0); } #endif #endif @@ -287,7 +293,7 @@ int16_t getStatusDotStarDataPin() { /****************************************************************************/ void statusLEDFade(uint32_t color, int numFades = 3) { // don't fade if our pixel is off - if (WS.status_pixel_brightness == 0.0) + if (WsV2.status_pixel_brightnessV2 == 0.0) return; // pulse `numFades` times @@ -359,12 +365,12 @@ uint32_t ledStatusStateToColor(ws_led_status_t statusState) { /****************************************************************************/ void statusLEDSolid(ws_led_status_t statusState = WS_LED_STATUS_ERROR_RUNTIME) { #ifdef USE_STATUS_LED - if (!WS.lockStatusLED) + if (!WsV2.lockStatusLEDV2) return; #endif #ifdef USE_STATUS_NEOPIXEL - if (!WS.lockStatusNeoPixel) + if (!WsV2.lockStatusNeoPixelV2) return; // status pixel is in-use elsewhere #endif @@ -382,12 +388,12 @@ void statusLEDSolid(ws_led_status_t statusState = WS_LED_STATUS_ERROR_RUNTIME) { /****************************************************************************/ void statusLEDBlink(ws_led_status_t statusState) { #ifdef USE_STATUS_LED - if (!WS.lockStatusLED) + if (!WsV2.lockStatusLEDV2) return; #endif #ifdef USE_STATUS_NEOPIXEL - if (!WS.lockStatusNeoPixel) + if (!WsV2.lockStatusNeoPixelV2) return; // status pixel is in-use elsewhere #endif diff --git a/src/components/uart/drivers/ws_uart_drv.h b/src/components/uart/drivers/ws_uart_drv.h deleted file mode 100644 index 8cdc9f0ef..000000000 --- a/src/components/uart/drivers/ws_uart_drv.h +++ /dev/null @@ -1,175 +0,0 @@ -/*! - * @file ws_uart_drv.h - * - * Base implementation for UART device drivers - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2023 for Adafruit Industries. - * - * MIT license, all text here must be included in any redistribution. - * - */ - -#ifndef WS_UART_DRV_H -#define WS_UART_DRV_H -#include "Wippersnapper.h" -#include - -// ESP8266 platform uses SoftwareSerial -// so does RP2040 (note that this has differences from the pure softwareserial -// library, see: https://arduino-pico.readthedocs.io/en/latest/piouart.html) -#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_RP2040) -#define USE_SW_UART -#include -#else -#include -#endif - -/**************************************************************************/ -/*! - @brief Base class for UART Device Drivers. -*/ -/**************************************************************************/ -class ws_uart_drv { -public: -#ifdef USE_SW_UART - /*******************************************************************************/ - /*! - @brief Initializes a UART device driver. - @param swSerial - Pointer to an instance of a SoftwareSerial object. - @param interval - How often the UART device will be polled, in milliseconds. - */ - /*******************************************************************************/ - ws_uart_drv(SoftwareSerial *swSerial, int32_t interval){}; -#else - /*******************************************************************************/ - /*! - @brief Initializes a UART device driver. - @param hwSerial - Pointer to an instance of a HardwareSerial object. - @param interval - How often the UART device will be polled, in milliseconds. - */ - /*******************************************************************************/ - ws_uart_drv(HardwareSerial *hwSerial, int32_t interval){}; -#endif - ~ws_uart_drv(void) {} - - /*******************************************************************************/ - /*! - @brief Checks if the UART device is ready to be polled at its time - interval. - @returns True if the UART device is ready to be polled, False otherwise. - */ - /*******************************************************************************/ - bool isReady() { - if (millis() - _prvPoll > pollingInterval) { - return true; - } - return false; - } - - /*******************************************************************************/ - /*! - @brief Sets the last time a UART device driver was polled - @param curTime - The current time, in milliseconds. - */ - /*******************************************************************************/ - void setPrvPollTime(unsigned long curTime) { _prvPoll = curTime; } - - /*******************************************************************************/ - /*! - @brief Gets the UART device's unique identifier. - @returns The UART device's unique identifier. - */ - /*******************************************************************************/ - const char *getDriverID() { return _driverID; } - - /*******************************************************************************/ - /*! - @brief Sets the UART driver's identifer. - @param id - The UART device's unique identifier. - */ - /*******************************************************************************/ - void setDriverID(const char *id) { _driverID = strdup(id); } - - /*******************************************************************************/ - /*! - @brief Provides the UART device driver with an instance of the - application's MQTT configuration. - @param AMQTT - Pointer to an Adafruit_MQTT object. - @param mqtt_topic - UART topic string, generated by adafruit MQTT - */ - /*******************************************************************************/ - virtual void set_mqtt_client(Adafruit_MQTT *AMQTT, const char *mqtt_topic) { - mqttClient = AMQTT; - uartTopic = mqtt_topic; - } - - /*******************************************************************************/ - /*! - @brief Initializes the UART device driver. - @returns True if UART device driver initialized successfully, False - otherwise. - */ - /*******************************************************************************/ - virtual bool begin() { return false; } - - /*******************************************************************************/ - /*! - @brief Checks if the UART device's data is ready. - @returns True if data is available, False otherwise. - */ - /*******************************************************************************/ - virtual bool read_data() { return false; } - - /*******************************************************************************/ - /*! - @brief Packs the UART device's data into a UARTResponse message. - @param msgUARTResponse - Pointer to a UARTResponse message. - @param event_index - Index of the UART device's event. - @param sensor_type - Type of sensor data. - @param sensor_value - Sensor data value. - */ - /*******************************************************************************/ - void packUARTResponse(wippersnapper_signal_v1_UARTResponse *msgUARTResponse, - int event_index, - wippersnapper_i2c_v1_SensorType sensor_type, - float sensor_value) { - msgUARTResponse->payload.resp_uart_device_event.sensor_event[event_index] - .type = sensor_type; - msgUARTResponse->payload.resp_uart_device_event.sensor_event[event_index] - .value = sensor_value; - } - - /*******************************************************************************/ - /*! - @brief Reads the UART device's data then packs and sends it to IO. - */ - /*******************************************************************************/ - virtual void send_data(){}; - - const char *uartTopic = nullptr; ///< UART device's MQTT topic - Adafruit_MQTT *mqttClient = nullptr; ///< Pointer to MQTT client object - unsigned long - pollingInterval; ///< UART device's polling interval, in milliseconds -private: - long _prvPoll = millis() - (24 * 60 * 60 * 1000); - ///< Last time (ms) the UART device was polled, set to 24 hours (max period) - const char *_driverID = nullptr; ///< UART device's ID -}; - -#endif // WS_UART_DRV_H diff --git a/src/components/uart/drivers/ws_uart_drv_pm25aqi.h b/src/components/uart/drivers/ws_uart_drv_pm25aqi.h deleted file mode 100644 index 4eb4c0c92..000000000 --- a/src/components/uart/drivers/ws_uart_drv_pm25aqi.h +++ /dev/null @@ -1,215 +0,0 @@ -/*! - * @file ws_uart_drv_pm25aqi.h - * - * WipperSnapper device driver for the Adafruit_PM25AQI Arduino Library - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2023 for Adafruit Industries. - * - * MIT license, all text here must be included in any redistribution. - * - */ -#ifndef WS_UART_DRV_PM25AQI_H -#define WS_UART_DRV_PM25AQI_H - -#include "Wippersnapper.h" -#include "ws_uart_drv.h" -#include - -/**************************************************************************/ -/*! - @brief Class that provides an interface for a PM25 AQI UART sensor. -*/ -/**************************************************************************/ -class ws_uart_drv_pm25aqi : public ws_uart_drv { -public: -#ifdef USE_SW_UART - /*******************************************************************************/ - /*! - @brief Initializes a PM25AQI UART device driver. - @param swSerial - Pointer to an instance of a SoftwareSerial object. - @param pollingInterval - How often the PM25AQI device will be polled, in milliseconds. - */ - /*******************************************************************************/ - ws_uart_drv_pm25aqi(SoftwareSerial *swSerial, int32_t interval) - : ws_uart_drv(swSerial, interval) { - _swSerial = swSerial; - pollingInterval = (unsigned long)interval; - }; -#else - /*******************************************************************************/ - /*! - @brief Initializes the PM25AQI UART device driver. - @param hwSerial - Pointer to an instance of a HardwareSerial object. - @param interval - How often the PM25AQI device will be polled, in milliseconds. - */ - /*******************************************************************************/ - ws_uart_drv_pm25aqi(HardwareSerial *hwSerial, int32_t interval) - : ws_uart_drv(hwSerial, interval) { - _hwSerial = hwSerial; - pollingInterval = (unsigned long)interval; - }; -#endif // USE_SW_UART - - /*******************************************************************************/ - /*! - @brief Destructor for a PM25AQI sensor. - */ - /*******************************************************************************/ - ~ws_uart_drv_pm25aqi() { - delete _aqi; -#ifdef USE_SW_UART - _swSerial = nullptr; -#else - _hwSerial = nullptr; -#endif - } - - /*******************************************************************************/ - /*! - @brief Initializes a PM25AQI sensor. - @returns True if the PM25AQI sensor was successfully initialized, - False otherwise. - */ - /*******************************************************************************/ - bool begin() override { - _aqi = new Adafruit_PM25AQI(); -#ifdef USE_SW_UART - if (!_aqi->begin_UART( - _swSerial)) { // connect to the sensor over software serial - return false; - } -#else - if (!_aqi->begin_UART( - _hwSerial)) { // connect to the sensor over hardware serial - return false; - } -#endif - return true; - } - - /*******************************************************************************/ - /*! - @brief Attempts to read data from the PM25AQI sensor. - @returns True if data was successfully read, False otherwise. - */ - /*******************************************************************************/ - bool read_data() override { - Serial.println("[UART, PM25] Reading data..."); - // Attempt to read the PM2.5 Sensor - if (!_aqi->read(&_data)) { - Serial.println("[UART, PM25] Data not available."); - delay(500); - return false; - } - Serial.println("[UART, PM25] Read data OK"); - Serial.println(); - Serial.println(F("---------------------------------------")); - Serial.println(F("Concentration Units (standard)")); - Serial.println(F("---------------------------------------")); - Serial.print(F("PM 1.0: ")); - Serial.print(_data.pm10_standard); - Serial.print(F("\t\tPM 2.5: ")); - Serial.print(_data.pm25_standard); - Serial.print(F("\t\tPM 10: ")); - Serial.println(_data.pm100_standard); - Serial.println(F("Concentration Units (environmental)")); - Serial.println(F("---------------------------------------")); - Serial.print(F("PM 1.0: ")); - Serial.print(_data.pm10_env); - Serial.print(F("\t\tPM 2.5: ")); - Serial.print(_data.pm25_env); - Serial.print(F("\t\tPM 10: ")); - Serial.println(_data.pm100_env); - Serial.println(F("---------------------------------------")); - - return true; - } - - /*******************************************************************************/ - /*! - @brief Packs and sends the device's event data to Adafruit IO. - */ - /*******************************************************************************/ - void send_data() override { - // Create a new UART response message - wippersnapper_signal_v1_UARTResponse msgUARTResponse = - wippersnapper_signal_v1_UARTResponse_init_zero; - msgUARTResponse.which_payload = - wippersnapper_signal_v1_UARTResponse_resp_uart_device_event_tag; - strcpy(msgUARTResponse.payload.resp_uart_device_event.device_id, - getDriverID()); - - // check if driverID is pm1006 - if (strcmp(getDriverID(), "pm1006") == 0) { - // PM1006 returns only PM2.5_ENV readings - msgUARTResponse.payload.resp_uart_device_event.sensor_event_count = 1; - packUARTResponse(&msgUARTResponse, 0, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_ENV, - (float)_data.pm25_env); - } else { - msgUARTResponse.payload.resp_uart_device_event.sensor_event_count = 6; - packUARTResponse(&msgUARTResponse, 0, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_STD, - (float)_data.pm10_standard); - - packUARTResponse(&msgUARTResponse, 1, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_STD, - (float)_data.pm25_standard); - - packUARTResponse(&msgUARTResponse, 2, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_STD, - (float)_data.pm100_standard); - - packUARTResponse(&msgUARTResponse, 3, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_ENV, - (float)_data.pm10_env); - - packUARTResponse(&msgUARTResponse, 4, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_ENV, - (float)_data.pm25_env); - - packUARTResponse(&msgUARTResponse, 5, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_ENV, - (float)_data.pm100_env); - } - - // Encode message data - uint8_t mqttBuffer[512] = {0}; - pb_ostream_t ostream = - pb_ostream_from_buffer(mqttBuffer, sizeof(mqttBuffer)); - if (!ws_pb_encode(&ostream, wippersnapper_signal_v1_UARTResponse_fields, - &msgUARTResponse)) { - Serial.println("[ERROR, UART]: Unable to encode device response!"); - return; - } - - // Publish message to IO - size_t msgSz; - pb_get_encoded_size(&msgSz, wippersnapper_signal_v1_UARTResponse_fields, - &msgUARTResponse); - Serial.print("[UART] Publishing event to IO.."); - mqttClient->publish(uartTopic, mqttBuffer, msgSz, 1); - Serial.println("Published!"); - - setPrvPollTime(millis()); - } - -protected: - Adafruit_PM25AQI *_aqi = nullptr; ///< Pointer to PM25AQI sensor object - PM25_AQI_Data _data; ///< PM25AQI sensor data struct. -#ifdef USE_SW_UART - SoftwareSerial *_swSerial = nullptr; ///< Pointer to Software UART interface -#else - HardwareSerial *_hwSerial = nullptr; ///< Pointer to Hardware UART interface -#endif -}; - -#endif // WS_UART_DRV_PM25AQI_H \ No newline at end of file diff --git a/src/components/uart/ws_uart.cpp b/src/components/uart/ws_uart.cpp deleted file mode 100644 index d26947eda..000000000 --- a/src/components/uart/ws_uart.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/*! - * @file ws_uart.cpp - * - * Base class that provides an interface between WipperSnapper's app - * and the device's UART bus. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2023 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ -#include "ws_uart.h" - -/*******************************************************************************/ -/*! - @brief UART class destructor. -*/ -/*******************************************************************************/ -ws_uart::~ws_uart(void) { -#ifdef USE_SW_UART - _swSerial = nullptr; -#else - _hwSerial = nullptr; -#endif -} - -/*******************************************************************************/ -/*! - @brief Initializes a UART bus. - @param msgUARTRequest - Pointer to a UARTDeviceAttachRequest message. -*/ -/*******************************************************************************/ -void ws_uart::initUARTBus( - wippersnapper_uart_v1_UARTDeviceAttachRequest *msgUARTRequest) { - // Parse bus_info - int32_t baud = msgUARTRequest->bus_info.baudrate; - int32_t rx = atoi(msgUARTRequest->bus_info.pin_rx + 1); - int32_t tx = atoi(msgUARTRequest->bus_info.pin_tx + 1); - bool invert = msgUARTRequest->bus_info.is_invert; - -// Initialize and begin UART bus depending if the platform supports either HW -// UART or SW UART -#ifdef USE_SW_UART -#ifndef ARDUINO_ARCH_RP2040 - _swSerial = new SoftwareSerial(rx, tx, invert); -#else // RP2040 SoftwareSerial emulation does not support inverted mode - _swSerial = new SoftwareSerial(rx, tx); -#endif - _swSerial->begin(baud); -#else -#ifndef ARDUINO_ARCH_SAMD - _hwSerial = new HardwareSerial(1); - _hwSerial->begin(baud, SERIAL_8N1, rx, tx, invert); -#else - _hwSerial = &Serial1; - _hwSerial->begin(baud); -#endif -#endif - _is_bus_initialized = true; -} - -#ifdef USE_SW_UART -/*******************************************************************************/ -/*! - @brief Initializes the PM25AQI device driver using SoftwareSerial. - @param swSerial - Pointer to a SoftwareSerial instance. - @param pollingInterval - Polling interval for the pms5003 device. - @param device_id - Which PM25 device are we communicating with? - @returns True if pms5003 driver was successfully initialized, False - otherwise. -*/ -/*******************************************************************************/ -bool ws_uart::initUARTDevicePM25AQI(SoftwareSerial *swSerial, - int32_t pollingInterval, - const char *device_id) { - if (_pm25aqi != nullptr) { - WS_DEBUG_PRINTLN( - "[ERROR, UART]: pms5003 driver already initialized on bus!"); - return false; - } - WS_DEBUG_PRINTLN("[INFO, UART]: Initializing PM25AQI driver..."); - _pm25aqi = new ws_uart_drv_pm25aqi(swSerial, pollingInterval); - _pm25aqi->setDriverID( - device_id); // Since the AdafruitPM25 driver works with both Adafruit PM - // sensor and PM1006, we need to set the driver ID - if (!_pm25aqi->begin()) { - WS_DEBUG_PRINTLN("[ERROR, UART]: PM25 driver initialization failed!"); - return false; - } - _pm25aqi->set_mqtt_client(WS._mqtt, WS._topic_signal_uart_device); - uartDrivers.push_back(_pm25aqi); - return true; -} -#else -/*******************************************************************************/ -/*! - @brief Initializes the pms5003 device driver using HardwareSerial. - @param hwSerial - Pointer to a HardwareSerial instance. - @param pollingInterval - Polling interval for the pms5003 device. - @param device_id - Which PM25 device are we communicating with? - @returns True if pms5003 driver was successfully initialized, False - otherwise. -*/ -/*******************************************************************************/ -bool ws_uart::initUARTDevicePM25AQI(HardwareSerial *hwSerial, - int32_t pollingInterval, - const char *device_id) { - if (_pm25aqi != nullptr) { - WS_DEBUG_PRINTLN( - "[ERROR, UART]: pms5003 driver already initialized on bus!"); - return false; - } - _pm25aqi = new ws_uart_drv_pm25aqi(hwSerial, pollingInterval); - _pm25aqi->setDriverID( - device_id); // Since the AdafruitPM25 driver works with both Adafruit PM - // sensor and PM1006, we need to set the driver ID - if (!_pm25aqi->begin()) { - WS_DEBUG_PRINTLN("[ERROR, UART]: PM25 driver initialization failed!"); - return false; - } - _pm25aqi->set_mqtt_client(WS._mqtt, WS._topic_signal_uart_device); - uartDrivers.push_back(_pm25aqi); - return true; -} -#endif - -/*******************************************************************************/ -/*! - @brief Checks if the UART bus has been initialized. - @returns True if the UART bus is initialized, False otherwise. -*/ -/*******************************************************************************/ -bool ws_uart::isUARTBusInitialized() { return _is_bus_initialized; } - -/*******************************************************************************/ -/*! - @brief Initializes a device on the UART bus. - @param msgUARTRequest - Pointer to a UARTDeviceAttachRequest message. - @returns True if UART driver was successfully initialized. -*/ -/*******************************************************************************/ -bool ws_uart::initUARTDevice( - wippersnapper_uart_v1_UARTDeviceAttachRequest *msgUARTRequest) { - // Ensure the protobuf contains a device identifier - if (strlen(msgUARTRequest->device_id) == 0) { - return false; - } - - // Do we already have a device with this ID? - for (ws_uart_drv *ptrUARTDriver : uartDrivers) { - if (strcmp(ptrUARTDriver->getDriverID(), msgUARTRequest->device_id) == 0) { - deinitUARTDevice( - msgUARTRequest->device_id); // Deinit the device and free resources - } - } - - // Check which device type we are initializing - if (strcmp(msgUARTRequest->device_id, "pms5003") == 0 || - strcmp(msgUARTRequest->device_id, "pm1006") == 0) { -// Attempt to initialize Adafruit_PM25 driver with either SW or HW UART -#ifdef USE_SW_UART - if (!initUARTDevicePM25AQI(_swSerial, msgUARTRequest->polling_interval, - msgUARTRequest->device_id)) - return false; -#else - if (!initUARTDevicePM25AQI(_hwSerial, msgUARTRequest->polling_interval, - msgUARTRequest->device_id)) - return false; -#endif - WS_DEBUG_PRINTLN("[INFO, UART]: PM25 UART driver initialized!"); - } else { - WS_DEBUG_PRINTLN("[ERROR, UART]: Could not find UART device type"); - return false; - } - return true; -} - -/*******************************************************************************/ -/*! - @brief Deinitializes a device from the UART bus and frees its memory. - @param device_id - Device identifier of the UART device to deinitialize. -*/ -/*******************************************************************************/ -void ws_uart::deinitUARTDevice(const char *device_id) { - // Start an iterator on the first driver within the uartDrivers vector - std::vector::iterator iter = uartDrivers.begin(); - // Iterate through the vector - while (iter != uartDrivers.end()) { - ws_uart_drv *ptrUARTDriver = *iter; // Get a pointer to the driver - if (strcmp(ptrUARTDriver->getDriverID(), device_id) == 0) { - if (ptrUARTDriver == _pm25aqi) { - _pm25aqi = nullptr; - } - // Erase the driver from the vector of drivers - iter = uartDrivers.erase(iter); - } else { - ++iter; - } - } -} - -/*******************************************************************************/ -/*! - @brief Detaches a UART device from the bus and frees its memory. - @param msgUARTDetachReq - Pointer to a UARTDeviceDetachRequest message. -*/ -/*******************************************************************************/ -void ws_uart::detachUARTDevice( - wippersnapper_uart_v1_UARTDeviceDetachRequest *msgUARTDetachReq) { - // Deallocate the memory pointed to by the driver and detach it from the bus - deinitUARTDevice(msgUARTDetachReq->device_id); -} - -/*******************************************************************************/ -/*! - @brief Polls the UART driver for new data and sends it to IO. -*/ -/*******************************************************************************/ -void ws_uart::update() { - for (ws_uart_drv *ptrUARTDriver : uartDrivers) { - if (ptrUARTDriver->isReady()) { - // Attempt to poll the UART driver for new data - if (ptrUARTDriver->read_data()) { - // Send UART driver's data to IO - ptrUARTDriver->send_data(); - } - } - } -} diff --git a/src/components/uart/ws_uart.h b/src/components/uart/ws_uart.h deleted file mode 100644 index 5a699ba25..000000000 --- a/src/components/uart/ws_uart.h +++ /dev/null @@ -1,64 +0,0 @@ -/*! - * @file ws_uart.h - * - * Base class that provides an interface between WipperSnapper's app - * and the device's UART bus. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Copyright (c) Brent Rubell 2023 for Adafruit Industries. - * - * BSD license, all text here must be included in any redistribution. - * - */ -#ifndef WS_UART_H -#define WS_UART_H - -#include "Wippersnapper.h" -#include "drivers/ws_uart_drv.h" -#include "drivers/ws_uart_drv_pm25aqi.h" - -/**************************************************************************/ -/*! - @brief Class that provides an interface between WipperSnapper's app - and the device's UART bus. -*/ -/**************************************************************************/ -class ws_uart { -public: - ws_uart(){}; - ~ws_uart(void); - - void - initUARTBus(wippersnapper_uart_v1_UARTDeviceAttachRequest - *msgUARTRequest); ///< Initializes the UART bus, called once - bool initUARTDevice(wippersnapper_uart_v1_UARTDeviceAttachRequest - *msgUARTRequest); ///< Initializes a UART driver. - bool isUARTBusInitialized(); ///< Returns true if the UART bus is initialized - void detachUARTDevice( - wippersnapper_uart_v1_UARTDeviceDetachRequest - *msgUARTDetachReq); ///< Detaches a UART device from the UART bus - void deinitUARTDevice(const char *device_id); - void update(); ///< Updates the UART device at every polling interval, must be - ///< called by main app. -#ifdef USE_SW_UART - bool initUARTDevicePM25AQI(SoftwareSerial *swSerial, int32_t pollingInterval, - const char *device_id); -#else - bool initUARTDevicePM25AQI(HardwareSerial *hwSerial, int32_t pollingInterval, - const char *device_id); -#endif -private: -#ifdef USE_SW_UART - SoftwareSerial *_swSerial = nullptr; ///< SoftwareSerial instance -#else - HardwareSerial *_hwSerial = nullptr; ///< HardwareSerial instance -#endif - bool _is_bus_initialized = false; ///< True if UART bus is initialized - std::vector uartDrivers; ///< Vector of UART drivers - ws_uart_drv_pm25aqi *_pm25aqi = nullptr; ///< Pointer to a PM25 AQI device -}; - -#endif // WS_UART_H \ No newline at end of file diff --git a/src/display/ws_display_driver.h b/src/display/ws_display_driver.h index 853119c78..80f149df7 100644 --- a/src/display/ws_display_driver.h +++ b/src/display/ws_display_driver.h @@ -51,6 +51,6 @@ class ws_display_driver { uint8_t _displayRotationMode; ///< Display rotation (mode, not number in degrees) }; -extern Wippersnapper WS; +extern Wippersnapper WS; ///< Global Wippersnapper instance #endif // WIPPERSNAPPER_DISPLAY_H \ No newline at end of file diff --git a/src/helpers/ws_helper_esp.h b/src/helpers/ws_helper_esp.h new file mode 100644 index 000000000..8f18c3f53 --- /dev/null +++ b/src/helpers/ws_helper_esp.h @@ -0,0 +1,58 @@ +/*! + * @file ws_helper_esp.h + * + * This file contains helper functions for the ESPx platforms. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_HELPER_ESP_H +#define WS_HELPER_ESP_H +#include "esp_task_wdt.h" +#include + +/*******************************************************************************************************************************/ +/*! + @brief Converts reset reason type to a C string.. This uses the mechanism + in IDF that persists crash reasons across a reset. see: + https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/misc_system_api.html#software-reset + @param r + The reset reason, esp_reset_reason_t + @return A C string representing the reset reason. +*/ +/*******************************************************************************************************************************/ +inline const char *resetReasonName(esp_reset_reason_t r) { + switch (r) { + case ESP_RST_UNKNOWN: + return "Unknown"; + case ESP_RST_POWERON: + return "PowerOn"; // Power on or RST pin toggled + case ESP_RST_EXT: + return "ExtPin"; // External pin - not applicable for ESP32 + case ESP_RST_SW: + return "Reboot"; // esp_restart() + case ESP_RST_PANIC: + return "Crash"; // Exception/panic + case ESP_RST_INT_WDT: + return "WDT_Int"; // Interrupt watchdog (software or hardware) + case ESP_RST_TASK_WDT: + return "WDT_Task"; // Task watchdog + case ESP_RST_WDT: + return "WDT_Other"; // Other watchdog + case ESP_RST_DEEPSLEEP: + return "Sleep"; // Reset after exiting deep sleep mode + case ESP_RST_BROWNOUT: + return "BrownOut"; // Brownout reset (software or hardware) + case ESP_RST_SDIO: + return "SDIO"; // Reset over SDIO + default: + return ""; + } +} +#endif // WS_HELPER_ESP_H diff --git a/src/helpers/ws_helper_macros.h b/src/helpers/ws_helper_macros.h new file mode 100644 index 000000000..e82393a28 --- /dev/null +++ b/src/helpers/ws_helper_macros.h @@ -0,0 +1,70 @@ +#ifndef WS_HELPER_MACROS_H +#define WS_HELPER_MACROS_H + +#define WS_DEBUG ///< Define to enable debugging to serial terminal +#define WS_PRINTER Serial ///< Where debug messages will be printed + +// Define actual debug output functions when necessary. +#ifdef WS_DEBUG +#define WS_DEBUG_PRINT(...) \ + { WS_PRINTER.print(__VA_ARGS__); } ///< Prints debug output. +#define WS_DEBUG_PRINTLN(...) \ + { WS_PRINTER.println(__VA_ARGS__); } ///< Prints line from debug output. +#define WS_DEBUG_PRINTHEX(...) \ + { WS_PRINTER.print(__VA_ARGS__, HEX); } ///< Prints debug output. +#else +#define WS_DEBUG_PRINT(...) \ + {} ///< Prints debug output +#define WS_DEBUG_PRINTLN(...) \ + {} ///< Prints line from debug output. +#endif + +#define WS_DELAY_WITH_WDT(timeout) \ + { \ + unsigned long start = millis(); \ + while (millis() - start < timeout) { \ + delay(10); \ + yield(); \ + feedWDT(); \ + if (millis() < start) { \ + start = millis(); /* if rollover */ \ + } \ + } \ + } ///< Delay function + +/**************************************************************************/ +/*! + @brief Retry a function until a condition is met or a timeout is reached. + @param func + The function to retry. + @param result_type + The type of the result of the function. + @param result_var + The variable to store the last result of the function. + @param condition + The condition to check the result against. + @param timeout + The maximum time to retry the function. + @param interval + The time to wait between retries. + @param ... + The arguments to pass to the function. +*/ +/**************************************************************************/ +#define RETRY_FUNCTION_UNTIL_TIMEOUT(func, result_type, result_var, condition, \ + timeout, interval, ...) \ + { \ + unsigned long startTime = millis(); \ + while (millis() - startTime < timeout) { \ + result_type result_var = func(__VA_ARGS__); \ + if (condition(result_var)) { \ + break; \ + } \ + if (startTime > millis()) { \ + startTime = millis(); /* if rollover */ \ + } \ + WS_DELAY_WITH_WDT(interval); \ + } \ + } ///< Retry a function until a condition is met or a timeout is reached. + +#endif // WS_HELPER_MACROS_H \ No newline at end of file diff --git a/src/helpers/ws_helper_status.h b/src/helpers/ws_helper_status.h new file mode 100644 index 000000000..84a8c5513 --- /dev/null +++ b/src/helpers/ws_helper_status.h @@ -0,0 +1,60 @@ +#ifndef WS_HELPER_STATUS_H +#define WS_HELPER_STATUS_H + +/** Defines the Adafruit IO connection status */ +typedef enum { + WS_IDLE = 0, // Waiting for connection establishement + WS_NET_DISCONNECTED = 1, // Network disconnected + WS_DISCONNECTED = 2, // Disconnected from Adafruit IO + WS_FINGERPRINT_UNKOWN = 3, // Unknown WS_SSL_FINGERPRINT + + WS_NET_CONNECT_FAILED = 10, // Failed to connect to network + WS_CONNECT_FAILED = 11, // Failed to connect to Adafruit IO + WS_FINGERPRINT_INVALID = 12, // Unknown WS_SSL_FINGERPRINT + WS_AUTH_FAILED = 13, // Invalid Adafruit IO login credentials provided. + WS_SSID_INVALID = + 14, // SSID is "" or otherwise invalid, connection not attempted + + WS_NET_CONNECTED = 20, // Connected to Adafruit IO + WS_CONNECTED = 21, // Connected to network + WS_CONNECTED_INSECURE = 22, // Insecurely (non-SSL) connected to network + WS_FINGERPRINT_UNSUPPORTED = 23, // Unsupported WS_SSL_FINGERPRINT + WS_FINGERPRINT_VALID = 24, // Valid WS_SSL_FINGERPRINT + WS_BOARD_DESC_INVALID = 25, // Unable to send board description + WS_BOARD_RESYNC_FAILED = 26 // Board sync failure +} ws_status_t; + +/** Defines the Adafruit IO MQTT broker's connection return codes */ +typedef enum { + WS_MQTT_CONNECTED = 0, // Connected + WS_MQTT_INVALID_PROTOCOL = 1, // Invalid mqtt protocol + WS_MQTT_INVALID_CID = 2, // Client id rejected + WS_MQTT_SERVICE_UNAVALIABLE = 3, // Malformed user/pass + WS_MQTT_INVALID_USER_PASS = 4, // Unauthorized access to resource + WS_MQTT_UNAUTHORIZED = 5, // MQTT service unavailable + WS_MQTT_THROTTLED = 6, // Account throttled + WS_MQTT_BANNED = 7 // Account banned +} ws_mqtt_status_t; + +/** Defines the Wippersnapper client's hardware registration status */ +typedef enum { + WS_BOARD_DEF_IDLE, + WS_BOARD_DEF_SEND_FAILED, + WS_BOARD_DEF_SENT, + WS_BOARD_DEF_OK, + WS_BOARD_DEF_INVALID, + WS_BOARD_DEF_UNSPECIFIED +} ws_board_status_t; + +/** Defines the Wippersnapper client's network status */ +typedef enum { + FSM_NET_IDLE, + FSM_NET_CONNECTED, + FSM_MQTT_CONNECTED, + FSM_NET_CHECK_MQTT, + FSM_NET_CHECK_NETWORK, + FSM_NET_ESTABLISH_NETWORK, + FSM_NET_ESTABLISH_MQTT, +} fsm_net_t; + +#endif // WS_HELPER_STATUS_H \ No newline at end of file diff --git a/src/helpers/ws_helper_topics.h b/src/helpers/ws_helper_topics.h new file mode 100644 index 000000000..f45c3b045 --- /dev/null +++ b/src/helpers/ws_helper_topics.h @@ -0,0 +1,18 @@ +#ifndef WS_HELPER_TOPICS_H +#define WS_HELPER_TOPICS_H + +// Reserved Adafruit IO MQTT topics +#define TOPIC_IO_THROTTLE "/throttle" ///< Adafruit IO Throttle MQTT Topic +#define TOPIC_IO_ERRORS "/errors" ///< Adafruit IO Error MQTT Topic + +// Reserved Wippersnapper topics +#define TOPIC_WS "/wprsnpr/" ///< WipperSnapper topic +#define TOPIC_INFO "/info/" ///< Registration sub-topic +#define TOPIC_SIGNALS "/signals/" ///< Signals sub-topic +#define TOPIC_I2C "/i2c" ///< I2C sub-topic +#define MQTT_TOPIC_PIXELS_DEVICE \ + "/signals/device/pixel" ///< Pixels device->broker topic +#define MQTT_TOPIC_PIXELS_BROKER \ + "/signals/broker/pixel" ///< Pixels broker->device topic + +#endif // WS_HELPER_TOPICS_H \ No newline at end of file diff --git a/src/nanopb/nanopb.pb.h b/src/nanopb/nanopb.pb.h deleted file mode 100644 index f5c9c6f34..000000000 --- a/src/nanopb/nanopb.pb.h +++ /dev/null @@ -1,911 +0,0 @@ -/* Common parts of the nanopb library. Most of these are quite low-level - * stuff. For the high-level interface, see pb_encode.h and pb_decode.h. - */ - -#ifndef PB_H_INCLUDED -#define PB_H_INCLUDED - -/***************************************************************** - * Nanopb compilation time options. You can change these here by * - * uncommenting the lines, or on the compiler command line. * - *****************************************************************/ - -/* Enable support for dynamically allocated fields */ -/* #define PB_ENABLE_MALLOC 1 */ - -/* Define this if your CPU / compiler combination does not support - * unaligned memory access to packed structures. Note that packed - * structures are only used when requested in .proto options. */ -/* #define PB_NO_PACKED_STRUCTS 1 */ - -/* Increase the number of required fields that are tracked. - * A compiler warning will tell if you need this. */ -/* #define PB_MAX_REQUIRED_FIELDS 256 */ - -/* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */ -/* #define PB_FIELD_32BIT 1 */ - -/* Disable support for error messages in order to save some code space. */ -/* #define PB_NO_ERRMSG 1 */ - -/* Disable support for custom streams (support only memory buffers). */ -/* #define PB_BUFFER_ONLY 1 */ - -/* Disable support for 64-bit datatypes, for compilers without int64_t - or to save some code space. */ -/* #define PB_WITHOUT_64BIT 1 */ - -/* Don't encode scalar arrays as packed. This is only to be used when - * the decoder on the receiving side cannot process packed scalar arrays. - * Such example is older protobuf.js. */ -/* #define PB_ENCODE_ARRAYS_UNPACKED 1 */ - -/* Enable conversion of doubles to floats for platforms that do not - * support 64-bit doubles. Most commonly AVR. */ -/* #define PB_CONVERT_DOUBLE_FLOAT 1 */ - -/* Check whether incoming strings are valid UTF-8 sequences. Slows down - * the string processing slightly and slightly increases code size. */ -/* #define PB_VALIDATE_UTF8 1 */ - -/* This can be defined if the platform is little-endian and has 8-bit bytes. - * Normally it is automatically detected based on __BYTE_ORDER__ macro. */ -/* #define PB_LITTLE_ENDIAN_8BIT 1 */ - -/* Configure static assert mechanism. Instead of changing these, set your - * compiler to C11 standard mode if possible. */ -/* #define PB_C99_STATIC_ASSERT 1 */ -/* #define PB_NO_STATIC_ASSERT 1 */ - -/****************************************************************** - * You usually don't need to change anything below this line. * - * Feel free to look around and use the defined macros, though. * - ******************************************************************/ - - -/* Version of the nanopb library. Just in case you want to check it in - * your own program. */ -#define NANOPB_VERSION "nanopb-0.4.6" - -/* Include all the system headers needed by nanopb. You will need the - * definitions of the following: - * - strlen, memcpy, memset functions - * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t - * - size_t - * - bool - * - * If you don't have the standard header files, you can instead provide - * a custom header that defines or includes all this. In that case, - * define PB_SYSTEM_HEADER to the path of this file. - */ -#ifdef PB_SYSTEM_HEADER -#include PB_SYSTEM_HEADER -#else -#include -#include -#include -#include -#include - -#ifdef PB_ENABLE_MALLOC -#include -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Macro for defining packed structures (compiler dependent). - * This just reduces memory requirements, but is not required. - */ -#if defined(PB_NO_PACKED_STRUCTS) - /* Disable struct packing */ -# define PB_PACKED_STRUCT_START -# define PB_PACKED_STRUCT_END -# define pb_packed -#elif defined(__GNUC__) || defined(__clang__) - /* For GCC and clang */ -# define PB_PACKED_STRUCT_START -# define PB_PACKED_STRUCT_END -# define pb_packed __attribute__((packed)) -#elif defined(__ICCARM__) || defined(__CC_ARM) - /* For IAR ARM and Keil MDK-ARM compilers */ -# define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") -# define PB_PACKED_STRUCT_END _Pragma("pack(pop)") -# define pb_packed -#elif defined(_MSC_VER) && (_MSC_VER >= 1500) - /* For Microsoft Visual C++ */ -# define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) -# define PB_PACKED_STRUCT_END __pragma(pack(pop)) -# define pb_packed -#else - /* Unknown compiler */ -# define PB_PACKED_STRUCT_START -# define PB_PACKED_STRUCT_END -# define pb_packed -#endif - -/* Detect endianness */ -#ifndef PB_LITTLE_ENDIAN_8BIT -#if ((defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ - (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ - defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \ - defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \ - defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM)) \ - && CHAR_BIT == 8 -#define PB_LITTLE_ENDIAN_8BIT 1 -#endif -#endif - -/* Handly macro for suppressing unreferenced-parameter compiler warnings. */ -#ifndef PB_UNUSED -#define PB_UNUSED(x) (void)(x) -#endif - -/* Harvard-architecture processors may need special attributes for storing - * field information in program memory. */ -#ifndef PB_PROGMEM -#ifdef __AVR__ -#include -#define PB_PROGMEM PROGMEM -#define PB_PROGMEM_READU32(x) pgm_read_dword(&x) -#else -#define PB_PROGMEM -#define PB_PROGMEM_READU32(x) (x) -#endif -#endif - -/* Compile-time assertion, used for checking compatible compilation options. - * If this does not work properly on your compiler, use - * #define PB_NO_STATIC_ASSERT to disable it. - * - * But before doing that, check carefully the error message / place where it - * comes from to see if the error has a real cause. Unfortunately the error - * message is not always very clear to read, but you can see the reason better - * in the place where the PB_STATIC_ASSERT macro was called. - */ -#ifndef PB_NO_STATIC_ASSERT -# ifndef PB_STATIC_ASSERT -# if defined(__ICCARM__) - /* IAR has static_assert keyword but no _Static_assert */ -# define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); -# elif defined(PB_C99_STATIC_ASSERT) - /* Classic negative-size-array static assert mechanism */ -# define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1]; -# define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) -# define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##_##LINE##_##COUNTER -# elif defined(__cplusplus) - /* C++11 standard static_assert mechanism */ -# define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); -# else - /* C11 standard _Static_assert mechanism */ -# define PB_STATIC_ASSERT(COND,MSG) _Static_assert(COND,#MSG); -# endif -# endif -#else - /* Static asserts disabled by PB_NO_STATIC_ASSERT */ -# define PB_STATIC_ASSERT(COND,MSG) -#endif - -/* Test that PB_STATIC_ASSERT works - * If you get errors here, you may need to do one of these: - * - Enable C11 standard support in your compiler - * - Define PB_C99_STATIC_ASSERT to enable C99 standard support - * - Define PB_NO_STATIC_ASSERT to disable static asserts altogether - */ -PB_STATIC_ASSERT(1, STATIC_ASSERT_IS_NOT_WORKING) - -/* Number of required fields to keep track of. */ -#ifndef PB_MAX_REQUIRED_FIELDS -#define PB_MAX_REQUIRED_FIELDS 64 -#endif - -#if PB_MAX_REQUIRED_FIELDS < 64 -#error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64). -#endif - -#ifdef PB_WITHOUT_64BIT -#ifdef PB_CONVERT_DOUBLE_FLOAT -/* Cannot use doubles without 64-bit types */ -#undef PB_CONVERT_DOUBLE_FLOAT -#endif -#endif - -/* List of possible field types. These are used in the autogenerated code. - * Least-significant 4 bits tell the scalar type - * Most-significant 4 bits specify repeated/required/packed etc. - */ - -typedef uint_least8_t pb_type_t; - -/**** Field data types ****/ - -/* Numeric types */ -#define PB_LTYPE_BOOL 0x00U /* bool */ -#define PB_LTYPE_VARINT 0x01U /* int32, int64, enum, bool */ -#define PB_LTYPE_UVARINT 0x02U /* uint32, uint64 */ -#define PB_LTYPE_SVARINT 0x03U /* sint32, sint64 */ -#define PB_LTYPE_FIXED32 0x04U /* fixed32, sfixed32, float */ -#define PB_LTYPE_FIXED64 0x05U /* fixed64, sfixed64, double */ - -/* Marker for last packable field type. */ -#define PB_LTYPE_LAST_PACKABLE 0x05U - -/* Byte array with pre-allocated buffer. - * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ -#define PB_LTYPE_BYTES 0x06U - -/* String with pre-allocated buffer. - * data_size is the maximum length. */ -#define PB_LTYPE_STRING 0x07U - -/* Submessage - * submsg_fields is pointer to field descriptions */ -#define PB_LTYPE_SUBMESSAGE 0x08U - -/* Submessage with pre-decoding callback - * The pre-decoding callback is stored as pb_callback_t right before pSize. - * submsg_fields is pointer to field descriptions */ -#define PB_LTYPE_SUBMSG_W_CB 0x09U - -/* Extension pseudo-field - * The field contains a pointer to pb_extension_t */ -#define PB_LTYPE_EXTENSION 0x0AU - -/* Byte array with inline, pre-allocated byffer. - * data_size is the length of the inline, allocated buffer. - * This differs from PB_LTYPE_BYTES by defining the element as - * pb_byte_t[data_size] rather than pb_bytes_array_t. */ -#define PB_LTYPE_FIXED_LENGTH_BYTES 0x0BU - -/* Number of declared LTYPES */ -#define PB_LTYPES_COUNT 0x0CU -#define PB_LTYPE_MASK 0x0FU - -/**** Field repetition rules ****/ - -#define PB_HTYPE_REQUIRED 0x00U -#define PB_HTYPE_OPTIONAL 0x10U -#define PB_HTYPE_SINGULAR 0x10U -#define PB_HTYPE_REPEATED 0x20U -#define PB_HTYPE_FIXARRAY 0x20U -#define PB_HTYPE_ONEOF 0x30U -#define PB_HTYPE_MASK 0x30U - -/**** Field allocation types ****/ - -#define PB_ATYPE_STATIC 0x00U -#define PB_ATYPE_POINTER 0x80U -#define PB_ATYPE_CALLBACK 0x40U -#define PB_ATYPE_MASK 0xC0U - -#define PB_ATYPE(x) ((x) & PB_ATYPE_MASK) -#define PB_HTYPE(x) ((x) & PB_HTYPE_MASK) -#define PB_LTYPE(x) ((x) & PB_LTYPE_MASK) -#define PB_LTYPE_IS_SUBMSG(x) (PB_LTYPE(x) == PB_LTYPE_SUBMESSAGE || \ - PB_LTYPE(x) == PB_LTYPE_SUBMSG_W_CB) - -/* Data type used for storing sizes of struct fields - * and array counts. - */ -#if defined(PB_FIELD_32BIT) - typedef uint32_t pb_size_t; - typedef int32_t pb_ssize_t; -#else - typedef uint_least16_t pb_size_t; - typedef int_least16_t pb_ssize_t; -#endif -#define PB_SIZE_MAX ((pb_size_t)-1) - -/* Data type for storing encoded data and other byte streams. - * This typedef exists to support platforms where uint8_t does not exist. - * You can regard it as equivalent on uint8_t on other platforms. - */ -typedef uint_least8_t pb_byte_t; - -/* Forward declaration of struct types */ -typedef struct pb_istream_s pb_istream_t; -typedef struct pb_ostream_s pb_ostream_t; -typedef struct pb_field_iter_s pb_field_iter_t; - -/* This structure is used in auto-generated constants - * to specify struct fields. - */ -typedef struct pb_msgdesc_s pb_msgdesc_t; -struct pb_msgdesc_s { - const uint32_t *field_info; - const pb_msgdesc_t * const * submsg_info; - const pb_byte_t *default_value; - - bool (*field_callback)(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field); - - pb_size_t field_count; - pb_size_t required_field_count; - pb_size_t largest_tag; -}; - -/* Iterator for message descriptor */ -struct pb_field_iter_s { - const pb_msgdesc_t *descriptor; /* Pointer to message descriptor constant */ - void *message; /* Pointer to start of the structure */ - - pb_size_t index; /* Index of the field */ - pb_size_t field_info_index; /* Index to descriptor->field_info array */ - pb_size_t required_field_index; /* Index that counts only the required fields */ - pb_size_t submessage_index; /* Index that counts only submessages */ - - pb_size_t tag; /* Tag of current field */ - pb_size_t data_size; /* sizeof() of a single item */ - pb_size_t array_size; /* Number of array entries */ - pb_type_t type; /* Type of current field */ - - void *pField; /* Pointer to current field in struct */ - void *pData; /* Pointer to current data contents. Different than pField for arrays and pointers. */ - void *pSize; /* Pointer to count/has field */ - - const pb_msgdesc_t *submsg_desc; /* For submessage fields, pointer to field descriptor for the submessage. */ -}; - -/* For compatibility with legacy code */ -typedef pb_field_iter_t pb_field_t; - -/* Make sure that the standard integer types are of the expected sizes. - * Otherwise fixed32/fixed64 fields can break. - * - * If you get errors here, it probably means that your stdint.h is not - * correct for your platform. - */ -#ifndef PB_WITHOUT_64BIT -PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE) -PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE) -#endif - -/* This structure is used for 'bytes' arrays. - * It has the number of bytes in the beginning, and after that an array. - * Note that actual structs used will have a different length of bytes array. - */ -#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; } -#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes)) - -struct pb_bytes_array_s { - pb_size_t size; - pb_byte_t bytes[1]; -}; -typedef struct pb_bytes_array_s pb_bytes_array_t; - -/* This structure is used for giving the callback function. - * It is stored in the message structure and filled in by the method that - * calls pb_decode. - * - * The decoding callback will be given a limited-length stream - * If the wire type was string, the length is the length of the string. - * If the wire type was a varint/fixed32/fixed64, the length is the length - * of the actual value. - * The function may be called multiple times (especially for repeated types, - * but also otherwise if the message happens to contain the field multiple - * times.) - * - * The encoding callback will receive the actual output stream. - * It should write all the data in one call, including the field tag and - * wire type. It can write multiple fields. - * - * The callback can be null if you want to skip a field. - */ -typedef struct pb_callback_s pb_callback_t; -struct pb_callback_s { - /* Callback functions receive a pointer to the arg field. - * You can access the value of the field as *arg, and modify it if needed. - */ - union { - bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); - bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); - } funcs; - - /* Free arg for use by callback */ - void *arg; -}; - -extern bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field); - -/* Wire types. Library user needs these only in encoder callbacks. */ -typedef enum { - PB_WT_VARINT = 0, - PB_WT_64BIT = 1, - PB_WT_STRING = 2, - PB_WT_32BIT = 5, - PB_WT_PACKED = 255 /* PB_WT_PACKED is internal marker for packed arrays. */ -} pb_wire_type_t; - -/* Structure for defining the handling of unknown/extension fields. - * Usually the pb_extension_type_t structure is automatically generated, - * while the pb_extension_t structure is created by the user. However, - * if you want to catch all unknown fields, you can also create a custom - * pb_extension_type_t with your own callback. - */ -typedef struct pb_extension_type_s pb_extension_type_t; -typedef struct pb_extension_s pb_extension_t; -struct pb_extension_type_s { - /* Called for each unknown field in the message. - * If you handle the field, read off all of its data and return true. - * If you do not handle the field, do not read anything and return true. - * If you run into an error, return false. - * Set to NULL for default handler. - */ - bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, - uint32_t tag, pb_wire_type_t wire_type); - - /* Called once after all regular fields have been encoded. - * If you have something to write, do so and return true. - * If you do not have anything to write, just return true. - * If you run into an error, return false. - * Set to NULL for default handler. - */ - bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); - - /* Free field for use by the callback. */ - const void *arg; -}; - -struct pb_extension_s { - /* Type describing the extension field. Usually you'll initialize - * this to a pointer to the automatically generated structure. */ - const pb_extension_type_t *type; - - /* Destination for the decoded data. This must match the datatype - * of the extension field. */ - void *dest; - - /* Pointer to the next extension handler, or NULL. - * If this extension does not match a field, the next handler is - * automatically called. */ - pb_extension_t *next; - - /* The decoder sets this to true if the extension was found. - * Ignored for encoding. */ - bool found; -}; - -#define pb_extension_init_zero {NULL,NULL,NULL,false} - -/* Memory allocation functions to use. You can define pb_realloc and - * pb_free to custom functions if you want. */ -#ifdef PB_ENABLE_MALLOC -# ifndef pb_realloc -# define pb_realloc(ptr, size) realloc(ptr, size) -# endif -# ifndef pb_free -# define pb_free(ptr) free(ptr) -# endif -#endif - -/* This is used to inform about need to regenerate .pb.h/.pb.c files. */ -#define PB_PROTO_HEADER_VERSION 40 - -/* These macros are used to declare pb_field_t's in the constant array. */ -/* Size of a structure member, in bytes. */ -#define pb_membersize(st, m) (sizeof ((st*)0)->m) -/* Number of entries in an array. */ -#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) -/* Delta from start of one member to the start of another member. */ -#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) - -/* Force expansion of macro value */ -#define PB_EXPAND(x) x - -/* Binding of a message field set into a specific structure */ -#define PB_BIND(msgname, structname, width) \ - const uint32_t structname ## _field_info[] PB_PROGMEM = \ - { \ - msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ ## width, structname) \ - 0 \ - }; \ - const pb_msgdesc_t* const structname ## _submsg_info[] = \ - { \ - msgname ## _FIELDLIST(PB_GEN_SUBMSG_INFO, structname) \ - NULL \ - }; \ - const pb_msgdesc_t structname ## _msg = \ - { \ - structname ## _field_info, \ - structname ## _submsg_info, \ - msgname ## _DEFAULT, \ - msgname ## _CALLBACK, \ - 0 msgname ## _FIELDLIST(PB_GEN_FIELD_COUNT, structname), \ - 0 msgname ## _FIELDLIST(PB_GEN_REQ_FIELD_COUNT, structname), \ - 0 msgname ## _FIELDLIST(PB_GEN_LARGEST_TAG, structname), \ - }; \ - msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ASSERT_ ## width, structname) - -#define PB_GEN_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) +1 -#define PB_GEN_REQ_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) \ - + (PB_HTYPE_ ## htype == PB_HTYPE_REQUIRED) -#define PB_GEN_LARGEST_TAG(structname, atype, htype, ltype, fieldname, tag) \ - * 0 + tag - -/* X-macro for generating the entries in struct_field_info[] array. */ -#define PB_GEN_FIELD_INFO_1(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_1(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) - -#define PB_GEN_FIELD_INFO_2(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_2(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) - -#define PB_GEN_FIELD_INFO_4(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_4(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) - -#define PB_GEN_FIELD_INFO_8(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_8(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) - -#define PB_GEN_FIELD_INFO_AUTO(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_ ## atype, _PB_HTYPE_ ## htype, _PB_LTYPE_ ## ltype), \ - tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) - -#define PB_FIELDINFO_AUTO2(width, tag, type, data_offset, data_size, size_offset, array_size) \ - PB_FIELDINFO_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) - -#define PB_FIELDINFO_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) \ - PB_FIELDINFO_ ## width(tag, type, data_offset, data_size, size_offset, array_size) - -/* X-macro for generating asserts that entries fit in struct_field_info[] array. - * The structure of macros here must match the structure above in PB_GEN_FIELD_INFO_x(), - * but it is not easily reused because of how macro substitutions work. */ -#define PB_GEN_FIELD_INFO_ASSERT_1(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_ASSERT_1(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) - -#define PB_GEN_FIELD_INFO_ASSERT_2(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_ASSERT_2(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) - -#define PB_GEN_FIELD_INFO_ASSERT_4(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_ASSERT_4(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) - -#define PB_GEN_FIELD_INFO_ASSERT_8(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_ASSERT_8(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) - -#define PB_GEN_FIELD_INFO_ASSERT_AUTO(structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_ASSERT_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_ ## atype, _PB_HTYPE_ ## htype, _PB_LTYPE_ ## ltype), \ - tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ - PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ - PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) - -#define PB_FIELDINFO_ASSERT_AUTO2(width, tag, type, data_offset, data_size, size_offset, array_size) \ - PB_FIELDINFO_ASSERT_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) - -#define PB_FIELDINFO_ASSERT_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) \ - PB_FIELDINFO_ASSERT_ ## width(tag, type, data_offset, data_size, size_offset, array_size) - -#define PB_DATA_OFFSET_STATIC(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) -#define PB_DATA_OFFSET_POINTER(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) -#define PB_DATA_OFFSET_CALLBACK(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) -#define PB_DO_PB_HTYPE_REQUIRED(structname, fieldname) offsetof(structname, fieldname) -#define PB_DO_PB_HTYPE_SINGULAR(structname, fieldname) offsetof(structname, fieldname) -#define PB_DO_PB_HTYPE_ONEOF(structname, fieldname) offsetof(structname, PB_ONEOF_NAME(FULL, fieldname)) -#define PB_DO_PB_HTYPE_OPTIONAL(structname, fieldname) offsetof(structname, fieldname) -#define PB_DO_PB_HTYPE_REPEATED(structname, fieldname) offsetof(structname, fieldname) -#define PB_DO_PB_HTYPE_FIXARRAY(structname, fieldname) offsetof(structname, fieldname) - -#define PB_SIZE_OFFSET_STATIC(htype, structname, fieldname) PB_SO ## htype(structname, fieldname) -#define PB_SIZE_OFFSET_POINTER(htype, structname, fieldname) PB_SO_PTR ## htype(structname, fieldname) -#define PB_SIZE_OFFSET_CALLBACK(htype, structname, fieldname) PB_SO_CB ## htype(structname, fieldname) -#define PB_SO_PB_HTYPE_REQUIRED(structname, fieldname) 0 -#define PB_SO_PB_HTYPE_SINGULAR(structname, fieldname) 0 -#define PB_SO_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF2(structname, PB_ONEOF_NAME(FULL, fieldname), PB_ONEOF_NAME(UNION, fieldname)) -#define PB_SO_PB_HTYPE_ONEOF2(structname, fullname, unionname) PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) -#define PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) pb_delta(structname, fullname, which_ ## unionname) -#define PB_SO_PB_HTYPE_OPTIONAL(structname, fieldname) pb_delta(structname, fieldname, has_ ## fieldname) -#define PB_SO_PB_HTYPE_REPEATED(structname, fieldname) pb_delta(structname, fieldname, fieldname ## _count) -#define PB_SO_PB_HTYPE_FIXARRAY(structname, fieldname) 0 -#define PB_SO_PTR_PB_HTYPE_REQUIRED(structname, fieldname) 0 -#define PB_SO_PTR_PB_HTYPE_SINGULAR(structname, fieldname) 0 -#define PB_SO_PTR_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF(structname, fieldname) -#define PB_SO_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) 0 -#define PB_SO_PTR_PB_HTYPE_REPEATED(structname, fieldname) PB_SO_PB_HTYPE_REPEATED(structname, fieldname) -#define PB_SO_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) 0 -#define PB_SO_CB_PB_HTYPE_REQUIRED(structname, fieldname) 0 -#define PB_SO_CB_PB_HTYPE_SINGULAR(structname, fieldname) 0 -#define PB_SO_CB_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF(structname, fieldname) -#define PB_SO_CB_PB_HTYPE_OPTIONAL(structname, fieldname) 0 -#define PB_SO_CB_PB_HTYPE_REPEATED(structname, fieldname) 0 -#define PB_SO_CB_PB_HTYPE_FIXARRAY(structname, fieldname) 0 - -#define PB_ARRAY_SIZE_STATIC(htype, structname, fieldname) PB_AS ## htype(structname, fieldname) -#define PB_ARRAY_SIZE_POINTER(htype, structname, fieldname) PB_AS_PTR ## htype(structname, fieldname) -#define PB_ARRAY_SIZE_CALLBACK(htype, structname, fieldname) 1 -#define PB_AS_PB_HTYPE_REQUIRED(structname, fieldname) 1 -#define PB_AS_PB_HTYPE_SINGULAR(structname, fieldname) 1 -#define PB_AS_PB_HTYPE_OPTIONAL(structname, fieldname) 1 -#define PB_AS_PB_HTYPE_ONEOF(structname, fieldname) 1 -#define PB_AS_PB_HTYPE_REPEATED(structname, fieldname) pb_arraysize(structname, fieldname) -#define PB_AS_PB_HTYPE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname) -#define PB_AS_PTR_PB_HTYPE_REQUIRED(structname, fieldname) 1 -#define PB_AS_PTR_PB_HTYPE_SINGULAR(structname, fieldname) 1 -#define PB_AS_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) 1 -#define PB_AS_PTR_PB_HTYPE_ONEOF(structname, fieldname) 1 -#define PB_AS_PTR_PB_HTYPE_REPEATED(structname, fieldname) 1 -#define PB_AS_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname[0]) - -#define PB_DATA_SIZE_STATIC(htype, structname, fieldname) PB_DS ## htype(structname, fieldname) -#define PB_DATA_SIZE_POINTER(htype, structname, fieldname) PB_DS_PTR ## htype(structname, fieldname) -#define PB_DATA_SIZE_CALLBACK(htype, structname, fieldname) PB_DS_CB ## htype(structname, fieldname) -#define PB_DS_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DS_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DS_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DS_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) -#define PB_DS_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DS_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DS_PTR_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DS_PTR_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DS_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DS_PTR_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)[0]) -#define PB_DS_PTR_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DS_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0][0]) -#define PB_DS_CB_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DS_CB_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DS_CB_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DS_CB_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) -#define PB_DS_CB_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DS_CB_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname) - -#define PB_ONEOF_NAME(type, tuple) PB_EXPAND(PB_ONEOF_NAME_ ## type tuple) -#define PB_ONEOF_NAME_UNION(unionname,membername,fullname) unionname -#define PB_ONEOF_NAME_MEMBER(unionname,membername,fullname) membername -#define PB_ONEOF_NAME_FULL(unionname,membername,fullname) fullname - -#define PB_GEN_SUBMSG_INFO(structname, atype, htype, ltype, fieldname, tag) \ - PB_SUBMSG_INFO_ ## htype(_PB_LTYPE_ ## ltype, structname, fieldname) - -#define PB_SUBMSG_INFO_REQUIRED(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) -#define PB_SUBMSG_INFO_SINGULAR(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) -#define PB_SUBMSG_INFO_OPTIONAL(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) -#define PB_SUBMSG_INFO_ONEOF(ltype, structname, fieldname) PB_SUBMSG_INFO_ONEOF2(ltype, structname, PB_ONEOF_NAME(UNION, fieldname), PB_ONEOF_NAME(MEMBER, fieldname)) -#define PB_SUBMSG_INFO_ONEOF2(ltype, structname, unionname, membername) PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) -#define PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) PB_SI ## ltype(structname ## _ ## unionname ## _ ## membername ## _MSGTYPE) -#define PB_SUBMSG_INFO_REPEATED(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) -#define PB_SUBMSG_INFO_FIXARRAY(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) -#define PB_SI_PB_LTYPE_BOOL(t) -#define PB_SI_PB_LTYPE_BYTES(t) -#define PB_SI_PB_LTYPE_DOUBLE(t) -#define PB_SI_PB_LTYPE_ENUM(t) -#define PB_SI_PB_LTYPE_UENUM(t) -#define PB_SI_PB_LTYPE_FIXED32(t) -#define PB_SI_PB_LTYPE_FIXED64(t) -#define PB_SI_PB_LTYPE_FLOAT(t) -#define PB_SI_PB_LTYPE_INT32(t) -#define PB_SI_PB_LTYPE_INT64(t) -#define PB_SI_PB_LTYPE_MESSAGE(t) PB_SUBMSG_DESCRIPTOR(t) -#define PB_SI_PB_LTYPE_MSG_W_CB(t) PB_SUBMSG_DESCRIPTOR(t) -#define PB_SI_PB_LTYPE_SFIXED32(t) -#define PB_SI_PB_LTYPE_SFIXED64(t) -#define PB_SI_PB_LTYPE_SINT32(t) -#define PB_SI_PB_LTYPE_SINT64(t) -#define PB_SI_PB_LTYPE_STRING(t) -#define PB_SI_PB_LTYPE_UINT32(t) -#define PB_SI_PB_LTYPE_UINT64(t) -#define PB_SI_PB_LTYPE_EXTENSION(t) -#define PB_SI_PB_LTYPE_FIXED_LENGTH_BYTES(t) -#define PB_SUBMSG_DESCRIPTOR(t) &(t ## _msg), - -/* The field descriptors use a variable width format, with width of either - * 1, 2, 4 or 8 of 32-bit words. The two lowest bytes of the first byte always - * encode the descriptor size, 6 lowest bits of field tag number, and 8 bits - * of the field type. - * - * Descriptor size is encoded as 0 = 1 word, 1 = 2 words, 2 = 4 words, 3 = 8 words. - * - * Formats, listed starting with the least significant bit of the first word. - * 1 word: [2-bit len] [6-bit tag] [8-bit type] [8-bit data_offset] [4-bit size_offset] [4-bit data_size] - * - * 2 words: [2-bit len] [6-bit tag] [8-bit type] [12-bit array_size] [4-bit size_offset] - * [16-bit data_offset] [12-bit data_size] [4-bit tag>>6] - * - * 4 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit array_size] - * [8-bit size_offset] [24-bit tag>>6] - * [32-bit data_offset] - * [32-bit data_size] - * - * 8 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit reserved] - * [8-bit size_offset] [24-bit tag>>6] - * [32-bit data_offset] - * [32-bit data_size] - * [32-bit array_size] - * [32-bit reserved] - * [32-bit reserved] - * [32-bit reserved] - */ - -#define PB_FIELDINFO_1(tag, type, data_offset, data_size, size_offset, array_size) \ - (0 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(data_offset) & 0xFF) << 16) | \ - (((uint32_t)(size_offset) & 0x0F) << 24) | (((uint32_t)(data_size) & 0x0F) << 28)), - -#define PB_FIELDINFO_2(tag, type, data_offset, data_size, size_offset, array_size) \ - (1 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFF) << 16) | (((uint32_t)(size_offset) & 0x0F) << 28)), \ - (((uint32_t)(data_offset) & 0xFFFF) | (((uint32_t)(data_size) & 0xFFF) << 16) | (((uint32_t)(tag) & 0x3c0) << 22)), - -#define PB_FIELDINFO_4(tag, type, data_offset, data_size, size_offset, array_size) \ - (2 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFFF) << 16)), \ - ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ - (data_offset), (data_size), - -#define PB_FIELDINFO_8(tag, type, data_offset, data_size, size_offset, array_size) \ - (3 | (((tag) << 2) & 0xFF) | ((type) << 8)), \ - ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ - (data_offset), (data_size), (array_size), 0, 0, 0, - -/* These assertions verify that the field information fits in the allocated space. - * The generator tries to automatically determine the correct width that can fit all - * data associated with a message. These asserts will fail only if there has been a - * problem in the automatic logic - this may be worth reporting as a bug. As a workaround, - * you can increase the descriptor width by defining PB_FIELDINFO_WIDTH or by setting - * descriptorsize option in .options file. - */ -#define PB_FITS(value,bits) ((uint32_t)(value) < ((uint32_t)1<2GB messages with nanopb anyway. - */ -#define PB_FIELDINFO_ASSERT_4(tag, type, data_offset, data_size, size_offset, array_size) \ - PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS(size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,16), FIELDINFO_DOES_NOT_FIT_width4_field ## tag) - -#define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, array_size) \ - PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS(size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,31), FIELDINFO_DOES_NOT_FIT_width8_field ## tag) -#endif - - -/* Automatic picking of FIELDINFO width: - * Uses width 1 when possible, otherwise resorts to width 2. - * This is used when PB_BIND() is called with "AUTO" as the argument. - * The generator will give explicit size argument when it knows that a message - * structure grows beyond 1-word format limits. - */ -#define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) PB_FI_WIDTH ## atype(htype, ltype) -#define PB_FI_WIDTH_PB_ATYPE_STATIC(htype, ltype) PB_FI_WIDTH ## htype(ltype) -#define PB_FI_WIDTH_PB_ATYPE_POINTER(htype, ltype) PB_FI_WIDTH ## htype(ltype) -#define PB_FI_WIDTH_PB_ATYPE_CALLBACK(htype, ltype) 2 -#define PB_FI_WIDTH_PB_HTYPE_REQUIRED(ltype) PB_FI_WIDTH ## ltype -#define PB_FI_WIDTH_PB_HTYPE_SINGULAR(ltype) PB_FI_WIDTH ## ltype -#define PB_FI_WIDTH_PB_HTYPE_OPTIONAL(ltype) PB_FI_WIDTH ## ltype -#define PB_FI_WIDTH_PB_HTYPE_ONEOF(ltype) PB_FI_WIDTH ## ltype -#define PB_FI_WIDTH_PB_HTYPE_REPEATED(ltype) 2 -#define PB_FI_WIDTH_PB_HTYPE_FIXARRAY(ltype) 2 -#define PB_FI_WIDTH_PB_LTYPE_BOOL 1 -#define PB_FI_WIDTH_PB_LTYPE_BYTES 2 -#define PB_FI_WIDTH_PB_LTYPE_DOUBLE 1 -#define PB_FI_WIDTH_PB_LTYPE_ENUM 1 -#define PB_FI_WIDTH_PB_LTYPE_UENUM 1 -#define PB_FI_WIDTH_PB_LTYPE_FIXED32 1 -#define PB_FI_WIDTH_PB_LTYPE_FIXED64 1 -#define PB_FI_WIDTH_PB_LTYPE_FLOAT 1 -#define PB_FI_WIDTH_PB_LTYPE_INT32 1 -#define PB_FI_WIDTH_PB_LTYPE_INT64 1 -#define PB_FI_WIDTH_PB_LTYPE_MESSAGE 2 -#define PB_FI_WIDTH_PB_LTYPE_MSG_W_CB 2 -#define PB_FI_WIDTH_PB_LTYPE_SFIXED32 1 -#define PB_FI_WIDTH_PB_LTYPE_SFIXED64 1 -#define PB_FI_WIDTH_PB_LTYPE_SINT32 1 -#define PB_FI_WIDTH_PB_LTYPE_SINT64 1 -#define PB_FI_WIDTH_PB_LTYPE_STRING 2 -#define PB_FI_WIDTH_PB_LTYPE_UINT32 1 -#define PB_FI_WIDTH_PB_LTYPE_UINT64 1 -#define PB_FI_WIDTH_PB_LTYPE_EXTENSION 1 -#define PB_FI_WIDTH_PB_LTYPE_FIXED_LENGTH_BYTES 2 - -/* The mapping from protobuf types to LTYPEs is done using these macros. */ -#define PB_LTYPE_MAP_BOOL PB_LTYPE_BOOL -#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES -#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 -#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT -#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT -#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 -#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 -#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 -#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT -#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT -#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE -#define PB_LTYPE_MAP_MSG_W_CB PB_LTYPE_SUBMSG_W_CB -#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32 -#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64 -#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT -#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT -#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING -#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT -#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT -#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION -#define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES - -/* These macros are used for giving out error messages. - * They are mostly a debugging aid; the main error information - * is the true/false return value from functions. - * Some code space can be saved by disabling the error - * messages if not used. - * - * PB_SET_ERROR() sets the error message if none has been set yet. - * msg must be a constant string literal. - * PB_GET_ERROR() always returns a pointer to a string. - * PB_RETURN_ERROR() sets the error and returns false from current - * function. - */ -#ifdef PB_NO_ERRMSG -#define PB_SET_ERROR(stream, msg) PB_UNUSED(stream) -#define PB_GET_ERROR(stream) "(errmsg disabled)" -#else -#define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg)) -#define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)") -#endif - -#define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#ifdef __cplusplus -#if __cplusplus >= 201103L -#define PB_CONSTEXPR constexpr -#else // __cplusplus >= 201103L -#define PB_CONSTEXPR -#endif // __cplusplus >= 201103L - -#if __cplusplus >= 201703L -#define PB_INLINE_CONSTEXPR inline constexpr -#else // __cplusplus >= 201703L -#define PB_INLINE_CONSTEXPR PB_CONSTEXPR -#endif // __cplusplus >= 201703L - -namespace nanopb { -// Each type will be partially specialized by the generator. -template struct MessageDescriptor; -} // namespace nanopb -#endif /* __cplusplus */ - -#endif diff --git a/src/nanopb/ws_pb_helpers.cpp b/src/nanopb/ws_pb_helpers.cpp index a3b2b8ef1..c5f35d24c 100644 --- a/src/nanopb/ws_pb_helpers.cpp +++ b/src/nanopb/ws_pb_helpers.cpp @@ -14,7 +14,7 @@ */ #include "ws_pb_helpers.h" -#include "../Wippersnapper.h" +#include "../Wippersnapper_V2.h" // ***************************************************************************** /*! diff --git a/src/protos/analogio.pb.c b/src/protos/analogio.pb.c new file mode 100644 index 000000000..1e29a849b --- /dev/null +++ b/src/protos/analogio.pb.c @@ -0,0 +1,18 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "analogio.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(wippersnapper_analogio_AnalogIOAdd, wippersnapper_analogio_AnalogIOAdd, AUTO) + + +PB_BIND(wippersnapper_analogio_AnalogIORemove, wippersnapper_analogio_AnalogIORemove, AUTO) + + +PB_BIND(wippersnapper_analogio_AnalogIOEvent, wippersnapper_analogio_AnalogIOEvent, AUTO) + + + diff --git a/src/protos/analogio.pb.h b/src/protos/analogio.pb.h new file mode 100644 index 000000000..6fe6b246b --- /dev/null +++ b/src/protos/analogio.pb.h @@ -0,0 +1,98 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_WIPPERSNAPPER_ANALOGIO_ANALOGIO_PB_H_INCLUDED +#define PB_WIPPERSNAPPER_ANALOGIO_ANALOGIO_PB_H_INCLUDED +#include +#include "sensor.pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +/* * + AnalogIOAdd adds an analog pin to the device. */ +typedef struct _wippersnapper_analogio_AnalogIOAdd { + char pin_name[64]; /* * Name of the pin. */ + float period; /* * Time between reads, in seconds. */ + wippersnapper_sensor_SensorType read_mode; /* * Desired read mode for the pin. */ +} wippersnapper_analogio_AnalogIOAdd; + +/* * + AnalogIORemove removes an analog pin from the device. */ +typedef struct _wippersnapper_analogio_AnalogIORemove { + char pin_name[64]; /* * Name of the pin. */ +} wippersnapper_analogio_AnalogIORemove; + +/* * + AnalogIOEvent is contains a value, sent when an analog pin is read. */ +typedef struct _wippersnapper_analogio_AnalogIOEvent { + char pin_name[64]; /* * Name of the pin. */ + bool has_sensor_event; + wippersnapper_sensor_SensorEvent sensor_event; /* * Reading(s) from an analog pin. */ +} wippersnapper_analogio_AnalogIOEvent; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define wippersnapper_analogio_AnalogIOAdd_init_default {"", 0, _wippersnapper_sensor_SensorType_MIN} +#define wippersnapper_analogio_AnalogIORemove_init_default {""} +#define wippersnapper_analogio_AnalogIOEvent_init_default {"", false, wippersnapper_sensor_SensorEvent_init_default} +#define wippersnapper_analogio_AnalogIOAdd_init_zero {"", 0, _wippersnapper_sensor_SensorType_MIN} +#define wippersnapper_analogio_AnalogIORemove_init_zero {""} +#define wippersnapper_analogio_AnalogIOEvent_init_zero {"", false, wippersnapper_sensor_SensorEvent_init_zero} + +/* Field tags (for use in manual encoding/decoding) */ +#define wippersnapper_analogio_AnalogIOAdd_pin_name_tag 1 +#define wippersnapper_analogio_AnalogIOAdd_period_tag 2 +#define wippersnapper_analogio_AnalogIOAdd_read_mode_tag 3 +#define wippersnapper_analogio_AnalogIORemove_pin_name_tag 1 +#define wippersnapper_analogio_AnalogIOEvent_pin_name_tag 1 +#define wippersnapper_analogio_AnalogIOEvent_sensor_event_tag 2 + +/* Struct field encoding specification for nanopb */ +#define wippersnapper_analogio_AnalogIOAdd_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pin_name, 1) \ +X(a, STATIC, SINGULAR, FLOAT, period, 2) \ +X(a, STATIC, SINGULAR, UENUM, read_mode, 3) +#define wippersnapper_analogio_AnalogIOAdd_CALLBACK NULL +#define wippersnapper_analogio_AnalogIOAdd_DEFAULT NULL + +#define wippersnapper_analogio_AnalogIORemove_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pin_name, 1) +#define wippersnapper_analogio_AnalogIORemove_CALLBACK NULL +#define wippersnapper_analogio_AnalogIORemove_DEFAULT NULL + +#define wippersnapper_analogio_AnalogIOEvent_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pin_name, 1) \ +X(a, STATIC, OPTIONAL, MESSAGE, sensor_event, 2) +#define wippersnapper_analogio_AnalogIOEvent_CALLBACK NULL +#define wippersnapper_analogio_AnalogIOEvent_DEFAULT NULL +#define wippersnapper_analogio_AnalogIOEvent_sensor_event_MSGTYPE wippersnapper_sensor_SensorEvent + +extern const pb_msgdesc_t wippersnapper_analogio_AnalogIOAdd_msg; +extern const pb_msgdesc_t wippersnapper_analogio_AnalogIORemove_msg; +extern const pb_msgdesc_t wippersnapper_analogio_AnalogIOEvent_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define wippersnapper_analogio_AnalogIOAdd_fields &wippersnapper_analogio_AnalogIOAdd_msg +#define wippersnapper_analogio_AnalogIORemove_fields &wippersnapper_analogio_AnalogIORemove_msg +#define wippersnapper_analogio_AnalogIOEvent_fields &wippersnapper_analogio_AnalogIOEvent_msg + +/* Maximum encoded size of messages (where known) */ +#define WIPPERSNAPPER_ANALOGIO_ANALOGIO_PB_H_MAX_SIZE wippersnapper_analogio_AnalogIOAdd_size +#define wippersnapper_analogio_AnalogIOAdd_size 72 +#define wippersnapper_analogio_AnalogIORemove_size 65 +#if defined(wippersnapper_sensor_SensorEvent_size) +#define wippersnapper_analogio_AnalogIOEvent_size (71 + wippersnapper_sensor_SensorEvent_size) +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/protos/checkin.pb.c b/src/protos/checkin.pb.c new file mode 100644 index 000000000..05f7f72d5 --- /dev/null +++ b/src/protos/checkin.pb.c @@ -0,0 +1,16 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "checkin.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(wippersnapper_checkin_CheckinRequest, wippersnapper_checkin_CheckinRequest, AUTO) + + +PB_BIND(wippersnapper_checkin_CheckinResponse, wippersnapper_checkin_CheckinResponse, AUTO) + + + + diff --git a/src/protos/checkin.pb.h b/src/protos/checkin.pb.h new file mode 100644 index 000000000..63de0007b --- /dev/null +++ b/src/protos/checkin.pb.h @@ -0,0 +1,97 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_WIPPERSNAPPER_CHECKIN_CHECKIN_PB_H_INCLUDED +#define PB_WIPPERSNAPPER_CHECKIN_CHECKIN_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Enum definitions */ +/* * + Response. Specifies if the hardware definiton is within the database. */ +typedef enum _wippersnapper_checkin_CheckinResponse_Response { + wippersnapper_checkin_CheckinResponse_Response_RESPONSE_UNSPECIFIED = 0, /* * Invalid response from server */ + wippersnapper_checkin_CheckinResponse_Response_RESPONSE_OK = 1, /* * Board found within definition index */ + wippersnapper_checkin_CheckinResponse_Response_RESPONSE_BOARD_NOT_FOUND = 2 /* * Board not found in definition index */ +} wippersnapper_checkin_CheckinResponse_Response; + +/* Struct definitions */ +/* * + CheckinRequest notifies the MQTT broker that a new/existing device is requesting to connect. */ +typedef struct _wippersnapper_checkin_CheckinRequest { + char hardware_uid[64]; /* * Identifies the client's physical hardware (board name + last 3 of NIC's MAC address). */ + char firmware_version[25]; /* * Identifies the client's firmware version. */ +} wippersnapper_checkin_CheckinRequest; + +/* * + CheckinResponse sends a broker response to the client's CheckinRequest. */ +typedef struct _wippersnapper_checkin_CheckinResponse { + wippersnapper_checkin_CheckinResponse_Response response; /* * Specifies if the hardware definition exists on the server. */ + int32_t total_gpio_pins; /* * Specifies the number of GPIO pins on the device. */ + int32_t total_analog_pins; /* * Specifies the number of analog pins on the device. */ + float reference_voltage; /* * Specifies the hardware's default reference voltage. */ +} wippersnapper_checkin_CheckinResponse; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Helper constants for enums */ +#define _wippersnapper_checkin_CheckinResponse_Response_MIN wippersnapper_checkin_CheckinResponse_Response_RESPONSE_UNSPECIFIED +#define _wippersnapper_checkin_CheckinResponse_Response_MAX wippersnapper_checkin_CheckinResponse_Response_RESPONSE_BOARD_NOT_FOUND +#define _wippersnapper_checkin_CheckinResponse_Response_ARRAYSIZE ((wippersnapper_checkin_CheckinResponse_Response)(wippersnapper_checkin_CheckinResponse_Response_RESPONSE_BOARD_NOT_FOUND+1)) + + +#define wippersnapper_checkin_CheckinResponse_response_ENUMTYPE wippersnapper_checkin_CheckinResponse_Response + + +/* Initializer values for message structs */ +#define wippersnapper_checkin_CheckinRequest_init_default {"", ""} +#define wippersnapper_checkin_CheckinResponse_init_default {_wippersnapper_checkin_CheckinResponse_Response_MIN, 0, 0, 0} +#define wippersnapper_checkin_CheckinRequest_init_zero {"", ""} +#define wippersnapper_checkin_CheckinResponse_init_zero {_wippersnapper_checkin_CheckinResponse_Response_MIN, 0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define wippersnapper_checkin_CheckinRequest_hardware_uid_tag 1 +#define wippersnapper_checkin_CheckinRequest_firmware_version_tag 2 +#define wippersnapper_checkin_CheckinResponse_response_tag 1 +#define wippersnapper_checkin_CheckinResponse_total_gpio_pins_tag 2 +#define wippersnapper_checkin_CheckinResponse_total_analog_pins_tag 3 +#define wippersnapper_checkin_CheckinResponse_reference_voltage_tag 4 + +/* Struct field encoding specification for nanopb */ +#define wippersnapper_checkin_CheckinRequest_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, hardware_uid, 1) \ +X(a, STATIC, SINGULAR, STRING, firmware_version, 2) +#define wippersnapper_checkin_CheckinRequest_CALLBACK NULL +#define wippersnapper_checkin_CheckinRequest_DEFAULT NULL + +#define wippersnapper_checkin_CheckinResponse_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, response, 1) \ +X(a, STATIC, SINGULAR, INT32, total_gpio_pins, 2) \ +X(a, STATIC, SINGULAR, INT32, total_analog_pins, 3) \ +X(a, STATIC, SINGULAR, FLOAT, reference_voltage, 4) +#define wippersnapper_checkin_CheckinResponse_CALLBACK NULL +#define wippersnapper_checkin_CheckinResponse_DEFAULT NULL + +extern const pb_msgdesc_t wippersnapper_checkin_CheckinRequest_msg; +extern const pb_msgdesc_t wippersnapper_checkin_CheckinResponse_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define wippersnapper_checkin_CheckinRequest_fields &wippersnapper_checkin_CheckinRequest_msg +#define wippersnapper_checkin_CheckinResponse_fields &wippersnapper_checkin_CheckinResponse_msg + +/* Maximum encoded size of messages (where known) */ +#define WIPPERSNAPPER_CHECKIN_CHECKIN_PB_H_MAX_SIZE wippersnapper_checkin_CheckinRequest_size +#define wippersnapper_checkin_CheckinRequest_size 91 +#define wippersnapper_checkin_CheckinResponse_size 29 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/protos/digitalio.pb.c b/src/protos/digitalio.pb.c new file mode 100644 index 000000000..5467990fd --- /dev/null +++ b/src/protos/digitalio.pb.c @@ -0,0 +1,23 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "digitalio.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(wippersnapper_digitalio_DigitalIOAdd, wippersnapper_digitalio_DigitalIOAdd, AUTO) + + +PB_BIND(wippersnapper_digitalio_DigitalIORemove, wippersnapper_digitalio_DigitalIORemove, AUTO) + + +PB_BIND(wippersnapper_digitalio_DigitalIOEvent, wippersnapper_digitalio_DigitalIOEvent, AUTO) + + +PB_BIND(wippersnapper_digitalio_DigitalIOWrite, wippersnapper_digitalio_DigitalIOWrite, AUTO) + + + + + diff --git a/src/protos/digitalio.pb.h b/src/protos/digitalio.pb.h new file mode 100644 index 000000000..19b98ef49 --- /dev/null +++ b/src/protos/digitalio.pb.h @@ -0,0 +1,160 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_WIPPERSNAPPER_DIGITALIO_DIGITALIO_PB_H_INCLUDED +#define PB_WIPPERSNAPPER_DIGITALIO_DIGITALIO_PB_H_INCLUDED +#include +#include "sensor.pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Enum definitions */ +/* * + DigitalIOSampleMode specifies the pin's sample mode. */ +typedef enum _wippersnapper_digitalio_DigitalIOSampleMode { + wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_UNSPECIFIED = 0, /* * Invalid Sample Mode from Broker. */ + wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_TIMER = 1, /* * Periodically sample the pin's value. */ + wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_EVENT = 2 /* * Sample the pin's value when an event occurs. */ +} wippersnapper_digitalio_DigitalIOSampleMode; + +/* * + DigitalIODirection specifies the pin's direction, INPUT/INPUT_PULL_UP/OUTPUT. */ +typedef enum _wippersnapper_digitalio_DigitalIODirection { + wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_UNSPECIFIED = 0, /* * Invalid Direction from Broker. */ + wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_INPUT = 1, /* * Set the pin to behave as an input. */ + wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_INPUT_PULL_UP = 2, /* * Set the pin to behave as an input. */ + wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_OUTPUT = 3 /* * Set the pin to behave as an output. */ +} wippersnapper_digitalio_DigitalIODirection; + +/* Struct definitions */ +/* * + DigitalIOAdd adds a digital pin to the device. */ +typedef struct _wippersnapper_digitalio_DigitalIOAdd { + char pin_name[64]; /* * The pin's name. */ + wippersnapper_digitalio_DigitalIODirection gpio_direction; /* * The pin's direction. */ + wippersnapper_digitalio_DigitalIOSampleMode sample_mode; /* * Specifies the pin's sample mode. */ + float period; /* * Time between measurements in seconds, if MODE_TIMER. */ + bool value; /* * Re-sync only - send the pin's value. */ +} wippersnapper_digitalio_DigitalIOAdd; + +/* * + DigitalIORemove removes a digital pin from the device. */ +typedef struct _wippersnapper_digitalio_DigitalIORemove { + char pin_name[64]; /* * The pin's name. */ +} wippersnapper_digitalio_DigitalIORemove; + +/* * + DigitalIOEvent is sent from the device to the broker when a digital pin's value changes. */ +typedef struct _wippersnapper_digitalio_DigitalIOEvent { + char pin_name[64]; /* * The pin's name. */ + bool has_value; + wippersnapper_sensor_SensorEvent value; /* * The pin's value. */ +} wippersnapper_digitalio_DigitalIOEvent; + +/* * + DigitalIOWrite writes a boolean value to a digital pin. */ +typedef struct _wippersnapper_digitalio_DigitalIOWrite { + char pin_name[64]; /* * The pin's name. */ + bool has_value; + wippersnapper_sensor_SensorEvent value; /* * The pin's value. */ +} wippersnapper_digitalio_DigitalIOWrite; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Helper constants for enums */ +#define _wippersnapper_digitalio_DigitalIOSampleMode_MIN wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_UNSPECIFIED +#define _wippersnapper_digitalio_DigitalIOSampleMode_MAX wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_EVENT +#define _wippersnapper_digitalio_DigitalIOSampleMode_ARRAYSIZE ((wippersnapper_digitalio_DigitalIOSampleMode)(wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_EVENT+1)) + +#define _wippersnapper_digitalio_DigitalIODirection_MIN wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_UNSPECIFIED +#define _wippersnapper_digitalio_DigitalIODirection_MAX wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_OUTPUT +#define _wippersnapper_digitalio_DigitalIODirection_ARRAYSIZE ((wippersnapper_digitalio_DigitalIODirection)(wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_OUTPUT+1)) + +#define wippersnapper_digitalio_DigitalIOAdd_gpio_direction_ENUMTYPE wippersnapper_digitalio_DigitalIODirection +#define wippersnapper_digitalio_DigitalIOAdd_sample_mode_ENUMTYPE wippersnapper_digitalio_DigitalIOSampleMode + + + + + +/* Initializer values for message structs */ +#define wippersnapper_digitalio_DigitalIOAdd_init_default {"", _wippersnapper_digitalio_DigitalIODirection_MIN, _wippersnapper_digitalio_DigitalIOSampleMode_MIN, 0, 0} +#define wippersnapper_digitalio_DigitalIORemove_init_default {""} +#define wippersnapper_digitalio_DigitalIOEvent_init_default {"", false, wippersnapper_sensor_SensorEvent_init_default} +#define wippersnapper_digitalio_DigitalIOWrite_init_default {"", false, wippersnapper_sensor_SensorEvent_init_default} +#define wippersnapper_digitalio_DigitalIOAdd_init_zero {"", _wippersnapper_digitalio_DigitalIODirection_MIN, _wippersnapper_digitalio_DigitalIOSampleMode_MIN, 0, 0} +#define wippersnapper_digitalio_DigitalIORemove_init_zero {""} +#define wippersnapper_digitalio_DigitalIOEvent_init_zero {"", false, wippersnapper_sensor_SensorEvent_init_zero} +#define wippersnapper_digitalio_DigitalIOWrite_init_zero {"", false, wippersnapper_sensor_SensorEvent_init_zero} + +/* Field tags (for use in manual encoding/decoding) */ +#define wippersnapper_digitalio_DigitalIOAdd_pin_name_tag 1 +#define wippersnapper_digitalio_DigitalIOAdd_gpio_direction_tag 2 +#define wippersnapper_digitalio_DigitalIOAdd_sample_mode_tag 3 +#define wippersnapper_digitalio_DigitalIOAdd_period_tag 4 +#define wippersnapper_digitalio_DigitalIOAdd_value_tag 5 +#define wippersnapper_digitalio_DigitalIORemove_pin_name_tag 1 +#define wippersnapper_digitalio_DigitalIOEvent_pin_name_tag 1 +#define wippersnapper_digitalio_DigitalIOEvent_value_tag 2 +#define wippersnapper_digitalio_DigitalIOWrite_pin_name_tag 1 +#define wippersnapper_digitalio_DigitalIOWrite_value_tag 2 + +/* Struct field encoding specification for nanopb */ +#define wippersnapper_digitalio_DigitalIOAdd_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pin_name, 1) \ +X(a, STATIC, SINGULAR, UENUM, gpio_direction, 2) \ +X(a, STATIC, SINGULAR, UENUM, sample_mode, 3) \ +X(a, STATIC, SINGULAR, FLOAT, period, 4) \ +X(a, STATIC, SINGULAR, BOOL, value, 5) +#define wippersnapper_digitalio_DigitalIOAdd_CALLBACK NULL +#define wippersnapper_digitalio_DigitalIOAdd_DEFAULT NULL + +#define wippersnapper_digitalio_DigitalIORemove_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pin_name, 1) +#define wippersnapper_digitalio_DigitalIORemove_CALLBACK NULL +#define wippersnapper_digitalio_DigitalIORemove_DEFAULT NULL + +#define wippersnapper_digitalio_DigitalIOEvent_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pin_name, 1) \ +X(a, STATIC, OPTIONAL, MESSAGE, value, 2) +#define wippersnapper_digitalio_DigitalIOEvent_CALLBACK NULL +#define wippersnapper_digitalio_DigitalIOEvent_DEFAULT NULL +#define wippersnapper_digitalio_DigitalIOEvent_value_MSGTYPE wippersnapper_sensor_SensorEvent + +#define wippersnapper_digitalio_DigitalIOWrite_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pin_name, 1) \ +X(a, STATIC, OPTIONAL, MESSAGE, value, 2) +#define wippersnapper_digitalio_DigitalIOWrite_CALLBACK NULL +#define wippersnapper_digitalio_DigitalIOWrite_DEFAULT NULL +#define wippersnapper_digitalio_DigitalIOWrite_value_MSGTYPE wippersnapper_sensor_SensorEvent + +extern const pb_msgdesc_t wippersnapper_digitalio_DigitalIOAdd_msg; +extern const pb_msgdesc_t wippersnapper_digitalio_DigitalIORemove_msg; +extern const pb_msgdesc_t wippersnapper_digitalio_DigitalIOEvent_msg; +extern const pb_msgdesc_t wippersnapper_digitalio_DigitalIOWrite_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define wippersnapper_digitalio_DigitalIOAdd_fields &wippersnapper_digitalio_DigitalIOAdd_msg +#define wippersnapper_digitalio_DigitalIORemove_fields &wippersnapper_digitalio_DigitalIORemove_msg +#define wippersnapper_digitalio_DigitalIOEvent_fields &wippersnapper_digitalio_DigitalIOEvent_msg +#define wippersnapper_digitalio_DigitalIOWrite_fields &wippersnapper_digitalio_DigitalIOWrite_msg + +/* Maximum encoded size of messages (where known) */ +#define WIPPERSNAPPER_DIGITALIO_DIGITALIO_PB_H_MAX_SIZE wippersnapper_digitalio_DigitalIOAdd_size +#define wippersnapper_digitalio_DigitalIOAdd_size 76 +#define wippersnapper_digitalio_DigitalIORemove_size 65 +#if defined(wippersnapper_sensor_SensorEvent_size) +#define wippersnapper_digitalio_DigitalIOEvent_size (71 + wippersnapper_sensor_SensorEvent_size) +#define wippersnapper_digitalio_DigitalIOWrite_size (71 + wippersnapper_sensor_SensorEvent_size) +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/protos/ds18x20.pb.c b/src/protos/ds18x20.pb.c new file mode 100644 index 000000000..e34ce503a --- /dev/null +++ b/src/protos/ds18x20.pb.c @@ -0,0 +1,21 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "ds18x20.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(wippersnapper_ds18x20_Ds18x20Add, wippersnapper_ds18x20_Ds18x20Add, AUTO) + + +PB_BIND(wippersnapper_ds18x20_Ds18x20Added, wippersnapper_ds18x20_Ds18x20Added, AUTO) + + +PB_BIND(wippersnapper_ds18x20_Ds18x20Remove, wippersnapper_ds18x20_Ds18x20Remove, AUTO) + + +PB_BIND(wippersnapper_ds18x20_Ds18x20Event, wippersnapper_ds18x20_Ds18x20Event, AUTO) + + + diff --git a/src/protos/ds18x20.pb.h b/src/protos/ds18x20.pb.h new file mode 100644 index 000000000..52040ab6a --- /dev/null +++ b/src/protos/ds18x20.pb.h @@ -0,0 +1,126 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_WIPPERSNAPPER_DS18X20_DS18X20_PB_H_INCLUDED +#define PB_WIPPERSNAPPER_DS18X20_DS18X20_PB_H_INCLUDED +#include +#include "sensor.pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +/* * + Ds18x20Add represents a to initialize + a DS18X20 Maxim temperature sensor, from the broker. + NOTE: This API currently only supports ONE device per OneWire bus. */ +typedef struct _wippersnapper_ds18x20_Ds18x20Add { + char onewire_pin[5]; /* * The desired pin to use as a OneWire bus. */ + int32_t sensor_resolution; /* * The desired sensor resolution (9, 10, 11, or 12 bits). */ + float period; /* * The desired period to read the sensor, in seconds. */ + pb_size_t sensor_types_count; + wippersnapper_sensor_SensorType sensor_types[2]; /* * SI types used by the DS18x20 sensor. */ +} wippersnapper_ds18x20_Ds18x20Add; + +/* * + Ds18x20AddDs18x20AddedResponse represents a device's response + to a Ds18x20Add message. */ +typedef struct _wippersnapper_ds18x20_Ds18x20Added { + bool is_initialized; /* * True if the 1-wire bus has been initialized successfully, False otherwise. */ + char onewire_pin[5]; /* * The pin being used as a OneWire bus. */ +} wippersnapper_ds18x20_Ds18x20Added; + +/* * + Ds18x20Remove represents a to de-initialize a DS18X20 + Maxim temperature sensor, from the broker. */ +typedef struct _wippersnapper_ds18x20_Ds18x20Remove { + char onewire_pin[5]; /* * The desired onewire bus to de-initialize a DS18x sensor on and release. */ +} wippersnapper_ds18x20_Ds18x20Remove; + +/* * + Ds18x20Event event represents data from **one** DS18X20 sensor. */ +typedef struct _wippersnapper_ds18x20_Ds18x20Event { + char onewire_pin[5]; /* * The desired pin to use as a OneWire bus. */ + pb_size_t sensor_events_count; + wippersnapper_sensor_SensorEvent sensor_events[2]; /* * The DS18X20's SensorEvent. */ +} wippersnapper_ds18x20_Ds18x20Event; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define wippersnapper_ds18x20_Ds18x20Add_init_default {"", 0, 0, 0, {_wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN}} +#define wippersnapper_ds18x20_Ds18x20Added_init_default {0, ""} +#define wippersnapper_ds18x20_Ds18x20Remove_init_default {""} +#define wippersnapper_ds18x20_Ds18x20Event_init_default {"", 0, {wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default}} +#define wippersnapper_ds18x20_Ds18x20Add_init_zero {"", 0, 0, 0, {_wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN}} +#define wippersnapper_ds18x20_Ds18x20Added_init_zero {0, ""} +#define wippersnapper_ds18x20_Ds18x20Remove_init_zero {""} +#define wippersnapper_ds18x20_Ds18x20Event_init_zero {"", 0, {wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero}} + +/* Field tags (for use in manual encoding/decoding) */ +#define wippersnapper_ds18x20_Ds18x20Add_onewire_pin_tag 1 +#define wippersnapper_ds18x20_Ds18x20Add_sensor_resolution_tag 2 +#define wippersnapper_ds18x20_Ds18x20Add_period_tag 3 +#define wippersnapper_ds18x20_Ds18x20Add_sensor_types_tag 4 +#define wippersnapper_ds18x20_Ds18x20Added_is_initialized_tag 1 +#define wippersnapper_ds18x20_Ds18x20Added_onewire_pin_tag 2 +#define wippersnapper_ds18x20_Ds18x20Remove_onewire_pin_tag 1 +#define wippersnapper_ds18x20_Ds18x20Event_onewire_pin_tag 1 +#define wippersnapper_ds18x20_Ds18x20Event_sensor_events_tag 2 + +/* Struct field encoding specification for nanopb */ +#define wippersnapper_ds18x20_Ds18x20Add_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, onewire_pin, 1) \ +X(a, STATIC, SINGULAR, INT32, sensor_resolution, 2) \ +X(a, STATIC, SINGULAR, FLOAT, period, 3) \ +X(a, STATIC, REPEATED, UENUM, sensor_types, 4) +#define wippersnapper_ds18x20_Ds18x20Add_CALLBACK NULL +#define wippersnapper_ds18x20_Ds18x20Add_DEFAULT NULL + +#define wippersnapper_ds18x20_Ds18x20Added_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, BOOL, is_initialized, 1) \ +X(a, STATIC, SINGULAR, STRING, onewire_pin, 2) +#define wippersnapper_ds18x20_Ds18x20Added_CALLBACK NULL +#define wippersnapper_ds18x20_Ds18x20Added_DEFAULT NULL + +#define wippersnapper_ds18x20_Ds18x20Remove_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, onewire_pin, 1) +#define wippersnapper_ds18x20_Ds18x20Remove_CALLBACK NULL +#define wippersnapper_ds18x20_Ds18x20Remove_DEFAULT NULL + +#define wippersnapper_ds18x20_Ds18x20Event_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, onewire_pin, 1) \ +X(a, STATIC, REPEATED, MESSAGE, sensor_events, 2) +#define wippersnapper_ds18x20_Ds18x20Event_CALLBACK NULL +#define wippersnapper_ds18x20_Ds18x20Event_DEFAULT NULL +#define wippersnapper_ds18x20_Ds18x20Event_sensor_events_MSGTYPE wippersnapper_sensor_SensorEvent + +extern const pb_msgdesc_t wippersnapper_ds18x20_Ds18x20Add_msg; +extern const pb_msgdesc_t wippersnapper_ds18x20_Ds18x20Added_msg; +extern const pb_msgdesc_t wippersnapper_ds18x20_Ds18x20Remove_msg; +extern const pb_msgdesc_t wippersnapper_ds18x20_Ds18x20Event_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define wippersnapper_ds18x20_Ds18x20Add_fields &wippersnapper_ds18x20_Ds18x20Add_msg +#define wippersnapper_ds18x20_Ds18x20Added_fields &wippersnapper_ds18x20_Ds18x20Added_msg +#define wippersnapper_ds18x20_Ds18x20Remove_fields &wippersnapper_ds18x20_Ds18x20Remove_msg +#define wippersnapper_ds18x20_Ds18x20Event_fields &wippersnapper_ds18x20_Ds18x20Event_msg + +/* Maximum encoded size of messages (where known) */ +#define WIPPERSNAPPER_DS18X20_DS18X20_PB_H_MAX_SIZE wippersnapper_ds18x20_Ds18x20Add_size +#define wippersnapper_ds18x20_Ds18x20Add_size 26 +#define wippersnapper_ds18x20_Ds18x20Added_size 8 +#define wippersnapper_ds18x20_Ds18x20Remove_size 6 +#if defined(wippersnapper_sensor_SensorEvent_size) +#define wippersnapper_ds18x20_Ds18x20Event_size (18 + 2*wippersnapper_sensor_SensorEvent_size) +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/protos/error.pb.c b/src/protos/error.pb.c new file mode 100644 index 000000000..431fe48ac --- /dev/null +++ b/src/protos/error.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "error.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(wippersnapper_error_Error, wippersnapper_error_Error, AUTO) + + + diff --git a/src/protos/error.pb.h b/src/protos/error.pb.h new file mode 100644 index 000000000..3ed3fbefc --- /dev/null +++ b/src/protos/error.pb.h @@ -0,0 +1,54 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_WIPPERSNAPPER_ERROR_ERROR_PB_H_INCLUDED +#define PB_WIPPERSNAPPER_ERROR_ERROR_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _wippersnapper_error_Error { + pb_size_t which_payload; + union { + int32_t ban_time; /* Account ban time, in seconds */ + int32_t throttle_time; /* Account time, in seconds */ + } payload; +} wippersnapper_error_Error; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define wippersnapper_error_Error_init_default {0, {0}} +#define wippersnapper_error_Error_init_zero {0, {0}} + +/* Field tags (for use in manual encoding/decoding) */ +#define wippersnapper_error_Error_ban_time_tag 1 +#define wippersnapper_error_Error_throttle_time_tag 2 + +/* Struct field encoding specification for nanopb */ +#define wippersnapper_error_Error_FIELDLIST(X, a) \ +X(a, STATIC, ONEOF, INT32, (payload,ban_time,payload.ban_time), 1) \ +X(a, STATIC, ONEOF, INT32, (payload,throttle_time,payload.throttle_time), 2) +#define wippersnapper_error_Error_CALLBACK NULL +#define wippersnapper_error_Error_DEFAULT NULL + +extern const pb_msgdesc_t wippersnapper_error_Error_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define wippersnapper_error_Error_fields &wippersnapper_error_Error_msg + +/* Maximum encoded size of messages (where known) */ +#define WIPPERSNAPPER_ERROR_ERROR_PB_H_MAX_SIZE wippersnapper_error_Error_size +#define wippersnapper_error_Error_size 11 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/protos/i2c.pb.c b/src/protos/i2c.pb.c new file mode 100644 index 000000000..6428602ee --- /dev/null +++ b/src/protos/i2c.pb.c @@ -0,0 +1,35 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "i2c.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(wippersnapper_i2c_I2cDeviceDescriptor, wippersnapper_i2c_I2cDeviceDescriptor, AUTO) + + +PB_BIND(wippersnapper_i2c_I2cBusScan, wippersnapper_i2c_I2cBusScan, AUTO) + + +PB_BIND(wippersnapper_i2c_I2cBusScanned, wippersnapper_i2c_I2cBusScanned, 4) + + +PB_BIND(wippersnapper_i2c_I2cDeviceAddOrReplace, wippersnapper_i2c_I2cDeviceAddOrReplace, AUTO) + + +PB_BIND(wippersnapper_i2c_I2cDeviceAddedOrReplaced, wippersnapper_i2c_I2cDeviceAddedOrReplaced, AUTO) + + +PB_BIND(wippersnapper_i2c_I2cDeviceRemove, wippersnapper_i2c_I2cDeviceRemove, AUTO) + + +PB_BIND(wippersnapper_i2c_I2cDeviceRemoved, wippersnapper_i2c_I2cDeviceRemoved, AUTO) + + +PB_BIND(wippersnapper_i2c_I2cDeviceEvent, wippersnapper_i2c_I2cDeviceEvent, 2) + + + + + diff --git a/src/protos/i2c.pb.h b/src/protos/i2c.pb.h new file mode 100644 index 000000000..826621304 --- /dev/null +++ b/src/protos/i2c.pb.h @@ -0,0 +1,276 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_WIPPERSNAPPER_I2C_I2C_PB_H_INCLUDED +#define PB_WIPPERSNAPPER_I2C_I2C_PB_H_INCLUDED +#include +#include "sensor.pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Enum definitions */ +/* * + I2cBusStatus represents the status of a board's I2C bus */ +typedef enum _wippersnapper_i2c_I2cBusStatus { + wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_UNSPECIFIED = 0, /* * Unspecified error occurred. * */ + wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_SUCCESS = 1, /* * I2C bus successfully initialized. * */ + wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_ERROR_HANG = 2, /* * I2C Bus hang, user should reset their board if this persists. * */ + wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_ERROR_PULLUPS = 3, /* * I2C bus failed to initialize - SDA or SCL needs a pull up. * */ + wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_ERROR_WIRING = 4, /* * I2C bus failed to communicate - Please check your wiring. * */ + wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_ERROR_INVALID_CHANNEL = 5 /* * I2C MUX failed - Output channel must be within range 0-7. * */ +} wippersnapper_i2c_I2cBusStatus; + +/* * + I2cDeviceStatus represents the state of an I2C device/peripheral */ +typedef enum _wippersnapper_i2c_I2cDeviceStatus { + wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_UNSPECIFIED = 0, /* * Unspecified error occurred. * */ + wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_SUCCESS = 1, /* * I2C device successfully initialized. * */ + wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_FAIL_INIT = 2, /* * I2C device failed to initialize. * */ + wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_FAIL_DEINIT = 3, /* * I2C device failed to deinitialize. * */ + wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_FAIL_UNSUPPORTED_SENSOR = 4, /* * WipperSnapper version is outdated and does not include this device. * */ + wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_NOT_FOUND = 5 /* * I2C device not found on the bus. * */ +} wippersnapper_i2c_I2cDeviceStatus; + +/* Struct definitions */ +/* * + I2cDeviceDescriptor represents the I2c device's address and related metadata. */ +typedef struct _wippersnapper_i2c_I2cDeviceDescriptor { + char i2c_bus_sda[15]; /* * Optional SDA pin for an alt. i2c bus.* */ + char i2c_bus_scl[15]; /* * Optional SCL pin for an alt. i2c bus.* */ + uint32_t i2c_device_address; /* * I2C Device's Address. * */ + uint32_t i2c_mux_address; /* * Optional I2C multiplexer address. * */ + uint32_t i2c_mux_channel; /* * Optional I2C multiplexer channel. * */ +} wippersnapper_i2c_I2cDeviceDescriptor; + +/* * + I2cBusScan represents a command for a device to perform an i2c scan. It is an empty message. */ +typedef struct _wippersnapper_i2c_I2cBusScan { + char dummy_field; +} wippersnapper_i2c_I2cBusScan; + +/* * + I2cBusScanned represents a list of I2c addresses + found on the bus after I2cScan has executed. */ +typedef struct _wippersnapper_i2c_I2cBusScanned { + pb_size_t i2c_bus_found_devices_count; + wippersnapper_i2c_I2cDeviceDescriptor i2c_bus_found_devices[120]; /* * The 7-bit addresses of the I2c devices found on the bus, empty if not found. */ + wippersnapper_i2c_I2cBusStatus i2c_bus_status; /* * The I2c bus' status. * */ +} wippersnapper_i2c_I2cBusScanned; + +/* * + I2cDeviceAddOrReplace is a message for initializing (or replacing/updating) an i2c device. */ +typedef struct _wippersnapper_i2c_I2cDeviceAddOrReplace { + bool has_i2c_device_description; + wippersnapper_i2c_I2cDeviceDescriptor i2c_device_description; /* * The I2c device's address and metadata. */ + char i2c_device_name[15]; /* * The I2c device's name, MUST MATCH the name on the JSON definition file on +https://github.com/adafruit/Wippersnapper_Components. */ + float i2c_device_period; /* * The desired period to update the I2c device's sensor(s), in seconds. */ + pb_size_t i2c_device_sensor_types_count; + wippersnapper_sensor_SensorType i2c_device_sensor_types[15]; /* * SI Types for each sensor on the I2c device. */ +} wippersnapper_i2c_I2cDeviceAddOrReplace; + +/* * + I2cDeviceAddedOrReplaced contains the response from a device after processing a I2cDeviceAddOrReplace message. */ +typedef struct _wippersnapper_i2c_I2cDeviceAddedOrReplaced { + bool has_i2c_device_description; + wippersnapper_i2c_I2cDeviceDescriptor i2c_device_description; /* * The I2c device's address and metadata. */ + wippersnapper_i2c_I2cBusStatus i2c_bus_status; /* * The I2c bus' status. * */ + wippersnapper_i2c_I2cDeviceStatus i2c_device_status; /* * The I2c device's status. * */ +} wippersnapper_i2c_I2cDeviceAddedOrReplaced; + +/* * + I2cDeviceRemove represents a request to de-init an i2c device. */ +typedef struct _wippersnapper_i2c_I2cDeviceRemove { + bool has_i2c_device_description; + wippersnapper_i2c_I2cDeviceDescriptor i2c_device_description; /* * The I2c device's address and metadata. */ +} wippersnapper_i2c_I2cDeviceRemove; + +/* * + I2cDeviceRemoved represents a response to a I2cDeviceRemove message. */ +typedef struct _wippersnapper_i2c_I2cDeviceRemoved { + bool has_i2c_device_description; + wippersnapper_i2c_I2cDeviceDescriptor i2c_device_description; /* * The I2c device's address and metadata. */ + wippersnapper_i2c_I2cBusStatus i2c_bus_status; /* * The I2c bus' status. * */ + wippersnapper_i2c_I2cDeviceStatus i2c_device_status; /* * The I2c device's status. * */ +} wippersnapper_i2c_I2cDeviceRemoved; + +/* * + Each I2cDeviceEvent represents data from **one** I2c sensor. + NOTE: An I2cDeviceEvent can have multiple sensor events if + the I2c device contains > 1 sensor. */ +typedef struct _wippersnapper_i2c_I2cDeviceEvent { + bool has_i2c_device_description; + wippersnapper_i2c_I2cDeviceDescriptor i2c_device_description; /* * The I2c device's address and metadata. */ + pb_size_t i2c_device_events_count; + wippersnapper_sensor_SensorEvent i2c_device_events[15]; /* * A, optionally repeated, SensorEvent from a sensor. */ +} wippersnapper_i2c_I2cDeviceEvent; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Helper constants for enums */ +#define _wippersnapper_i2c_I2cBusStatus_MIN wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_UNSPECIFIED +#define _wippersnapper_i2c_I2cBusStatus_MAX wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_ERROR_INVALID_CHANNEL +#define _wippersnapper_i2c_I2cBusStatus_ARRAYSIZE ((wippersnapper_i2c_I2cBusStatus)(wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_ERROR_INVALID_CHANNEL+1)) + +#define _wippersnapper_i2c_I2cDeviceStatus_MIN wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_UNSPECIFIED +#define _wippersnapper_i2c_I2cDeviceStatus_MAX wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_NOT_FOUND +#define _wippersnapper_i2c_I2cDeviceStatus_ARRAYSIZE ((wippersnapper_i2c_I2cDeviceStatus)(wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_NOT_FOUND+1)) + + + +#define wippersnapper_i2c_I2cBusScanned_i2c_bus_status_ENUMTYPE wippersnapper_i2c_I2cBusStatus + +#define wippersnapper_i2c_I2cDeviceAddOrReplace_i2c_device_sensor_types_ENUMTYPE wippersnapper_sensor_SensorType + +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_i2c_bus_status_ENUMTYPE wippersnapper_i2c_I2cBusStatus +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_i2c_device_status_ENUMTYPE wippersnapper_i2c_I2cDeviceStatus + + +#define wippersnapper_i2c_I2cDeviceRemoved_i2c_bus_status_ENUMTYPE wippersnapper_i2c_I2cBusStatus +#define wippersnapper_i2c_I2cDeviceRemoved_i2c_device_status_ENUMTYPE wippersnapper_i2c_I2cDeviceStatus + + + +/* Initializer values for message structs */ +#define wippersnapper_i2c_I2cDeviceDescriptor_init_default {"", "", 0, 0, 0} +#define wippersnapper_i2c_I2cBusScan_init_default {0} +#define wippersnapper_i2c_I2cBusScanned_init_default {0, {wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default, wippersnapper_i2c_I2cDeviceDescriptor_init_default}, _wippersnapper_i2c_I2cBusStatus_MIN} +#define wippersnapper_i2c_I2cDeviceAddOrReplace_init_default {false, wippersnapper_i2c_I2cDeviceDescriptor_init_default, "", 0, 0, {_wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN}} +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_init_default {false, wippersnapper_i2c_I2cDeviceDescriptor_init_default, _wippersnapper_i2c_I2cBusStatus_MIN, _wippersnapper_i2c_I2cDeviceStatus_MIN} +#define wippersnapper_i2c_I2cDeviceRemove_init_default {false, wippersnapper_i2c_I2cDeviceDescriptor_init_default} +#define wippersnapper_i2c_I2cDeviceRemoved_init_default {false, wippersnapper_i2c_I2cDeviceDescriptor_init_default, _wippersnapper_i2c_I2cBusStatus_MIN, _wippersnapper_i2c_I2cDeviceStatus_MIN} +#define wippersnapper_i2c_I2cDeviceEvent_init_default {false, wippersnapper_i2c_I2cDeviceDescriptor_init_default, 0, {wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default, wippersnapper_sensor_SensorEvent_init_default}} +#define wippersnapper_i2c_I2cDeviceDescriptor_init_zero {"", "", 0, 0, 0} +#define wippersnapper_i2c_I2cBusScan_init_zero {0} +#define wippersnapper_i2c_I2cBusScanned_init_zero {0, {wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, wippersnapper_i2c_I2cDeviceDescriptor_init_zero}, _wippersnapper_i2c_I2cBusStatus_MIN} +#define wippersnapper_i2c_I2cDeviceAddOrReplace_init_zero {false, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, "", 0, 0, {_wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN, _wippersnapper_sensor_SensorType_MIN}} +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_init_zero {false, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, _wippersnapper_i2c_I2cBusStatus_MIN, _wippersnapper_i2c_I2cDeviceStatus_MIN} +#define wippersnapper_i2c_I2cDeviceRemove_init_zero {false, wippersnapper_i2c_I2cDeviceDescriptor_init_zero} +#define wippersnapper_i2c_I2cDeviceRemoved_init_zero {false, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, _wippersnapper_i2c_I2cBusStatus_MIN, _wippersnapper_i2c_I2cDeviceStatus_MIN} +#define wippersnapper_i2c_I2cDeviceEvent_init_zero {false, wippersnapper_i2c_I2cDeviceDescriptor_init_zero, 0, {wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero, wippersnapper_sensor_SensorEvent_init_zero}} + +/* Field tags (for use in manual encoding/decoding) */ +#define wippersnapper_i2c_I2cDeviceDescriptor_i2c_bus_sda_tag 1 +#define wippersnapper_i2c_I2cDeviceDescriptor_i2c_bus_scl_tag 2 +#define wippersnapper_i2c_I2cDeviceDescriptor_i2c_device_address_tag 3 +#define wippersnapper_i2c_I2cDeviceDescriptor_i2c_mux_address_tag 4 +#define wippersnapper_i2c_I2cDeviceDescriptor_i2c_mux_channel_tag 5 +#define wippersnapper_i2c_I2cBusScanned_i2c_bus_found_devices_tag 1 +#define wippersnapper_i2c_I2cBusScanned_i2c_bus_status_tag 2 +#define wippersnapper_i2c_I2cDeviceAddOrReplace_i2c_device_description_tag 1 +#define wippersnapper_i2c_I2cDeviceAddOrReplace_i2c_device_name_tag 2 +#define wippersnapper_i2c_I2cDeviceAddOrReplace_i2c_device_period_tag 3 +#define wippersnapper_i2c_I2cDeviceAddOrReplace_i2c_device_sensor_types_tag 4 +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_i2c_device_description_tag 1 +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_i2c_bus_status_tag 2 +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_i2c_device_status_tag 3 +#define wippersnapper_i2c_I2cDeviceRemove_i2c_device_description_tag 1 +#define wippersnapper_i2c_I2cDeviceRemoved_i2c_device_description_tag 1 +#define wippersnapper_i2c_I2cDeviceRemoved_i2c_bus_status_tag 2 +#define wippersnapper_i2c_I2cDeviceRemoved_i2c_device_status_tag 3 +#define wippersnapper_i2c_I2cDeviceEvent_i2c_device_description_tag 1 +#define wippersnapper_i2c_I2cDeviceEvent_i2c_device_events_tag 2 + +/* Struct field encoding specification for nanopb */ +#define wippersnapper_i2c_I2cDeviceDescriptor_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, i2c_bus_sda, 1) \ +X(a, STATIC, SINGULAR, STRING, i2c_bus_scl, 2) \ +X(a, STATIC, SINGULAR, UINT32, i2c_device_address, 3) \ +X(a, STATIC, SINGULAR, UINT32, i2c_mux_address, 4) \ +X(a, STATIC, SINGULAR, UINT32, i2c_mux_channel, 5) +#define wippersnapper_i2c_I2cDeviceDescriptor_CALLBACK NULL +#define wippersnapper_i2c_I2cDeviceDescriptor_DEFAULT NULL + +#define wippersnapper_i2c_I2cBusScan_FIELDLIST(X, a) \ + +#define wippersnapper_i2c_I2cBusScan_CALLBACK NULL +#define wippersnapper_i2c_I2cBusScan_DEFAULT NULL + +#define wippersnapper_i2c_I2cBusScanned_FIELDLIST(X, a) \ +X(a, STATIC, REPEATED, MESSAGE, i2c_bus_found_devices, 1) \ +X(a, STATIC, SINGULAR, UENUM, i2c_bus_status, 2) +#define wippersnapper_i2c_I2cBusScanned_CALLBACK NULL +#define wippersnapper_i2c_I2cBusScanned_DEFAULT NULL +#define wippersnapper_i2c_I2cBusScanned_i2c_bus_found_devices_MSGTYPE wippersnapper_i2c_I2cDeviceDescriptor + +#define wippersnapper_i2c_I2cDeviceAddOrReplace_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, i2c_device_description, 1) \ +X(a, STATIC, SINGULAR, STRING, i2c_device_name, 2) \ +X(a, STATIC, SINGULAR, FLOAT, i2c_device_period, 3) \ +X(a, STATIC, REPEATED, UENUM, i2c_device_sensor_types, 4) +#define wippersnapper_i2c_I2cDeviceAddOrReplace_CALLBACK NULL +#define wippersnapper_i2c_I2cDeviceAddOrReplace_DEFAULT NULL +#define wippersnapper_i2c_I2cDeviceAddOrReplace_i2c_device_description_MSGTYPE wippersnapper_i2c_I2cDeviceDescriptor + +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, i2c_device_description, 1) \ +X(a, STATIC, SINGULAR, UENUM, i2c_bus_status, 2) \ +X(a, STATIC, SINGULAR, UENUM, i2c_device_status, 3) +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_CALLBACK NULL +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_DEFAULT NULL +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_i2c_device_description_MSGTYPE wippersnapper_i2c_I2cDeviceDescriptor + +#define wippersnapper_i2c_I2cDeviceRemove_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, i2c_device_description, 1) +#define wippersnapper_i2c_I2cDeviceRemove_CALLBACK NULL +#define wippersnapper_i2c_I2cDeviceRemove_DEFAULT NULL +#define wippersnapper_i2c_I2cDeviceRemove_i2c_device_description_MSGTYPE wippersnapper_i2c_I2cDeviceDescriptor + +#define wippersnapper_i2c_I2cDeviceRemoved_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, i2c_device_description, 1) \ +X(a, STATIC, SINGULAR, UENUM, i2c_bus_status, 2) \ +X(a, STATIC, SINGULAR, UENUM, i2c_device_status, 3) +#define wippersnapper_i2c_I2cDeviceRemoved_CALLBACK NULL +#define wippersnapper_i2c_I2cDeviceRemoved_DEFAULT NULL +#define wippersnapper_i2c_I2cDeviceRemoved_i2c_device_description_MSGTYPE wippersnapper_i2c_I2cDeviceDescriptor + +#define wippersnapper_i2c_I2cDeviceEvent_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, i2c_device_description, 1) \ +X(a, STATIC, REPEATED, MESSAGE, i2c_device_events, 2) +#define wippersnapper_i2c_I2cDeviceEvent_CALLBACK NULL +#define wippersnapper_i2c_I2cDeviceEvent_DEFAULT NULL +#define wippersnapper_i2c_I2cDeviceEvent_i2c_device_description_MSGTYPE wippersnapper_i2c_I2cDeviceDescriptor +#define wippersnapper_i2c_I2cDeviceEvent_i2c_device_events_MSGTYPE wippersnapper_sensor_SensorEvent + +extern const pb_msgdesc_t wippersnapper_i2c_I2cDeviceDescriptor_msg; +extern const pb_msgdesc_t wippersnapper_i2c_I2cBusScan_msg; +extern const pb_msgdesc_t wippersnapper_i2c_I2cBusScanned_msg; +extern const pb_msgdesc_t wippersnapper_i2c_I2cDeviceAddOrReplace_msg; +extern const pb_msgdesc_t wippersnapper_i2c_I2cDeviceAddedOrReplaced_msg; +extern const pb_msgdesc_t wippersnapper_i2c_I2cDeviceRemove_msg; +extern const pb_msgdesc_t wippersnapper_i2c_I2cDeviceRemoved_msg; +extern const pb_msgdesc_t wippersnapper_i2c_I2cDeviceEvent_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define wippersnapper_i2c_I2cDeviceDescriptor_fields &wippersnapper_i2c_I2cDeviceDescriptor_msg +#define wippersnapper_i2c_I2cBusScan_fields &wippersnapper_i2c_I2cBusScan_msg +#define wippersnapper_i2c_I2cBusScanned_fields &wippersnapper_i2c_I2cBusScanned_msg +#define wippersnapper_i2c_I2cDeviceAddOrReplace_fields &wippersnapper_i2c_I2cDeviceAddOrReplace_msg +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_fields &wippersnapper_i2c_I2cDeviceAddedOrReplaced_msg +#define wippersnapper_i2c_I2cDeviceRemove_fields &wippersnapper_i2c_I2cDeviceRemove_msg +#define wippersnapper_i2c_I2cDeviceRemoved_fields &wippersnapper_i2c_I2cDeviceRemoved_msg +#define wippersnapper_i2c_I2cDeviceEvent_fields &wippersnapper_i2c_I2cDeviceEvent_msg + +/* Maximum encoded size of messages (where known) */ +#define WIPPERSNAPPER_I2C_I2C_PB_H_MAX_SIZE wippersnapper_i2c_I2cBusScanned_size +#define wippersnapper_i2c_I2cBusScan_size 0 +#define wippersnapper_i2c_I2cBusScanned_size 6242 +#define wippersnapper_i2c_I2cDeviceAddOrReplace_size 103 +#define wippersnapper_i2c_I2cDeviceAddedOrReplaced_size 56 +#define wippersnapper_i2c_I2cDeviceDescriptor_size 50 +#define wippersnapper_i2c_I2cDeviceRemove_size 52 +#define wippersnapper_i2c_I2cDeviceRemoved_size 56 +#if defined(wippersnapper_sensor_SensorEvent_size) +#define wippersnapper_i2c_I2cDeviceEvent_size (142 + 15*wippersnapper_sensor_SensorEvent_size) +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/protos/pixels.pb.c b/src/protos/pixels.pb.c new file mode 100644 index 000000000..21a6eed14 --- /dev/null +++ b/src/protos/pixels.pb.c @@ -0,0 +1,23 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "pixels.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(wippersnapper_pixels_PixelsAdd, wippersnapper_pixels_PixelsAdd, AUTO) + + +PB_BIND(wippersnapper_pixels_PixelsAdded, wippersnapper_pixels_PixelsAdded, AUTO) + + +PB_BIND(wippersnapper_pixels_PixelsRemove, wippersnapper_pixels_PixelsRemove, AUTO) + + +PB_BIND(wippersnapper_pixels_PixelsWrite, wippersnapper_pixels_PixelsWrite, AUTO) + + + + + diff --git a/src/protos/pixels.pb.h b/src/protos/pixels.pb.h new file mode 100644 index 000000000..b2b1c23b5 --- /dev/null +++ b/src/protos/pixels.pb.h @@ -0,0 +1,167 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_WIPPERSNAPPER_PIXELS_PIXELS_PB_H_INCLUDED +#define PB_WIPPERSNAPPER_PIXELS_PIXELS_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Enum definitions */ +/* * + PixelsType defines the type/model of pixel strand. */ +typedef enum _wippersnapper_pixels_PixelsType { + wippersnapper_pixels_PixelsType_PIXELS_TYPE_UNSPECIFIED = 0, /* * Unspecified pixel type, error. */ + wippersnapper_pixels_PixelsType_PIXELS_TYPE_NEOPIXEL = 1, /* * NeoPixel pixel strand. */ + wippersnapper_pixels_PixelsType_PIXELS_TYPE_DOTSTAR = 2 /* * DotStar pixel strand. */ +} wippersnapper_pixels_PixelsType; + +/* * + PixelsOrder defines the color ordering. */ +typedef enum _wippersnapper_pixels_PixelsOrder { + wippersnapper_pixels_PixelsOrder_PIXELS_ORDER_UNSPECIFIED = 0, /* * Unspecified color ordering, error. */ + wippersnapper_pixels_PixelsOrder_PIXELS_ORDER_GRB = 1, /* * DEFAULT for NeoPixels - Green, Red, Blue */ + wippersnapper_pixels_PixelsOrder_PIXELS_ORDER_GRBW = 2, /* * Green, Red, Blue, White */ + wippersnapper_pixels_PixelsOrder_PIXELS_ORDER_RGB = 3, /* * Red, Green, Blue */ + wippersnapper_pixels_PixelsOrder_PIXELS_ORDER_RGBW = 4, /* * Red, Green, Blue, White */ + wippersnapper_pixels_PixelsOrder_PIXELS_ORDER_BRG = 5, /* * DEFAULT for DotStars - Blue, Red, Green */ + wippersnapper_pixels_PixelsOrder_PIXELS_ORDER_RBG = 6, /* * Red, Blue Green */ + wippersnapper_pixels_PixelsOrder_PIXELS_ORDER_GBR = 7, /* * Green, Blue, Red */ + wippersnapper_pixels_PixelsOrder_PIXELS_ORDER_BGR = 8 /* * Blue, Green, Red */ +} wippersnapper_pixels_PixelsOrder; + +/* Struct definitions */ +/* * + PixelsAdd represents a call from IO to a device. + Adds a strand of addressable pixels. + Initial brightness is always 128. */ +typedef struct _wippersnapper_pixels_PixelsAdd { + wippersnapper_pixels_PixelsType pixels_type; /* * Defines the model/type of pixel strand */ + uint32_t pixels_num; /* * Number of pixels attached to strand. */ + wippersnapper_pixels_PixelsOrder pixels_ordering; /* * Defines the pixel strand's color ordering. */ + uint32_t pixels_brightness; /* * Strand brightness, 0 to 255 */ + char pixels_pin_data[6]; /* * Data pin a NeoPixel or DotStar strand is connected to. */ + char pixels_pin_dotstar_clock[6]; /* * Clock pin a DotStar strand is connected to. */ +} wippersnapper_pixels_PixelsAdd; + +/* * + PixelsAdded represents response from a WipperSnapper + device to IO after a PixelsAdd call */ +typedef struct _wippersnapper_pixels_PixelsAdded { + bool is_success; /* * True if the strand initialized successfully, False otherwise. */ + char pixels_pin_data[6]; /* * Data pin the responding strand is connected to. */ +} wippersnapper_pixels_PixelsAdded; + +/* * + PixelAdd represents a call from IO to a device + Removes a strand of addressable pixels and release the resources and pin. */ +typedef struct _wippersnapper_pixels_PixelsRemove { + char pixels_pin_data[6]; /* * Data pin the pixel strand is connected to. */ +} wippersnapper_pixels_PixelsRemove; + +/* * + PixelsWrite represents a call from IO to a device. + Writes to a strand of pixels. */ +typedef struct _wippersnapper_pixels_PixelsWrite { + char pixels_pin_data[6]; /* * Data pin a strand is connected to. */ + uint32_t pixels_color; /* 32-bit color value. Most significant byte is white (for RGBW pixels) or ignored (for RGB pixels), +next is red, then green, and least significant byte is blue. */ +} wippersnapper_pixels_PixelsWrite; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Helper constants for enums */ +#define _wippersnapper_pixels_PixelsType_MIN wippersnapper_pixels_PixelsType_PIXELS_TYPE_UNSPECIFIED +#define _wippersnapper_pixels_PixelsType_MAX wippersnapper_pixels_PixelsType_PIXELS_TYPE_DOTSTAR +#define _wippersnapper_pixels_PixelsType_ARRAYSIZE ((wippersnapper_pixels_PixelsType)(wippersnapper_pixels_PixelsType_PIXELS_TYPE_DOTSTAR+1)) + +#define _wippersnapper_pixels_PixelsOrder_MIN wippersnapper_pixels_PixelsOrder_PIXELS_ORDER_UNSPECIFIED +#define _wippersnapper_pixels_PixelsOrder_MAX wippersnapper_pixels_PixelsOrder_PIXELS_ORDER_BGR +#define _wippersnapper_pixels_PixelsOrder_ARRAYSIZE ((wippersnapper_pixels_PixelsOrder)(wippersnapper_pixels_PixelsOrder_PIXELS_ORDER_BGR+1)) + +#define wippersnapper_pixels_PixelsAdd_pixels_type_ENUMTYPE wippersnapper_pixels_PixelsType +#define wippersnapper_pixels_PixelsAdd_pixels_ordering_ENUMTYPE wippersnapper_pixels_PixelsOrder + + + + + +/* Initializer values for message structs */ +#define wippersnapper_pixels_PixelsAdd_init_default {_wippersnapper_pixels_PixelsType_MIN, 0, _wippersnapper_pixels_PixelsOrder_MIN, 0, "", ""} +#define wippersnapper_pixels_PixelsAdded_init_default {0, ""} +#define wippersnapper_pixels_PixelsRemove_init_default {""} +#define wippersnapper_pixels_PixelsWrite_init_default {"", 0} +#define wippersnapper_pixels_PixelsAdd_init_zero {_wippersnapper_pixels_PixelsType_MIN, 0, _wippersnapper_pixels_PixelsOrder_MIN, 0, "", ""} +#define wippersnapper_pixels_PixelsAdded_init_zero {0, ""} +#define wippersnapper_pixels_PixelsRemove_init_zero {""} +#define wippersnapper_pixels_PixelsWrite_init_zero {"", 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define wippersnapper_pixels_PixelsAdd_pixels_type_tag 1 +#define wippersnapper_pixels_PixelsAdd_pixels_num_tag 2 +#define wippersnapper_pixels_PixelsAdd_pixels_ordering_tag 3 +#define wippersnapper_pixels_PixelsAdd_pixels_brightness_tag 4 +#define wippersnapper_pixels_PixelsAdd_pixels_pin_data_tag 5 +#define wippersnapper_pixels_PixelsAdd_pixels_pin_dotstar_clock_tag 6 +#define wippersnapper_pixels_PixelsAdded_is_success_tag 1 +#define wippersnapper_pixels_PixelsAdded_pixels_pin_data_tag 2 +#define wippersnapper_pixels_PixelsRemove_pixels_pin_data_tag 1 +#define wippersnapper_pixels_PixelsWrite_pixels_pin_data_tag 1 +#define wippersnapper_pixels_PixelsWrite_pixels_color_tag 2 + +/* Struct field encoding specification for nanopb */ +#define wippersnapper_pixels_PixelsAdd_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, pixels_type, 1) \ +X(a, STATIC, SINGULAR, UINT32, pixels_num, 2) \ +X(a, STATIC, SINGULAR, UENUM, pixels_ordering, 3) \ +X(a, STATIC, SINGULAR, UINT32, pixels_brightness, 4) \ +X(a, STATIC, SINGULAR, STRING, pixels_pin_data, 5) \ +X(a, STATIC, SINGULAR, STRING, pixels_pin_dotstar_clock, 6) +#define wippersnapper_pixels_PixelsAdd_CALLBACK NULL +#define wippersnapper_pixels_PixelsAdd_DEFAULT NULL + +#define wippersnapper_pixels_PixelsAdded_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, BOOL, is_success, 1) \ +X(a, STATIC, SINGULAR, STRING, pixels_pin_data, 2) +#define wippersnapper_pixels_PixelsAdded_CALLBACK NULL +#define wippersnapper_pixels_PixelsAdded_DEFAULT NULL + +#define wippersnapper_pixels_PixelsRemove_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pixels_pin_data, 1) +#define wippersnapper_pixels_PixelsRemove_CALLBACK NULL +#define wippersnapper_pixels_PixelsRemove_DEFAULT NULL + +#define wippersnapper_pixels_PixelsWrite_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pixels_pin_data, 1) \ +X(a, STATIC, SINGULAR, UINT32, pixels_color, 2) +#define wippersnapper_pixels_PixelsWrite_CALLBACK NULL +#define wippersnapper_pixels_PixelsWrite_DEFAULT NULL + +extern const pb_msgdesc_t wippersnapper_pixels_PixelsAdd_msg; +extern const pb_msgdesc_t wippersnapper_pixels_PixelsAdded_msg; +extern const pb_msgdesc_t wippersnapper_pixels_PixelsRemove_msg; +extern const pb_msgdesc_t wippersnapper_pixels_PixelsWrite_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define wippersnapper_pixels_PixelsAdd_fields &wippersnapper_pixels_PixelsAdd_msg +#define wippersnapper_pixels_PixelsAdded_fields &wippersnapper_pixels_PixelsAdded_msg +#define wippersnapper_pixels_PixelsRemove_fields &wippersnapper_pixels_PixelsRemove_msg +#define wippersnapper_pixels_PixelsWrite_fields &wippersnapper_pixels_PixelsWrite_msg + +/* Maximum encoded size of messages (where known) */ +#define WIPPERSNAPPER_PIXELS_PIXELS_PB_H_MAX_SIZE wippersnapper_pixels_PixelsAdd_size +#define wippersnapper_pixels_PixelsAdd_size 30 +#define wippersnapper_pixels_PixelsAdded_size 9 +#define wippersnapper_pixels_PixelsRemove_size 7 +#define wippersnapper_pixels_PixelsWrite_size 13 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/protos/pwm.pb.c b/src/protos/pwm.pb.c new file mode 100644 index 000000000..9d52e1045 --- /dev/null +++ b/src/protos/pwm.pb.c @@ -0,0 +1,27 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "pwm.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(wippersnapper_pwm_PWMAdd, wippersnapper_pwm_PWMAdd, AUTO) + + +PB_BIND(wippersnapper_pwm_PWMAdded, wippersnapper_pwm_PWMAdded, AUTO) + + +PB_BIND(wippersnapper_pwm_PWMRemove, wippersnapper_pwm_PWMRemove, AUTO) + + +PB_BIND(wippersnapper_pwm_PWMWriteDutyCycle, wippersnapper_pwm_PWMWriteDutyCycle, AUTO) + + +PB_BIND(wippersnapper_pwm_PWMWriteDutyCycleMulti, wippersnapper_pwm_PWMWriteDutyCycleMulti, AUTO) + + +PB_BIND(wippersnapper_pwm_PWMWriteFrequency, wippersnapper_pwm_PWMWriteFrequency, AUTO) + + + diff --git a/src/protos/pwm.pb.h b/src/protos/pwm.pb.h new file mode 100644 index 000000000..0f3083a2d --- /dev/null +++ b/src/protos/pwm.pb.h @@ -0,0 +1,161 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_WIPPERSNAPPER_PWM_PWM_PB_H_INCLUDED +#define PB_WIPPERSNAPPER_PWM_PWM_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +/* * + PWMAdd represents a to a device to attach/allocate a PWM pin. + On ESP32 Arduino, this will "attach" a pin to a LEDC channel/timer group. + On non-ESP32 Arduino, this does nothing. */ +typedef struct _wippersnapper_pwm_PWMAdd { + char pin[6]; /* * The pin to be attached. */ + int32_t frequency; /* * PWM frequency of an analog pin, in Hz. * */ + int32_t resolution; /* * The resolution of an analog pin, in bits. * */ +} wippersnapper_pwm_PWMAdd; + +/* * + PWMAdded represents a response from a device's execution of an + Add message. */ +typedef struct _wippersnapper_pwm_PWMAdded { + char pin[6]; /* * The ed pin. */ + bool did_attach; /* * True if Add successful, False otherwise. */ +} wippersnapper_pwm_PWMAdded; + +/* * + PWMRemove represents a to stop PWM'ing and release the pin for re-use. + On ESP32, this will "detach" a pin from a LEDC channel/timer group. + On non-ESP32 Arduino, this calls digitalWrite(LOW) on the pin */ +typedef struct _wippersnapper_pwm_PWMRemove { + char pin[6]; /* * The PWM pin to de-initialized. */ +} wippersnapper_pwm_PWMRemove; + +/* * + PWMWriteDutyCycle represents a to write a duty cycle to a pin with a frequency (fixed). + This is used for controlling LEDs. */ +typedef struct _wippersnapper_pwm_PWMWriteDutyCycle { + char pin[6]; /* * The pin to write to. */ + int32_t duty_cycle; /* * The desired duty cycle to write (range is from 0 to (2 ** duty_resolution)). +This value will be changed by the slider on Adafruit IO. * */ +} wippersnapper_pwm_PWMWriteDutyCycle; + +/* * + PWMWriteDutyCycleMulti represents a wrapper to write duty cycles to multiple pins. + This is used for controlling RGB/RGBW LEDs. */ +typedef struct _wippersnapper_pwm_PWMWriteDutyCycleMulti { + pb_size_t write_duty_cycle_reqs_count; + wippersnapper_pwm_PWMWriteDutyCycle write_duty_cycle_reqs[4]; /* * Multiple duty cycles to write, one per pin of a RGB LED. * */ +} wippersnapper_pwm_PWMWriteDutyCycleMulti; + +/* * + PWMWriteFrequency represents a to write a Frequency, in Hz, to a pin with a duty cycle of 50%. + This is used for playing tones using a piezo buzzer or speaker. */ +typedef struct _wippersnapper_pwm_PWMWriteFrequency { + char pin[6]; /* * The pin to write to. */ + int32_t frequency; /* * The desired PWM frequency, in Hz. This value will be changed by the slider on Adafruit IO. * */ +} wippersnapper_pwm_PWMWriteFrequency; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define wippersnapper_pwm_PWMAdd_init_default {"", 0, 0} +#define wippersnapper_pwm_PWMAdded_init_default {"", 0} +#define wippersnapper_pwm_PWMRemove_init_default {""} +#define wippersnapper_pwm_PWMWriteDutyCycle_init_default {"", 0} +#define wippersnapper_pwm_PWMWriteDutyCycleMulti_init_default {0, {wippersnapper_pwm_PWMWriteDutyCycle_init_default, wippersnapper_pwm_PWMWriteDutyCycle_init_default, wippersnapper_pwm_PWMWriteDutyCycle_init_default, wippersnapper_pwm_PWMWriteDutyCycle_init_default}} +#define wippersnapper_pwm_PWMWriteFrequency_init_default {"", 0} +#define wippersnapper_pwm_PWMAdd_init_zero {"", 0, 0} +#define wippersnapper_pwm_PWMAdded_init_zero {"", 0} +#define wippersnapper_pwm_PWMRemove_init_zero {""} +#define wippersnapper_pwm_PWMWriteDutyCycle_init_zero {"", 0} +#define wippersnapper_pwm_PWMWriteDutyCycleMulti_init_zero {0, {wippersnapper_pwm_PWMWriteDutyCycle_init_zero, wippersnapper_pwm_PWMWriteDutyCycle_init_zero, wippersnapper_pwm_PWMWriteDutyCycle_init_zero, wippersnapper_pwm_PWMWriteDutyCycle_init_zero}} +#define wippersnapper_pwm_PWMWriteFrequency_init_zero {"", 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define wippersnapper_pwm_PWMAdd_pin_tag 1 +#define wippersnapper_pwm_PWMAdd_frequency_tag 2 +#define wippersnapper_pwm_PWMAdd_resolution_tag 3 +#define wippersnapper_pwm_PWMAdded_pin_tag 1 +#define wippersnapper_pwm_PWMAdded_did_attach_tag 2 +#define wippersnapper_pwm_PWMRemove_pin_tag 1 +#define wippersnapper_pwm_PWMWriteDutyCycle_pin_tag 1 +#define wippersnapper_pwm_PWMWriteDutyCycle_duty_cycle_tag 2 +#define wippersnapper_pwm_PWMWriteDutyCycleMulti_write_duty_cycle_reqs_tag 1 +#define wippersnapper_pwm_PWMWriteFrequency_pin_tag 1 +#define wippersnapper_pwm_PWMWriteFrequency_frequency_tag 2 + +/* Struct field encoding specification for nanopb */ +#define wippersnapper_pwm_PWMAdd_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pin, 1) \ +X(a, STATIC, SINGULAR, INT32, frequency, 2) \ +X(a, STATIC, SINGULAR, INT32, resolution, 3) +#define wippersnapper_pwm_PWMAdd_CALLBACK NULL +#define wippersnapper_pwm_PWMAdd_DEFAULT NULL + +#define wippersnapper_pwm_PWMAdded_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pin, 1) \ +X(a, STATIC, SINGULAR, BOOL, did_attach, 2) +#define wippersnapper_pwm_PWMAdded_CALLBACK NULL +#define wippersnapper_pwm_PWMAdded_DEFAULT NULL + +#define wippersnapper_pwm_PWMRemove_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pin, 1) +#define wippersnapper_pwm_PWMRemove_CALLBACK NULL +#define wippersnapper_pwm_PWMRemove_DEFAULT NULL + +#define wippersnapper_pwm_PWMWriteDutyCycle_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pin, 1) \ +X(a, STATIC, SINGULAR, INT32, duty_cycle, 2) +#define wippersnapper_pwm_PWMWriteDutyCycle_CALLBACK NULL +#define wippersnapper_pwm_PWMWriteDutyCycle_DEFAULT NULL + +#define wippersnapper_pwm_PWMWriteDutyCycleMulti_FIELDLIST(X, a) \ +X(a, STATIC, REPEATED, MESSAGE, write_duty_cycle_reqs, 1) +#define wippersnapper_pwm_PWMWriteDutyCycleMulti_CALLBACK NULL +#define wippersnapper_pwm_PWMWriteDutyCycleMulti_DEFAULT NULL +#define wippersnapper_pwm_PWMWriteDutyCycleMulti_write_duty_cycle_reqs_MSGTYPE wippersnapper_pwm_PWMWriteDutyCycle + +#define wippersnapper_pwm_PWMWriteFrequency_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, pin, 1) \ +X(a, STATIC, SINGULAR, INT32, frequency, 2) +#define wippersnapper_pwm_PWMWriteFrequency_CALLBACK NULL +#define wippersnapper_pwm_PWMWriteFrequency_DEFAULT NULL + +extern const pb_msgdesc_t wippersnapper_pwm_PWMAdd_msg; +extern const pb_msgdesc_t wippersnapper_pwm_PWMAdded_msg; +extern const pb_msgdesc_t wippersnapper_pwm_PWMRemove_msg; +extern const pb_msgdesc_t wippersnapper_pwm_PWMWriteDutyCycle_msg; +extern const pb_msgdesc_t wippersnapper_pwm_PWMWriteDutyCycleMulti_msg; +extern const pb_msgdesc_t wippersnapper_pwm_PWMWriteFrequency_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define wippersnapper_pwm_PWMAdd_fields &wippersnapper_pwm_PWMAdd_msg +#define wippersnapper_pwm_PWMAdded_fields &wippersnapper_pwm_PWMAdded_msg +#define wippersnapper_pwm_PWMRemove_fields &wippersnapper_pwm_PWMRemove_msg +#define wippersnapper_pwm_PWMWriteDutyCycle_fields &wippersnapper_pwm_PWMWriteDutyCycle_msg +#define wippersnapper_pwm_PWMWriteDutyCycleMulti_fields &wippersnapper_pwm_PWMWriteDutyCycleMulti_msg +#define wippersnapper_pwm_PWMWriteFrequency_fields &wippersnapper_pwm_PWMWriteFrequency_msg + +/* Maximum encoded size of messages (where known) */ +#define WIPPERSNAPPER_PWM_PWM_PB_H_MAX_SIZE wippersnapper_pwm_PWMWriteDutyCycleMulti_size +#define wippersnapper_pwm_PWMAdd_size 29 +#define wippersnapper_pwm_PWMAdded_size 9 +#define wippersnapper_pwm_PWMRemove_size 7 +#define wippersnapper_pwm_PWMWriteDutyCycleMulti_size 80 +#define wippersnapper_pwm_PWMWriteDutyCycle_size 18 +#define wippersnapper_pwm_PWMWriteFrequency_size 18 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/protos/sensor.pb.c b/src/protos/sensor.pb.c new file mode 100644 index 000000000..6aabf0885 --- /dev/null +++ b/src/protos/sensor.pb.c @@ -0,0 +1,22 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "sensor.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(wippersnapper_sensor_SensorEvent, wippersnapper_sensor_SensorEvent, AUTO) + + +PB_BIND(wippersnapper_sensor_SensorEvent_SensorEventColor, wippersnapper_sensor_SensorEvent_SensorEventColor, AUTO) + + +PB_BIND(wippersnapper_sensor_SensorEvent_SensorEvent3DVector, wippersnapper_sensor_SensorEvent_SensorEvent3DVector, AUTO) + + +PB_BIND(wippersnapper_sensor_SensorEvent_SensorEventOrientation, wippersnapper_sensor_SensorEvent_SensorEventOrientation, AUTO) + + + + diff --git a/src/protos/sensor.pb.h b/src/protos/sensor.pb.h new file mode 100644 index 000000000..ca74080a0 --- /dev/null +++ b/src/protos/sensor.pb.h @@ -0,0 +1,201 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_WIPPERSNAPPER_SENSOR_SENSOR_PB_H_INCLUDED +#define PB_WIPPERSNAPPER_SENSOR_SENSOR_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Enum definitions */ +/* * + SensorType allows us determine what types of units the sensor uses, etc. */ +typedef enum _wippersnapper_sensor_SensorType { + wippersnapper_sensor_SensorType_SENSOR_TYPE_UNSPECIFIED = 0, /* * Sensor value type which is not defined by this list, "Raw Value: {value}". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER = 1, /* * Acceleration, in meter per second per second, "{value}m/s/s". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_MAGNETIC_FIELD = 2, /* * Magnetic field strength, in micro-Tesla, "{value}µT". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_ORIENTATION = 3, /* * Orientation angle, in degrees, "{value}°". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_GYROSCOPE = 4, /* * Angular rate, in radians per second, "{value}rad/s". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_LIGHT = 5, /* * Light-level, non-unit-specific (For a unit-specific measurement, see: Lux), +"Raw Value: {value}". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_PRESSURE = 6, /* * Pressure, in hectopascal, , "{value}hPa". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_PROXIMITY = 8, /* * Distance from an object to a sensor, non-unit-specific, "Raw Value: {value}". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_GRAVITY = 9, /* * Metres per second squared, "{value}m/s^2". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_LINEAR_ACCELERATION = 10, /* * Acceleration not including gravity, in meter per second squared, "{value}m/s^2". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_ROTATION_VECTOR = 11, /* * An angle in radians, "{value} rad". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_RELATIVE_HUMIDITY = 12, /* * in percent (%), "{value}%". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE = 13, /* * Temperature of the air around a sensor, in degrees Celsius, "{value}°C". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE = 14, /* * Temperature of the object a sensor is touching/pointed at, in degrees Celsius, "{value}°C". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE = 15, /* * Volts, "{value}V". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_CURRENT = 16, /* * Milliamps, "{value}mA". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_COLOR = 17, /* * Values are in 0..1.0 RGB channel luminosity and 32-bit RGBA format. "Color: {value}". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW = 18, /* * Sensor reads a value which is not defined by this list, "Raw Value: {value}". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_PM10_STD = 19, /* * Standard Particulate Matter 1.0, in ppm, "{value}ppm". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_PM25_STD = 20, /* * Standard Particulate Matter 2.5, in ppm, "{value}ppm". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_PM100_STD = 21, /* * Standard Particulate Matter 100, in ppm, "{value}ppm". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_PM10_ENV = 22, /* * Environmental Particulate Matter 1.0, in ppm, "{value}ppm". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_PM25_ENV = 23, /* * Environmental Particulate Matter 2.5, in ppm, "{value}ppm". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_PM100_ENV = 24, /* * Environmental Particulate Matter 100, in ppm, "{value}ppm". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_CO2 = 25, /* * Measured CO2, in ppm, "{value}ppm". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_GAS_RESISTANCE = 26, /* * Proportional to the amount of VOC particles in the air, in Ohms, "{value}Ω". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_ALTITUDE = 27, /* * Values are in meters (m), "${$v} m". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_LUX = 28, /* * Light level, in lux, "Lux: {value}". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_ECO2 = 29, /* * equivalent/estimated CO2 in ppm (estimated from some other measurement), "{value}ppm". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_UNITLESS_PERCENT = 30, /* * Percentage, unit-less, "{value}%". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT = 31, /* * Temperature of the air around a sensor, in degrees Fahrenheit, "{value}°F". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT = 32, /* * Temperature of the object a sensor is touching/pointed at, in Fahrenheit, "{value}°F". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_VOC_INDEX = 33, /* * Values are an index from 1-500 with 100 being normal, "${$v} VOC". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_NOX_INDEX = 34, /* * Values are an index from 1-500 with 100 being normal, "${$v} NOx". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_TVOC = 35, /* * Values are in parts per billion (ppb), "${$v} ppb". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_BYTES = 36, /* * Values are in bytes, "${$v} bytes". */ + wippersnapper_sensor_SensorType_SENSOR_TYPE_BOOLEAN = 37 /* * Values are boolean, "Boolean Value: ${$v}". */ +} wippersnapper_sensor_SensorType; + +/* Struct definitions */ +/* * + SensorEventColor is used to return a sensor's color values in RGB colorspace. */ +typedef struct _wippersnapper_sensor_SensorEvent_SensorEventColor { + float r; /* * The sensor's red channel value as a float. */ + float g; /* * The sensor's green channel value as a float. */ + float b; /* * The sensor's blue channel value as a float. */ + float a; /* * The sensor's (optional) alpha channel value as a float. */ +} wippersnapper_sensor_SensorEvent_SensorEventColor; + +/* * + SensorEvent3DVector is used to return a sensor's 3D vector values. */ +typedef struct _wippersnapper_sensor_SensorEvent_SensorEvent3DVector { + float x; /* * The sensor's x-axis value as a float. */ + float y; /* * The sensor's y-axis value as a float. */ + float z; /* * The sensor's z-axis value as a float. */ +} wippersnapper_sensor_SensorEvent_SensorEvent3DVector; + +/* * + SensorEventOrientation is used to return an orientation sensor's values. */ +typedef struct _wippersnapper_sensor_SensorEvent_SensorEventOrientation { + float roll; /* * The sensor's roll value as a float. */ + float pitch; /* * The sensor's pitch value as a float. */ + float heading; /* * The sensor's heading value as a float. */ +} wippersnapper_sensor_SensorEvent_SensorEventOrientation; + +/* * + SensorEvent is used to return the sensor's value and type. */ +typedef struct _wippersnapper_sensor_SensorEvent { + wippersnapper_sensor_SensorType type; /* * The sensor's type and corresponding SI unit */ + pb_size_t which_value; + union { + float float_value; /* * The sensor's value as a float. */ + pb_callback_t bytes_value; /* * The sensor's value as a byte array. */ + wippersnapper_sensor_SensorEvent_SensorEvent3DVector vector_value; /* * The sensor's 3D vector values, as floats. */ + wippersnapper_sensor_SensorEvent_SensorEventOrientation orientation_value; /* * The sensor's orientation values, as floats. */ + wippersnapper_sensor_SensorEvent_SensorEventColor color_value; /* * The sensor's color values, as floats. */ + bool bool_value; /* * The sensor's value, as a boolean. */ + } value; +} wippersnapper_sensor_SensorEvent; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Helper constants for enums */ +#define _wippersnapper_sensor_SensorType_MIN wippersnapper_sensor_SensorType_SENSOR_TYPE_UNSPECIFIED +#define _wippersnapper_sensor_SensorType_MAX wippersnapper_sensor_SensorType_SENSOR_TYPE_BOOLEAN +#define _wippersnapper_sensor_SensorType_ARRAYSIZE ((wippersnapper_sensor_SensorType)(wippersnapper_sensor_SensorType_SENSOR_TYPE_BOOLEAN+1)) + +#define wippersnapper_sensor_SensorEvent_type_ENUMTYPE wippersnapper_sensor_SensorType + + + + + +/* Initializer values for message structs */ +#define wippersnapper_sensor_SensorEvent_init_default {_wippersnapper_sensor_SensorType_MIN, 0, {0}} +#define wippersnapper_sensor_SensorEvent_SensorEventColor_init_default {0, 0, 0, 0} +#define wippersnapper_sensor_SensorEvent_SensorEvent3DVector_init_default {0, 0, 0} +#define wippersnapper_sensor_SensorEvent_SensorEventOrientation_init_default {0, 0, 0} +#define wippersnapper_sensor_SensorEvent_init_zero {_wippersnapper_sensor_SensorType_MIN, 0, {0}} +#define wippersnapper_sensor_SensorEvent_SensorEventColor_init_zero {0, 0, 0, 0} +#define wippersnapper_sensor_SensorEvent_SensorEvent3DVector_init_zero {0, 0, 0} +#define wippersnapper_sensor_SensorEvent_SensorEventOrientation_init_zero {0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define wippersnapper_sensor_SensorEvent_SensorEventColor_r_tag 1 +#define wippersnapper_sensor_SensorEvent_SensorEventColor_g_tag 2 +#define wippersnapper_sensor_SensorEvent_SensorEventColor_b_tag 3 +#define wippersnapper_sensor_SensorEvent_SensorEventColor_a_tag 4 +#define wippersnapper_sensor_SensorEvent_SensorEvent3DVector_x_tag 1 +#define wippersnapper_sensor_SensorEvent_SensorEvent3DVector_y_tag 2 +#define wippersnapper_sensor_SensorEvent_SensorEvent3DVector_z_tag 3 +#define wippersnapper_sensor_SensorEvent_SensorEventOrientation_roll_tag 1 +#define wippersnapper_sensor_SensorEvent_SensorEventOrientation_pitch_tag 2 +#define wippersnapper_sensor_SensorEvent_SensorEventOrientation_heading_tag 3 +#define wippersnapper_sensor_SensorEvent_type_tag 1 +#define wippersnapper_sensor_SensorEvent_float_value_tag 2 +#define wippersnapper_sensor_SensorEvent_bytes_value_tag 3 +#define wippersnapper_sensor_SensorEvent_vector_value_tag 4 +#define wippersnapper_sensor_SensorEvent_orientation_value_tag 5 +#define wippersnapper_sensor_SensorEvent_color_value_tag 6 +#define wippersnapper_sensor_SensorEvent_bool_value_tag 7 + +/* Struct field encoding specification for nanopb */ +#define wippersnapper_sensor_SensorEvent_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, type, 1) \ +X(a, STATIC, ONEOF, FLOAT, (value,float_value,value.float_value), 2) \ +X(a, CALLBACK, ONEOF, BYTES, (value,bytes_value,value.bytes_value), 3) \ +X(a, STATIC, ONEOF, MESSAGE, (value,vector_value,value.vector_value), 4) \ +X(a, STATIC, ONEOF, MESSAGE, (value,orientation_value,value.orientation_value), 5) \ +X(a, STATIC, ONEOF, MESSAGE, (value,color_value,value.color_value), 6) \ +X(a, STATIC, ONEOF, BOOL, (value,bool_value,value.bool_value), 7) +#define wippersnapper_sensor_SensorEvent_CALLBACK pb_default_field_callback +#define wippersnapper_sensor_SensorEvent_DEFAULT NULL +#define wippersnapper_sensor_SensorEvent_value_vector_value_MSGTYPE wippersnapper_sensor_SensorEvent_SensorEvent3DVector +#define wippersnapper_sensor_SensorEvent_value_orientation_value_MSGTYPE wippersnapper_sensor_SensorEvent_SensorEventOrientation +#define wippersnapper_sensor_SensorEvent_value_color_value_MSGTYPE wippersnapper_sensor_SensorEvent_SensorEventColor + +#define wippersnapper_sensor_SensorEvent_SensorEventColor_FIELDLIST(X, a_) \ +X(a_, STATIC, SINGULAR, FLOAT, r, 1) \ +X(a_, STATIC, SINGULAR, FLOAT, g, 2) \ +X(a_, STATIC, SINGULAR, FLOAT, b, 3) \ +X(a_, STATIC, SINGULAR, FLOAT, a, 4) +#define wippersnapper_sensor_SensorEvent_SensorEventColor_CALLBACK NULL +#define wippersnapper_sensor_SensorEvent_SensorEventColor_DEFAULT NULL + +#define wippersnapper_sensor_SensorEvent_SensorEvent3DVector_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, FLOAT, x, 1) \ +X(a, STATIC, SINGULAR, FLOAT, y, 2) \ +X(a, STATIC, SINGULAR, FLOAT, z, 3) +#define wippersnapper_sensor_SensorEvent_SensorEvent3DVector_CALLBACK NULL +#define wippersnapper_sensor_SensorEvent_SensorEvent3DVector_DEFAULT NULL + +#define wippersnapper_sensor_SensorEvent_SensorEventOrientation_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, FLOAT, roll, 1) \ +X(a, STATIC, SINGULAR, FLOAT, pitch, 2) \ +X(a, STATIC, SINGULAR, FLOAT, heading, 3) +#define wippersnapper_sensor_SensorEvent_SensorEventOrientation_CALLBACK NULL +#define wippersnapper_sensor_SensorEvent_SensorEventOrientation_DEFAULT NULL + +extern const pb_msgdesc_t wippersnapper_sensor_SensorEvent_msg; +extern const pb_msgdesc_t wippersnapper_sensor_SensorEvent_SensorEventColor_msg; +extern const pb_msgdesc_t wippersnapper_sensor_SensorEvent_SensorEvent3DVector_msg; +extern const pb_msgdesc_t wippersnapper_sensor_SensorEvent_SensorEventOrientation_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define wippersnapper_sensor_SensorEvent_fields &wippersnapper_sensor_SensorEvent_msg +#define wippersnapper_sensor_SensorEvent_SensorEventColor_fields &wippersnapper_sensor_SensorEvent_SensorEventColor_msg +#define wippersnapper_sensor_SensorEvent_SensorEvent3DVector_fields &wippersnapper_sensor_SensorEvent_SensorEvent3DVector_msg +#define wippersnapper_sensor_SensorEvent_SensorEventOrientation_fields &wippersnapper_sensor_SensorEvent_SensorEventOrientation_msg + +/* Maximum encoded size of messages (where known) */ +/* wippersnapper_sensor_SensorEvent_size depends on runtime parameters */ +#define WIPPERSNAPPER_SENSOR_SENSOR_PB_H_MAX_SIZE wippersnapper_sensor_SensorEvent_SensorEventColor_size +#define wippersnapper_sensor_SensorEvent_SensorEvent3DVector_size 15 +#define wippersnapper_sensor_SensorEvent_SensorEventColor_size 20 +#define wippersnapper_sensor_SensorEvent_SensorEventOrientation_size 15 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/protos/servo.pb.c b/src/protos/servo.pb.c new file mode 100644 index 000000000..902cce097 --- /dev/null +++ b/src/protos/servo.pb.c @@ -0,0 +1,21 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "servo.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(wippersnapper_servo_ServoAdd, wippersnapper_servo_ServoAdd, AUTO) + + +PB_BIND(wippersnapper_servo_ServoAdded, wippersnapper_servo_ServoAdded, AUTO) + + +PB_BIND(wippersnapper_servo_ServoRemove, wippersnapper_servo_ServoRemove, AUTO) + + +PB_BIND(wippersnapper_servo_ServoWrite, wippersnapper_servo_ServoWrite, AUTO) + + + diff --git a/src/protos/servo.pb.h b/src/protos/servo.pb.h new file mode 100644 index 000000000..5471c9f55 --- /dev/null +++ b/src/protos/servo.pb.h @@ -0,0 +1,120 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_WIPPERSNAPPER_SERVO_SERVO_PB_H_INCLUDED +#define PB_WIPPERSNAPPER_SERVO_SERVO_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +/* * + ServoAdd represents a request to attach a servo to a pin. */ +typedef struct _wippersnapper_servo_ServoAdd { + char servo_pin[6]; /* * The name of pin to attach a servo to. */ + int32_t servo_freq; /* * The overall PWM frequency, default sent by Adafruit IO is 50Hz. * */ + int32_t min_pulse_width; /* * The minimum pulse length in uS. Default sent by Adafruit IO is 500uS. * */ + int32_t max_pulse_width; /* * The maximum pulse length in uS. Default sent by Adafruit IO is 2500uS. * */ +} wippersnapper_servo_ServoAdd; + +/* * + ServoAdded represents the result of attaching a servo to a pin. */ +typedef struct _wippersnapper_servo_ServoAdded { + bool attach_success; /* * True if a servo was attached successfully, False otherwise. * */ + char servo_pin[6]; /* * The name of pin we're responding about. */ +} wippersnapper_servo_ServoAdded; + +/* * + ServoRemove represents a request to detach a servo from a pin and de-initialize the pin for other uses. */ +typedef struct _wippersnapper_servo_ServoRemove { + char servo_pin[6]; /* * The name of pin to use as a servo pin. */ +} wippersnapper_servo_ServoRemove; + +/* * + ServoWrite represents a message to write the servo's position. + + NOTE: Position is sent from Adafruit IO as a pulse width in uS between 0uS + and 2500uS. The client application must convert pulse width to duty cycle w/fixed + freq of 50Hz prior to writing to the servo pin. */ +typedef struct _wippersnapper_servo_ServoWrite { + char servo_pin[6]; /* * The name of pin we're addressing. */ + int32_t pulse_width; /* * The pulse width to write to the servo, in uS * */ +} wippersnapper_servo_ServoWrite; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define wippersnapper_servo_ServoAdd_init_default {"", 0, 0, 0} +#define wippersnapper_servo_ServoAdded_init_default {0, ""} +#define wippersnapper_servo_ServoRemove_init_default {""} +#define wippersnapper_servo_ServoWrite_init_default {"", 0} +#define wippersnapper_servo_ServoAdd_init_zero {"", 0, 0, 0} +#define wippersnapper_servo_ServoAdded_init_zero {0, ""} +#define wippersnapper_servo_ServoRemove_init_zero {""} +#define wippersnapper_servo_ServoWrite_init_zero {"", 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define wippersnapper_servo_ServoAdd_servo_pin_tag 1 +#define wippersnapper_servo_ServoAdd_servo_freq_tag 2 +#define wippersnapper_servo_ServoAdd_min_pulse_width_tag 3 +#define wippersnapper_servo_ServoAdd_max_pulse_width_tag 4 +#define wippersnapper_servo_ServoAdded_attach_success_tag 1 +#define wippersnapper_servo_ServoAdded_servo_pin_tag 2 +#define wippersnapper_servo_ServoRemove_servo_pin_tag 1 +#define wippersnapper_servo_ServoWrite_servo_pin_tag 1 +#define wippersnapper_servo_ServoWrite_pulse_width_tag 2 + +/* Struct field encoding specification for nanopb */ +#define wippersnapper_servo_ServoAdd_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, servo_pin, 1) \ +X(a, STATIC, SINGULAR, INT32, servo_freq, 2) \ +X(a, STATIC, SINGULAR, INT32, min_pulse_width, 3) \ +X(a, STATIC, SINGULAR, INT32, max_pulse_width, 4) +#define wippersnapper_servo_ServoAdd_CALLBACK NULL +#define wippersnapper_servo_ServoAdd_DEFAULT NULL + +#define wippersnapper_servo_ServoAdded_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, BOOL, attach_success, 1) \ +X(a, STATIC, SINGULAR, STRING, servo_pin, 2) +#define wippersnapper_servo_ServoAdded_CALLBACK NULL +#define wippersnapper_servo_ServoAdded_DEFAULT NULL + +#define wippersnapper_servo_ServoRemove_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, servo_pin, 1) +#define wippersnapper_servo_ServoRemove_CALLBACK NULL +#define wippersnapper_servo_ServoRemove_DEFAULT NULL + +#define wippersnapper_servo_ServoWrite_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, servo_pin, 1) \ +X(a, STATIC, SINGULAR, INT32, pulse_width, 2) +#define wippersnapper_servo_ServoWrite_CALLBACK NULL +#define wippersnapper_servo_ServoWrite_DEFAULT NULL + +extern const pb_msgdesc_t wippersnapper_servo_ServoAdd_msg; +extern const pb_msgdesc_t wippersnapper_servo_ServoAdded_msg; +extern const pb_msgdesc_t wippersnapper_servo_ServoRemove_msg; +extern const pb_msgdesc_t wippersnapper_servo_ServoWrite_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define wippersnapper_servo_ServoAdd_fields &wippersnapper_servo_ServoAdd_msg +#define wippersnapper_servo_ServoAdded_fields &wippersnapper_servo_ServoAdded_msg +#define wippersnapper_servo_ServoRemove_fields &wippersnapper_servo_ServoRemove_msg +#define wippersnapper_servo_ServoWrite_fields &wippersnapper_servo_ServoWrite_msg + +/* Maximum encoded size of messages (where known) */ +#define WIPPERSNAPPER_SERVO_SERVO_PB_H_MAX_SIZE wippersnapper_servo_ServoAdd_size +#define wippersnapper_servo_ServoAdd_size 40 +#define wippersnapper_servo_ServoAdded_size 9 +#define wippersnapper_servo_ServoRemove_size 7 +#define wippersnapper_servo_ServoWrite_size 18 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/protos/signal.pb.c b/src/protos/signal.pb.c new file mode 100644 index 000000000..97a7a6367 --- /dev/null +++ b/src/protos/signal.pb.c @@ -0,0 +1,15 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "signal.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(wippersnapper_signal_BrokerToDevice, wippersnapper_signal_BrokerToDevice, 2) + + +PB_BIND(wippersnapper_signal_DeviceToBroker, wippersnapper_signal_DeviceToBroker, 4) + + + diff --git a/src/protos/signal.pb.h b/src/protos/signal.pb.h new file mode 100644 index 000000000..3262a6c05 --- /dev/null +++ b/src/protos/signal.pb.h @@ -0,0 +1,272 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_WIPPERSNAPPER_SIGNAL_SIGNAL_PB_H_INCLUDED +#define PB_WIPPERSNAPPER_SIGNAL_SIGNAL_PB_H_INCLUDED +#include +#include "analogio.pb.h" +#include "checkin.pb.h" +#include "digitalio.pb.h" +#include "ds18x20.pb.h" +#include "error.pb.h" +#include "i2c.pb.h" +#include "pixels.pb.h" +#include "pwm.pb.h" +#include "servo.pb.h" +#include "uart.pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +/* BrokerToDevice + The BrokerToDevice message is sent from the broker to the device. + It contains a oneof payload, which is a union of all the possible + messages that can be sent from the broker to a device. */ +typedef struct _wippersnapper_signal_BrokerToDevice { + pb_callback_t cb_payload; + pb_size_t which_payload; + union { + /* digitalio.proto */ + wippersnapper_digitalio_DigitalIOAdd digitalio_add; + wippersnapper_digitalio_DigitalIORemove digitalio_remove; + wippersnapper_digitalio_DigitalIOEvent digitalio_event; + wippersnapper_digitalio_DigitalIOWrite digitalio_write; + /* analogio.proto */ + wippersnapper_analogio_AnalogIOAdd analogio_add; + wippersnapper_analogio_AnalogIORemove analogio_remove; + /* checkin.proto */ + wippersnapper_checkin_CheckinResponse checkin_response; + /* servo.proto */ + wippersnapper_servo_ServoAdd servo_add; + wippersnapper_servo_ServoRemove servo_remove; + wippersnapper_servo_ServoWrite servo_write; + /* pwm.proto */ + wippersnapper_pwm_PWMAdd pwm_add; + wippersnapper_pwm_PWMRemove pwm_remove; + wippersnapper_pwm_PWMWriteDutyCycle pwm_write_duty; + wippersnapper_pwm_PWMWriteDutyCycleMulti pwm_write_duty_multi; + wippersnapper_pwm_PWMWriteFrequency pwm_write_freq; + /* pixels.proto */ + wippersnapper_pixels_PixelsAdd pixels_add; + wippersnapper_pixels_PixelsRemove pixels_remove; + wippersnapper_pixels_PixelsWrite pixels_write; + /* ds18x20.proto */ + wippersnapper_ds18x20_Ds18x20Add ds18x20_add; + wippersnapper_ds18x20_Ds18x20Remove ds18x20_remove; + /* uart.proto */ + wippersnapper_uart_UARTAdd uart_add; + wippersnapper_uart_UARTRemove uart_remove; + /* i2c.proto */ + wippersnapper_i2c_I2cBusScan i2c_bus_scan; + wippersnapper_i2c_I2cDeviceAddOrReplace i2c_device_add_replace; + wippersnapper_i2c_I2cDeviceRemove i2c_device_remove; + /* error.proto */ + wippersnapper_error_Error error; + } payload; +} wippersnapper_signal_BrokerToDevice; + +/* DeviceToBroker + The DeviceToBroker message is sent from the device to the broker. + It contains a oneof payload, which is a union of all the possible + messages that can be sent from a device to the broker. */ +typedef struct _wippersnapper_signal_DeviceToBroker { + pb_callback_t cb_payload; + pb_size_t which_payload; + union { + /* digitalio.proto */ + wippersnapper_digitalio_DigitalIOEvent digitalio_event; + /* analogio.proto */ + wippersnapper_analogio_AnalogIOEvent analogio_event; + /* checkin.proto */ + wippersnapper_checkin_CheckinRequest checkin_request; + /* servo.proto */ + wippersnapper_servo_ServoAdded servo_added; + /* pwm.proto */ + wippersnapper_pwm_PWMAdded pwm_added; + /* pixels.proto */ + wippersnapper_pixels_PixelsAdded pixels_added; + /* ds18x20.proto */ + wippersnapper_ds18x20_Ds18x20Added ds18x20_added; + wippersnapper_ds18x20_Ds18x20Event ds18x20_event; + /* uart.proto */ + wippersnapper_uart_UARTAdded uart_added; + wippersnapper_uart_UARTEvent uart_event; + /* i2c.proto */ + wippersnapper_i2c_I2cBusScanned i2c_bus_scanned; + wippersnapper_i2c_I2cDeviceAddedOrReplaced i2c_device_added_replaced; + wippersnapper_i2c_I2cDeviceRemoved i2c_device_removed; + wippersnapper_i2c_I2cDeviceEvent i2c_device_event; + } payload; +} wippersnapper_signal_DeviceToBroker; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define wippersnapper_signal_BrokerToDevice_init_default {{{NULL}, NULL}, 0, {wippersnapper_digitalio_DigitalIOAdd_init_default}} +#define wippersnapper_signal_DeviceToBroker_init_default {{{NULL}, NULL}, 0, {wippersnapper_digitalio_DigitalIOEvent_init_default}} +#define wippersnapper_signal_BrokerToDevice_init_zero {{{NULL}, NULL}, 0, {wippersnapper_digitalio_DigitalIOAdd_init_zero}} +#define wippersnapper_signal_DeviceToBroker_init_zero {{{NULL}, NULL}, 0, {wippersnapper_digitalio_DigitalIOEvent_init_zero}} + +/* Field tags (for use in manual encoding/decoding) */ +#define wippersnapper_signal_BrokerToDevice_digitalio_add_tag 10 +#define wippersnapper_signal_BrokerToDevice_digitalio_remove_tag 11 +#define wippersnapper_signal_BrokerToDevice_digitalio_event_tag 12 +#define wippersnapper_signal_BrokerToDevice_digitalio_write_tag 13 +#define wippersnapper_signal_BrokerToDevice_analogio_add_tag 20 +#define wippersnapper_signal_BrokerToDevice_analogio_remove_tag 21 +#define wippersnapper_signal_BrokerToDevice_checkin_response_tag 30 +#define wippersnapper_signal_BrokerToDevice_servo_add_tag 40 +#define wippersnapper_signal_BrokerToDevice_servo_remove_tag 41 +#define wippersnapper_signal_BrokerToDevice_servo_write_tag 42 +#define wippersnapper_signal_BrokerToDevice_pwm_add_tag 50 +#define wippersnapper_signal_BrokerToDevice_pwm_remove_tag 51 +#define wippersnapper_signal_BrokerToDevice_pwm_write_duty_tag 52 +#define wippersnapper_signal_BrokerToDevice_pwm_write_duty_multi_tag 53 +#define wippersnapper_signal_BrokerToDevice_pwm_write_freq_tag 54 +#define wippersnapper_signal_BrokerToDevice_pixels_add_tag 60 +#define wippersnapper_signal_BrokerToDevice_pixels_remove_tag 61 +#define wippersnapper_signal_BrokerToDevice_pixels_write_tag 62 +#define wippersnapper_signal_BrokerToDevice_ds18x20_add_tag 70 +#define wippersnapper_signal_BrokerToDevice_ds18x20_remove_tag 71 +#define wippersnapper_signal_BrokerToDevice_uart_add_tag 80 +#define wippersnapper_signal_BrokerToDevice_uart_remove_tag 81 +#define wippersnapper_signal_BrokerToDevice_i2c_bus_scan_tag 90 +#define wippersnapper_signal_BrokerToDevice_i2c_device_add_replace_tag 91 +#define wippersnapper_signal_BrokerToDevice_i2c_device_remove_tag 92 +#define wippersnapper_signal_BrokerToDevice_error_tag 100 +#define wippersnapper_signal_DeviceToBroker_digitalio_event_tag 10 +#define wippersnapper_signal_DeviceToBroker_analogio_event_tag 20 +#define wippersnapper_signal_DeviceToBroker_checkin_request_tag 30 +#define wippersnapper_signal_DeviceToBroker_servo_added_tag 40 +#define wippersnapper_signal_DeviceToBroker_pwm_added_tag 50 +#define wippersnapper_signal_DeviceToBroker_pixels_added_tag 60 +#define wippersnapper_signal_DeviceToBroker_ds18x20_added_tag 70 +#define wippersnapper_signal_DeviceToBroker_ds18x20_event_tag 80 +#define wippersnapper_signal_DeviceToBroker_uart_added_tag 90 +#define wippersnapper_signal_DeviceToBroker_uart_event_tag 100 +#define wippersnapper_signal_DeviceToBroker_i2c_bus_scanned_tag 110 +#define wippersnapper_signal_DeviceToBroker_i2c_device_added_replaced_tag 111 +#define wippersnapper_signal_DeviceToBroker_i2c_device_removed_tag 112 +#define wippersnapper_signal_DeviceToBroker_i2c_device_event_tag 113 + +/* Struct field encoding specification for nanopb */ +#define wippersnapper_signal_BrokerToDevice_FIELDLIST(X, a) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,digitalio_add,payload.digitalio_add), 10) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,digitalio_remove,payload.digitalio_remove), 11) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,digitalio_event,payload.digitalio_event), 12) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,digitalio_write,payload.digitalio_write), 13) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,analogio_add,payload.analogio_add), 20) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,analogio_remove,payload.analogio_remove), 21) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,checkin_response,payload.checkin_response), 30) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,servo_add,payload.servo_add), 40) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,servo_remove,payload.servo_remove), 41) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,servo_write,payload.servo_write), 42) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,pwm_add,payload.pwm_add), 50) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,pwm_remove,payload.pwm_remove), 51) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,pwm_write_duty,payload.pwm_write_duty), 52) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,pwm_write_duty_multi,payload.pwm_write_duty_multi), 53) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,pwm_write_freq,payload.pwm_write_freq), 54) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,pixels_add,payload.pixels_add), 60) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,pixels_remove,payload.pixels_remove), 61) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,pixels_write,payload.pixels_write), 62) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,ds18x20_add,payload.ds18x20_add), 70) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,ds18x20_remove,payload.ds18x20_remove), 71) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,uart_add,payload.uart_add), 80) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,uart_remove,payload.uart_remove), 81) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,i2c_bus_scan,payload.i2c_bus_scan), 90) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,i2c_device_add_replace,payload.i2c_device_add_replace), 91) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,i2c_device_remove,payload.i2c_device_remove), 92) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,error,payload.error), 100) +#define wippersnapper_signal_BrokerToDevice_CALLBACK NULL +#define wippersnapper_signal_BrokerToDevice_DEFAULT NULL +#define wippersnapper_signal_BrokerToDevice_payload_digitalio_add_MSGTYPE wippersnapper_digitalio_DigitalIOAdd +#define wippersnapper_signal_BrokerToDevice_payload_digitalio_remove_MSGTYPE wippersnapper_digitalio_DigitalIORemove +#define wippersnapper_signal_BrokerToDevice_payload_digitalio_event_MSGTYPE wippersnapper_digitalio_DigitalIOEvent +#define wippersnapper_signal_BrokerToDevice_payload_digitalio_write_MSGTYPE wippersnapper_digitalio_DigitalIOWrite +#define wippersnapper_signal_BrokerToDevice_payload_analogio_add_MSGTYPE wippersnapper_analogio_AnalogIOAdd +#define wippersnapper_signal_BrokerToDevice_payload_analogio_remove_MSGTYPE wippersnapper_analogio_AnalogIORemove +#define wippersnapper_signal_BrokerToDevice_payload_checkin_response_MSGTYPE wippersnapper_checkin_CheckinResponse +#define wippersnapper_signal_BrokerToDevice_payload_servo_add_MSGTYPE wippersnapper_servo_ServoAdd +#define wippersnapper_signal_BrokerToDevice_payload_servo_remove_MSGTYPE wippersnapper_servo_ServoRemove +#define wippersnapper_signal_BrokerToDevice_payload_servo_write_MSGTYPE wippersnapper_servo_ServoWrite +#define wippersnapper_signal_BrokerToDevice_payload_pwm_add_MSGTYPE wippersnapper_pwm_PWMAdd +#define wippersnapper_signal_BrokerToDevice_payload_pwm_remove_MSGTYPE wippersnapper_pwm_PWMRemove +#define wippersnapper_signal_BrokerToDevice_payload_pwm_write_duty_MSGTYPE wippersnapper_pwm_PWMWriteDutyCycle +#define wippersnapper_signal_BrokerToDevice_payload_pwm_write_duty_multi_MSGTYPE wippersnapper_pwm_PWMWriteDutyCycleMulti +#define wippersnapper_signal_BrokerToDevice_payload_pwm_write_freq_MSGTYPE wippersnapper_pwm_PWMWriteFrequency +#define wippersnapper_signal_BrokerToDevice_payload_pixels_add_MSGTYPE wippersnapper_pixels_PixelsAdd +#define wippersnapper_signal_BrokerToDevice_payload_pixels_remove_MSGTYPE wippersnapper_pixels_PixelsRemove +#define wippersnapper_signal_BrokerToDevice_payload_pixels_write_MSGTYPE wippersnapper_pixels_PixelsWrite +#define wippersnapper_signal_BrokerToDevice_payload_ds18x20_add_MSGTYPE wippersnapper_ds18x20_Ds18x20Add +#define wippersnapper_signal_BrokerToDevice_payload_ds18x20_remove_MSGTYPE wippersnapper_ds18x20_Ds18x20Remove +#define wippersnapper_signal_BrokerToDevice_payload_uart_add_MSGTYPE wippersnapper_uart_UARTAdd +#define wippersnapper_signal_BrokerToDevice_payload_uart_remove_MSGTYPE wippersnapper_uart_UARTRemove +#define wippersnapper_signal_BrokerToDevice_payload_i2c_bus_scan_MSGTYPE wippersnapper_i2c_I2cBusScan +#define wippersnapper_signal_BrokerToDevice_payload_i2c_device_add_replace_MSGTYPE wippersnapper_i2c_I2cDeviceAddOrReplace +#define wippersnapper_signal_BrokerToDevice_payload_i2c_device_remove_MSGTYPE wippersnapper_i2c_I2cDeviceRemove +#define wippersnapper_signal_BrokerToDevice_payload_error_MSGTYPE wippersnapper_error_Error + +#define wippersnapper_signal_DeviceToBroker_FIELDLIST(X, a) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,digitalio_event,payload.digitalio_event), 10) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,analogio_event,payload.analogio_event), 20) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,checkin_request,payload.checkin_request), 30) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,servo_added,payload.servo_added), 40) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,pwm_added,payload.pwm_added), 50) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,pixels_added,payload.pixels_added), 60) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,ds18x20_added,payload.ds18x20_added), 70) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,ds18x20_event,payload.ds18x20_event), 80) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,uart_added,payload.uart_added), 90) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,uart_event,payload.uart_event), 100) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,i2c_bus_scanned,payload.i2c_bus_scanned), 110) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,i2c_device_added_replaced,payload.i2c_device_added_replaced), 111) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,i2c_device_removed,payload.i2c_device_removed), 112) \ +X(a, STATIC, ONEOF, MSG_W_CB, (payload,i2c_device_event,payload.i2c_device_event), 113) +#define wippersnapper_signal_DeviceToBroker_CALLBACK NULL +#define wippersnapper_signal_DeviceToBroker_DEFAULT NULL +#define wippersnapper_signal_DeviceToBroker_payload_digitalio_event_MSGTYPE wippersnapper_digitalio_DigitalIOEvent +#define wippersnapper_signal_DeviceToBroker_payload_analogio_event_MSGTYPE wippersnapper_analogio_AnalogIOEvent +#define wippersnapper_signal_DeviceToBroker_payload_checkin_request_MSGTYPE wippersnapper_checkin_CheckinRequest +#define wippersnapper_signal_DeviceToBroker_payload_servo_added_MSGTYPE wippersnapper_servo_ServoAdded +#define wippersnapper_signal_DeviceToBroker_payload_pwm_added_MSGTYPE wippersnapper_pwm_PWMAdded +#define wippersnapper_signal_DeviceToBroker_payload_pixels_added_MSGTYPE wippersnapper_pixels_PixelsAdded +#define wippersnapper_signal_DeviceToBroker_payload_ds18x20_added_MSGTYPE wippersnapper_ds18x20_Ds18x20Added +#define wippersnapper_signal_DeviceToBroker_payload_ds18x20_event_MSGTYPE wippersnapper_ds18x20_Ds18x20Event +#define wippersnapper_signal_DeviceToBroker_payload_uart_added_MSGTYPE wippersnapper_uart_UARTAdded +#define wippersnapper_signal_DeviceToBroker_payload_uart_event_MSGTYPE wippersnapper_uart_UARTEvent +#define wippersnapper_signal_DeviceToBroker_payload_i2c_bus_scanned_MSGTYPE wippersnapper_i2c_I2cBusScanned +#define wippersnapper_signal_DeviceToBroker_payload_i2c_device_added_replaced_MSGTYPE wippersnapper_i2c_I2cDeviceAddedOrReplaced +#define wippersnapper_signal_DeviceToBroker_payload_i2c_device_removed_MSGTYPE wippersnapper_i2c_I2cDeviceRemoved +#define wippersnapper_signal_DeviceToBroker_payload_i2c_device_event_MSGTYPE wippersnapper_i2c_I2cDeviceEvent + +extern const pb_msgdesc_t wippersnapper_signal_BrokerToDevice_msg; +extern const pb_msgdesc_t wippersnapper_signal_DeviceToBroker_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define wippersnapper_signal_BrokerToDevice_fields &wippersnapper_signal_BrokerToDevice_msg +#define wippersnapper_signal_DeviceToBroker_fields &wippersnapper_signal_DeviceToBroker_msg + +/* Maximum encoded size of messages (where known) */ +#if defined(wippersnapper_digitalio_DigitalIOEvent_size) && defined(wippersnapper_digitalio_DigitalIOWrite_size) && defined(wippersnapper_uart_UARTAdd_size) && defined(wippersnapper_uart_UARTRemove_size) +union wippersnapper_signal_BrokerToDevice_payload_size_union {char f12[(6 + wippersnapper_digitalio_DigitalIOEvent_size)]; char f13[(6 + wippersnapper_digitalio_DigitalIOWrite_size)]; char f80[(7 + wippersnapper_uart_UARTAdd_size)]; char f81[(7 + wippersnapper_uart_UARTRemove_size)]; char f0[106];}; +#endif +#if defined(wippersnapper_digitalio_DigitalIOEvent_size) && defined(wippersnapper_analogio_AnalogIOEvent_size) && defined(wippersnapper_ds18x20_Ds18x20Event_size) && defined(wippersnapper_uart_UARTAdded_size) && defined(wippersnapper_uart_UARTEvent_size) && defined(wippersnapper_i2c_I2cDeviceEvent_size) +union wippersnapper_signal_DeviceToBroker_payload_size_union {char f10[(6 + wippersnapper_digitalio_DigitalIOEvent_size)]; char f20[(7 + wippersnapper_analogio_AnalogIOEvent_size)]; char f80[(7 + wippersnapper_ds18x20_Ds18x20Event_size)]; char f90[(7 + wippersnapper_uart_UARTAdded_size)]; char f100[(7 + wippersnapper_uart_UARTEvent_size)]; char f113[(7 + wippersnapper_i2c_I2cDeviceEvent_size)]; char f0[6246];}; +#endif +#if defined(wippersnapper_digitalio_DigitalIOEvent_size) && defined(wippersnapper_digitalio_DigitalIOWrite_size) && defined(wippersnapper_uart_UARTAdd_size) && defined(wippersnapper_uart_UARTRemove_size) +#define WIPPERSNAPPER_SIGNAL_SIGNAL_PB_H_MAX_SIZE wippersnapper_signal_BrokerToDevice_size +#define wippersnapper_signal_BrokerToDevice_size (0 + sizeof(union wippersnapper_signal_BrokerToDevice_payload_size_union)) +#endif +#if defined(wippersnapper_digitalio_DigitalIOEvent_size) && defined(wippersnapper_analogio_AnalogIOEvent_size) && defined(wippersnapper_ds18x20_Ds18x20Event_size) && defined(wippersnapper_uart_UARTAdded_size) && defined(wippersnapper_uart_UARTEvent_size) && defined(wippersnapper_i2c_I2cDeviceEvent_size) +#define wippersnapper_signal_DeviceToBroker_size (0 + sizeof(union wippersnapper_signal_DeviceToBroker_payload_size_union)) +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/protos/uart.pb.c b/src/protos/uart.pb.c new file mode 100644 index 000000000..827e9c1d6 --- /dev/null +++ b/src/protos/uart.pb.c @@ -0,0 +1,24 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "uart.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(wippersnapper_uart_UARTBusData, wippersnapper_uart_UARTBusData, AUTO) + + +PB_BIND(wippersnapper_uart_UARTAdd, wippersnapper_uart_UARTAdd, AUTO) + + +PB_BIND(wippersnapper_uart_UARTAdded, wippersnapper_uart_UARTAdded, AUTO) + + +PB_BIND(wippersnapper_uart_UARTRemove, wippersnapper_uart_UARTRemove, AUTO) + + +PB_BIND(wippersnapper_uart_UARTEvent, wippersnapper_uart_UARTEvent, AUTO) + + + diff --git a/src/protos/uart.pb.h b/src/protos/uart.pb.h new file mode 100644 index 000000000..6c4e07eaa --- /dev/null +++ b/src/protos/uart.pb.h @@ -0,0 +1,147 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_WIPPERSNAPPER_UART_UART_PB_H_INCLUDED +#define PB_WIPPERSNAPPER_UART_UART_PB_H_INCLUDED +#include +#include "sensor.pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +/* * + UARTBusData represents a message to configure a UART bus for communication with a device. + NOTE: This message is never sent directly, it is packed inside UARTAdd. */ +typedef struct _wippersnapper_uart_UARTBusData { + int32_t baudrate; /* * The baudrate to use for UART communication (may be a common baud rate such as: +1200bps, 2400bps, 4800bps, 19200bps, 38400bps, 57600bps, or 115200bps). */ + char pin_rx[6]; /* * The pin on which to receive UART stream data. */ + char pin_tx[6]; /* * The pin on which to transmit UART stream data. */ + bool is_invert; /* * Inverts the UART signal on RX and TX pins. Defaults to False. */ +} wippersnapper_uart_UARTBusData; + +/* * + UARTAdd represents a message sent from IO to a device + to configure the UART bus (if not already configured) and attach a device. */ +typedef struct _wippersnapper_uart_UARTAdd { + bool has_bus_info; + wippersnapper_uart_UARTBusData bus_info; /* * The UART bus configuration. */ + pb_callback_t device_id; /* * The unique identifier of the device to attach to the UART bus, from Adafruit_WipperSnapper_Components. */ + int32_t polling_interval; /* * The polling interval, in milliseconds, to use for the device. */ +} wippersnapper_uart_UARTAdd; + +/* * + UARTAdded represents a message sent from a device to IO to + confirm that a device has been attached to the UART bus. */ +typedef struct _wippersnapper_uart_UARTAdded { + pb_callback_t device_id; /* * The unique identifier of the device to attach to the UART bus, from Adafruit_WipperSnapper_Components. */ + bool is_success; /* * True if the UARTInit was successful, False otherwise. */ +} wippersnapper_uart_UARTAdded; + +/* UARTRemove represents a message sent from IO to a device + to detach a device from the UART bus. */ +typedef struct _wippersnapper_uart_UARTRemove { + pb_callback_t device_id; /* * The unique identifier of the device to detach from the UART bus. */ +} wippersnapper_uart_UARTRemove; + +/* * + UARTEvent represents incoming data from a UART sensor. */ +typedef struct _wippersnapper_uart_UARTEvent { + pb_callback_t device_id; /* * Unique identifier of the device to attach to the UART bus, from Adafruit_WipperSnapper_Components. */ + pb_callback_t sensor_events; /* * An optionally repeated event from a sensor. */ +} wippersnapper_uart_UARTEvent; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define wippersnapper_uart_UARTBusData_init_default {0, "", "", 0} +#define wippersnapper_uart_UARTAdd_init_default {false, wippersnapper_uart_UARTBusData_init_default, {{NULL}, NULL}, 0} +#define wippersnapper_uart_UARTAdded_init_default {{{NULL}, NULL}, 0} +#define wippersnapper_uart_UARTRemove_init_default {{{NULL}, NULL}} +#define wippersnapper_uart_UARTEvent_init_default {{{NULL}, NULL}, {{NULL}, NULL}} +#define wippersnapper_uart_UARTBusData_init_zero {0, "", "", 0} +#define wippersnapper_uart_UARTAdd_init_zero {false, wippersnapper_uart_UARTBusData_init_zero, {{NULL}, NULL}, 0} +#define wippersnapper_uart_UARTAdded_init_zero {{{NULL}, NULL}, 0} +#define wippersnapper_uart_UARTRemove_init_zero {{{NULL}, NULL}} +#define wippersnapper_uart_UARTEvent_init_zero {{{NULL}, NULL}, {{NULL}, NULL}} + +/* Field tags (for use in manual encoding/decoding) */ +#define wippersnapper_uart_UARTBusData_baudrate_tag 1 +#define wippersnapper_uart_UARTBusData_pin_rx_tag 2 +#define wippersnapper_uart_UARTBusData_pin_tx_tag 3 +#define wippersnapper_uart_UARTBusData_is_invert_tag 4 +#define wippersnapper_uart_UARTAdd_bus_info_tag 1 +#define wippersnapper_uart_UARTAdd_device_id_tag 2 +#define wippersnapper_uart_UARTAdd_polling_interval_tag 3 +#define wippersnapper_uart_UARTAdded_device_id_tag 1 +#define wippersnapper_uart_UARTAdded_is_success_tag 2 +#define wippersnapper_uart_UARTRemove_device_id_tag 1 +#define wippersnapper_uart_UARTEvent_device_id_tag 1 +#define wippersnapper_uart_UARTEvent_sensor_events_tag 2 + +/* Struct field encoding specification for nanopb */ +#define wippersnapper_uart_UARTBusData_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, baudrate, 1) \ +X(a, STATIC, SINGULAR, STRING, pin_rx, 2) \ +X(a, STATIC, SINGULAR, STRING, pin_tx, 3) \ +X(a, STATIC, SINGULAR, BOOL, is_invert, 4) +#define wippersnapper_uart_UARTBusData_CALLBACK NULL +#define wippersnapper_uart_UARTBusData_DEFAULT NULL + +#define wippersnapper_uart_UARTAdd_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, bus_info, 1) \ +X(a, CALLBACK, SINGULAR, STRING, device_id, 2) \ +X(a, STATIC, SINGULAR, INT32, polling_interval, 3) +#define wippersnapper_uart_UARTAdd_CALLBACK pb_default_field_callback +#define wippersnapper_uart_UARTAdd_DEFAULT NULL +#define wippersnapper_uart_UARTAdd_bus_info_MSGTYPE wippersnapper_uart_UARTBusData + +#define wippersnapper_uart_UARTAdded_FIELDLIST(X, a) \ +X(a, CALLBACK, SINGULAR, STRING, device_id, 1) \ +X(a, STATIC, SINGULAR, BOOL, is_success, 2) +#define wippersnapper_uart_UARTAdded_CALLBACK pb_default_field_callback +#define wippersnapper_uart_UARTAdded_DEFAULT NULL + +#define wippersnapper_uart_UARTRemove_FIELDLIST(X, a) \ +X(a, CALLBACK, SINGULAR, STRING, device_id, 1) +#define wippersnapper_uart_UARTRemove_CALLBACK pb_default_field_callback +#define wippersnapper_uart_UARTRemove_DEFAULT NULL + +#define wippersnapper_uart_UARTEvent_FIELDLIST(X, a) \ +X(a, CALLBACK, SINGULAR, STRING, device_id, 1) \ +X(a, CALLBACK, REPEATED, MESSAGE, sensor_events, 2) +#define wippersnapper_uart_UARTEvent_CALLBACK pb_default_field_callback +#define wippersnapper_uart_UARTEvent_DEFAULT NULL +#define wippersnapper_uart_UARTEvent_sensor_events_MSGTYPE wippersnapper_sensor_SensorEvent + +extern const pb_msgdesc_t wippersnapper_uart_UARTBusData_msg; +extern const pb_msgdesc_t wippersnapper_uart_UARTAdd_msg; +extern const pb_msgdesc_t wippersnapper_uart_UARTAdded_msg; +extern const pb_msgdesc_t wippersnapper_uart_UARTRemove_msg; +extern const pb_msgdesc_t wippersnapper_uart_UARTEvent_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define wippersnapper_uart_UARTBusData_fields &wippersnapper_uart_UARTBusData_msg +#define wippersnapper_uart_UARTAdd_fields &wippersnapper_uart_UARTAdd_msg +#define wippersnapper_uart_UARTAdded_fields &wippersnapper_uart_UARTAdded_msg +#define wippersnapper_uart_UARTRemove_fields &wippersnapper_uart_UARTRemove_msg +#define wippersnapper_uart_UARTEvent_fields &wippersnapper_uart_UARTEvent_msg + +/* Maximum encoded size of messages (where known) */ +/* wippersnapper_uart_UARTAdd_size depends on runtime parameters */ +/* wippersnapper_uart_UARTAdded_size depends on runtime parameters */ +/* wippersnapper_uart_UARTRemove_size depends on runtime parameters */ +/* wippersnapper_uart_UARTEvent_size depends on runtime parameters */ +#define WIPPERSNAPPER_UART_UART_PB_H_MAX_SIZE wippersnapper_uart_UARTBusData_size +#define wippersnapper_uart_UARTBusData_size 27 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/provisioning/littlefs/WipperSnapper_LittleFS.cpp b/src/provisioning/littlefs/WipperSnapper_LittleFS.cpp index 57a534a86..697614180 100644 --- a/src/provisioning/littlefs/WipperSnapper_LittleFS.cpp +++ b/src/provisioning/littlefs/WipperSnapper_LittleFS.cpp @@ -7,7 +7,7 @@ * please support Adafruit and open-source hardware by purchasing * products from Adafruit! * - * Copyright (c) Brent Rubell 2021-2022 for Adafruit Industries. + * Copyright (c) Brent Rubell 2021-2024 for Adafruit Industries. * * BSD license, all text here must be included in any redistribution. * @@ -17,7 +17,8 @@ defined(ARDUINO_ADAFRUIT_ITSYBITSY_ESP32) || \ defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2) || \ defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO) || \ - defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3) + defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3) || defined(ARDUINO_ESP32_DEV) || \ + defined(ESP32_DEV) #include "WipperSnapper_LittleFS.h" /**************************************************************************/ @@ -29,8 +30,8 @@ WipperSnapper_LittleFS::WipperSnapper_LittleFS() { // Attempt to initialize filesystem if (!LittleFS.begin()) { - setStatusLEDColor(RED); - fsHalt("ERROR: Failure initializing LittleFS!"); + fsHalt("ERROR: Failure initializing LittleFS!", + WS_LED_STATUS_WAITING_FOR_REG_MSG); } } @@ -69,7 +70,7 @@ void WipperSnapper_LittleFS::parseSecrets() { } if (doc.containsKey("network_type_wifi")) { // set default network config - convertFromJson(doc["network_type_wifi"], WS._config.network); + convertFromJson(doc["network_type_wifi"], WsV2._configV2.network); if (!doc["network_type_wifi"].containsKey("alternative_networks")) { // do nothing extra, we already have the only network @@ -96,13 +97,13 @@ void WipperSnapper_LittleFS::parseSecrets() { WS_DEBUG_PRINTLN(altnetworks[i]["network_ssid"].as()); break; } - convertFromJson(altnetworks[i], WS._multiNetworks[i]); + convertFromJson(altnetworks[i], WsV2._multiNetworksV2[i]); WS_DEBUG_PRINT("Added SSID: "); - WS_DEBUG_PRINTLN(WS._multiNetworks[i].ssid); + WS_DEBUG_PRINTLN(WsV2._multiNetworksV2[i].ssid); WS_DEBUG_PRINT("PASS: "); - WS_DEBUG_PRINTLN(WS._multiNetworks[i].pass); + WS_DEBUG_PRINTLN(WsV2._multiNetworksV2[i].pass); } - WS._isWiFiMulti = true; + WsV2._isWiFiMultiV2 = true; } else { fsHalt("ERROR: Unrecognised value type for " "network_type_wifi.alternative_networks in secrets.json!"); @@ -112,18 +113,18 @@ void WipperSnapper_LittleFS::parseSecrets() { } // Extract a config struct from the JSON document - WS._config = doc.as(); + WsV2._configV2 = doc.as(); // Validate the config struct is not filled with default values - if (strcmp(WS._config.aio_user, "YOUR_IO_USERNAME_HERE") == 0 || - strcmp(WS._config.aio_key, "YOUR_IO_KEY_HERE") == 0) { + if (strcmp(WsV2._configV2.aio_user, "YOUR_IO_USERNAME_HERE") == 0 || + strcmp(WsV2._configV2.aio_key, "YOUR_IO_KEY_HERE") == 0) { fsHalt( "ERROR: Invalid IO credentials in secrets.json! TO FIX: Please change " "io_username and io_key to match your Adafruit IO credentials!\n"); } - if (strcmp(WS._config.network.ssid, "YOUR_WIFI_SSID_HERE") == 0 || - strcmp(WS._config.network.pass, "YOUR_WIFI_PASS_HERE") == 0) { + if (strcmp(WsV2._configV2.network.ssid, "YOUR_WIFI_SSID_HERE") == 0 || + strcmp(WsV2._configV2.network.pass, "YOUR_WIFI_PASS_HERE") == 0) { fsHalt("ERROR: Invalid network credentials in secrets.json! TO FIX: Please " "change network_ssid and network_password to match your Adafruit IO " "credentials!\n"); @@ -143,8 +144,8 @@ void WipperSnapper_LittleFS::parseSecrets() { Error message to print to serial console. */ /**************************************************************************/ -void WipperSnapper_LittleFS::fsHalt(String msg) { - statusLEDSolid(WS_LED_STATUS_FS_WRITE); +void WipperSnapper_LittleFS::fsHalt(String msg, ws_led_status_t status_state) { + statusLEDSolid(status_state); while (1) { WS_DEBUG_PRINTLN("Fatal Error: Halted execution!"); WS_DEBUG_PRINTLN(msg.c_str()); @@ -153,4 +154,28 @@ void WipperSnapper_LittleFS::fsHalt(String msg) { } } +/**************************************************************************/ +/*! + @brief Attempts to obtain the hardware's CS pin from the + config.json file. +*/ +/**************************************************************************/ +void WipperSnapper_LittleFS::GetSDCSPin() { + // Attempt to open and deserialize the config.json file + File file_cfg = LittleFS.open("/config.json"); + if (!file_cfg) + WsV2.pin_sd_cs = 255; + + DeserializationError error = deserializeJson(WsV2._config_doc, file_cfg); + if (error) { + file_cfg.close(); + WsV2.pin_sd_cs = 255; + } + + // Parse config.json and save the SD CS pin + JsonObject exportedFromDevice = WsV2._config_doc["exportedFromDevice"]; + WsV2.pin_sd_cs = exportedFromDevice["sd_cs_pin"] | 255; + file_cfg.close(); +} + #endif \ No newline at end of file diff --git a/src/provisioning/littlefs/WipperSnapper_LittleFS.h b/src/provisioning/littlefs/WipperSnapper_LittleFS.h index 782e8569b..05b80875a 100644 --- a/src/provisioning/littlefs/WipperSnapper_LittleFS.h +++ b/src/provisioning/littlefs/WipperSnapper_LittleFS.h @@ -12,16 +12,14 @@ * BSD license, all text here must be included in any redistribution. * */ -#ifndef WIPPERSNAPPER_LITTLEFS_H -#define WIPPERSNAPPER_LITTLEFS_H +#ifndef WIPPERSNAPPER_LITTLEFS_V2_H +#define WIPPERSNAPPER_LITTLEFS_V2_H -#include "Wippersnapper.h" - -#include +#include "Wippersnapper_V2.h" #include // forward decl. -class Wippersnapper; +class Wippersnapper_V2; /***************************************************************************/ /*! @@ -33,8 +31,9 @@ class WipperSnapper_LittleFS { WipperSnapper_LittleFS(); ~WipperSnapper_LittleFS(); void parseSecrets(); - void fsHalt(String msg); + void fsHalt(String msg, + ws_led_status_t status_state = WS_LED_STATUS_ERROR_RUNTIME); + void GetSDCSPin(); }; - -extern Wippersnapper WS; +extern Wippersnapper_V2 WsV2; #endif // WIPPERSNAPPER_LITTLEFS_H \ No newline at end of file diff --git a/src/provisioning/sdcard/ws_sdcard.cpp b/src/provisioning/sdcard/ws_sdcard.cpp new file mode 100644 index 000000000..14b945a05 --- /dev/null +++ b/src/provisioning/sdcard/ws_sdcard.cpp @@ -0,0 +1,1273 @@ +/*! + * @file ws_sdcard.cpp + * + * Interface for Wippersnapper's SD card filesystem. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#include "ws_sdcard.h" + +/**************************************************************************/ +/*! + @brief Constructs an instance of the Wippersnapper SD card class. +*/ +/**************************************************************************/ +ws_sdcard::ws_sdcard() +#ifdef SD_USE_SPI_1 + : _sd_spi_cfg(WsV2.pin_sd_cs, DEDICATED_SPI, SPI_SD_CLOCK, &SPI1) { +#else + : _sd_spi_cfg(WsV2.pin_sd_cs, DEDICATED_SPI, SPI_SD_CLOCK) { +#endif + is_mode_offline = false; + _use_test_data = false; + _is_soft_rtc = false; + _sz_cur_log_file = 0; + _sd_cur_log_files = 0; + + if (WsV2.pin_sd_cs == PIN_SD_CS_ERROR) + return; + + if (!_sd.begin(_sd_spi_cfg)) { + WS_DEBUG_PRINTLN( + "[SD] Runtime Error: SD initialization failed.\nDo not reformat the " + "card!\nIs the card " + "correctly inserted?\nIs there a wiring/soldering problem\n"); + is_mode_offline = false; + return; + } + + // Card initialized - calculate file limits + is_mode_offline = true; + calculateFileLimits(); +} + +/**************************************************************************/ +/*! + @brief Destructs an instance of the Wippersnapper SD card class. +*/ +/**************************************************************************/ +ws_sdcard::~ws_sdcard() { + if (is_mode_offline) { + _sd.end(); // Close the SD card interface + } + is_mode_offline = false; +} + +void ws_sdcard::calculateFileLimits() { + // Calculate the maximum number of log files that can be stored on the SD card + csd_t csd; + if (!_sd.card()->readCSD(&csd)) { + WS_DEBUG_PRINTLN("[SD] Runtime Error: Could not read card information"); + return; + } + + // get the complete sdcard capacity in bytes + _sd_capacity = (uint64_t)512 * csd.capacity(); + // account for 3-5% fatfs overhead utilization + size_t sd_capacity_usable = _sd_capacity * (1 - 0.05); + // proportionally set sz of each log file to 10% of the SD card's usable + // capacity + _max_sz_log_file = sd_capacity_usable / 10; + // Regardless of sd card size, cap log files to 512MB + if (_max_sz_log_file > MAX_SZ_LOG_FILE) { + _max_sz_log_file = MAX_SZ_LOG_FILE; + } + _sd_max_num_log_files = sd_capacity_usable / _max_sz_log_file; +} +/**************************************************************************/ +/*! + @brief Initializes a DS1307 RTC + @returns True if the RTC was successfully initialized, False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::InitDS1307() { + _rtc_ds1307 = new RTC_DS1307(); + if (!_rtc_ds1307->begin()) { + if (!_rtc_ds1307->begin(&Wire1)) { + WS_DEBUG_PRINTLN("[SD] Runtime Error: Failed to initialize DS1307 RTC"); + delete _rtc_ds1307; + return false; + } + } + if (!_rtc_ds1307->isrunning()) + _rtc_ds1307->adjust(DateTime(F(__DATE__), F(__TIME__))); + return true; +} + +/**************************************************************************/ +/*! + @brief Initializes a DS3231 RTC. + @returns True if the RTC was successfully initialized, False + otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::InitDS3231() { + WS_DEBUG_PRINTLN("Begin DS3231 init"); + _rtc_ds3231 = new RTC_DS3231(); + if (!_rtc_ds3231->begin(&Wire)) { + if (!_rtc_ds3231->begin(&Wire1)) { + WS_DEBUG_PRINTLN("[SD] Runtime Error: Failed to initialize DS3231 RTC"); + delete _rtc_ds3231; + return false; + } + } + if (_rtc_ds3231->lostPower()) + _rtc_ds3231->adjust(DateTime(F(__DATE__), F(__TIME__))); + return true; +} + +/**************************************************************************/ +/*! + @brief Initializes a PCF8523 RTC. + @returns True if the RTC was successfully initialized, False + otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::InitPCF8523() { + _rtc_pcf8523 = new RTC_PCF8523(); + if (!_rtc_pcf8523->begin(&Wire)) { + WS_DEBUG_PRINTLN( + "[SD] Runtime Error: Failed to initialize PCF8523 RTC on WIRE"); + if (!_rtc_pcf8523->begin(&Wire1)) { + WS_DEBUG_PRINTLN( + "[SD] Runtime Error: Failed to initialize PCF8523 RTC on WIRE1"); + delete _rtc_pcf8523; + return false; + } + } + if (!_rtc_pcf8523->initialized() || _rtc_pcf8523->lostPower()) { + _rtc_pcf8523->adjust(DateTime(F(__DATE__), F(__TIME__))); + } + _rtc_pcf8523->start(); + return true; +} + +/**************************************************************************/ +/*! + @brief Initializes a "soft" RTC for devices without a physical + RTC module attached. + @returns True if the soft RTC was successfully initialized, False + otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::InitSoftRTC() { + _is_soft_rtc = true; + _soft_rtc_counter = 0; + return _is_soft_rtc; +} + +/**************************************************************************/ +/*! + @brief Increments the "soft" RTC. +*/ +/**************************************************************************/ +void ws_sdcard::TickSoftRTC() { _soft_rtc_counter++; } + +/**************************************************************************/ +/*! + @brief Returns the current timestamp from the RTC. + @returns The current timestamp from the RTC. +*/ +/**************************************************************************/ +uint32_t ws_sdcard::GetSoftRTCTime() { return _soft_rtc_counter; } + +/**************************************************************************/ +/*! + @brief Initializes and configures a RTC for logging. + @param rtc_type + The desired type of RTC to configure. + @returns True if the RTC was successfully configured, False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::ConfigureRTC(const char *rtc_type) { + if (strcmp(rtc_type, "DS1307") == 0) { + return InitDS1307(); + } else if (strcmp(rtc_type, "DS3231") == 0) { + return InitDS3231(); + } else if (strcmp(rtc_type, "PCF8523") == 0) { + return InitPCF8523(); + } else if (strcmp(rtc_type, "SOFT") == 0) { + return InitSoftRTC(); + } else + WS_DEBUG_PRINTLN( + "[SD] Runtime Error: Unknown RTC type found in JSON string!"); + return false; +} + +/**************************************************************************/ +/*! + @brief Configure's the hardware from the JSON's exportedFromDevice + object. + @param max_digital_pins + The total number of digital pins on the device. + @param max_analog_pins + The total number of analog pins on the device. + @param ref_voltage + The reference voltage of the device, in Volts. +*/ +/**************************************************************************/ +void ws_sdcard::CheckIn(uint8_t max_digital_pins, uint8_t max_analog_pins, + float ref_voltage) { + WsV2.digital_io_controller->SetMaxDigitalPins(max_digital_pins); + WsV2.analogio_controller->SetTotalAnalogPins(max_analog_pins); + WsV2.analogio_controller->SetRefVoltage(ref_voltage); +} + +/**************************************************************************/ +/*! + @brief Parses a sensor type from the JSON configuration file. + @param sensor_type + The sensor type to parse. + @returns The corresponding SensorType +*/ +/**************************************************************************/ +wippersnapper_sensor_SensorType +ws_sdcard::ParseSensorType(const char *sensor_type) { + if (strcmp(sensor_type, "raw") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW; + } else if (strcmp(sensor_type, "voltage") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE; + } else if (strcmp(sensor_type, "current") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_CURRENT; + } else if (strcmp(sensor_type, "object-temp-fahrenheit") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT; + } else if (strcmp(sensor_type, "object-temp") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE; + } else if (strcmp(sensor_type, "ambient-temp") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE; + } else if (strcmp(sensor_type, "ambient-temp-fahrenheit") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT; + } else if (strcmp(sensor_type, "accelerometer") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; + } else if (strcmp(sensor_type, "magnetic-field") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_MAGNETIC_FIELD; + } else if (strcmp(sensor_type, "orientation") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_ORIENTATION; + } else if (strcmp(sensor_type, "gyroscope") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_GYROSCOPE; + } else if (strcmp(sensor_type, "gravity") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_GRAVITY; + } else if (strcmp(sensor_type, "linear-acceleration") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_LINEAR_ACCELERATION; + } else if (strcmp(sensor_type, "rotation-vector") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_ROTATION_VECTOR; + } else if (strcmp(sensor_type, "altitude") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_ALTITUDE; + } else if (strcmp(sensor_type, "relative-humidity") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_RELATIVE_HUMIDITY; + } else if (strcmp(sensor_type, "pressure") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_PRESSURE; + } else if (strcmp(sensor_type, "light") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_LIGHT; + } else if (strcmp(sensor_type, "lux") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_LUX; + } else if (strcmp(sensor_type, "proximity") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_PROXIMITY; + } else if (strcmp(sensor_type, "pm10-std") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_PM10_STD; + } else if (strcmp(sensor_type, "pm25-std") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_PM25_STD; + } else if (strcmp(sensor_type, "pm100-std") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_PM100_STD; + } else if (strcmp(sensor_type, "pm10-env") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_PM10_ENV; + } else if (strcmp(sensor_type, "pm25-env") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_PM25_ENV; + } else if (strcmp(sensor_type, "pm100-env") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_PM100_ENV; + } else if (strcmp(sensor_type, "co2") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_CO2; + } else if (strcmp(sensor_type, "eco2") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_ECO2; + } else if (strcmp(sensor_type, "gas-resistance") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_GAS_RESISTANCE; + } else if (strcmp(sensor_type, "voc-index") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_VOC_INDEX; + } else if (strcmp(sensor_type, "nox-index") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_NOX_INDEX; + } else if (strcmp(sensor_type, "tvoc") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_TVOC; + } else if (strcmp(sensor_type, "color") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_COLOR; + } else if (strcmp(sensor_type, "unitless-percent") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_UNITLESS_PERCENT; + } else if (strcmp(sensor_type, "bytes") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_BYTES; + } else if (strcmp(sensor_type, "boolean") == 0) { + return wippersnapper_sensor_SensorType_SENSOR_TYPE_BOOLEAN; + } else { + WS_DEBUG_PRINT("[SD] ERROR: Found unspecified SensorType - "); + WS_DEBUG_PRINTLN(sensor_type); + return wippersnapper_sensor_SensorType_SENSOR_TYPE_UNSPECIFIED; + } +} + +bool ws_sdcard::ValidateJSONKey(const char *key, const char *error_msg) { + if (strcmp(key, UNKNOWN_VALUE) == 0) { + WS_DEBUG_PRINTLN(error_msg); + return false; + } + return true; +} + +/**************************************************************************/ +/*! + @brief Parses a DigitalIOAdd message from the JSON configuration file. + @param msg_DigitalIOAdd + The DigitalIOAdd message to populate. + @param pin + The GPIO pin name. + @param period + The desired period to read the sensor, in seconds. + @param value + The sensor value. + @param sample_mode + The sample mode. + @param direction + The GPIO pin direction. + @param pull + The GPIO pin pull. + @returns True if the DigitalIOAdd message was successfully parsed, + False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::ParseDigitalIOAdd( + wippersnapper_digitalio_DigitalIOAdd &msg_DigitalIOAdd, const char *pin, + float period, bool value, const char *sample_mode, const char *direction, + const char *pull) { + if (!ValidateJSONKey(pin, "[SD] Parsing Error: Digital pin name not found!")) + return false; + strcpy(msg_DigitalIOAdd.pin_name, pin); + + if (period == 0.0) { + WS_DEBUG_PRINTLN("[SD] Parsing Error: Invalid pin period!"); + return false; + } + msg_DigitalIOAdd.period = period; + msg_DigitalIOAdd.value = value; + + // Determine the sample mode + if (!ValidateJSONKey( + sample_mode, + "[SD] Parsing Error: Digital pin's sample mode not found!")) { + return false; + } else if (strcmp(sample_mode, "TIMER") == 0) { + msg_DigitalIOAdd.sample_mode = + wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_TIMER; + } else if (strcmp(sample_mode, "EVENT") == 0) { + msg_DigitalIOAdd.sample_mode = + wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_EVENT; + } else { + WS_DEBUG_PRINTLN("[SD] Parsing Error: Unknown sample mode found: " + + String(sample_mode)); + } + + // Determine the pin direction and pull + if (!ValidateJSONKey( + direction, + "[SD] Parsing Error: Digital pin's direction not found!")) { + return false; + } else if (strcmp(direction, "INPUT") == 0) { + if (pull != nullptr) { + msg_DigitalIOAdd.gpio_direction = + wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_INPUT_PULL_UP; + } else { + msg_DigitalIOAdd.gpio_direction = + wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_INPUT; + } + } else if (strcmp(direction, "OUTPUT") == 0) { + WS_DEBUG_PRINTLN( + "[SD] Error - Can not set OUTPUT direction in offline mode!"); + return false; + } else { + WS_DEBUG_PRINTLN("[SD] Parsing Error: Unknown direction found: " + + String(direction)); + return false; + } + return true; +} + +/**************************************************************************/ +/*! + @brief Parses an AnalogIOAdd message from the JSON configuration file. + @param msg_AnalogIOAdd + The AnalogIOAdd message to populate. + @param pin + The GPIO pin name. + @param period + The desired period to read the sensor, in seconds. + @param mode + The sensor read mode. + @returns True if the AnalogIOAdd message was successfully parsed, + False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::ParseAnalogIOAdd( + wippersnapper_analogio_AnalogIOAdd &msg_AnalogIOAdd, const char *pin, + float period, const char *mode) { + + if (!ValidateJSONKey(pin, "[SD] Parsing Error: Analog pin name not found!")) + return false; + strcpy(msg_AnalogIOAdd.pin_name, pin); + + if (period == 0.0) { + WS_DEBUG_PRINTLN("[SD] Parsing Error: Analog pin period less than 1.0 " + "seconds or not found!"); + return false; + } + msg_AnalogIOAdd.period = period; + + if (!ValidateJSONKey(mode, + "[SD] Parsing Error: Analog pin read mode not found!")) + return false; + msg_AnalogIOAdd.read_mode = ParseSensorType(mode); + if (msg_AnalogIOAdd.read_mode == + wippersnapper_sensor_SensorType_SENSOR_TYPE_UNSPECIFIED) { + WS_DEBUG_PRINTLN("[SD] Parsing Error: Unknown read mode found: " + + String(mode)); + return false; + } + return true; +} + +bool ws_sdcard::ParseDS18X20Add( + wippersnapper_ds18x20_Ds18x20Add &msg_DS18X20Add, const char *pin, + int resolution, float period, int num_sensors, const char *sensor_type_1, + const char *sensor_type_2) { + + if (strcmp(pin, UNKNOWN_VALUE) == 0) { + WS_DEBUG_PRINTLN("[SD] Parsing Error: DS18X20 pin name not found!"); + return false; + } + strcpy(msg_DS18X20Add.onewire_pin, pin); + + if (resolution == 0) { + WS_DEBUG_PRINTLN( + "[SD] Parsing Error: DS18X20 sensor resolution not found!"); + return false; + } + msg_DS18X20Add.sensor_resolution = resolution; + + if (period == 0.0) { + WS_DEBUG_PRINTLN("[SD] Parsing Error: DS18X20 sensor period not found!"); + return false; + } + msg_DS18X20Add.period = period; + + if (num_sensors == 0) { + WS_DEBUG_PRINTLN("[SD] Parsing Error: DS18X20 sensor count not found!"); + return false; + } + msg_DS18X20Add.sensor_types_count = num_sensors; + + // Parse the first sensor type + if (strcmp(sensor_type_1, UNKNOWN_VALUE) == 0) { + WS_DEBUG_PRINTLN("[SD] Parsing Error: DS18X20 sensor type 1 not found!"); + return false; + } + msg_DS18X20Add.sensor_types[0] = ParseSensorType(sensor_type_1); + // Parse the second sensor type, if it exists + if (num_sensors == 2) { + if (strcmp(sensor_type_2, UNKNOWN_VALUE) == 0) { + WS_DEBUG_PRINTLN("[SD] Parsing Error: DS18X20 sensor type 2 not found!"); + return false; + } + msg_DS18X20Add.sensor_types[1] = ParseSensorType(sensor_type_2); + } + return true; +} + +/**************************************************************************/ +/*! + @brief Converts a string-encoded hex value to an integer. + @param hex_str + The string-encoded hex value to convert. + @returns The integer value of the hex string. +*/ +/**************************************************************************/ +uint32_t ws_sdcard::HexStrToInt(const char *hex_str) { + return std::stoi(hex_str, nullptr, 16); +} + +/**************************************************************************/ +/*! + @brief Parses an I2cDeviceAddOrReplace message from the JSON + configuration file. + @param component + The JSON object to parse. + @param msg_i2c_add + The I2cDeviceAddOrReplace message to populate. + @returns True if the I2cDeviceAddOrReplace message was successfully + parsed, False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::ParseI2cDeviceAddReplace( + JsonObject &component, + wippersnapper_i2c_I2cDeviceAddOrReplace &msg_i2c_add) { + strcpy(msg_i2c_add.i2c_device_name, + component["i2cDeviceName"] | UNKNOWN_VALUE); + msg_i2c_add.i2c_device_period = component["period"] | 0.0; + if (msg_i2c_add.i2c_device_period == 0.0) { + WS_DEBUG_PRINTLN("[SD] Parsing Error: Invalid I2C device period!"); + return false; + } + + msg_i2c_add.has_i2c_device_description = true; + strcpy(msg_i2c_add.i2c_device_description.i2c_bus_scl, + component["i2cBusScl"] | "default"); + strcpy(msg_i2c_add.i2c_device_description.i2c_bus_sda, + component["i2cBusSda"] | "default"); + + const char *addr_device = component["i2cDeviceAddress"] | "0x00"; + msg_i2c_add.i2c_device_description.i2c_device_address = + HexStrToInt(addr_device); + + const char *addr_mux = component["i2cMuxAddress"] | "0x00"; + msg_i2c_add.i2c_device_description.i2c_mux_address = HexStrToInt(addr_mux); + + const char *mux_channel = component["i2cMuxChannel"] | "0xFFFF"; + msg_i2c_add.i2c_device_description.i2c_mux_channel = HexStrToInt(mux_channel); + + msg_i2c_add.i2c_device_sensor_types_count = 0; + for (JsonObject components_0_i2cDeviceSensorType : + component["i2cDeviceSensorTypes"].as()) { + msg_i2c_add + .i2c_device_sensor_types[msg_i2c_add.i2c_device_sensor_types_count] = + ParseSensorType(components_0_i2cDeviceSensorType["type"]); + msg_i2c_add.i2c_device_sensor_types_count++; + } + + return true; +} + +/**************************************************************************/ +/*! + @brief Pushes a signal message to the shared buffer. + @param msg_signal + The signal message to push. + @returns True if the signal message was successfully pushed to the shared + buffer, False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::AddSignalMessageToSharedBuffer( + wippersnapper_signal_BrokerToDevice &msg_signal) { + // Create a temporary buffer to hold the encoded signal message + std::vector tempBuf(512); + size_t tempBufSz; + + // Get the encoded size of the signal message first so we can resize the + // buffer prior to encoding + if (!pb_get_encoded_size(&tempBufSz, + wippersnapper_signal_BrokerToDevice_fields, + &msg_signal)) { + WS_DEBUG_PRINTLN("[SD] Runtime Error: Unable to get signal message size!"); + return false; + } + + // Encode and push the signal message to the shared config buffer + tempBuf.resize(tempBufSz); + pb_ostream_t ostream = pb_ostream_from_buffer(tempBuf.data(), tempBuf.size()); + if (!ws_pb_encode(&ostream, wippersnapper_signal_BrokerToDevice_fields, + &msg_signal)) { + WS_DEBUG_PRINTLN( + "[SD] Runtime Error: Unable to encode D2B signal message!"); + return false; + } + WsV2._sharedConfigBuffers.push_back(std::move(tempBuf)); + return true; +} + +/**************************************************************************/ +/*! + @brief Creates a new logging file on the SD card using the RTC's + timestamp and sets the current log file path to reflect this + file. + @returns True if a log file was successfully created, False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::CreateNewLogFile() { + if (_sd_cur_log_files >= _sd_max_num_log_files) { + WS_DEBUG_PRINTLN("[SD] Runtime Error: Maximum number of log files for SD " + "card capacity reached!"); + return false; + } + + String logFilename; + // Generate a name for the new log file using the RTC's timestamp + if (!_is_soft_rtc) + logFilename = "log_" + String(GetTimestamp()) + ".log"; + else + logFilename = "log_" + String(millis()) + ".log"; + static char log_filename_buffer[256]; + strncpy(log_filename_buffer, logFilename.c_str(), + sizeof(log_filename_buffer) - 1); + log_filename_buffer[sizeof(log_filename_buffer) - 1] = '\0'; + _log_filename = log_filename_buffer; + _sz_cur_log_file = 0; // Reset the current log file size + + // Attempt to create a new log file + File32 file; + if (!file.open(_log_filename, O_RDWR | O_CREAT | O_AT_END)) + return false; + WS_DEBUG_PRINT("[SD] Created new log file on SD card: "); + WS_DEBUG_PRINTLN(_log_filename); + _sd_cur_log_files++; + return true; +} + +bool ws_sdcard::ValidateChecksum(JsonDocument &doc) { + int json_doc_checksum = doc["checksum"]; + // Calculate the checksum of the JSON document without the checksum field + doc.remove("checksum"); + String doc_without_checksum; + serializeJson(doc, doc_without_checksum); + uint8_t calculated_checksum = 0; + for (unsigned int i = 0; i < doc_without_checksum.length(); i++) { + calculated_checksum += doc_without_checksum[i]; + } + calculated_checksum &= 0xFF; // take lsb + + if (json_doc_checksum != calculated_checksum) + return false; + return true; +} + +/**************************************************************************/ +/*! + @brief Searches for and parses the JSON configuration file and sets up + the hardware accordingly. + @returns True if the JSON file was successfully parsed and the hardware + was successfully configured. False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::parseConfigFile() { + DeserializationError error; + JsonDocument doc; + delay(5000); + + // Parse configuration data +#ifndef OFFLINE_MODE_DEBUG + WS_DEBUG_PRINTLN("[SD] Parsing config.json..."); + doc = WsV2._config_doc; +#else + // Use test data rather than data from the filesystem + if (!_use_test_data) { + WS_DEBUG_PRINTLN("[SD] Parsing Serial Input..."); + WS_DEBUG_PRINTLN(_serialInput); + error = deserializeJson(doc, _serialInput.c_str(), MAX_LEN_CFG_JSON); + } else { + WS_DEBUG_PRINTLN("[SD] Parsing Test Data..."); + error = deserializeJson(doc, json_test_data, MAX_LEN_CFG_JSON); + } +#endif + // It is not possible to continue running in offline mode without a valid + // config file + if (error) { + WS_DEBUG_PRINT("[SD] Runtime Error: Unable to deserialize config.json"); + WS_DEBUG_PRINTLN("\nError Code: " + String(error.c_str())); + return false; + } + WS_DEBUG_PRINTLN("[SD] Successfully deserialized JSON config file!"); + + // Check config.json file's integrity + if (!ValidateChecksum(doc)) { + WS_DEBUG_PRINTLN("[SD] Checksum mismatch, file has been modified from its " + "original state!"); + } + WS_DEBUG_PRINTLN("[SD] Checksum OK!"); + + // Begin parsing the JSON document + JsonObject exportedFromDevice = doc["exportedFromDevice"]; + if (exportedFromDevice.isNull()) { + WS_DEBUG_PRINTLN("[SD] Runtime Error: Required exportedFromDevice not " + "found in config file!"); + return false; + } + + WS_DEBUG_PRINTLN("Parsing components array..."); + // TODO: It gets stuck here because we reformated how components works, + // try possibly adding another component like a button and then troubleshoot + JsonArray components_ar = doc["components"].as(); + if (components_ar.isNull()) { + WS_DEBUG_PRINTLN( + "[SD] Runtime Error: Required components array not found!"); + return false; + } + + WS_DEBUG_PRINTLN("Parsing exportedFromDevice object..."); + + // We don't talk to IO here, mock an "offline" device check-in + CheckIn(exportedFromDevice["totalGPIOPins"] | 0, + exportedFromDevice["totalAnalogPins"] | 0, + exportedFromDevice["referenceVoltage"] | 0.0); + WS_DEBUG_PRINT("status LED brightness: "); + int exportedFromDevice_statusLEDBrightness = + exportedFromDevice["statusLEDBrightness"]; + WS_DEBUG_PRINTLN(exportedFromDevice_statusLEDBrightness); + setStatusLEDBrightness(exportedFromDevice["statusLEDBrightness"] | 0.3); + + WS_DEBUG_PRINTLN("Configuring RTC..."); +#ifndef OFFLINE_MODE_WOKWI + const char *json_rtc = exportedFromDevice["rtc"] | "SOFT"; + WS_DEBUG_PRINT("RTC Type: "); + WS_DEBUG_PRINTLN(json_rtc); + if (!ConfigureRTC(json_rtc)) { + WS_DEBUG_PRINTLN("[SD] Runtime Error: Failed to to configure RTC!"); + return false; + } +#endif + + WS_DEBUG_PRINTLN("Parsing components array..."); + + // Parse each component from JSON->PB and push into a shared buffer + for (JsonObject component : doc["components"].as()) { + wippersnapper_signal_BrokerToDevice msg_signal_b2d = + wippersnapper_signal_BrokerToDevice_init_default; + + // Parse the component API type + const char *component_api_type = component["componentAPI"]; + if (component_api_type == nullptr) { + WS_DEBUG_PRINTLN("[SD] Runtime Error: Missing component API type!"); + return false; + } + + // Determine the component type and parse it into a PB message + if (strcmp(component_api_type, "digitalio") == 0) { + WS_DEBUG_PRINTLN( + "[SD] DigitalIO component found, decoding JSON to PB..."); + wippersnapper_digitalio_DigitalIOAdd msg_DigitalIOAdd = + wippersnapper_digitalio_DigitalIOAdd_init_default; + if (!ParseDigitalIOAdd( + msg_DigitalIOAdd, component["pinName"] | UNKNOWN_VALUE, + component["period"] | 0.0, component["value"], + component["sampleMode"] | UNKNOWN_VALUE, + component["direction"] | UNKNOWN_VALUE, component["pull"])) { + WS_DEBUG_PRINT( + "[SD] Runtime Error: Unable to parse DigitalIO Component, Pin: "); + WS_DEBUG_PRINTLN(component["pinName"] | UNKNOWN_VALUE); + return false; + } + + msg_signal_b2d.which_payload = + wippersnapper_signal_BrokerToDevice_digitalio_add_tag; + msg_signal_b2d.payload.digitalio_add = msg_DigitalIOAdd; + } else if (strcmp(component_api_type, "analogio") == 0) { + WS_DEBUG_PRINTLN("[SD] AnalogIO component found, decoding JSON to PB..."); + wippersnapper_analogio_AnalogIOAdd msg_AnalogIOAdd = + wippersnapper_analogio_AnalogIOAdd_init_default; + if (!ParseAnalogIOAdd(msg_AnalogIOAdd, + component["pinName"] | UNKNOWN_VALUE, + component["period"] | 0.0, + component["analogReadMode"] | UNKNOWN_VALUE)) { + WS_DEBUG_PRINTLN( + "[SD] Runtime Error: Unable to parse AnalogIO Component, Pin: "); + WS_DEBUG_PRINTLN(component["pinName"] | UNKNOWN_VALUE); + return false; + } + + msg_signal_b2d.which_payload = + wippersnapper_signal_BrokerToDevice_analogio_add_tag; + msg_signal_b2d.payload.analogio_add = msg_AnalogIOAdd; + } else if (strcmp(component_api_type, "ds18x20") == 0) { + WS_DEBUG_PRINTLN("[SD] Ds18x20 component found, decoding JSON to PB..."); + wippersnapper_ds18x20_Ds18x20Add msg_DS18X20Add = + wippersnapper_ds18x20_Ds18x20Add_init_default; + if (!ParseDS18X20Add(msg_DS18X20Add, component["pinName"] | UNKNOWN_VALUE, + component["sensorResolution"] | 0, + component["period"] | 0.0, + component["sensorTypeCount"] | 0, + component["sensorType1"] | UNKNOWN_VALUE, + component["sensorType2"] | UNKNOWN_VALUE)) { + WS_DEBUG_PRINTLN( + "[SD] Runtime Error: Unable to parse DS18X20 Component, Pin: "); + WS_DEBUG_PRINTLN(component["pinName"] | UNKNOWN_VALUE); + return false; + } + msg_signal_b2d.which_payload = + wippersnapper_signal_BrokerToDevice_ds18x20_add_tag; + msg_signal_b2d.payload.ds18x20_add = msg_DS18X20Add; + } else if (strcmp(component_api_type, "i2c") == 0) { + WS_DEBUG_PRINTLN("[SD] I2C component found, decoding JSON to PB..."); + wippersnapper_i2c_I2cDeviceAddOrReplace msg_i2c_add_replace = + wippersnapper_i2c_I2cDeviceAddOrReplace_init_default; + if (!ParseI2cDeviceAddReplace(component, msg_i2c_add_replace)) { + WS_DEBUG_PRINTLN("[SD] Runtime Error: Unable to parse I2C Component"); + return false; + } + msg_signal_b2d.which_payload = + wippersnapper_signal_BrokerToDevice_i2c_device_add_replace_tag; + msg_signal_b2d.payload.i2c_device_add_replace = msg_i2c_add_replace; + } else { + WS_DEBUG_PRINTLN("[SD] Runtime Error: Unknown Component API Type: " + + String(component_api_type)); + return false; + } + + // App handles the signal messages, in-order + if (!AddSignalMessageToSharedBuffer(msg_signal_b2d)) { + WS_DEBUG_PRINTLN("[SD] Runtime Error: Unable to add signal message(s) " + "to shared buffer!"); + return false; + } + } + return true; +} + +/**************************************************************************/ +/*! + @brief Obtains a timestamp from the hardware (or software) RTC. + @returns The current timestamp, in unixtime format. +*/ +/**************************************************************************/ +uint32_t ws_sdcard::GetTimestamp() { + DateTime now; + if (_rtc_ds3231 != nullptr) + now = _rtc_ds3231->now(); + else if (_rtc_ds1307 != nullptr) + now = _rtc_ds1307->now(); + else if (_rtc_pcf8523 != nullptr) + now = _rtc_pcf8523->now(); + else if (_is_soft_rtc) { + uint32_t cur_time = GetSoftRTCTime(); + TickSoftRTC(); + return cur_time; // early-return as we are not converting this "soft rtc" to + // unixtime + } else { // we're either using a simulator or have undefined behavior + return 0; + } + + return now.unixtime(); +} + +/**************************************************************************/ +/*! + @brief Converts a SensorType enum to a string. + @param sensorType + The SensorType enum to convert. + @returns A string representation of the SensorType enum. +*/ +/**************************************************************************/ +const char *SensorTypeToSIUnit(wippersnapper_sensor_SensorType sensorType) { + switch (sensorType) { + case wippersnapper_sensor_SensorType_SENSOR_TYPE_UNSPECIFIED: + return "UNSPECIFIED"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER: + return "m/s/s"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_MAGNETIC_FIELD: + return "µT"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_ORIENTATION: + return "\xB0"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_GYROSCOPE: + return "rad/s"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_LIGHT: + return "none"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_PRESSURE: + return "hPa"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_PROXIMITY: + return "none"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_GRAVITY: + return "m/s^2"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_LINEAR_ACCELERATION: + return "m/s^2"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_ROTATION_VECTOR: + return "rad"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_RELATIVE_HUMIDITY: + return "\x25"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE: + return "C"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE: + return "C"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE: + return "V"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_CURRENT: + return "mA"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_COLOR: + return "none"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW: + return "none"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_PM10_STD: + return "ppm"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_PM25_STD: + return "ppm"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_PM100_STD: + return "ppm"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_PM10_ENV: + return "ppm"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_PM25_ENV: + return "ppm"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_PM100_ENV: + return "ppm"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_CO2: + return "ppm"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_GAS_RESISTANCE: + return "\u03A9"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_ALTITUDE: + return "m"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_LUX: + return "lux"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_ECO2: + return "ppm"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_UNITLESS_PERCENT: + return "\x25"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT: + return "F"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT: + return "F"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_VOC_INDEX: + return "VOC"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_NOX_INDEX: + return "NOX"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_TVOC: + return "ppb"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_BYTES: + return "bytes"; + case wippersnapper_sensor_SensorType_SENSOR_TYPE_BOOLEAN: + return "boolean"; + default: + return "UNKNOWN"; + } +} + +/**************************************************************************/ +/*! + @brief Builds a JSON document for a sensor event. + @param doc + The JSON document to populate. + @param pin + The GPIO pin number. + @param value + The sensor value. + @param read_type + The sensor type. +*/ +/**************************************************************************/ +void ws_sdcard::BuildJSONDoc(JsonDocument &doc, uint8_t pin, float value, + wippersnapper_sensor_SensorType read_type) { + doc["timestamp"] = GetTimestamp(); + doc["pin"] = "A" + String(pin); + doc["value"] = value; + doc["si_unit"] = SensorTypeToSIUnit(read_type); +} + +/**************************************************************************/ +/*! + @brief Builds a JSON document for a sensor event. + @param doc + The JSON document to populate. + @param pin + The GPIO pin number. + @param value + The sensor value. + @param read_type + The sensor type. +*/ +/**************************************************************************/ +void ws_sdcard::BuildJSONDoc(JsonDocument &doc, uint8_t pin, uint16_t value, + wippersnapper_sensor_SensorType read_type) { + doc["timestamp"] = GetTimestamp(); + doc["pin"] = "A" + String(pin); + doc["value"] = value; + doc["si_unit"] = SensorTypeToSIUnit(read_type); +} + +/**************************************************************************/ +/*! + @brief Builds a JSON document for a sensor event. + @param doc + The JSON document to populate. + @param pin + The GPIO pin number. + @param value + The sensor value. + @param read_type + The sensor type. +*/ +/**************************************************************************/ +void ws_sdcard::BuildJSONDoc(JsonDocument &doc, uint8_t pin, bool value, + wippersnapper_sensor_SensorType read_type) { + doc["timestamp"] = GetTimestamp(); + doc["pin"] = "D" + String(pin); + doc["value"] = value; + doc["si_unit"] = SensorTypeToSIUnit(read_type); +} + +/**************************************************************************/ +/*! + @brief Logs a JSON document to the SD card. + @param doc + The JSON document to log. + @returns True if the document was successfully logged, False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::LogJSONDoc(JsonDocument &doc) { + size_t szJson; + +#ifndef OFFLINE_MODE_DEBUG + File32 file; + file = _sd.open(_log_filename, O_RDWR | O_CREAT | O_AT_END); + if (!file) { + WS_DEBUG_PRINTLN( + "[SD] Runtime Error: Unable to open log file for writing!"); + return false; + } + BufferingPrint bufferedFile(file, 64); // Add buffering to the file + szJson = serializeJson( + doc, file); // Serialize the JSON to the file in 64-byte chunks + bufferedFile.print("\n"); // JSONL format specifier + bufferedFile.flush(); // Send the remaining bytes + file.close(); + // Update log file's size + _sz_cur_log_file += (szJson + 2); // +2 for newline + // print the doc to the serial + serializeJson(doc, Serial); + Serial.print("\n"); +#else + szJson = serializeJson(doc, Serial); + Serial.print("\n"); // Required JSONL format specifier +#endif + + // Do we need a new log file? + if (_sz_cur_log_file >= _max_sz_log_file) { + WS_DEBUG_PRINTLN( + "[SD] NOTE: Log file has exceeded maximum size! Attempting to " + "create a new file..."); + return CreateNewLogFile(); + } + + return true; +} + +/**************************************************************************/ +/*! + @brief Logs a GPIO sensor event to the SD card. + @param pin + The GPIO pin number. + @param value + The sensor value. + @param read_type + The sensor type. + @returns True if the event was successfully logged, False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::LogGPIOSensorEventToSD( + uint8_t pin, float value, wippersnapper_sensor_SensorType read_type) { + JsonDocument doc; + BuildJSONDoc(doc, pin, value, read_type); + if (!LogJSONDoc(doc)) + return false; + return true; +} + +/**************************************************************************/ +/*! + @brief Logs a GPIO sensor event to the SD card. + @param pin + The GPIO pin number. + @param value + The sensor value. + @param read_type + The sensor type. + @returns True if the event was successfully logged, False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::LogGPIOSensorEventToSD( + uint8_t pin, uint16_t value, wippersnapper_sensor_SensorType read_type) { + JsonDocument doc; + BuildJSONDoc(doc, pin, value, read_type); + if (!LogJSONDoc(doc)) + return false; + return true; +} + +/**************************************************************************/ +/*! + @brief Logs a GPIO sensor event to the SD card. + @param pin + The GPIO pin number. + @param value + The sensor value. + @param read_type + The sensor type. + @returns True if the event was successfully logged, False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::LogGPIOSensorEventToSD( + uint8_t pin, bool value, wippersnapper_sensor_SensorType read_type) { + JsonDocument doc; + BuildJSONDoc(doc, pin, value, read_type); + if (!LogJSONDoc(doc)) + return false; + return true; +} + +/**************************************************************************/ +/*! + @brief Logs a GPIO sensor event to the SD card. + @param pin + The GPIO pin number. + @param value + The sensor value. + @param read_type + The sensor type. + @returns True if the event was successfully logged, False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::LogDS18xSensorEventToSD( + wippersnapper_ds18x20_Ds18x20Event *event_msg) { + JsonDocument doc; + // Iterate over the event message's sensor events + // TODO: Standardize this Event with I2C + for (int i = 0; i < event_msg->sensor_events_count; i++) { + uint32_t timestamp = GetTimestamp(); + doc["timestamp"] = timestamp; + doc["pin"] = event_msg->onewire_pin; + doc["value"] = event_msg->sensor_events[i].value.float_value; + doc["si_unit"] = SensorTypeToSIUnit(event_msg->sensor_events[i].type); + LogJSONDoc(doc); + } + return true; +} + +/**************************************************************************/ +/*! + @brief Logs an I2C sensor event to the SD card. + @param msg_device_event + The I2cDeviceEvent message to log. + @returns True if the event was successfully logged, False otherwise. +*/ +/**************************************************************************/ +bool ws_sdcard::LogI2cDeviceEvent( + wippersnapper_i2c_I2cDeviceEvent *msg_device_event) { + JsonDocument doc; + // Pull the DeviceDescriptor out + wippersnapper_i2c_I2cDeviceDescriptor descriptor = + msg_device_event->i2c_device_description; + char hex_addr[5]; + snprintf(hex_addr, sizeof(hex_addr), "0x%02X", descriptor.i2c_device_address); + doc["i2c_address"] = hex_addr; + + // Using I2C MUX? + if (descriptor.i2c_mux_address != 0x00) { + snprintf(hex_addr, sizeof(hex_addr), "0x%02X", descriptor.i2c_mux_address); + doc["i2c_mux_addr"] = hex_addr; + doc["i2c_mux_ch"] = descriptor.i2c_mux_channel; + } + + // Log each event + for (pb_size_t i = 0; i < msg_device_event->i2c_device_events_count; i++) { + doc["timestamp"] = GetTimestamp(); + doc["value"] = msg_device_event->i2c_device_events[i].value.float_value; + doc["si_unit"] = + SensorTypeToSIUnit(msg_device_event->i2c_device_events[i].type); + if (!LogJSONDoc(doc)) + return false; + } + return true; +} + +#ifdef OFFLINE_MODE_DEBUG +/**************************************************************************/ +/*! + @brief Waits for a valid JSON string to be received via the hardware's + serial input or from a hardcoded test JSON string. + @returns True if a valid JSON string was received, False otherwise. +*/ +/**************************************************************************/ +void ws_sdcard::waitForSerialConfig() { + json_test_data = "{" + "\"exportVersion\": \"1.0.0\"," + "\"exportedBy\": \"tester\"," + "\"exportedAt\": \"2024-10-28T18:58:23.976Z\"," + "\"exportedFromDevice\": {" + "\"board\": \"metroesp32s3\"," + "\"firmwareVersion\": \"1.0.0-beta.93\"," + "\"referenceVoltage\": 2.6," + "\"totalGPIOPins\": 11," + "\"totalAnalogPins\": 6" + "}," + "\"components\": [" + "{" + "\"componentAPI\": \"analogio\"," + "\"name\": \"Analog Pin\"," + "\"pinName\": \"D14\"," + "\"type\": \"analog_pin\"," + "\"mode\": \"ANALOG\"," + "\"direction\": \"INPUT\"," + "\"sampleMode\": \"TIMER\"," + "\"analogReadMode\": \"PIN_VALUE\"," + "\"period\": 5," + "\"isPin\": true" + "}," + "{" + "\"componentAPI\": \"analogio\"," + "\"name\": \"Analog Pin\"," + "\"pinName\": \"D27\"," + "\"type\": \"analog_pin\"," + "\"mode\": \"ANALOG\"," + "\"direction\": \"INPUT\"," + "\"sampleMode\": \"TIMER\"," + "\"analogReadMode\": \"PIN_VALUE\"," + "\"period\": 5," + "\"isPin\": true" + "}," + "{" + "\"componentAPI\": \"digitalio\"," + "\"name\": \"Button (D4)\"," + "\"pinName\": \"D4\"," + "\"type\": \"push_button\"," + "\"mode\": \"DIGITAL\"," + "\"sampleMode\": \"EVENT\"," + "\"direction\": \"INPUT\"," + "\"period\": 5," + "\"pull\": \"UP\"," + "\"isPin\": true" + "}," + "{" + "\"componentAPI\": \"ds18x20\"," + "\"name\": \"DS18B20: Temperature Sensor (°F)\"," + "\"sensorTypeCount\": 2," + "\"sensorType1\": \"object-temp-fahrenheit\"," + "\"sensorType2\": \"object-temp\"," + "\"pinName\": \"D12\"," + "\"sensorResolution\": 12," + "\"period\": 5" + "}," + "{" + "\"componentAPI\": \"ds18x20\"," + "\"name\": \"DS18B20: Temperature Sensor (°F)\"," + "\"sensorTypeCount\": 2," + "\"sensorType1\": \"object-temp-fahrenheit\"," + "\"sensorType2\": \"object-temp\"," + "\"pinName\": \"D25\"," + "\"sensorResolution\": 12," + "\"period\": 5" + "}" + "]" + "}\\n\r\n"; + + _serialInput = ""; // Clear the serial input buffer + if (!_use_test_data) { + WS_DEBUG_PRINTLN("[SD] Waiting for incoming JSON string..."); + while (true) { + // Check if there is data available to read + if (Serial.available() > 0) { + char c = Serial.read(); + _serialInput += c; + if (_serialInput.endsWith("\\n")) { + break; + } + } + } + } + // Remove the newline + _serialInput.trim(); + WS_DEBUG_PRINTLN("[SD] JSON string received!"); +} +#endif \ No newline at end of file diff --git a/src/provisioning/sdcard/ws_sdcard.h b/src/provisioning/sdcard/ws_sdcard.h new file mode 100644 index 000000000..d2a5760db --- /dev/null +++ b/src/provisioning/sdcard/ws_sdcard.h @@ -0,0 +1,130 @@ +/*! + * @file ws_sdcard.h + * + * Interface for Wippersnapper's SD card filesystem. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ +#ifndef WS_SDCARD_H +#define WS_SDCARD_H +#include "RTClib.h" +#include "SdFat.h" +#include "StreamUtils.h" +#include "Wippersnapper_V2.h" +#include "sdios.h" + +#if defined(ARDUINO_FEATHER_ESP32) || \ + defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO) || \ + defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2) +#define SPI_SD_CLOCK \ + SD_SCK_MHZ(25) ///< For ESP32/Pico silicon rev 3.0, we clock at 25MHz +#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER) +#define SPI_SD_CLOCK \ + SD_SCK_MHZ(16) ///< For the RP2040 adalogger, we clock at 16MHz +#else +#define SPI_SD_CLOCK SD_SCK_MHZ(50) ///< Default SPI clock speed +#endif + +#define SD_FAT_TYPE 3 ///< SD type (3 = FAT16/FAT32 and exFAT) +#define PIN_SD_CS_ERROR 255 ///< Error code for invalid SD card CS pin +#define UNKNOWN_VALUE "unknown" ///< Default unknown JSON field value +#define MAX_SZ_LOG_FILE (512 * 1024 * 1024) ///< Maximum log file size, in Bytes +#define MAX_LEN_CFG_JSON \ + 4096 ///< Maximum length of the configuration JSON file, in Bytes + +// forward decl. +class Wippersnapper_V2; + +/***************************************************************************/ +/*! + @brief Class that handles Wippersnapper's optional filesystem commands + and storage. +*/ +/***************************************************************************/ +class ws_sdcard { +public: + ws_sdcard(); + ~ws_sdcard(); + bool isSDCardInitialized() { return is_mode_offline; } + bool parseConfigFile(); + bool CreateNewLogFile(); + bool isModeOffline() { return is_mode_offline; } + void waitForSerialConfig(); + bool LogGPIOSensorEventToSD(uint8_t pin, float value, + wippersnapper_sensor_SensorType read_type); + bool LogGPIOSensorEventToSD(uint8_t pin, bool value, + wippersnapper_sensor_SensorType read_type); + bool LogGPIOSensorEventToSD(uint8_t pin, uint16_t value, + wippersnapper_sensor_SensorType read_type); + bool LogDS18xSensorEventToSD(wippersnapper_ds18x20_Ds18x20Event *event_msg); + bool LogI2cDeviceEvent(wippersnapper_i2c_I2cDeviceEvent *msg_device_event); + +private: + void calculateFileLimits(); + bool ValidateChecksum(JsonDocument &doc); + bool ValidateJSONKey(const char *key, const char *error_msg); + void CheckIn(uint8_t max_digital_pins, uint8_t max_analog_pins, + float ref_voltage); + bool ConfigureRTC(const char *rtc_type); + uint32_t GetTimestamp(); + bool InitDS1307(); + bool InitDS3231(); + bool InitPCF8523(); + bool InitSoftRTC(); + void TickSoftRTC(); + uint32_t GetSoftRTCTime(); + wippersnapper_sensor_SensorType ParseSensorType(const char *sensor_type); + bool ParseDigitalIOAdd(wippersnapper_digitalio_DigitalIOAdd &msg_DigitalIOAdd, + const char *pin, float period, bool value, + const char *sample_mode, const char *direction, + const char *pull); + bool ParseAnalogIOAdd(wippersnapper_analogio_AnalogIOAdd &msg_AnalogIOAdd, + const char *pin, float period, const char *mode); + bool ParseDS18X20Add(wippersnapper_ds18x20_Ds18x20Add &msg_DS18X20Add, + const char *pin, int resolution, float period, + int num_sensors, const char *sensor_type_1, + const char *sensor_type_2); + bool ParseI2cDeviceAddReplace( + JsonObject &component, + wippersnapper_i2c_I2cDeviceAddOrReplace &msg_i2c_device_add_replace); + uint32_t HexStrToInt(const char *hex_str); + + void BuildJSONDoc(JsonDocument &doc, uint8_t pin, float value, + wippersnapper_sensor_SensorType read_type); + void BuildJSONDoc(JsonDocument &doc, uint8_t pin, uint16_t value, + wippersnapper_sensor_SensorType read_type); + void BuildJSONDoc(JsonDocument &doc, uint8_t pin, bool value, + wippersnapper_sensor_SensorType read_type); + bool LogJSONDoc(JsonDocument &doc); + bool AddSignalMessageToSharedBuffer( + wippersnapper_signal_BrokerToDevice &msg_signal); + + SdSpiConfig _sd_spi_cfg; ///< SPI configuration for the SD card + SdFat _sd; ///< SD object from Adafruit SDFat library + size_t _sd_capacity; ///< Capacity of the SD card, in Bytes + size_t _sz_cur_log_file; ///< Size of the current log file, in Bytes + size_t _max_sz_log_file; ///< Calculated maximum size of a log file, in Bytes + int _sd_max_num_log_files; ///< Maximum number of log files that can fit on + ///< the SD card + int _sd_cur_log_files; ///< Current number of log files that can fit on the SD + ///< card + bool is_mode_offline; ///< True if offline mode is enabled, False otherwise + String _serialInput; ///< Serial input buffer + const char *json_test_data; ///< Json test data + const char *_log_filename; ///< Path to the log file + RTC_DS3231 *_rtc_ds3231 = nullptr; ///< DS3231 RTC object + RTC_DS1307 *_rtc_ds1307 = nullptr; ///< DS1307 RTC object + RTC_PCF8523 *_rtc_pcf8523 = nullptr; ///< PCF8523 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 +}; +extern Wippersnapper_V2 WsV2; +#endif // WS_SDCARD_H \ No newline at end of file diff --git a/src/provisioning/tinyusb/Wippersnapper_FS.cpp b/src/provisioning/tinyusb/Wippersnapper_FS.cpp index 3dbbcf4bc..03bb68b90 100644 --- a/src/provisioning/tinyusb/Wippersnapper_FS.cpp +++ b/src/provisioning/tinyusb/Wippersnapper_FS.cpp @@ -1,19 +1,19 @@ /*! * @file Wippersnapper_FS.cpp * - * Wippersnapper TinyUSB Filesystem + * Wippersnapper TinyUSB Filesystem Driver * * Adafruit invests time and resources providing this open source code, * please support Adafruit and open-source hardware by purchasing * products from Adafruit! * - * Copyright (c) Brent Rubell 2023 for Adafruit Industries. + * Copyright (c) Brent Rubell 2024 for Adafruit Industries. * * BSD license, all text here must be included in any redistribution. * */ #if defined(ARDUINO_MAGTAG29_ESP32S2) || defined(ARDUINO_METRO_ESP32S2) || \ - defined(ARDUINO_FUNHOUSE_ESP32S2) || \ + defined(ARDUINO_METRO_ESP32S3) || defined(ARDUINO_FUNHOUSE_ESP32S2) || \ defined(ADAFRUIT_PYPORTAL_M4_TITANO) || \ defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE) || defined(ADAFRUIT_PYPORTAL) || \ defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2) || \ @@ -26,61 +26,74 @@ defined(ARDUINO_RASPBERRY_PI_PICO_W) || \ defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_REVTFT) || \ defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2_REVTFT) || \ - defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_N4R2) + defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_N4R2) || \ + defined(ARDUINO_RASPBERRY_PI_PICO) || \ + defined(ARDUINO_RASPBERRY_PI_PICO_2) || \ + defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER) || \ + defined(ARDUINO_ADAFRUIT_METRO_RP2350) #include "Wippersnapper_FS.h" // On-board external flash (QSPI or SPI) macros should already // defined in your board variant if supported // - EXTERNAL_FLASH_USE_QSPI // - EXTERNAL_FLASH_USE_CS/EXTERNAL_FLASH_USE_SPI #if defined(EXTERNAL_FLASH_USE_QSPI) -Adafruit_FlashTransport_QSPI flashTransport; +Adafruit_FlashTransport_QSPI flashTransport_v2; #elif defined(EXTERNAL_FLASH_USE_SPI) -Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, - EXTERNAL_FLASH_USE_SPI); +Adafruit_FlashTransport_SPI flashTransport_v2(EXTERNAL_FLASH_USE_CS, + EXTERNAL_FLASH_USE_SPI); #elif defined(ARDUINO_ARCH_ESP32) // ESP32-S2 uses same flash device that stores code. // Therefore there is no need to specify the SPI and SS -Adafruit_FlashTransport_ESP32 flashTransport; +Adafruit_FlashTransport_ESP32 flashTransport_v2; #elif defined(ARDUINO_ARCH_RP2040) // RP2040 use same flash device that store code. // Therefore there is no need to specify the SPI and SS // Use default (no-args) constructor to be compatible with CircuitPython // partition scheme -Adafruit_FlashTransport_RP2040 flashTransport; +Adafruit_FlashTransport_RP2040 flashTransport_v2; #else #error No QSPI/SPI flash are defined on your board variant.h! #endif -Adafruit_SPIFlash flash(&flashTransport); ///< SPIFlash object -FatVolume wipperFatFs; ///< File system object from Adafruit SDFat +Adafruit_SPIFlash flash_v2(&flashTransport_v2); ///< SPIFlash object +FatVolume wipperFatFs_v2; ///< File system object from Adafruit SDFat library +Adafruit_USBD_MSC usb_msc_v2; /*!< USB mass storage object */ -Adafruit_USBD_MSC usb_msc; /*!< USB mass storage object */ - -FATFS elmchamFatfs; ///< Elm Cham's fatfs object -uint8_t workbuf[4096]; ///< Working buffer for f_fdisk function. +/**************************************************************************/ +/*! + @brief Formats the flash filesystem as FAT12. + @returns FR_OK if filesystem formatted correctly, + otherwise any FRESULT enum. +*/ +/**************************************************************************/ +FRESULT format_fs_fat12(void) { + FATFS elmchamFatfs_v2; + uint8_t workbuf_v2[4096]; + FRESULT r; -bool makeFilesystem() { - FRESULT r = f_mkfs("", FM_FAT | FM_SFD, 0, workbuf, sizeof(workbuf)); - if (r != FR_OK) { - return false; - } - return true; -} + // make filesystem + r = f_mkfs("", FM_FAT | FM_SFD, 0, workbuf_v2, sizeof(workbuf_v2)); + if (r != FR_OK) + return r; -bool setVolumeLabel() { // mount to set disk label - FRESULT r = f_mount(&elmchamFatfs, "0:", 1); - if (r != FR_OK) { - return false; - } - // set label + r = f_mount(&elmchamFatfs_v2, "0:", 1); + if (r != FR_OK) + return r; + + // set fs label r = f_setlabel("WIPPER"); - if (r != FR_OK) { - return false; - } - // unmount the fs - f_unmount("0:"); - return true; + if (r != FR_OK) + return r; + + // unmount fs + r = f_unmount("0:"); + if (r != FR_OK) + return r; + + // sync to make sure all data is written to flash + flash_v2.syncBlocks(); + return r; } /**************************************************************************/ @@ -94,19 +107,57 @@ Wippersnapper_FS::Wippersnapper_FS() { // Wait for detach delay(500); - // If a filesystem does not already exist - attempt to initialize a new - // filesystem - if (!initFilesystem() && !initFilesystem(true)) { + // Attempt to initialize the flash chip + if (!flash_v2.begin()) { + setStatusLEDColor(RED); + fsHalt("Failed to initialize the flash chip!"); + } + + // Attempt to initialize the filesystem + bool is_fs_formatted = wipperFatFs_v2.begin(&flash_v2); + + // If we are not formatted, attempt to format the filesystem as fat12 + if (!is_fs_formatted) { + FRESULT rc = format_fs_fat12(); + + if (rc != FR_OK) { + setStatusLEDColor(RED); + fsHalt("FATAL ERROR: Failed to format the filesystem!"); + } + + // Now that we have a formatted filesystem, we need to inititalize it + if (!wipperFatFs_v2.begin(&flash_v2)) { + setStatusLEDColor(RED); + fsHalt("FATAL ERROR: Failed to mount newly created filesystem!"); + } + } + + // Write contents to the formatted filesystem + if (!writeFSContents()) { setStatusLEDColor(RED); - fsHalt("ERROR Initializing Filesystem"); + fsHalt("FATAL ERROR: Could not write filesystem contents!"); } - // Initialize USB-MSD + // Initialize USB-MSC initUSBMSC(); - // If we created a new filesystem, halt until user RESETs device. - if (_freshFS) - fsHalt("New filesystem created! Press the reset button on your board."); + // If we wrote a fresh secrets.json file, halt until user edits the file and + // RESETs the device Signal to user that action must be taken (edit + // secrets.json) + if (_is_secrets_file_empty) { + writeToBootOut( + "Please edit the secrets.json file. Then, reset your board.\n"); +#ifdef USE_DISPLAY + WsV2._ui_helper->show_scr_error( + "INVALID SETTINGS FILE", + "The settings.json file on the WIPPER drive contains default values. " + "Please edit it to reflect your Adafruit IO and network credentials. " + "When you're done, press RESET on the board."); +#endif + fsHalt("The settings.json file on the WIPPER drive contains default " + "values\n. Using a text editor, edit it to reflect your Adafruit IO " + "and WiFi credentials. Then, reset the board."); + } } /************************************************************/ @@ -114,76 +165,96 @@ Wippersnapper_FS::Wippersnapper_FS() { @brief Filesystem destructor */ /************************************************************/ -Wippersnapper_FS::~Wippersnapper_FS() {} +Wippersnapper_FS::~Wippersnapper_FS() { + // Unmount filesystem + wipperFatFs_v2.end(); +} /**************************************************************************/ /*! - @brief Initializes the flash filesystem. - @param force_format - If true, forces a new filesystem to be created. [DESTRUCTIVE] - @return True if filesystem initialized correctly, false otherwise. + @brief Attempts to obtain the hardware's CS pin from the + config.json file. */ /**************************************************************************/ -bool Wippersnapper_FS::initFilesystem(bool force_format) { - // Init. flash library - if (!flash.begin()) - return false; - - // Check if FS exists - if (force_format || !wipperFatFs.begin(&flash)) { - // No filesystem exists - create a new FS - // NOTE: THIS WILL ERASE ALL DATA ON THE FLASH - if (!makeFilesystem()) - return false; - - // set volume label - if (!setVolumeLabel()) - return false; - - // sync all data to flash - flash.syncBlocks(); - - _freshFS = true; +void Wippersnapper_FS::GetSDCSPin() { + File32 file_cfg; + DeserializationError error; + // Attempt to open and deserialize the config.json file + file_cfg = wipperFatFs_v2.open("/config.json"); + if (!file_cfg) { + WsV2.pin_sd_cs = 255; + return; } - // Check new FS - if (!wipperFatFs.begin(&flash)) - return false; - - // If CircuitPython was previously installed - erase CPY FS - eraseCPFS(); + error = deserializeJson(WsV2._config_doc, file_cfg); + if (error) { + file_cfg.close(); + WsV2.pin_sd_cs = 255; + return; + } - // If WipperSnapper was previously installed - remove the - // wippersnapper_boot_out.txt file - eraseBootFile(); + // Parse config.json and save the SD CS pin + JsonObject exportedFromDevice = WsV2._config_doc["exportedFromDevice"]; + WsV2.pin_sd_cs = exportedFromDevice["sd_cs_pin"] | 255; + file_cfg.close(); +} - // No file indexing on macOS - wipperFatFs.mkdir("/.fseventsd/"); - File32 writeFile = wipperFatFs.open("/.fseventsd/no_log", FILE_WRITE); +/**************************************************************************/ +/*! + @brief Writes files to the filesystem to disable macOS from indexing. + @returns True if files written successfully, false otherwise. +*/ +/**************************************************************************/ +bool disableMacOSIndexing() { + wipperFatFs_v2.mkdir("/.fseventsd/"); + File32 writeFile = wipperFatFs_v2.open("/.fseventsd/no_log", FILE_WRITE); if (!writeFile) return false; writeFile.close(); - writeFile = wipperFatFs.open("/.metadata_never_index", FILE_WRITE); + writeFile = wipperFatFs_v2.open("/.metadata_never_index", FILE_WRITE); if (!writeFile) return false; writeFile.close(); - writeFile = wipperFatFs.open("/.Trashes", FILE_WRITE); + writeFile = wipperFatFs_v2.open("/.Trashes", FILE_WRITE); if (!writeFile) return false; writeFile.close(); + return true; +} + +/**************************************************************************/ +/*! + @brief Initializes the flash filesystem. + @param force_format + If true, forces a new filesystem to be created. [DESTRUCTIVE] + @return True if filesystem initialized correctly, false otherwise. +*/ +/**************************************************************************/ +bool Wippersnapper_FS::writeFSContents() { + // If CircuitPython was previously installed - erase CircuitPython's default + // filesystem + eraseCPFS(); + + // If WipperSnapper was previously installed - remove the old + // wippersnapper_boot_out.txt file + eraseBootFile(); + + // Disble indexing on macOS + disableMacOSIndexing(); + // Create wippersnapper_boot_out.txt file if (!createBootFile()) return false; // Check if secrets.json file already exists - if (!configFileExists()) { + if (!getSecretsFile()) { // Create new secrets.json file and halt createSecretsFile(); + _is_secrets_file_empty = true; } - return true; } @@ -195,23 +266,24 @@ bool Wippersnapper_FS::initFilesystem(bool force_format) { void Wippersnapper_FS::initUSBMSC() { // Set disk vendor id, product id and revision with string up to 8, 16, 4 // characters respectively - usb_msc.setID("Adafruit", "External Flash", "1.0"); + usb_msc_v2.setID("Adafruit", "External Flash", "1.0"); // Set callback - usb_msc.setReadWriteCallback(qspi_msc_read_cb, qspi_msc_write_cb, - qspi_msc_flush_cb); + usb_msc_v2.setReadWriteCallback(qspi_msc_read_cb_v2, qspi_msc_write_cb_v2, + qspi_msc_flush_cb_v2); // Set disk size, block size should be 512 regardless of spi flash page size - usb_msc.setCapacity(flash.pageSize() * flash.numPages() / 512, 512); + usb_msc_v2.setCapacity(flash_v2.pageSize() * flash_v2.numPages() / 512, 512); // MSC is ready for read/write - usb_msc.setUnitReady(true); + usb_msc_v2.setUnitReady(true); // init MSC - usb_msc.begin(); + usb_msc_v2.begin(); - // re-attach the usb device + // If already enumerated, additional class driverr begin() e.g msc, hid, midi + // won't take effect until re-enumeration + // Attach MSC and wait for enumeration TinyUSBDevice.attach(); - // wait for enumeration delay(500); } @@ -221,11 +293,9 @@ void Wippersnapper_FS::initUSBMSC() { @returns True if secrets.json file exists, False otherwise. */ /**************************************************************************/ -bool Wippersnapper_FS::configFileExists() { +bool Wippersnapper_FS::getSecretsFile() { // Does secrets.json file exist? - if (!wipperFatFs.exists("/secrets.json")) - return false; - return true; + return wipperFatFs_v2.exists("/secrets.json"); } /**************************************************************************/ @@ -234,10 +304,10 @@ bool Wippersnapper_FS::configFileExists() { */ /**************************************************************************/ void Wippersnapper_FS::eraseCPFS() { - if (wipperFatFs.exists("/boot_out.txt")) { - wipperFatFs.remove("/boot_out.txt"); - wipperFatFs.remove("/code.py"); - File32 libDir = wipperFatFs.open("/lib"); + if (wipperFatFs_v2.exists("/boot_out.txt")) { + wipperFatFs_v2.remove("/boot_out.txt"); + wipperFatFs_v2.remove("/code.py"); + File32 libDir = wipperFatFs_v2.open("/lib"); libDir.rmRfStar(); } } @@ -249,9 +319,8 @@ void Wippersnapper_FS::eraseCPFS() { /**************************************************************************/ void Wippersnapper_FS::eraseBootFile() { // overwrite previous boot_out file on each boot - if (wipperFatFs.exists("/wipper_boot_out.txt")) { - wipperFatFs.remove("/wipper_boot_out.txt"); - } + if (wipperFatFs_v2.exists("/wipper_boot_out.txt")) + wipperFatFs_v2.remove("/wipper_boot_out.txt"); } /**************************************************************************/ @@ -263,7 +332,7 @@ bool Wippersnapper_FS::createBootFile() { bool is_success = false; char sMAC[18] = {0}; - File32 bootFile = wipperFatFs.open("/wipper_boot_out.txt", FILE_WRITE); + File32 bootFile = wipperFatFs_v2.open("/wipper_boot_out.txt", FILE_WRITE); if (bootFile) { bootFile.println("Adafruit.io WipperSnapper"); @@ -273,21 +342,21 @@ bool Wippersnapper_FS::createBootFile() { bootFile.print("Board ID: "); bootFile.println(BOARD_ID); - sprintf(sMAC, "%02X:%02X:%02X:%02X:%02X:%02X", WS._macAddr[0], - WS._macAddr[1], WS._macAddr[2], WS._macAddr[3], WS._macAddr[4], - WS._macAddr[5]); + sprintf(sMAC, "%02X:%02X:%02X:%02X:%02X:%02X", WsV2._macAddrV2[0], + WsV2._macAddrV2[1], WsV2._macAddrV2[2], WsV2._macAddrV2[3], + WsV2._macAddrV2[4], WsV2._macAddrV2[5]); bootFile.print("MAC Address: "); bootFile.println(sMAC); - // Print ESP-specific info to boot file - #ifdef ARDUINO_ARCH_ESP32 +// Print ESP-specific info to boot file +#ifdef ARDUINO_ARCH_ESP32 // Get version of ESP-IDF bootFile.print("ESP-IDF Version: "); bootFile.println(ESP.getSdkVersion()); // Get version of this core bootFile.print("ESP32 Core Version: "); bootFile.println(ESP.getCoreVersion()); - #endif +#endif bootFile.flush(); bootFile.close(); @@ -305,7 +374,7 @@ bool Wippersnapper_FS::createBootFile() { /**************************************************************************/ void Wippersnapper_FS::createSecretsFile() { // Open file for writing - File32 secretsFile = wipperFatFs.open("/secrets.json", FILE_WRITE); + File32 secretsFile = wipperFatFs_v2.open("/secrets.json", FILE_WRITE); // Create a default secretsConfig structure secretsConfig secretsConfig; @@ -326,18 +395,6 @@ void Wippersnapper_FS::createSecretsFile() { secretsFile.flush(); secretsFile.close(); delay(2500); - - // Signal to user that action must be taken (edit secrets.json) - writeToBootOut( - "ERROR: Please edit the secrets.json file. Then, reset your board.\n"); -#ifdef USE_DISPLAY - WS._ui_helper->show_scr_error( - "INVALID SETTINGS FILE", - "The settings.json file on the WIPPER drive contains default values. " - "Please edit it to reflect your Adafruit IO and network credentials. " - "When you're done, press RESET on the board."); -#endif - fsHalt("ERROR: Please edit the secrets.json file. Then, reset your board."); } /**************************************************************************/ @@ -347,7 +404,7 @@ void Wippersnapper_FS::createSecretsFile() { /**************************************************************************/ void Wippersnapper_FS::parseSecrets() { // Attempt to open the secrets.json file for reading - File32 secretsFile = wipperFatFs.open("/secrets.json"); + File32 secretsFile = wipperFatFs_v2.open("/secrets.json"); if (!secretsFile) { fsHalt("ERROR: Could not open secrets.json file for reading!"); } @@ -363,7 +420,7 @@ void Wippersnapper_FS::parseSecrets() { if (doc.containsKey("network_type_wifi")) { // set default network config - convertFromJson(doc["network_type_wifi"], WS._config.network); + convertFromJson(doc["network_type_wifi"], WsV2._configV2.network); if (!doc["network_type_wifi"].containsKey("alternative_networks")) { // do nothing extra, we already have the only network @@ -390,13 +447,13 @@ void Wippersnapper_FS::parseSecrets() { WS_DEBUG_PRINTLN(altnetworks[i]["network_ssid"].as()); break; } - convertFromJson(altnetworks[i], WS._multiNetworks[i]); + convertFromJson(altnetworks[i], WsV2._multiNetworksV2[i]); WS_DEBUG_PRINT("Added SSID: "); - WS_DEBUG_PRINTLN(WS._multiNetworks[i].ssid); + WS_DEBUG_PRINTLN(WsV2._multiNetworksV2[i].ssid); WS_DEBUG_PRINT("PASS: "); - WS_DEBUG_PRINTLN(WS._multiNetworks[i].pass); + WS_DEBUG_PRINTLN(WsV2._multiNetworksV2[i].pass); } - WS._isWiFiMulti = true; + WsV2._isWiFiMultiV2 = true; } else { fsHalt("ERROR: Unrecognised value type for " "network_type_wifi.alternative_networks in secrets.json!"); @@ -406,16 +463,16 @@ void Wippersnapper_FS::parseSecrets() { } // Extract a config struct from the JSON document - WS._config = doc.as(); + WsV2._configV2 = doc.as(); // Validate the config struct is not filled with default values - if (strcmp(WS._config.aio_user, "YOUR_IO_USERNAME_HERE") == 0 || - strcmp(WS._config.aio_key, "YOUR_IO_KEY_HERE") == 0) { + if (strcmp(WsV2._configV2.aio_user, "YOUR_IO_USERNAME_HERE") == 0 || + strcmp(WsV2._configV2.aio_key, "YOUR_IO_KEY_HERE") == 0) { writeToBootOut( "ERROR: Invalid IO credentials in secrets.json! TO FIX: Please change " "io_username and io_key to match your Adafruit IO credentials!\n"); #ifdef USE_DISPLAY - WS._ui_helper->show_scr_error( + WsV2._ui_helper->show_scr_error( "INVALID IO CREDS", "The \"io_username/io_key\" fields within secrets.json are invalid, " "please " @@ -426,13 +483,13 @@ void Wippersnapper_FS::parseSecrets() { "io_username and io_key to match your Adafruit IO credentials!"); } - if (strcmp(WS._config.network.ssid, "YOUR_WIFI_SSID_HERE") == 0 || - strcmp(WS._config.network.pass, "YOUR_WIFI_PASS_HERE") == 0) { + if (strcmp(WsV2._configV2.network.ssid, "YOUR_WIFI_SSID_HERE") == 0 || + strcmp(WsV2._configV2.network.pass, "YOUR_WIFI_PASS_HERE") == 0) { writeToBootOut("ERROR: Invalid network credentials in secrets.json! TO " "FIX: Please change network_ssid and network_password to " "match your Adafruit IO credentials!\n"); #ifdef USE_DISPLAY - WS._ui_helper->show_scr_error( + WsV2._ui_helper->show_scr_error( "INVALID NETWORK", "The \"network_ssid and network_password\" fields within secrets.json " "are invalid, please change it to match your WiFi credentials. Then, " @@ -443,6 +500,14 @@ void Wippersnapper_FS::parseSecrets() { "credentials!"); } + writeToBootOut("Secrets Contents\n"); + writeToBootOut("Network Info\n: "); + writeToBootOut(WsV2._configV2.network.ssid); + writeToBootOut(WsV2._configV2.network.pass); + writeToBootOut("IO Creds.\n: "); + writeToBootOut(WsV2._configV2.aio_user); + writeToBootOut(WsV2._configV2.aio_key); + // Close secrets.json file secretsFile.close(); } @@ -456,16 +521,12 @@ void Wippersnapper_FS::parseSecrets() { /**************************************************************************/ void Wippersnapper_FS::writeToBootOut(PGM_P str) { // Append error output to FS - File32 bootFile = wipperFatFs.open("/wipper_boot_out.txt", FILE_WRITE); - if (bootFile) { - bootFile.print(str); - bootFile.flush(); - bootFile.close(); - } else { - WS_DEBUG_PRINTLN("ERROR: Unable to open wipper_boot_out.txt for logging!"); - // feels like we should check why, if good use-case ok, otherwise fsHalt - // as indicates fs corruption or disc access issue (maybe latter is okay) - } + File32 bootFile = wipperFatFs_v2.open("/wipper_boot_out.txt", FILE_WRITE); + if (!bootFile) + fsHalt("ERROR: Unable to open wipper_boot_out.txt for logging!"); + bootFile.print(str); + bootFile.flush(); + bootFile.close(); } /**************************************************************************/ @@ -480,17 +541,41 @@ void Wippersnapper_FS::fsHalt(String msg) { delay(500); statusLEDSolid(WS_LED_STATUS_FS_WRITE); while (1) { - WS_DEBUG_PRINTLN("Fatal Error: Halted execution!"); + WS_DEBUG_PRINT("Execution Halted: "); WS_DEBUG_PRINTLN(msg.c_str()); - delay(1000); + delay(5000); + yield(); + } +} + +/**************************************************************************/ +/*! + @brief Halts execution and blinks the status LEDs yellow. + @param msg + Error message to print to serial console. +*/ +/**************************************************************************/ +void Wippersnapper_FS::fsHalt(String msg, ws_led_status_t ledStatusColor) { + TinyUSBDevice.attach(); + delay(500); + statusLEDSolid(ledStatusColor); + while (1) { + WS_DEBUG_PRINT("Execution Halted: "); + WS_DEBUG_PRINTLN(msg.c_str()); + delay(5000); yield(); } } #ifdef ARDUINO_FUNHOUSE_ESP32S2 +/**************************************************************************/ +/*! + @brief Creates a default display_config.json file on the filesystem. +*/ +/**************************************************************************/ void Wippersnapper_FS::createDisplayConfig() { // Open file for writing - File32 displayFile = wipperFatFs.open("/display_config.json", FILE_WRITE); + File32 displayFile = wipperFatFs_v2.open("/display_config.json", FILE_WRITE); // Create a default displayConfig structure displayConfig displayConfig; @@ -517,9 +602,16 @@ void Wippersnapper_FS::createDisplayConfig() { delay(2500); // give FS some time to write the file } +/**************************************************************************/ +/*! + @brief Parses a display_config.json file on the flash filesystem. + @param dispCfg + displayConfig struct to populate. +*/ +/**************************************************************************/ void Wippersnapper_FS::parseDisplayConfig(displayConfig &dispCfg) { // Check if display_config.json file exists, if not, generate it - if (!wipperFatFs.exists("/display_config.json")) { + if (!wipperFatFs_v2.exists("/display_config.json")) { WS_DEBUG_PRINTLN("Could not find display_config.json, generating..."); #ifdef ARDUINO_FUNHOUSE_ESP32S2 createDisplayConfig(); // generate a default display_config.json for @@ -528,7 +620,7 @@ void Wippersnapper_FS::parseDisplayConfig(displayConfig &dispCfg) { } // Attempt to open file for JSON parsing - File32 file = wipperFatFs.open("/display_config.json", FILE_READ); + File32 file = wipperFatFs_v2.open("/display_config.json", FILE_READ); if (!file) { fsHalt("FATAL ERROR: Unable to open display_config.json for parsing"); } @@ -561,11 +653,12 @@ void Wippersnapper_FS::parseDisplayConfig(displayConfig &dispCfg) { @returns Number of written bytes (must be multiple of block size) */ /**************************************************************************/ -int32_t qspi_msc_read_cb(uint32_t lba, void *buffer, uint32_t bufsize) { +int32_t qspi_msc_read_cb_v2(uint32_t lba, void *buffer, uint32_t bufsize) { // Note: SPIFLash Bock API: readBlocks/writeBlocks/syncBlocks // already include 4K sector caching internally. We don't need to cache it, // yahhhh!! - return flash.readBlocks(lba, (uint8_t *)buffer, bufsize / 512) ? bufsize : -1; + return flash_v2.readBlocks(lba, (uint8_t *)buffer, bufsize / 512) ? bufsize + : -1; } /**************************************************************************/ @@ -581,11 +674,11 @@ int32_t qspi_msc_read_cb(uint32_t lba, void *buffer, uint32_t bufsize) { @returns Number of written bytes (must be multiple of block size) */ /**************************************************************************/ -int32_t qspi_msc_write_cb(uint32_t lba, uint8_t *buffer, uint32_t bufsize) { +int32_t qspi_msc_write_cb_v2(uint32_t lba, uint8_t *buffer, uint32_t bufsize) { // Note: SPIFLash Bock API: readBlocks/writeBlocks/syncBlocks // already include 4K sector caching internally. We don't need to cache it, // yahhhh!! - return flash.writeBlocks(lba, buffer, bufsize / 512) ? bufsize : -1; + return flash_v2.writeBlocks(lba, buffer, bufsize / 512) ? bufsize : -1; } /***************************************************************************/ @@ -594,11 +687,11 @@ int32_t qspi_msc_write_cb(uint32_t lba, uint8_t *buffer, uint32_t bufsize) { received and accepted by host). Used to flush any pending cache. */ /***************************************************************************/ -void qspi_msc_flush_cb(void) { +void qspi_msc_flush_cb_v2(void) { // sync w/flash - flash.syncBlocks(); + flash_v2.syncBlocks(); // clear file system's cache to force refresh - wipperFatFs.cacheClear(); + wipperFatFs_v2.cacheClear(); } //--------------------------------------------------------------------+ @@ -622,7 +715,7 @@ DRESULT disk_read(BYTE pdrv, /* Physical drive nmuber to identify the drive */ UINT count /* Number of sectors to read */ ) { (void)pdrv; - return flash.readBlocks(sector, buff, count) ? RES_OK : RES_ERROR; + return flash_v2.readBlocks(sector, buff, count) ? RES_OK : RES_ERROR; } DRESULT disk_write(BYTE pdrv, /* Physical drive nmuber to identify the drive */ @@ -631,7 +724,7 @@ DRESULT disk_write(BYTE pdrv, /* Physical drive nmuber to identify the drive */ UINT count /* Number of sectors to write */ ) { (void)pdrv; - return flash.writeBlocks(sector, buff, count) ? RES_OK : RES_ERROR; + return flash_v2.writeBlocks(sector, buff, count) ? RES_OK : RES_ERROR; } DRESULT disk_ioctl(BYTE pdrv, /* Physical drive nmuber (0..) */ @@ -642,11 +735,11 @@ DRESULT disk_ioctl(BYTE pdrv, /* Physical drive nmuber (0..) */ switch (cmd) { case CTRL_SYNC: - flash.syncBlocks(); + flash_v2.syncBlocks(); return RES_OK; case GET_SECTOR_COUNT: - *((DWORD *)buff) = flash.size() / 512; + *((DWORD *)buff) = flash_v2.size() / 512; return RES_OK; case GET_SECTOR_SIZE: diff --git a/src/provisioning/tinyusb/Wippersnapper_FS.h b/src/provisioning/tinyusb/Wippersnapper_FS.h index 22fe7df27..0d672de57 100644 --- a/src/provisioning/tinyusb/Wippersnapper_FS.h +++ b/src/provisioning/tinyusb/Wippersnapper_FS.h @@ -11,9 +11,9 @@ * * BSD license, all text here must be included in any redistribution. * -*/ -#ifndef WIPPERSNAPPER_FS_H -#define WIPPERSNAPPER_FS_H + */ +#ifndef WIPPERSNAPPER_FS_V2_H +#define WIPPERSNAPPER_FS_V2_H #include "Adafruit_SPIFlash.h" #include "Adafruit_TinyUSB.h" @@ -22,16 +22,16 @@ #include "fatfs/ff.h" // NOTE: This should be #included before fatfs/diskio.h!!! #include "fatfs/diskio.h" -#include "Wippersnapper.h" +#include "Wippersnapper_V2.h" // forward decl. -class Wippersnapper; +class Wippersnapper_V2; struct displayConfig; // global TinyUSB callbacks -int32_t qspi_msc_write_cb(uint32_t lba, uint8_t *buffer, uint32_t bufsize); -int32_t qspi_msc_read_cb(uint32_t lba, void *buffer, uint32_t bufsize); -void qspi_msc_flush_cb(void); +int32_t qspi_msc_write_cb_v2(uint32_t lba, uint8_t *buffer, uint32_t bufsize); +int32_t qspi_msc_read_cb_v2(uint32_t lba, void *buffer, uint32_t bufsize); +void qspi_msc_flush_cb_v2(void); /***************************************************************************/ /*! @@ -44,28 +44,29 @@ class Wippersnapper_FS { Wippersnapper_FS(); ~Wippersnapper_FS(); - bool initFilesystem(bool force_format = false); void initUSBMSC(); + void GetSDCSPin(); + + bool writeFSContents(); + void fsHalt(String msg); + void fsHalt(String msg, ws_led_status_t ledStatusColor); void eraseCPFS(); - void eraseBootFile(); - bool configFileExists(); - void createSecretsFile(); bool createBootFile(); void writeToBootOut(PGM_P str); - void fsHalt(String msg); + void eraseBootFile(); + // Secrets.json API + void createSecretsFile(); + bool getSecretsFile(); void parseSecrets(); - #ifdef ARDUINO_FUNHOUSE_ESP32S2 void parseDisplayConfig(displayConfig &displayFile); void createDisplayConfig(); #endif private: - bool _freshFS = false; /*!< True if filesystem was initialized by - WipperSnapper, False otherwise. */ + bool _is_secrets_file_empty = false; }; - -extern Wippersnapper WS; -#endif // WIPPERSNAPPER_FS_H \ No newline at end of file +extern Wippersnapper_V2 WsV2; +#endif // Wippersnapper_FS_V2_V2_H \ No newline at end of file diff --git a/src/wippersnapper/description/v1/description.pb.c b/src/wippersnapper/description/v1/description.pb.c deleted file mode 100644 index 892b3cd94..000000000 --- a/src/wippersnapper/description/v1/description.pb.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#include "wippersnapper/description/v1/description.pb.h" -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -PB_BIND(wippersnapper_description_v1_CreateDescriptionRequest, wippersnapper_description_v1_CreateDescriptionRequest, AUTO) - - -PB_BIND(wippersnapper_description_v1_CreateDescriptionRequest_Version, wippersnapper_description_v1_CreateDescriptionRequest_Version, AUTO) - - -PB_BIND(wippersnapper_description_v1_CreateDescriptionResponse, wippersnapper_description_v1_CreateDescriptionResponse, AUTO) - - -PB_BIND(wippersnapper_description_v1_RegistrationComplete, wippersnapper_description_v1_RegistrationComplete, AUTO) - - -PB_BIND(wippersnapper_description_v1_GetDefinitionRequest, wippersnapper_description_v1_GetDefinitionRequest, AUTO) - - -PB_BIND(wippersnapper_description_v1_GetDefinitionResponse, wippersnapper_description_v1_GetDefinitionResponse, AUTO) - - - - diff --git a/src/wippersnapper/description/v1/description.pb.h b/src/wippersnapper/description/v1/description.pb.h deleted file mode 100644 index f9a22c7d7..000000000 --- a/src/wippersnapper/description/v1/description.pb.h +++ /dev/null @@ -1,157 +0,0 @@ -/* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#ifndef PB_WIPPERSNAPPER_DESCRIPTION_V1_WIPPERSNAPPER_DESCRIPTION_V1_DESCRIPTION_PB_H_INCLUDED -#define PB_WIPPERSNAPPER_DESCRIPTION_V1_WIPPERSNAPPER_DESCRIPTION_V1_DESCRIPTION_PB_H_INCLUDED -#include -#include "nanopb/nanopb.pb.h" - -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -/* Enum definitions */ -typedef enum _wippersnapper_description_v1_CreateDescriptionResponse_Response { - wippersnapper_description_v1_CreateDescriptionResponse_Response_RESPONSE_UNSPECIFIED = 0, - wippersnapper_description_v1_CreateDescriptionResponse_Response_RESPONSE_OK = 1, - wippersnapper_description_v1_CreateDescriptionResponse_Response_RESPONSE_BOARD_NOT_FOUND = 2 -} wippersnapper_description_v1_CreateDescriptionResponse_Response; - -/* Struct definitions */ -typedef struct _wippersnapper_description_v1_CreateDescriptionRequest_Version { - char dummy_field; -} wippersnapper_description_v1_CreateDescriptionRequest_Version; - -typedef struct _wippersnapper_description_v1_GetDefinitionRequest { - char dummy_field; -} wippersnapper_description_v1_GetDefinitionRequest; - -typedef struct _wippersnapper_description_v1_GetDefinitionResponse { - char dummy_field; -} wippersnapper_description_v1_GetDefinitionResponse; - -typedef struct _wippersnapper_description_v1_CreateDescriptionRequest { - char machine_name[64]; - int32_t mac_addr; - int32_t usb_vid; - int32_t usb_pid; - char str_version[20]; -} wippersnapper_description_v1_CreateDescriptionRequest; - -typedef struct _wippersnapper_description_v1_CreateDescriptionResponse { - wippersnapper_description_v1_CreateDescriptionResponse_Response response; - int32_t total_gpio_pins; - int32_t total_analog_pins; - float reference_voltage; - int32_t total_i2c_ports; -} wippersnapper_description_v1_CreateDescriptionResponse; - -typedef struct _wippersnapper_description_v1_RegistrationComplete { - bool is_complete; -} wippersnapper_description_v1_RegistrationComplete; - - -/* Helper constants for enums */ -#define _wippersnapper_description_v1_CreateDescriptionResponse_Response_MIN wippersnapper_description_v1_CreateDescriptionResponse_Response_RESPONSE_UNSPECIFIED -#define _wippersnapper_description_v1_CreateDescriptionResponse_Response_MAX wippersnapper_description_v1_CreateDescriptionResponse_Response_RESPONSE_BOARD_NOT_FOUND -#define _wippersnapper_description_v1_CreateDescriptionResponse_Response_ARRAYSIZE ((wippersnapper_description_v1_CreateDescriptionResponse_Response)(wippersnapper_description_v1_CreateDescriptionResponse_Response_RESPONSE_BOARD_NOT_FOUND+1)) - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Initializer values for message structs */ -#define wippersnapper_description_v1_CreateDescriptionRequest_init_default {"", 0, 0, 0, ""} -#define wippersnapper_description_v1_CreateDescriptionRequest_Version_init_default {0} -#define wippersnapper_description_v1_CreateDescriptionResponse_init_default {_wippersnapper_description_v1_CreateDescriptionResponse_Response_MIN, 0, 0, 0, 0} -#define wippersnapper_description_v1_RegistrationComplete_init_default {0} -#define wippersnapper_description_v1_GetDefinitionRequest_init_default {0} -#define wippersnapper_description_v1_GetDefinitionResponse_init_default {0} -#define wippersnapper_description_v1_CreateDescriptionRequest_init_zero {"", 0, 0, 0, ""} -#define wippersnapper_description_v1_CreateDescriptionRequest_Version_init_zero {0} -#define wippersnapper_description_v1_CreateDescriptionResponse_init_zero {_wippersnapper_description_v1_CreateDescriptionResponse_Response_MIN, 0, 0, 0, 0} -#define wippersnapper_description_v1_RegistrationComplete_init_zero {0} -#define wippersnapper_description_v1_GetDefinitionRequest_init_zero {0} -#define wippersnapper_description_v1_GetDefinitionResponse_init_zero {0} - -/* Field tags (for use in manual encoding/decoding) */ -#define wippersnapper_description_v1_CreateDescriptionRequest_machine_name_tag 1 -#define wippersnapper_description_v1_CreateDescriptionRequest_mac_addr_tag 2 -#define wippersnapper_description_v1_CreateDescriptionRequest_usb_vid_tag 3 -#define wippersnapper_description_v1_CreateDescriptionRequest_usb_pid_tag 4 -#define wippersnapper_description_v1_CreateDescriptionRequest_str_version_tag 15 -#define wippersnapper_description_v1_CreateDescriptionResponse_response_tag 1 -#define wippersnapper_description_v1_CreateDescriptionResponse_total_gpio_pins_tag 2 -#define wippersnapper_description_v1_CreateDescriptionResponse_total_analog_pins_tag 3 -#define wippersnapper_description_v1_CreateDescriptionResponse_reference_voltage_tag 4 -#define wippersnapper_description_v1_CreateDescriptionResponse_total_i2c_ports_tag 5 -#define wippersnapper_description_v1_RegistrationComplete_is_complete_tag 1 - -/* Struct field encoding specification for nanopb */ -#define wippersnapper_description_v1_CreateDescriptionRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, machine_name, 1) \ -X(a, STATIC, SINGULAR, INT32, mac_addr, 2) \ -X(a, STATIC, SINGULAR, INT32, usb_vid, 3) \ -X(a, STATIC, SINGULAR, INT32, usb_pid, 4) \ -X(a, STATIC, SINGULAR, STRING, str_version, 15) -#define wippersnapper_description_v1_CreateDescriptionRequest_CALLBACK NULL -#define wippersnapper_description_v1_CreateDescriptionRequest_DEFAULT NULL - -#define wippersnapper_description_v1_CreateDescriptionRequest_Version_FIELDLIST(X, a) \ - -#define wippersnapper_description_v1_CreateDescriptionRequest_Version_CALLBACK NULL -#define wippersnapper_description_v1_CreateDescriptionRequest_Version_DEFAULT NULL - -#define wippersnapper_description_v1_CreateDescriptionResponse_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, response, 1) \ -X(a, STATIC, SINGULAR, INT32, total_gpio_pins, 2) \ -X(a, STATIC, SINGULAR, INT32, total_analog_pins, 3) \ -X(a, STATIC, SINGULAR, FLOAT, reference_voltage, 4) \ -X(a, STATIC, SINGULAR, INT32, total_i2c_ports, 5) -#define wippersnapper_description_v1_CreateDescriptionResponse_CALLBACK NULL -#define wippersnapper_description_v1_CreateDescriptionResponse_DEFAULT NULL - -#define wippersnapper_description_v1_RegistrationComplete_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, is_complete, 1) -#define wippersnapper_description_v1_RegistrationComplete_CALLBACK NULL -#define wippersnapper_description_v1_RegistrationComplete_DEFAULT NULL - -#define wippersnapper_description_v1_GetDefinitionRequest_FIELDLIST(X, a) \ - -#define wippersnapper_description_v1_GetDefinitionRequest_CALLBACK NULL -#define wippersnapper_description_v1_GetDefinitionRequest_DEFAULT NULL - -#define wippersnapper_description_v1_GetDefinitionResponse_FIELDLIST(X, a) \ - -#define wippersnapper_description_v1_GetDefinitionResponse_CALLBACK NULL -#define wippersnapper_description_v1_GetDefinitionResponse_DEFAULT NULL - -extern const pb_msgdesc_t wippersnapper_description_v1_CreateDescriptionRequest_msg; -extern const pb_msgdesc_t wippersnapper_description_v1_CreateDescriptionRequest_Version_msg; -extern const pb_msgdesc_t wippersnapper_description_v1_CreateDescriptionResponse_msg; -extern const pb_msgdesc_t wippersnapper_description_v1_RegistrationComplete_msg; -extern const pb_msgdesc_t wippersnapper_description_v1_GetDefinitionRequest_msg; -extern const pb_msgdesc_t wippersnapper_description_v1_GetDefinitionResponse_msg; - -/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define wippersnapper_description_v1_CreateDescriptionRequest_fields &wippersnapper_description_v1_CreateDescriptionRequest_msg -#define wippersnapper_description_v1_CreateDescriptionRequest_Version_fields &wippersnapper_description_v1_CreateDescriptionRequest_Version_msg -#define wippersnapper_description_v1_CreateDescriptionResponse_fields &wippersnapper_description_v1_CreateDescriptionResponse_msg -#define wippersnapper_description_v1_RegistrationComplete_fields &wippersnapper_description_v1_RegistrationComplete_msg -#define wippersnapper_description_v1_GetDefinitionRequest_fields &wippersnapper_description_v1_GetDefinitionRequest_msg -#define wippersnapper_description_v1_GetDefinitionResponse_fields &wippersnapper_description_v1_GetDefinitionResponse_msg - -/* Maximum encoded size of messages (where known) */ -#define wippersnapper_description_v1_CreateDescriptionRequest_size 119 -#define wippersnapper_description_v1_CreateDescriptionRequest_Version_size 0 -#define wippersnapper_description_v1_CreateDescriptionResponse_size 40 -#define wippersnapper_description_v1_RegistrationComplete_size 2 -#define wippersnapper_description_v1_GetDefinitionRequest_size 0 -#define wippersnapper_description_v1_GetDefinitionResponse_size 0 - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/wippersnapper/ds18x20/v1/ds18x20.pb.c b/src/wippersnapper/ds18x20/v1/ds18x20.pb.c deleted file mode 100644 index 4d3172b5d..000000000 --- a/src/wippersnapper/ds18x20/v1/ds18x20.pb.c +++ /dev/null @@ -1,21 +0,0 @@ -/* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#include "wippersnapper/ds18x20/v1/ds18x20.pb.h" -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -PB_BIND(wippersnapper_ds18x20_v1_Ds18x20InitRequest, wippersnapper_ds18x20_v1_Ds18x20InitRequest, AUTO) - - -PB_BIND(wippersnapper_ds18x20_v1_Ds18x20InitResponse, wippersnapper_ds18x20_v1_Ds18x20InitResponse, AUTO) - - -PB_BIND(wippersnapper_ds18x20_v1_Ds18x20DeInitRequest, wippersnapper_ds18x20_v1_Ds18x20DeInitRequest, AUTO) - - -PB_BIND(wippersnapper_ds18x20_v1_Ds18x20DeviceEvent, wippersnapper_ds18x20_v1_Ds18x20DeviceEvent, AUTO) - - - diff --git a/src/wippersnapper/ds18x20/v1/ds18x20.pb.h b/src/wippersnapper/ds18x20/v1/ds18x20.pb.h deleted file mode 100644 index 101908aba..000000000 --- a/src/wippersnapper/ds18x20/v1/ds18x20.pb.h +++ /dev/null @@ -1,110 +0,0 @@ -/* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#ifndef PB_WIPPERSNAPPER_DS18X20_V1_WIPPERSNAPPER_DS18X20_V1_DS18X20_PB_H_INCLUDED -#define PB_WIPPERSNAPPER_DS18X20_V1_WIPPERSNAPPER_DS18X20_V1_DS18X20_PB_H_INCLUDED -#include -#include "nanopb/nanopb.pb.h" -#include "wippersnapper/i2c/v1/i2c.pb.h" - -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -/* Struct definitions */ -typedef struct _wippersnapper_ds18x20_v1_Ds18x20DeInitRequest { - char onewire_pin[5]; -} wippersnapper_ds18x20_v1_Ds18x20DeInitRequest; - -typedef struct _wippersnapper_ds18x20_v1_Ds18x20DeviceEvent { - char onewire_pin[5]; - pb_size_t sensor_event_count; - wippersnapper_i2c_v1_SensorEvent sensor_event[2]; -} wippersnapper_ds18x20_v1_Ds18x20DeviceEvent; - -typedef struct _wippersnapper_ds18x20_v1_Ds18x20InitRequest { - char onewire_pin[5]; - int32_t sensor_resolution; - pb_size_t i2c_device_properties_count; - wippersnapper_i2c_v1_I2CDeviceSensorProperties i2c_device_properties[2]; -} wippersnapper_ds18x20_v1_Ds18x20InitRequest; - -typedef struct _wippersnapper_ds18x20_v1_Ds18x20InitResponse { - bool is_initialized; - char onewire_pin[5]; -} wippersnapper_ds18x20_v1_Ds18x20InitResponse; - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Initializer values for message structs */ -#define wippersnapper_ds18x20_v1_Ds18x20InitRequest_init_default {"", 0, 0, {wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default}} -#define wippersnapper_ds18x20_v1_Ds18x20InitResponse_init_default {0, ""} -#define wippersnapper_ds18x20_v1_Ds18x20DeInitRequest_init_default {""} -#define wippersnapper_ds18x20_v1_Ds18x20DeviceEvent_init_default {"", 0, {wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default}} -#define wippersnapper_ds18x20_v1_Ds18x20InitRequest_init_zero {"", 0, 0, {wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero}} -#define wippersnapper_ds18x20_v1_Ds18x20InitResponse_init_zero {0, ""} -#define wippersnapper_ds18x20_v1_Ds18x20DeInitRequest_init_zero {""} -#define wippersnapper_ds18x20_v1_Ds18x20DeviceEvent_init_zero {"", 0, {wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero}} - -/* Field tags (for use in manual encoding/decoding) */ -#define wippersnapper_ds18x20_v1_Ds18x20DeInitRequest_onewire_pin_tag 1 -#define wippersnapper_ds18x20_v1_Ds18x20DeviceEvent_onewire_pin_tag 1 -#define wippersnapper_ds18x20_v1_Ds18x20DeviceEvent_sensor_event_tag 2 -#define wippersnapper_ds18x20_v1_Ds18x20InitRequest_onewire_pin_tag 1 -#define wippersnapper_ds18x20_v1_Ds18x20InitRequest_sensor_resolution_tag 2 -#define wippersnapper_ds18x20_v1_Ds18x20InitRequest_i2c_device_properties_tag 3 -#define wippersnapper_ds18x20_v1_Ds18x20InitResponse_is_initialized_tag 1 -#define wippersnapper_ds18x20_v1_Ds18x20InitResponse_onewire_pin_tag 2 - -/* Struct field encoding specification for nanopb */ -#define wippersnapper_ds18x20_v1_Ds18x20InitRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, onewire_pin, 1) \ -X(a, STATIC, SINGULAR, INT32, sensor_resolution, 2) \ -X(a, STATIC, REPEATED, MESSAGE, i2c_device_properties, 3) -#define wippersnapper_ds18x20_v1_Ds18x20InitRequest_CALLBACK NULL -#define wippersnapper_ds18x20_v1_Ds18x20InitRequest_DEFAULT NULL -#define wippersnapper_ds18x20_v1_Ds18x20InitRequest_i2c_device_properties_MSGTYPE wippersnapper_i2c_v1_I2CDeviceSensorProperties - -#define wippersnapper_ds18x20_v1_Ds18x20InitResponse_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, is_initialized, 1) \ -X(a, STATIC, SINGULAR, STRING, onewire_pin, 2) -#define wippersnapper_ds18x20_v1_Ds18x20InitResponse_CALLBACK NULL -#define wippersnapper_ds18x20_v1_Ds18x20InitResponse_DEFAULT NULL - -#define wippersnapper_ds18x20_v1_Ds18x20DeInitRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, onewire_pin, 1) -#define wippersnapper_ds18x20_v1_Ds18x20DeInitRequest_CALLBACK NULL -#define wippersnapper_ds18x20_v1_Ds18x20DeInitRequest_DEFAULT NULL - -#define wippersnapper_ds18x20_v1_Ds18x20DeviceEvent_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, onewire_pin, 1) \ -X(a, STATIC, REPEATED, MESSAGE, sensor_event, 2) -#define wippersnapper_ds18x20_v1_Ds18x20DeviceEvent_CALLBACK NULL -#define wippersnapper_ds18x20_v1_Ds18x20DeviceEvent_DEFAULT NULL -#define wippersnapper_ds18x20_v1_Ds18x20DeviceEvent_sensor_event_MSGTYPE wippersnapper_i2c_v1_SensorEvent - -extern const pb_msgdesc_t wippersnapper_ds18x20_v1_Ds18x20InitRequest_msg; -extern const pb_msgdesc_t wippersnapper_ds18x20_v1_Ds18x20InitResponse_msg; -extern const pb_msgdesc_t wippersnapper_ds18x20_v1_Ds18x20DeInitRequest_msg; -extern const pb_msgdesc_t wippersnapper_ds18x20_v1_Ds18x20DeviceEvent_msg; - -/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define wippersnapper_ds18x20_v1_Ds18x20InitRequest_fields &wippersnapper_ds18x20_v1_Ds18x20InitRequest_msg -#define wippersnapper_ds18x20_v1_Ds18x20InitResponse_fields &wippersnapper_ds18x20_v1_Ds18x20InitResponse_msg -#define wippersnapper_ds18x20_v1_Ds18x20DeInitRequest_fields &wippersnapper_ds18x20_v1_Ds18x20DeInitRequest_msg -#define wippersnapper_ds18x20_v1_Ds18x20DeviceEvent_fields &wippersnapper_ds18x20_v1_Ds18x20DeviceEvent_msg - -/* Maximum encoded size of messages (where known) */ -#define wippersnapper_ds18x20_v1_Ds18x20InitRequest_size 37 -#define wippersnapper_ds18x20_v1_Ds18x20InitResponse_size 8 -#define wippersnapper_ds18x20_v1_Ds18x20DeInitRequest_size 6 -#define wippersnapper_ds18x20_v1_Ds18x20DeviceEvent_size 24 - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/wippersnapper/i2c/v1/i2c.pb.c b/src/wippersnapper/i2c/v1/i2c.pb.c deleted file mode 100644 index b0f46a992..000000000 --- a/src/wippersnapper/i2c/v1/i2c.pb.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#include "wippersnapper/i2c/v1/i2c.pb.h" -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -PB_BIND(wippersnapper_i2c_v1_I2CBusInitRequest, wippersnapper_i2c_v1_I2CBusInitRequest, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_I2CBusInitResponse, wippersnapper_i2c_v1_I2CBusInitResponse, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_I2CBusSetFrequency, wippersnapper_i2c_v1_I2CBusSetFrequency, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_I2CBusScanRequest, wippersnapper_i2c_v1_I2CBusScanRequest, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_I2CBusScanResponse, wippersnapper_i2c_v1_I2CBusScanResponse, 2) - - -PB_BIND(wippersnapper_i2c_v1_I2CDeviceSensorProperties, wippersnapper_i2c_v1_I2CDeviceSensorProperties, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_I2CDeviceInitRequests, wippersnapper_i2c_v1_I2CDeviceInitRequests, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_I2CDeviceInitRequest, wippersnapper_i2c_v1_I2CDeviceInitRequest, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_I2CDeviceInitResponse, wippersnapper_i2c_v1_I2CDeviceInitResponse, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_I2CDeviceUpdateRequest, wippersnapper_i2c_v1_I2CDeviceUpdateRequest, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_I2CDeviceUpdateResponse, wippersnapper_i2c_v1_I2CDeviceUpdateResponse, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_I2CDeviceDeinitRequest, wippersnapper_i2c_v1_I2CDeviceDeinitRequest, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_I2CDeviceDeinitResponse, wippersnapper_i2c_v1_I2CDeviceDeinitResponse, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_SensorEvent, wippersnapper_i2c_v1_SensorEvent, AUTO) - - -PB_BIND(wippersnapper_i2c_v1_I2CDeviceEvent, wippersnapper_i2c_v1_I2CDeviceEvent, AUTO) - - - - - diff --git a/src/wippersnapper/i2c/v1/i2c.pb.h b/src/wippersnapper/i2c/v1/i2c.pb.h deleted file mode 100644 index f6865e1fd..000000000 --- a/src/wippersnapper/i2c/v1/i2c.pb.h +++ /dev/null @@ -1,390 +0,0 @@ -/* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#ifndef PB_WIPPERSNAPPER_I2C_V1_WIPPERSNAPPER_I2C_V1_I2C_PB_H_INCLUDED -#define PB_WIPPERSNAPPER_I2C_V1_WIPPERSNAPPER_I2C_V1_I2C_PB_H_INCLUDED -#include -#include "nanopb/nanopb.pb.h" - -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -/* Enum definitions */ -typedef enum _wippersnapper_i2c_v1_BusResponse { - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_UNSPECIFIED = 0, - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS = 1, - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_ERROR_HANG = 2, - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_ERROR_PULLUPS = 3, - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_ERROR_WIRING = 4, - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_UNSUPPORTED_SENSOR = 5, - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL = 6, - wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_DEINIT_FAIL = 7 -} wippersnapper_i2c_v1_BusResponse; - -typedef enum _wippersnapper_i2c_v1_SensorType { - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_UNSPECIFIED = 0, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_ACCELEROMETER = 1, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_MAGNETIC_FIELD = 2, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_ORIENTATION = 3, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_GYROSCOPE = 4, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_LIGHT = 5, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PRESSURE = 6, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PROXIMITY = 8, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_GRAVITY = 9, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_LINEAR_ACCELERATION = 10, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_ROTATION_VECTOR = 11, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_RELATIVE_HUMIDITY = 12, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE = 13, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE = 14, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOLTAGE = 15, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_CURRENT = 16, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_COLOR = 17, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_RAW = 18, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_STD = 19, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_STD = 20, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_STD = 21, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_ENV = 22, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_ENV = 23, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_ENV = 24, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_CO2 = 25, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_GAS_RESISTANCE = 26, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_ALTITUDE = 27, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_LUX = 28, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_ECO2 = 29, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_UNITLESS_PERCENT = 30, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT = 31, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT = 32, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOC_INDEX = 33, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_NOX_INDEX = 34, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_TVOC = 35 -} wippersnapper_i2c_v1_SensorType; - -/* Struct definitions */ -typedef struct _wippersnapper_i2c_v1_I2CDeviceInitRequests { - pb_callback_t list; -} wippersnapper_i2c_v1_I2CDeviceInitRequests; - -typedef struct _wippersnapper_i2c_v1_I2CBusInitRequest { - int32_t i2c_pin_scl; - int32_t i2c_pin_sda; - uint32_t i2c_frequency; - int32_t i2c_port_number; -} wippersnapper_i2c_v1_I2CBusInitRequest; - -typedef struct _wippersnapper_i2c_v1_I2CBusInitResponse { - wippersnapper_i2c_v1_BusResponse bus_response; -} wippersnapper_i2c_v1_I2CBusInitResponse; - -typedef struct _wippersnapper_i2c_v1_I2CBusScanResponse { - pb_size_t addresses_found_count; - uint32_t addresses_found[120]; - wippersnapper_i2c_v1_BusResponse bus_response; -} wippersnapper_i2c_v1_I2CBusScanResponse; - -typedef struct _wippersnapper_i2c_v1_I2CBusSetFrequency { - uint32_t frequency; - int32_t bus_id; -} wippersnapper_i2c_v1_I2CBusSetFrequency; - -typedef struct _wippersnapper_i2c_v1_I2CDeviceDeinitRequest { - int32_t i2c_port_number; - uint32_t i2c_device_address; -} wippersnapper_i2c_v1_I2CDeviceDeinitRequest; - -typedef struct _wippersnapper_i2c_v1_I2CDeviceDeinitResponse { - uint32_t i2c_device_address; - wippersnapper_i2c_v1_BusResponse bus_response; -} wippersnapper_i2c_v1_I2CDeviceDeinitResponse; - -typedef struct _wippersnapper_i2c_v1_I2CDeviceInitResponse { - uint32_t i2c_device_address; - wippersnapper_i2c_v1_BusResponse bus_response; -} wippersnapper_i2c_v1_I2CDeviceInitResponse; - -typedef struct _wippersnapper_i2c_v1_I2CDeviceSensorProperties { - wippersnapper_i2c_v1_SensorType sensor_type; - uint32_t sensor_period; -} wippersnapper_i2c_v1_I2CDeviceSensorProperties; - -typedef struct _wippersnapper_i2c_v1_I2CDeviceUpdateResponse { - uint32_t i2c_device_address; - wippersnapper_i2c_v1_BusResponse bus_response; -} wippersnapper_i2c_v1_I2CDeviceUpdateResponse; - -typedef struct _wippersnapper_i2c_v1_SensorEvent { - wippersnapper_i2c_v1_SensorType type; - float value; -} wippersnapper_i2c_v1_SensorEvent; - -typedef struct _wippersnapper_i2c_v1_I2CBusScanRequest { - int32_t i2c_port_number; - bool has_bus_init_request; - wippersnapper_i2c_v1_I2CBusInitRequest bus_init_request; -} wippersnapper_i2c_v1_I2CBusScanRequest; - -typedef struct _wippersnapper_i2c_v1_I2CDeviceEvent { - uint32_t sensor_address; - pb_size_t sensor_event_count; - wippersnapper_i2c_v1_SensorEvent sensor_event[15]; -} wippersnapper_i2c_v1_I2CDeviceEvent; - -typedef struct _wippersnapper_i2c_v1_I2CDeviceInitRequest { - int32_t i2c_port_number; - bool has_i2c_bus_init_req; - wippersnapper_i2c_v1_I2CBusInitRequest i2c_bus_init_req; - uint32_t i2c_device_address; - char i2c_device_name[15]; - pb_size_t i2c_device_properties_count; - wippersnapper_i2c_v1_I2CDeviceSensorProperties i2c_device_properties[15]; -} wippersnapper_i2c_v1_I2CDeviceInitRequest; - -typedef struct _wippersnapper_i2c_v1_I2CDeviceUpdateRequest { - int32_t i2c_port_number; - uint32_t i2c_device_address; - char i2c_device_name[15]; - pb_size_t i2c_device_properties_count; - wippersnapper_i2c_v1_I2CDeviceSensorProperties i2c_device_properties[15]; -} wippersnapper_i2c_v1_I2CDeviceUpdateRequest; - - -/* Helper constants for enums */ -#define _wippersnapper_i2c_v1_BusResponse_MIN wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_UNSPECIFIED -#define _wippersnapper_i2c_v1_BusResponse_MAX wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_DEINIT_FAIL -#define _wippersnapper_i2c_v1_BusResponse_ARRAYSIZE ((wippersnapper_i2c_v1_BusResponse)(wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_DEINIT_FAIL+1)) - -#define _wippersnapper_i2c_v1_SensorType_MIN wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_UNSPECIFIED -#define _wippersnapper_i2c_v1_SensorType_MAX wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_TVOC -#define _wippersnapper_i2c_v1_SensorType_ARRAYSIZE ((wippersnapper_i2c_v1_SensorType)(wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_TVOC+1)) - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Initializer values for message structs */ -#define wippersnapper_i2c_v1_I2CBusInitRequest_init_default {0, 0, 0, 0} -#define wippersnapper_i2c_v1_I2CBusInitResponse_init_default {_wippersnapper_i2c_v1_BusResponse_MIN} -#define wippersnapper_i2c_v1_I2CBusSetFrequency_init_default {0, 0} -#define wippersnapper_i2c_v1_I2CBusScanRequest_init_default {0, false, wippersnapper_i2c_v1_I2CBusInitRequest_init_default} -#define wippersnapper_i2c_v1_I2CBusScanResponse_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, _wippersnapper_i2c_v1_BusResponse_MIN} -#define wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default {_wippersnapper_i2c_v1_SensorType_MIN, 0} -#define wippersnapper_i2c_v1_I2CDeviceInitRequests_init_default {{{NULL}, NULL}} -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_init_default {0, false, wippersnapper_i2c_v1_I2CBusInitRequest_init_default, 0, "", 0, {wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default}} -#define wippersnapper_i2c_v1_I2CDeviceInitResponse_init_default {0, _wippersnapper_i2c_v1_BusResponse_MIN} -#define wippersnapper_i2c_v1_I2CDeviceUpdateRequest_init_default {0, 0, "", 0, {wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_default}} -#define wippersnapper_i2c_v1_I2CDeviceUpdateResponse_init_default {0, _wippersnapper_i2c_v1_BusResponse_MIN} -#define wippersnapper_i2c_v1_I2CDeviceDeinitRequest_init_default {0, 0} -#define wippersnapper_i2c_v1_I2CDeviceDeinitResponse_init_default {0, _wippersnapper_i2c_v1_BusResponse_MIN} -#define wippersnapper_i2c_v1_SensorEvent_init_default {_wippersnapper_i2c_v1_SensorType_MIN, 0} -#define wippersnapper_i2c_v1_I2CDeviceEvent_init_default {0, 0, {wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default}} -#define wippersnapper_i2c_v1_I2CBusInitRequest_init_zero {0, 0, 0, 0} -#define wippersnapper_i2c_v1_I2CBusInitResponse_init_zero {_wippersnapper_i2c_v1_BusResponse_MIN} -#define wippersnapper_i2c_v1_I2CBusSetFrequency_init_zero {0, 0} -#define wippersnapper_i2c_v1_I2CBusScanRequest_init_zero {0, false, wippersnapper_i2c_v1_I2CBusInitRequest_init_zero} -#define wippersnapper_i2c_v1_I2CBusScanResponse_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, _wippersnapper_i2c_v1_BusResponse_MIN} -#define wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero {_wippersnapper_i2c_v1_SensorType_MIN, 0} -#define wippersnapper_i2c_v1_I2CDeviceInitRequests_init_zero {{{NULL}, NULL}} -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_init_zero {0, false, wippersnapper_i2c_v1_I2CBusInitRequest_init_zero, 0, "", 0, {wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero}} -#define wippersnapper_i2c_v1_I2CDeviceInitResponse_init_zero {0, _wippersnapper_i2c_v1_BusResponse_MIN} -#define wippersnapper_i2c_v1_I2CDeviceUpdateRequest_init_zero {0, 0, "", 0, {wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero, wippersnapper_i2c_v1_I2CDeviceSensorProperties_init_zero}} -#define wippersnapper_i2c_v1_I2CDeviceUpdateResponse_init_zero {0, _wippersnapper_i2c_v1_BusResponse_MIN} -#define wippersnapper_i2c_v1_I2CDeviceDeinitRequest_init_zero {0, 0} -#define wippersnapper_i2c_v1_I2CDeviceDeinitResponse_init_zero {0, _wippersnapper_i2c_v1_BusResponse_MIN} -#define wippersnapper_i2c_v1_SensorEvent_init_zero {_wippersnapper_i2c_v1_SensorType_MIN, 0} -#define wippersnapper_i2c_v1_I2CDeviceEvent_init_zero {0, 0, {wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero}} - -/* Field tags (for use in manual encoding/decoding) */ -#define wippersnapper_i2c_v1_I2CDeviceInitRequests_list_tag 1 -#define wippersnapper_i2c_v1_I2CBusInitRequest_i2c_pin_scl_tag 1 -#define wippersnapper_i2c_v1_I2CBusInitRequest_i2c_pin_sda_tag 2 -#define wippersnapper_i2c_v1_I2CBusInitRequest_i2c_frequency_tag 3 -#define wippersnapper_i2c_v1_I2CBusInitRequest_i2c_port_number_tag 4 -#define wippersnapper_i2c_v1_I2CBusInitResponse_bus_response_tag 2 -#define wippersnapper_i2c_v1_I2CBusScanResponse_addresses_found_tag 1 -#define wippersnapper_i2c_v1_I2CBusScanResponse_bus_response_tag 2 -#define wippersnapper_i2c_v1_I2CBusSetFrequency_frequency_tag 1 -#define wippersnapper_i2c_v1_I2CBusSetFrequency_bus_id_tag 2 -#define wippersnapper_i2c_v1_I2CDeviceDeinitRequest_i2c_port_number_tag 1 -#define wippersnapper_i2c_v1_I2CDeviceDeinitRequest_i2c_device_address_tag 2 -#define wippersnapper_i2c_v1_I2CDeviceDeinitResponse_i2c_device_address_tag 2 -#define wippersnapper_i2c_v1_I2CDeviceDeinitResponse_bus_response_tag 3 -#define wippersnapper_i2c_v1_I2CDeviceInitResponse_i2c_device_address_tag 2 -#define wippersnapper_i2c_v1_I2CDeviceInitResponse_bus_response_tag 3 -#define wippersnapper_i2c_v1_I2CDeviceSensorProperties_sensor_type_tag 1 -#define wippersnapper_i2c_v1_I2CDeviceSensorProperties_sensor_period_tag 2 -#define wippersnapper_i2c_v1_I2CDeviceUpdateResponse_i2c_device_address_tag 1 -#define wippersnapper_i2c_v1_I2CDeviceUpdateResponse_bus_response_tag 3 -#define wippersnapper_i2c_v1_SensorEvent_type_tag 1 -#define wippersnapper_i2c_v1_SensorEvent_value_tag 2 -#define wippersnapper_i2c_v1_I2CBusScanRequest_i2c_port_number_tag 1 -#define wippersnapper_i2c_v1_I2CBusScanRequest_bus_init_request_tag 2 -#define wippersnapper_i2c_v1_I2CDeviceEvent_sensor_address_tag 1 -#define wippersnapper_i2c_v1_I2CDeviceEvent_sensor_event_tag 2 -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_i2c_port_number_tag 1 -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_i2c_bus_init_req_tag 2 -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_i2c_device_address_tag 3 -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_i2c_device_name_tag 4 -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_i2c_device_properties_tag 5 -#define wippersnapper_i2c_v1_I2CDeviceUpdateRequest_i2c_port_number_tag 1 -#define wippersnapper_i2c_v1_I2CDeviceUpdateRequest_i2c_device_address_tag 2 -#define wippersnapper_i2c_v1_I2CDeviceUpdateRequest_i2c_device_name_tag 3 -#define wippersnapper_i2c_v1_I2CDeviceUpdateRequest_i2c_device_properties_tag 4 - -/* Struct field encoding specification for nanopb */ -#define wippersnapper_i2c_v1_I2CBusInitRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, INT32, i2c_pin_scl, 1) \ -X(a, STATIC, SINGULAR, INT32, i2c_pin_sda, 2) \ -X(a, STATIC, SINGULAR, UINT32, i2c_frequency, 3) \ -X(a, STATIC, SINGULAR, INT32, i2c_port_number, 4) -#define wippersnapper_i2c_v1_I2CBusInitRequest_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CBusInitRequest_DEFAULT NULL - -#define wippersnapper_i2c_v1_I2CBusInitResponse_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, bus_response, 2) -#define wippersnapper_i2c_v1_I2CBusInitResponse_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CBusInitResponse_DEFAULT NULL - -#define wippersnapper_i2c_v1_I2CBusSetFrequency_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, frequency, 1) \ -X(a, STATIC, SINGULAR, INT32, bus_id, 2) -#define wippersnapper_i2c_v1_I2CBusSetFrequency_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CBusSetFrequency_DEFAULT NULL - -#define wippersnapper_i2c_v1_I2CBusScanRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, INT32, i2c_port_number, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, bus_init_request, 2) -#define wippersnapper_i2c_v1_I2CBusScanRequest_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CBusScanRequest_DEFAULT NULL -#define wippersnapper_i2c_v1_I2CBusScanRequest_bus_init_request_MSGTYPE wippersnapper_i2c_v1_I2CBusInitRequest - -#define wippersnapper_i2c_v1_I2CBusScanResponse_FIELDLIST(X, a) \ -X(a, STATIC, REPEATED, UINT32, addresses_found, 1) \ -X(a, STATIC, SINGULAR, UENUM, bus_response, 2) -#define wippersnapper_i2c_v1_I2CBusScanResponse_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CBusScanResponse_DEFAULT NULL - -#define wippersnapper_i2c_v1_I2CDeviceSensorProperties_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, sensor_type, 1) \ -X(a, STATIC, SINGULAR, UINT32, sensor_period, 2) -#define wippersnapper_i2c_v1_I2CDeviceSensorProperties_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CDeviceSensorProperties_DEFAULT NULL - -#define wippersnapper_i2c_v1_I2CDeviceInitRequests_FIELDLIST(X, a) \ -X(a, CALLBACK, REPEATED, MESSAGE, list, 1) -#define wippersnapper_i2c_v1_I2CDeviceInitRequests_CALLBACK pb_default_field_callback -#define wippersnapper_i2c_v1_I2CDeviceInitRequests_DEFAULT NULL -#define wippersnapper_i2c_v1_I2CDeviceInitRequests_list_MSGTYPE wippersnapper_i2c_v1_I2CDeviceInitRequest - -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, INT32, i2c_port_number, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, i2c_bus_init_req, 2) \ -X(a, STATIC, SINGULAR, UINT32, i2c_device_address, 3) \ -X(a, STATIC, SINGULAR, STRING, i2c_device_name, 4) \ -X(a, STATIC, REPEATED, MESSAGE, i2c_device_properties, 5) -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_DEFAULT NULL -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_i2c_bus_init_req_MSGTYPE wippersnapper_i2c_v1_I2CBusInitRequest -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_i2c_device_properties_MSGTYPE wippersnapper_i2c_v1_I2CDeviceSensorProperties - -#define wippersnapper_i2c_v1_I2CDeviceInitResponse_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, i2c_device_address, 2) \ -X(a, STATIC, SINGULAR, UENUM, bus_response, 3) -#define wippersnapper_i2c_v1_I2CDeviceInitResponse_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CDeviceInitResponse_DEFAULT NULL - -#define wippersnapper_i2c_v1_I2CDeviceUpdateRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, INT32, i2c_port_number, 1) \ -X(a, STATIC, SINGULAR, UINT32, i2c_device_address, 2) \ -X(a, STATIC, SINGULAR, STRING, i2c_device_name, 3) \ -X(a, STATIC, REPEATED, MESSAGE, i2c_device_properties, 4) -#define wippersnapper_i2c_v1_I2CDeviceUpdateRequest_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CDeviceUpdateRequest_DEFAULT NULL -#define wippersnapper_i2c_v1_I2CDeviceUpdateRequest_i2c_device_properties_MSGTYPE wippersnapper_i2c_v1_I2CDeviceSensorProperties - -#define wippersnapper_i2c_v1_I2CDeviceUpdateResponse_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, i2c_device_address, 1) \ -X(a, STATIC, SINGULAR, UENUM, bus_response, 3) -#define wippersnapper_i2c_v1_I2CDeviceUpdateResponse_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CDeviceUpdateResponse_DEFAULT NULL - -#define wippersnapper_i2c_v1_I2CDeviceDeinitRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, INT32, i2c_port_number, 1) \ -X(a, STATIC, SINGULAR, UINT32, i2c_device_address, 2) -#define wippersnapper_i2c_v1_I2CDeviceDeinitRequest_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CDeviceDeinitRequest_DEFAULT NULL - -#define wippersnapper_i2c_v1_I2CDeviceDeinitResponse_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, i2c_device_address, 2) \ -X(a, STATIC, SINGULAR, UENUM, bus_response, 3) -#define wippersnapper_i2c_v1_I2CDeviceDeinitResponse_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CDeviceDeinitResponse_DEFAULT NULL - -#define wippersnapper_i2c_v1_SensorEvent_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, type, 1) \ -X(a, STATIC, SINGULAR, FLOAT, value, 2) -#define wippersnapper_i2c_v1_SensorEvent_CALLBACK NULL -#define wippersnapper_i2c_v1_SensorEvent_DEFAULT NULL - -#define wippersnapper_i2c_v1_I2CDeviceEvent_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, sensor_address, 1) \ -X(a, STATIC, REPEATED, MESSAGE, sensor_event, 2) -#define wippersnapper_i2c_v1_I2CDeviceEvent_CALLBACK NULL -#define wippersnapper_i2c_v1_I2CDeviceEvent_DEFAULT NULL -#define wippersnapper_i2c_v1_I2CDeviceEvent_sensor_event_MSGTYPE wippersnapper_i2c_v1_SensorEvent - -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CBusInitRequest_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CBusInitResponse_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CBusSetFrequency_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CBusScanRequest_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CBusScanResponse_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CDeviceSensorProperties_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CDeviceInitRequests_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CDeviceInitRequest_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CDeviceInitResponse_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CDeviceUpdateRequest_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CDeviceUpdateResponse_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CDeviceDeinitRequest_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CDeviceDeinitResponse_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_SensorEvent_msg; -extern const pb_msgdesc_t wippersnapper_i2c_v1_I2CDeviceEvent_msg; - -/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define wippersnapper_i2c_v1_I2CBusInitRequest_fields &wippersnapper_i2c_v1_I2CBusInitRequest_msg -#define wippersnapper_i2c_v1_I2CBusInitResponse_fields &wippersnapper_i2c_v1_I2CBusInitResponse_msg -#define wippersnapper_i2c_v1_I2CBusSetFrequency_fields &wippersnapper_i2c_v1_I2CBusSetFrequency_msg -#define wippersnapper_i2c_v1_I2CBusScanRequest_fields &wippersnapper_i2c_v1_I2CBusScanRequest_msg -#define wippersnapper_i2c_v1_I2CBusScanResponse_fields &wippersnapper_i2c_v1_I2CBusScanResponse_msg -#define wippersnapper_i2c_v1_I2CDeviceSensorProperties_fields &wippersnapper_i2c_v1_I2CDeviceSensorProperties_msg -#define wippersnapper_i2c_v1_I2CDeviceInitRequests_fields &wippersnapper_i2c_v1_I2CDeviceInitRequests_msg -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_fields &wippersnapper_i2c_v1_I2CDeviceInitRequest_msg -#define wippersnapper_i2c_v1_I2CDeviceInitResponse_fields &wippersnapper_i2c_v1_I2CDeviceInitResponse_msg -#define wippersnapper_i2c_v1_I2CDeviceUpdateRequest_fields &wippersnapper_i2c_v1_I2CDeviceUpdateRequest_msg -#define wippersnapper_i2c_v1_I2CDeviceUpdateResponse_fields &wippersnapper_i2c_v1_I2CDeviceUpdateResponse_msg -#define wippersnapper_i2c_v1_I2CDeviceDeinitRequest_fields &wippersnapper_i2c_v1_I2CDeviceDeinitRequest_msg -#define wippersnapper_i2c_v1_I2CDeviceDeinitResponse_fields &wippersnapper_i2c_v1_I2CDeviceDeinitResponse_msg -#define wippersnapper_i2c_v1_SensorEvent_fields &wippersnapper_i2c_v1_SensorEvent_msg -#define wippersnapper_i2c_v1_I2CDeviceEvent_fields &wippersnapper_i2c_v1_I2CDeviceEvent_msg - -/* Maximum encoded size of messages (where known) */ -#define wippersnapper_i2c_v1_I2CBusInitRequest_size 39 -#define wippersnapper_i2c_v1_I2CBusInitResponse_size 2 -#define wippersnapper_i2c_v1_I2CBusSetFrequency_size 17 -#define wippersnapper_i2c_v1_I2CBusScanRequest_size 52 -#define wippersnapper_i2c_v1_I2CBusScanResponse_size 722 -#define wippersnapper_i2c_v1_I2CDeviceSensorProperties_size 8 -/* wippersnapper_i2c_v1_I2CDeviceInitRequests_size depends on runtime parameters */ -#define wippersnapper_i2c_v1_I2CDeviceInitRequest_size 224 -#define wippersnapper_i2c_v1_I2CDeviceInitResponse_size 8 -#define wippersnapper_i2c_v1_I2CDeviceUpdateRequest_size 183 -#define wippersnapper_i2c_v1_I2CDeviceUpdateResponse_size 8 -#define wippersnapper_i2c_v1_I2CDeviceDeinitRequest_size 17 -#define wippersnapper_i2c_v1_I2CDeviceDeinitResponse_size 8 -#define wippersnapper_i2c_v1_SensorEvent_size 7 -#define wippersnapper_i2c_v1_I2CDeviceEvent_size 141 - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/wippersnapper/pin/v1/pin.pb.c b/src/wippersnapper/pin/v1/pin.pb.c deleted file mode 100644 index cadf00dee..000000000 --- a/src/wippersnapper/pin/v1/pin.pb.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#include "wippersnapper/pin/v1/pin.pb.h" -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -PB_BIND(wippersnapper_pin_v1_ConfigurePinRequests, wippersnapper_pin_v1_ConfigurePinRequests, AUTO) - - -PB_BIND(wippersnapper_pin_v1_ConfigurePinRequest, wippersnapper_pin_v1_ConfigurePinRequest, AUTO) - - -PB_BIND(wippersnapper_pin_v1_PinEvent, wippersnapper_pin_v1_PinEvent, AUTO) - - -PB_BIND(wippersnapper_pin_v1_ConfigureReferenceVoltage, wippersnapper_pin_v1_ConfigureReferenceVoltage, AUTO) - - -PB_BIND(wippersnapper_pin_v1_PinEvents, wippersnapper_pin_v1_PinEvents, AUTO) - - -PB_BIND(wippersnapper_pin_v1_ConfigurePWMPinRequest, wippersnapper_pin_v1_ConfigurePWMPinRequest, AUTO) - - -PB_BIND(wippersnapper_pin_v1_ConfigurePWMPinRequests, wippersnapper_pin_v1_ConfigurePWMPinRequests, AUTO) - - -PB_BIND(wippersnapper_pin_v1_PWMPinEvent, wippersnapper_pin_v1_PWMPinEvent, AUTO) - - -PB_BIND(wippersnapper_pin_v1_PWMPinEvents, wippersnapper_pin_v1_PWMPinEvents, AUTO) - - - - - - - - diff --git a/src/wippersnapper/pin/v1/pin.pb.h b/src/wippersnapper/pin/v1/pin.pb.h deleted file mode 100644 index 9859c9ff2..000000000 --- a/src/wippersnapper/pin/v1/pin.pb.h +++ /dev/null @@ -1,244 +0,0 @@ -/* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#ifndef PB_WIPPERSNAPPER_PIN_V1_WIPPERSNAPPER_PIN_V1_PIN_PB_H_INCLUDED -#define PB_WIPPERSNAPPER_PIN_V1_WIPPERSNAPPER_PIN_V1_PIN_PB_H_INCLUDED -#include -#include "nanopb/nanopb.pb.h" - -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -/* Enum definitions */ -typedef enum _wippersnapper_pin_v1_Mode { - wippersnapper_pin_v1_Mode_MODE_UNSPECIFIED = 0, - wippersnapper_pin_v1_Mode_MODE_ANALOG = 1, - wippersnapper_pin_v1_Mode_MODE_DIGITAL = 2 -} wippersnapper_pin_v1_Mode; - -typedef enum _wippersnapper_pin_v1_ConfigurePinRequest_Direction { - wippersnapper_pin_v1_ConfigurePinRequest_Direction_DIRECTION_UNSPECIFIED = 0, - wippersnapper_pin_v1_ConfigurePinRequest_Direction_DIRECTION_INPUT = 1, - wippersnapper_pin_v1_ConfigurePinRequest_Direction_DIRECTION_OUTPUT = 2 -} wippersnapper_pin_v1_ConfigurePinRequest_Direction; - -typedef enum _wippersnapper_pin_v1_ConfigurePinRequest_Pull { - wippersnapper_pin_v1_ConfigurePinRequest_Pull_PULL_UNSPECIFIED = 0, - wippersnapper_pin_v1_ConfigurePinRequest_Pull_PULL_UP = 1, - wippersnapper_pin_v1_ConfigurePinRequest_Pull_PULL_DOWN = 2 -} wippersnapper_pin_v1_ConfigurePinRequest_Pull; - -typedef enum _wippersnapper_pin_v1_ConfigurePinRequest_RequestType { - wippersnapper_pin_v1_ConfigurePinRequest_RequestType_REQUEST_TYPE_UNSPECIFIED = 0, - wippersnapper_pin_v1_ConfigurePinRequest_RequestType_REQUEST_TYPE_CREATE = 1, - wippersnapper_pin_v1_ConfigurePinRequest_RequestType_REQUEST_TYPE_UPDATE = 2, - wippersnapper_pin_v1_ConfigurePinRequest_RequestType_REQUEST_TYPE_DELETE = 3 -} wippersnapper_pin_v1_ConfigurePinRequest_RequestType; - -typedef enum _wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode { - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_UNSPECIFIED = 0, - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_PIN_VALUE = 1, - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_PIN_VOLTAGE = 2 -} wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode; - -/* Struct definitions */ -typedef struct _wippersnapper_pin_v1_ConfigurePWMPinRequest { - char dummy_field; -} wippersnapper_pin_v1_ConfigurePWMPinRequest; - -typedef struct _wippersnapper_pin_v1_ConfigurePWMPinRequests { - char dummy_field; -} wippersnapper_pin_v1_ConfigurePWMPinRequests; - -typedef struct _wippersnapper_pin_v1_ConfigurePinRequests { - pb_callback_t list; -} wippersnapper_pin_v1_ConfigurePinRequests; - -typedef struct _wippersnapper_pin_v1_PWMPinEvent { - char dummy_field; -} wippersnapper_pin_v1_PWMPinEvent; - -typedef struct _wippersnapper_pin_v1_PWMPinEvents { - char dummy_field; -} wippersnapper_pin_v1_PWMPinEvents; - -typedef struct _wippersnapper_pin_v1_PinEvents { - pb_callback_t list; -} wippersnapper_pin_v1_PinEvents; - -typedef struct _wippersnapper_pin_v1_ConfigurePinRequest { - char pin_name[5]; - wippersnapper_pin_v1_Mode mode; - wippersnapper_pin_v1_ConfigurePinRequest_Direction direction; - wippersnapper_pin_v1_ConfigurePinRequest_Pull pull; - float period; - wippersnapper_pin_v1_ConfigurePinRequest_RequestType request_type; - float aref; - wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode analog_read_mode; -} wippersnapper_pin_v1_ConfigurePinRequest; - -typedef struct _wippersnapper_pin_v1_ConfigureReferenceVoltage { - float reference_voltage; -} wippersnapper_pin_v1_ConfigureReferenceVoltage; - -typedef struct _wippersnapper_pin_v1_PinEvent { - char pin_name[5]; - char pin_value[12]; -} wippersnapper_pin_v1_PinEvent; - - -/* Helper constants for enums */ -#define _wippersnapper_pin_v1_Mode_MIN wippersnapper_pin_v1_Mode_MODE_UNSPECIFIED -#define _wippersnapper_pin_v1_Mode_MAX wippersnapper_pin_v1_Mode_MODE_DIGITAL -#define _wippersnapper_pin_v1_Mode_ARRAYSIZE ((wippersnapper_pin_v1_Mode)(wippersnapper_pin_v1_Mode_MODE_DIGITAL+1)) - -#define _wippersnapper_pin_v1_ConfigurePinRequest_Direction_MIN wippersnapper_pin_v1_ConfigurePinRequest_Direction_DIRECTION_UNSPECIFIED -#define _wippersnapper_pin_v1_ConfigurePinRequest_Direction_MAX wippersnapper_pin_v1_ConfigurePinRequest_Direction_DIRECTION_OUTPUT -#define _wippersnapper_pin_v1_ConfigurePinRequest_Direction_ARRAYSIZE ((wippersnapper_pin_v1_ConfigurePinRequest_Direction)(wippersnapper_pin_v1_ConfigurePinRequest_Direction_DIRECTION_OUTPUT+1)) - -#define _wippersnapper_pin_v1_ConfigurePinRequest_Pull_MIN wippersnapper_pin_v1_ConfigurePinRequest_Pull_PULL_UNSPECIFIED -#define _wippersnapper_pin_v1_ConfigurePinRequest_Pull_MAX wippersnapper_pin_v1_ConfigurePinRequest_Pull_PULL_DOWN -#define _wippersnapper_pin_v1_ConfigurePinRequest_Pull_ARRAYSIZE ((wippersnapper_pin_v1_ConfigurePinRequest_Pull)(wippersnapper_pin_v1_ConfigurePinRequest_Pull_PULL_DOWN+1)) - -#define _wippersnapper_pin_v1_ConfigurePinRequest_RequestType_MIN wippersnapper_pin_v1_ConfigurePinRequest_RequestType_REQUEST_TYPE_UNSPECIFIED -#define _wippersnapper_pin_v1_ConfigurePinRequest_RequestType_MAX wippersnapper_pin_v1_ConfigurePinRequest_RequestType_REQUEST_TYPE_DELETE -#define _wippersnapper_pin_v1_ConfigurePinRequest_RequestType_ARRAYSIZE ((wippersnapper_pin_v1_ConfigurePinRequest_RequestType)(wippersnapper_pin_v1_ConfigurePinRequest_RequestType_REQUEST_TYPE_DELETE+1)) - -#define _wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_MIN wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_UNSPECIFIED -#define _wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_MAX wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_PIN_VOLTAGE -#define _wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ARRAYSIZE ((wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode)(wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_PIN_VOLTAGE+1)) - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Initializer values for message structs */ -#define wippersnapper_pin_v1_ConfigurePinRequests_init_default {{{NULL}, NULL}} -#define wippersnapper_pin_v1_ConfigurePinRequest_init_default {"", _wippersnapper_pin_v1_Mode_MIN, _wippersnapper_pin_v1_ConfigurePinRequest_Direction_MIN, _wippersnapper_pin_v1_ConfigurePinRequest_Pull_MIN, 0, _wippersnapper_pin_v1_ConfigurePinRequest_RequestType_MIN, 0, _wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_MIN} -#define wippersnapper_pin_v1_PinEvent_init_default {"", ""} -#define wippersnapper_pin_v1_ConfigureReferenceVoltage_init_default {0} -#define wippersnapper_pin_v1_PinEvents_init_default {{{NULL}, NULL}} -#define wippersnapper_pin_v1_ConfigurePWMPinRequest_init_default {0} -#define wippersnapper_pin_v1_ConfigurePWMPinRequests_init_default {0} -#define wippersnapper_pin_v1_PWMPinEvent_init_default {0} -#define wippersnapper_pin_v1_PWMPinEvents_init_default {0} -#define wippersnapper_pin_v1_ConfigurePinRequests_init_zero {{{NULL}, NULL}} -#define wippersnapper_pin_v1_ConfigurePinRequest_init_zero {"", _wippersnapper_pin_v1_Mode_MIN, _wippersnapper_pin_v1_ConfigurePinRequest_Direction_MIN, _wippersnapper_pin_v1_ConfigurePinRequest_Pull_MIN, 0, _wippersnapper_pin_v1_ConfigurePinRequest_RequestType_MIN, 0, _wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_MIN} -#define wippersnapper_pin_v1_PinEvent_init_zero {"", ""} -#define wippersnapper_pin_v1_ConfigureReferenceVoltage_init_zero {0} -#define wippersnapper_pin_v1_PinEvents_init_zero {{{NULL}, NULL}} -#define wippersnapper_pin_v1_ConfigurePWMPinRequest_init_zero {0} -#define wippersnapper_pin_v1_ConfigurePWMPinRequests_init_zero {0} -#define wippersnapper_pin_v1_PWMPinEvent_init_zero {0} -#define wippersnapper_pin_v1_PWMPinEvents_init_zero {0} - -/* Field tags (for use in manual encoding/decoding) */ -#define wippersnapper_pin_v1_ConfigurePinRequests_list_tag 1 -#define wippersnapper_pin_v1_PinEvents_list_tag 1 -#define wippersnapper_pin_v1_ConfigurePinRequest_pin_name_tag 1 -#define wippersnapper_pin_v1_ConfigurePinRequest_mode_tag 2 -#define wippersnapper_pin_v1_ConfigurePinRequest_direction_tag 3 -#define wippersnapper_pin_v1_ConfigurePinRequest_pull_tag 4 -#define wippersnapper_pin_v1_ConfigurePinRequest_period_tag 5 -#define wippersnapper_pin_v1_ConfigurePinRequest_request_type_tag 6 -#define wippersnapper_pin_v1_ConfigurePinRequest_aref_tag 7 -#define wippersnapper_pin_v1_ConfigurePinRequest_analog_read_mode_tag 8 -#define wippersnapper_pin_v1_ConfigureReferenceVoltage_reference_voltage_tag 1 -#define wippersnapper_pin_v1_PinEvent_pin_name_tag 1 -#define wippersnapper_pin_v1_PinEvent_pin_value_tag 2 - -/* Struct field encoding specification for nanopb */ -#define wippersnapper_pin_v1_ConfigurePinRequests_FIELDLIST(X, a) \ -X(a, CALLBACK, REPEATED, MESSAGE, list, 1) -#define wippersnapper_pin_v1_ConfigurePinRequests_CALLBACK pb_default_field_callback -#define wippersnapper_pin_v1_ConfigurePinRequests_DEFAULT NULL -#define wippersnapper_pin_v1_ConfigurePinRequests_list_MSGTYPE wippersnapper_pin_v1_ConfigurePinRequest - -#define wippersnapper_pin_v1_ConfigurePinRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, pin_name, 1) \ -X(a, STATIC, SINGULAR, UENUM, mode, 2) \ -X(a, STATIC, SINGULAR, UENUM, direction, 3) \ -X(a, STATIC, SINGULAR, UENUM, pull, 4) \ -X(a, STATIC, SINGULAR, FLOAT, period, 5) \ -X(a, STATIC, SINGULAR, UENUM, request_type, 6) \ -X(a, STATIC, SINGULAR, FLOAT, aref, 7) \ -X(a, STATIC, SINGULAR, UENUM, analog_read_mode, 8) -#define wippersnapper_pin_v1_ConfigurePinRequest_CALLBACK NULL -#define wippersnapper_pin_v1_ConfigurePinRequest_DEFAULT NULL - -#define wippersnapper_pin_v1_PinEvent_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, pin_name, 1) \ -X(a, STATIC, SINGULAR, STRING, pin_value, 2) -#define wippersnapper_pin_v1_PinEvent_CALLBACK NULL -#define wippersnapper_pin_v1_PinEvent_DEFAULT NULL - -#define wippersnapper_pin_v1_ConfigureReferenceVoltage_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, FLOAT, reference_voltage, 1) -#define wippersnapper_pin_v1_ConfigureReferenceVoltage_CALLBACK NULL -#define wippersnapper_pin_v1_ConfigureReferenceVoltage_DEFAULT NULL - -#define wippersnapper_pin_v1_PinEvents_FIELDLIST(X, a) \ -X(a, CALLBACK, REPEATED, MESSAGE, list, 1) -#define wippersnapper_pin_v1_PinEvents_CALLBACK pb_default_field_callback -#define wippersnapper_pin_v1_PinEvents_DEFAULT NULL -#define wippersnapper_pin_v1_PinEvents_list_MSGTYPE wippersnapper_pin_v1_PinEvent - -#define wippersnapper_pin_v1_ConfigurePWMPinRequest_FIELDLIST(X, a) \ - -#define wippersnapper_pin_v1_ConfigurePWMPinRequest_CALLBACK NULL -#define wippersnapper_pin_v1_ConfigurePWMPinRequest_DEFAULT NULL - -#define wippersnapper_pin_v1_ConfigurePWMPinRequests_FIELDLIST(X, a) \ - -#define wippersnapper_pin_v1_ConfigurePWMPinRequests_CALLBACK NULL -#define wippersnapper_pin_v1_ConfigurePWMPinRequests_DEFAULT NULL - -#define wippersnapper_pin_v1_PWMPinEvent_FIELDLIST(X, a) \ - -#define wippersnapper_pin_v1_PWMPinEvent_CALLBACK NULL -#define wippersnapper_pin_v1_PWMPinEvent_DEFAULT NULL - -#define wippersnapper_pin_v1_PWMPinEvents_FIELDLIST(X, a) \ - -#define wippersnapper_pin_v1_PWMPinEvents_CALLBACK NULL -#define wippersnapper_pin_v1_PWMPinEvents_DEFAULT NULL - -extern const pb_msgdesc_t wippersnapper_pin_v1_ConfigurePinRequests_msg; -extern const pb_msgdesc_t wippersnapper_pin_v1_ConfigurePinRequest_msg; -extern const pb_msgdesc_t wippersnapper_pin_v1_PinEvent_msg; -extern const pb_msgdesc_t wippersnapper_pin_v1_ConfigureReferenceVoltage_msg; -extern const pb_msgdesc_t wippersnapper_pin_v1_PinEvents_msg; -extern const pb_msgdesc_t wippersnapper_pin_v1_ConfigurePWMPinRequest_msg; -extern const pb_msgdesc_t wippersnapper_pin_v1_ConfigurePWMPinRequests_msg; -extern const pb_msgdesc_t wippersnapper_pin_v1_PWMPinEvent_msg; -extern const pb_msgdesc_t wippersnapper_pin_v1_PWMPinEvents_msg; - -/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define wippersnapper_pin_v1_ConfigurePinRequests_fields &wippersnapper_pin_v1_ConfigurePinRequests_msg -#define wippersnapper_pin_v1_ConfigurePinRequest_fields &wippersnapper_pin_v1_ConfigurePinRequest_msg -#define wippersnapper_pin_v1_PinEvent_fields &wippersnapper_pin_v1_PinEvent_msg -#define wippersnapper_pin_v1_ConfigureReferenceVoltage_fields &wippersnapper_pin_v1_ConfigureReferenceVoltage_msg -#define wippersnapper_pin_v1_PinEvents_fields &wippersnapper_pin_v1_PinEvents_msg -#define wippersnapper_pin_v1_ConfigurePWMPinRequest_fields &wippersnapper_pin_v1_ConfigurePWMPinRequest_msg -#define wippersnapper_pin_v1_ConfigurePWMPinRequests_fields &wippersnapper_pin_v1_ConfigurePWMPinRequests_msg -#define wippersnapper_pin_v1_PWMPinEvent_fields &wippersnapper_pin_v1_PWMPinEvent_msg -#define wippersnapper_pin_v1_PWMPinEvents_fields &wippersnapper_pin_v1_PWMPinEvents_msg - -/* Maximum encoded size of messages (where known) */ -/* wippersnapper_pin_v1_ConfigurePinRequests_size depends on runtime parameters */ -#define wippersnapper_pin_v1_ConfigurePinRequest_size 26 -#define wippersnapper_pin_v1_PinEvent_size 19 -#define wippersnapper_pin_v1_ConfigureReferenceVoltage_size 5 -/* wippersnapper_pin_v1_PinEvents_size depends on runtime parameters */ -#define wippersnapper_pin_v1_ConfigurePWMPinRequest_size 0 -#define wippersnapper_pin_v1_ConfigurePWMPinRequests_size 0 -#define wippersnapper_pin_v1_PWMPinEvent_size 0 -#define wippersnapper_pin_v1_PWMPinEvents_size 0 - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/wippersnapper/pixels/v1/pixels.pb.c b/src/wippersnapper/pixels/v1/pixels.pb.c deleted file mode 100644 index 1e3532d81..000000000 --- a/src/wippersnapper/pixels/v1/pixels.pb.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#include "wippersnapper/pixels/v1/pixels.pb.h" -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -PB_BIND(wippersnapper_pixels_v1_PixelsCreateRequest, wippersnapper_pixels_v1_PixelsCreateRequest, AUTO) - - -PB_BIND(wippersnapper_pixels_v1_PixelsCreateResponse, wippersnapper_pixels_v1_PixelsCreateResponse, AUTO) - - -PB_BIND(wippersnapper_pixels_v1_PixelsDeleteRequest, wippersnapper_pixels_v1_PixelsDeleteRequest, AUTO) - - -PB_BIND(wippersnapper_pixels_v1_PixelsWriteRequest, wippersnapper_pixels_v1_PixelsWriteRequest, AUTO) - - - - - diff --git a/src/wippersnapper/pixels/v1/pixels.pb.h b/src/wippersnapper/pixels/v1/pixels.pb.h deleted file mode 100644 index 81a309c19..000000000 --- a/src/wippersnapper/pixels/v1/pixels.pb.h +++ /dev/null @@ -1,152 +0,0 @@ -/* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#ifndef PB_WIPPERSNAPPER_PIXELS_V1_WIPPERSNAPPER_PIXELS_V1_PIXELS_PB_H_INCLUDED -#define PB_WIPPERSNAPPER_PIXELS_V1_WIPPERSNAPPER_PIXELS_V1_PIXELS_PB_H_INCLUDED -#include -#include "nanopb/nanopb.pb.h" - -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -/* Enum definitions */ -typedef enum _wippersnapper_pixels_v1_PixelsType { - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_UNSPECIFIED = 0, - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_NEOPIXEL = 1, - wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_DOTSTAR = 2 -} wippersnapper_pixels_v1_PixelsType; - -typedef enum _wippersnapper_pixels_v1_PixelsOrder { - wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_UNSPECIFIED = 0, - wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_GRB = 1, - wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_GRBW = 2, - wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_RGB = 3, - wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_RGBW = 4, - wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_BRG = 5, - wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_RBG = 6, - wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_GBR = 7, - wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_BGR = 8 -} wippersnapper_pixels_v1_PixelsOrder; - -/* Struct definitions */ -typedef struct _wippersnapper_pixels_v1_PixelsCreateRequest { - wippersnapper_pixels_v1_PixelsType pixels_type; - uint32_t pixels_num; - wippersnapper_pixels_v1_PixelsOrder pixels_ordering; - uint32_t pixels_brightness; - char pixels_pin_neopixel[6]; - char pixels_pin_dotstar_data[6]; - char pixels_pin_dotstar_clock[6]; -} wippersnapper_pixels_v1_PixelsCreateRequest; - -typedef struct _wippersnapper_pixels_v1_PixelsCreateResponse { - bool is_success; - char pixels_pin_data[6]; -} wippersnapper_pixels_v1_PixelsCreateResponse; - -typedef struct _wippersnapper_pixels_v1_PixelsDeleteRequest { - wippersnapper_pixels_v1_PixelsType pixels_type; - char pixels_pin_data[6]; -} wippersnapper_pixels_v1_PixelsDeleteRequest; - -typedef struct _wippersnapper_pixels_v1_PixelsWriteRequest { - wippersnapper_pixels_v1_PixelsType pixels_type; - char pixels_pin_data[6]; - uint32_t pixels_color; -} wippersnapper_pixels_v1_PixelsWriteRequest; - - -/* Helper constants for enums */ -#define _wippersnapper_pixels_v1_PixelsType_MIN wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_UNSPECIFIED -#define _wippersnapper_pixels_v1_PixelsType_MAX wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_DOTSTAR -#define _wippersnapper_pixels_v1_PixelsType_ARRAYSIZE ((wippersnapper_pixels_v1_PixelsType)(wippersnapper_pixels_v1_PixelsType_PIXELS_TYPE_DOTSTAR+1)) - -#define _wippersnapper_pixels_v1_PixelsOrder_MIN wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_UNSPECIFIED -#define _wippersnapper_pixels_v1_PixelsOrder_MAX wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_BGR -#define _wippersnapper_pixels_v1_PixelsOrder_ARRAYSIZE ((wippersnapper_pixels_v1_PixelsOrder)(wippersnapper_pixels_v1_PixelsOrder_PIXELS_ORDER_BGR+1)) - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Initializer values for message structs */ -#define wippersnapper_pixels_v1_PixelsCreateRequest_init_default {_wippersnapper_pixels_v1_PixelsType_MIN, 0, _wippersnapper_pixels_v1_PixelsOrder_MIN, 0, "", "", ""} -#define wippersnapper_pixels_v1_PixelsCreateResponse_init_default {0, ""} -#define wippersnapper_pixels_v1_PixelsDeleteRequest_init_default {_wippersnapper_pixels_v1_PixelsType_MIN, ""} -#define wippersnapper_pixels_v1_PixelsWriteRequest_init_default {_wippersnapper_pixels_v1_PixelsType_MIN, "", 0} -#define wippersnapper_pixels_v1_PixelsCreateRequest_init_zero {_wippersnapper_pixels_v1_PixelsType_MIN, 0, _wippersnapper_pixels_v1_PixelsOrder_MIN, 0, "", "", ""} -#define wippersnapper_pixels_v1_PixelsCreateResponse_init_zero {0, ""} -#define wippersnapper_pixels_v1_PixelsDeleteRequest_init_zero {_wippersnapper_pixels_v1_PixelsType_MIN, ""} -#define wippersnapper_pixels_v1_PixelsWriteRequest_init_zero {_wippersnapper_pixels_v1_PixelsType_MIN, "", 0} - -/* Field tags (for use in manual encoding/decoding) */ -#define wippersnapper_pixels_v1_PixelsCreateRequest_pixels_type_tag 1 -#define wippersnapper_pixels_v1_PixelsCreateRequest_pixels_num_tag 2 -#define wippersnapper_pixels_v1_PixelsCreateRequest_pixels_ordering_tag 3 -#define wippersnapper_pixels_v1_PixelsCreateRequest_pixels_brightness_tag 4 -#define wippersnapper_pixels_v1_PixelsCreateRequest_pixels_pin_neopixel_tag 5 -#define wippersnapper_pixels_v1_PixelsCreateRequest_pixels_pin_dotstar_data_tag 6 -#define wippersnapper_pixels_v1_PixelsCreateRequest_pixels_pin_dotstar_clock_tag 7 -#define wippersnapper_pixels_v1_PixelsCreateResponse_is_success_tag 1 -#define wippersnapper_pixels_v1_PixelsCreateResponse_pixels_pin_data_tag 2 -#define wippersnapper_pixels_v1_PixelsDeleteRequest_pixels_type_tag 1 -#define wippersnapper_pixels_v1_PixelsDeleteRequest_pixels_pin_data_tag 2 -#define wippersnapper_pixels_v1_PixelsWriteRequest_pixels_type_tag 1 -#define wippersnapper_pixels_v1_PixelsWriteRequest_pixels_pin_data_tag 2 -#define wippersnapper_pixels_v1_PixelsWriteRequest_pixels_color_tag 3 - -/* Struct field encoding specification for nanopb */ -#define wippersnapper_pixels_v1_PixelsCreateRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, pixels_type, 1) \ -X(a, STATIC, SINGULAR, UINT32, pixels_num, 2) \ -X(a, STATIC, SINGULAR, UENUM, pixels_ordering, 3) \ -X(a, STATIC, SINGULAR, UINT32, pixels_brightness, 4) \ -X(a, STATIC, SINGULAR, STRING, pixels_pin_neopixel, 5) \ -X(a, STATIC, SINGULAR, STRING, pixels_pin_dotstar_data, 6) \ -X(a, STATIC, SINGULAR, STRING, pixels_pin_dotstar_clock, 7) -#define wippersnapper_pixels_v1_PixelsCreateRequest_CALLBACK NULL -#define wippersnapper_pixels_v1_PixelsCreateRequest_DEFAULT NULL - -#define wippersnapper_pixels_v1_PixelsCreateResponse_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, is_success, 1) \ -X(a, STATIC, SINGULAR, STRING, pixels_pin_data, 2) -#define wippersnapper_pixels_v1_PixelsCreateResponse_CALLBACK NULL -#define wippersnapper_pixels_v1_PixelsCreateResponse_DEFAULT NULL - -#define wippersnapper_pixels_v1_PixelsDeleteRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, pixels_type, 1) \ -X(a, STATIC, SINGULAR, STRING, pixels_pin_data, 2) -#define wippersnapper_pixels_v1_PixelsDeleteRequest_CALLBACK NULL -#define wippersnapper_pixels_v1_PixelsDeleteRequest_DEFAULT NULL - -#define wippersnapper_pixels_v1_PixelsWriteRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, pixels_type, 1) \ -X(a, STATIC, SINGULAR, STRING, pixels_pin_data, 2) \ -X(a, STATIC, SINGULAR, UINT32, pixels_color, 3) -#define wippersnapper_pixels_v1_PixelsWriteRequest_CALLBACK NULL -#define wippersnapper_pixels_v1_PixelsWriteRequest_DEFAULT NULL - -extern const pb_msgdesc_t wippersnapper_pixels_v1_PixelsCreateRequest_msg; -extern const pb_msgdesc_t wippersnapper_pixels_v1_PixelsCreateResponse_msg; -extern const pb_msgdesc_t wippersnapper_pixels_v1_PixelsDeleteRequest_msg; -extern const pb_msgdesc_t wippersnapper_pixels_v1_PixelsWriteRequest_msg; - -/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define wippersnapper_pixels_v1_PixelsCreateRequest_fields &wippersnapper_pixels_v1_PixelsCreateRequest_msg -#define wippersnapper_pixels_v1_PixelsCreateResponse_fields &wippersnapper_pixels_v1_PixelsCreateResponse_msg -#define wippersnapper_pixels_v1_PixelsDeleteRequest_fields &wippersnapper_pixels_v1_PixelsDeleteRequest_msg -#define wippersnapper_pixels_v1_PixelsWriteRequest_fields &wippersnapper_pixels_v1_PixelsWriteRequest_msg - -/* Maximum encoded size of messages (where known) */ -#define wippersnapper_pixels_v1_PixelsCreateRequest_size 37 -#define wippersnapper_pixels_v1_PixelsCreateResponse_size 9 -#define wippersnapper_pixels_v1_PixelsDeleteRequest_size 9 -#define wippersnapper_pixels_v1_PixelsWriteRequest_size 15 - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/wippersnapper/pwm/v1/pwm.pb.c b/src/wippersnapper/pwm/v1/pwm.pb.c deleted file mode 100644 index 743548385..000000000 --- a/src/wippersnapper/pwm/v1/pwm.pb.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#include "wippersnapper/pwm/v1/pwm.pb.h" -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -PB_BIND(wippersnapper_pwm_v1_PWMAttachRequest, wippersnapper_pwm_v1_PWMAttachRequest, AUTO) - - -PB_BIND(wippersnapper_pwm_v1_PWMAttachResponse, wippersnapper_pwm_v1_PWMAttachResponse, AUTO) - - -PB_BIND(wippersnapper_pwm_v1_PWMDetachRequest, wippersnapper_pwm_v1_PWMDetachRequest, AUTO) - - -PB_BIND(wippersnapper_pwm_v1_PWMWriteDutyCycleRequest, wippersnapper_pwm_v1_PWMWriteDutyCycleRequest, AUTO) - - -PB_BIND(wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest, wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest, AUTO) - - -PB_BIND(wippersnapper_pwm_v1_PWMWriteFrequencyRequest, wippersnapper_pwm_v1_PWMWriteFrequencyRequest, AUTO) - - - diff --git a/src/wippersnapper/pwm/v1/pwm.pb.h b/src/wippersnapper/pwm/v1/pwm.pb.h deleted file mode 100644 index 5146ed396..000000000 --- a/src/wippersnapper/pwm/v1/pwm.pb.h +++ /dev/null @@ -1,140 +0,0 @@ -/* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#ifndef PB_WIPPERSNAPPER_PWM_V1_WIPPERSNAPPER_PWM_V1_PWM_PB_H_INCLUDED -#define PB_WIPPERSNAPPER_PWM_V1_WIPPERSNAPPER_PWM_V1_PWM_PB_H_INCLUDED -#include -#include "nanopb/nanopb.pb.h" - -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -/* Struct definitions */ -typedef struct _wippersnapper_pwm_v1_PWMAttachRequest { - char pin[6]; - int32_t frequency; - int32_t resolution; -} wippersnapper_pwm_v1_PWMAttachRequest; - -typedef struct _wippersnapper_pwm_v1_PWMAttachResponse { - char pin[6]; - bool did_attach; -} wippersnapper_pwm_v1_PWMAttachResponse; - -typedef struct _wippersnapper_pwm_v1_PWMDetachRequest { - char pin[6]; -} wippersnapper_pwm_v1_PWMDetachRequest; - -typedef struct _wippersnapper_pwm_v1_PWMWriteDutyCycleRequest { - char pin[6]; - int32_t duty_cycle; -} wippersnapper_pwm_v1_PWMWriteDutyCycleRequest; - -typedef struct _wippersnapper_pwm_v1_PWMWriteFrequencyRequest { - char pin[6]; - int32_t frequency; -} wippersnapper_pwm_v1_PWMWriteFrequencyRequest; - -typedef struct _wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest { - pb_size_t write_duty_cycle_req_count; - wippersnapper_pwm_v1_PWMWriteDutyCycleRequest write_duty_cycle_req[4]; -} wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest; - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Initializer values for message structs */ -#define wippersnapper_pwm_v1_PWMAttachRequest_init_default {"", 0, 0} -#define wippersnapper_pwm_v1_PWMAttachResponse_init_default {"", 0} -#define wippersnapper_pwm_v1_PWMDetachRequest_init_default {""} -#define wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_init_default {"", 0} -#define wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest_init_default {0, {wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_init_default, wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_init_default, wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_init_default, wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_init_default}} -#define wippersnapper_pwm_v1_PWMWriteFrequencyRequest_init_default {"", 0} -#define wippersnapper_pwm_v1_PWMAttachRequest_init_zero {"", 0, 0} -#define wippersnapper_pwm_v1_PWMAttachResponse_init_zero {"", 0} -#define wippersnapper_pwm_v1_PWMDetachRequest_init_zero {""} -#define wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_init_zero {"", 0} -#define wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest_init_zero {0, {wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_init_zero, wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_init_zero, wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_init_zero, wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_init_zero}} -#define wippersnapper_pwm_v1_PWMWriteFrequencyRequest_init_zero {"", 0} - -/* Field tags (for use in manual encoding/decoding) */ -#define wippersnapper_pwm_v1_PWMAttachRequest_pin_tag 1 -#define wippersnapper_pwm_v1_PWMAttachRequest_frequency_tag 2 -#define wippersnapper_pwm_v1_PWMAttachRequest_resolution_tag 3 -#define wippersnapper_pwm_v1_PWMAttachResponse_pin_tag 1 -#define wippersnapper_pwm_v1_PWMAttachResponse_did_attach_tag 2 -#define wippersnapper_pwm_v1_PWMDetachRequest_pin_tag 1 -#define wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_pin_tag 1 -#define wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_duty_cycle_tag 2 -#define wippersnapper_pwm_v1_PWMWriteFrequencyRequest_pin_tag 1 -#define wippersnapper_pwm_v1_PWMWriteFrequencyRequest_frequency_tag 2 -#define wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest_write_duty_cycle_req_tag 1 - -/* Struct field encoding specification for nanopb */ -#define wippersnapper_pwm_v1_PWMAttachRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, pin, 1) \ -X(a, STATIC, SINGULAR, INT32, frequency, 2) \ -X(a, STATIC, SINGULAR, INT32, resolution, 3) -#define wippersnapper_pwm_v1_PWMAttachRequest_CALLBACK NULL -#define wippersnapper_pwm_v1_PWMAttachRequest_DEFAULT NULL - -#define wippersnapper_pwm_v1_PWMAttachResponse_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, pin, 1) \ -X(a, STATIC, SINGULAR, BOOL, did_attach, 2) -#define wippersnapper_pwm_v1_PWMAttachResponse_CALLBACK NULL -#define wippersnapper_pwm_v1_PWMAttachResponse_DEFAULT NULL - -#define wippersnapper_pwm_v1_PWMDetachRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, pin, 1) -#define wippersnapper_pwm_v1_PWMDetachRequest_CALLBACK NULL -#define wippersnapper_pwm_v1_PWMDetachRequest_DEFAULT NULL - -#define wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, pin, 1) \ -X(a, STATIC, SINGULAR, INT32, duty_cycle, 2) -#define wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_CALLBACK NULL -#define wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_DEFAULT NULL - -#define wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest_FIELDLIST(X, a) \ -X(a, STATIC, REPEATED, MESSAGE, write_duty_cycle_req, 1) -#define wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest_CALLBACK NULL -#define wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest_DEFAULT NULL -#define wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest_write_duty_cycle_req_MSGTYPE wippersnapper_pwm_v1_PWMWriteDutyCycleRequest - -#define wippersnapper_pwm_v1_PWMWriteFrequencyRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, pin, 1) \ -X(a, STATIC, SINGULAR, INT32, frequency, 2) -#define wippersnapper_pwm_v1_PWMWriteFrequencyRequest_CALLBACK NULL -#define wippersnapper_pwm_v1_PWMWriteFrequencyRequest_DEFAULT NULL - -extern const pb_msgdesc_t wippersnapper_pwm_v1_PWMAttachRequest_msg; -extern const pb_msgdesc_t wippersnapper_pwm_v1_PWMAttachResponse_msg; -extern const pb_msgdesc_t wippersnapper_pwm_v1_PWMDetachRequest_msg; -extern const pb_msgdesc_t wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_msg; -extern const pb_msgdesc_t wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest_msg; -extern const pb_msgdesc_t wippersnapper_pwm_v1_PWMWriteFrequencyRequest_msg; - -/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define wippersnapper_pwm_v1_PWMAttachRequest_fields &wippersnapper_pwm_v1_PWMAttachRequest_msg -#define wippersnapper_pwm_v1_PWMAttachResponse_fields &wippersnapper_pwm_v1_PWMAttachResponse_msg -#define wippersnapper_pwm_v1_PWMDetachRequest_fields &wippersnapper_pwm_v1_PWMDetachRequest_msg -#define wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_fields &wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_msg -#define wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest_fields &wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest_msg -#define wippersnapper_pwm_v1_PWMWriteFrequencyRequest_fields &wippersnapper_pwm_v1_PWMWriteFrequencyRequest_msg - -/* Maximum encoded size of messages (where known) */ -#define wippersnapper_pwm_v1_PWMAttachRequest_size 29 -#define wippersnapper_pwm_v1_PWMAttachResponse_size 9 -#define wippersnapper_pwm_v1_PWMDetachRequest_size 7 -#define wippersnapper_pwm_v1_PWMWriteDutyCycleRequest_size 18 -#define wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest_size 80 -#define wippersnapper_pwm_v1_PWMWriteFrequencyRequest_size 18 - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/wippersnapper/servo/v1/servo.pb.c b/src/wippersnapper/servo/v1/servo.pb.c deleted file mode 100644 index e96dc47b1..000000000 --- a/src/wippersnapper/servo/v1/servo.pb.c +++ /dev/null @@ -1,21 +0,0 @@ -/* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#include "wippersnapper/servo/v1/servo.pb.h" -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -PB_BIND(wippersnapper_servo_v1_ServoAttachRequest, wippersnapper_servo_v1_ServoAttachRequest, AUTO) - - -PB_BIND(wippersnapper_servo_v1_ServoAttachResponse, wippersnapper_servo_v1_ServoAttachResponse, AUTO) - - -PB_BIND(wippersnapper_servo_v1_ServoDetachRequest, wippersnapper_servo_v1_ServoDetachRequest, AUTO) - - -PB_BIND(wippersnapper_servo_v1_ServoWriteRequest, wippersnapper_servo_v1_ServoWriteRequest, AUTO) - - - diff --git a/src/wippersnapper/servo/v1/servo.pb.h b/src/wippersnapper/servo/v1/servo.pb.h deleted file mode 100644 index ee5fdeb43..000000000 --- a/src/wippersnapper/servo/v1/servo.pb.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#ifndef PB_WIPPERSNAPPER_SERVO_V1_WIPPERSNAPPER_SERVO_V1_SERVO_PB_H_INCLUDED -#define PB_WIPPERSNAPPER_SERVO_V1_WIPPERSNAPPER_SERVO_V1_SERVO_PB_H_INCLUDED -#include -#include "nanopb/nanopb.pb.h" - -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -/* Struct definitions */ -typedef struct _wippersnapper_servo_v1_ServoAttachRequest { - char servo_pin[6]; - int32_t servo_freq; - int32_t min_pulse_width; - int32_t max_pulse_width; -} wippersnapper_servo_v1_ServoAttachRequest; - -typedef struct _wippersnapper_servo_v1_ServoAttachResponse { - bool attach_success; - char servo_pin[6]; -} wippersnapper_servo_v1_ServoAttachResponse; - -typedef struct _wippersnapper_servo_v1_ServoDetachRequest { - char servo_pin[5]; -} wippersnapper_servo_v1_ServoDetachRequest; - -typedef struct _wippersnapper_servo_v1_ServoWriteRequest { - char servo_pin[5]; - int32_t pulse_width; -} wippersnapper_servo_v1_ServoWriteRequest; - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Initializer values for message structs */ -#define wippersnapper_servo_v1_ServoAttachRequest_init_default {"", 0, 0, 0} -#define wippersnapper_servo_v1_ServoAttachResponse_init_default {0, ""} -#define wippersnapper_servo_v1_ServoDetachRequest_init_default {""} -#define wippersnapper_servo_v1_ServoWriteRequest_init_default {"", 0} -#define wippersnapper_servo_v1_ServoAttachRequest_init_zero {"", 0, 0, 0} -#define wippersnapper_servo_v1_ServoAttachResponse_init_zero {0, ""} -#define wippersnapper_servo_v1_ServoDetachRequest_init_zero {""} -#define wippersnapper_servo_v1_ServoWriteRequest_init_zero {"", 0} - -/* Field tags (for use in manual encoding/decoding) */ -#define wippersnapper_servo_v1_ServoAttachRequest_servo_pin_tag 1 -#define wippersnapper_servo_v1_ServoAttachRequest_servo_freq_tag 2 -#define wippersnapper_servo_v1_ServoAttachRequest_min_pulse_width_tag 3 -#define wippersnapper_servo_v1_ServoAttachRequest_max_pulse_width_tag 4 -#define wippersnapper_servo_v1_ServoAttachResponse_attach_success_tag 1 -#define wippersnapper_servo_v1_ServoAttachResponse_servo_pin_tag 2 -#define wippersnapper_servo_v1_ServoDetachRequest_servo_pin_tag 1 -#define wippersnapper_servo_v1_ServoWriteRequest_servo_pin_tag 1 -#define wippersnapper_servo_v1_ServoWriteRequest_pulse_width_tag 2 - -/* Struct field encoding specification for nanopb */ -#define wippersnapper_servo_v1_ServoAttachRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, servo_pin, 1) \ -X(a, STATIC, SINGULAR, INT32, servo_freq, 2) \ -X(a, STATIC, SINGULAR, INT32, min_pulse_width, 3) \ -X(a, STATIC, SINGULAR, INT32, max_pulse_width, 4) -#define wippersnapper_servo_v1_ServoAttachRequest_CALLBACK NULL -#define wippersnapper_servo_v1_ServoAttachRequest_DEFAULT NULL - -#define wippersnapper_servo_v1_ServoAttachResponse_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, BOOL, attach_success, 1) \ -X(a, STATIC, SINGULAR, STRING, servo_pin, 2) -#define wippersnapper_servo_v1_ServoAttachResponse_CALLBACK NULL -#define wippersnapper_servo_v1_ServoAttachResponse_DEFAULT NULL - -#define wippersnapper_servo_v1_ServoDetachRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, servo_pin, 1) -#define wippersnapper_servo_v1_ServoDetachRequest_CALLBACK NULL -#define wippersnapper_servo_v1_ServoDetachRequest_DEFAULT NULL - -#define wippersnapper_servo_v1_ServoWriteRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, servo_pin, 1) \ -X(a, STATIC, SINGULAR, INT32, pulse_width, 2) -#define wippersnapper_servo_v1_ServoWriteRequest_CALLBACK NULL -#define wippersnapper_servo_v1_ServoWriteRequest_DEFAULT NULL - -extern const pb_msgdesc_t wippersnapper_servo_v1_ServoAttachRequest_msg; -extern const pb_msgdesc_t wippersnapper_servo_v1_ServoAttachResponse_msg; -extern const pb_msgdesc_t wippersnapper_servo_v1_ServoDetachRequest_msg; -extern const pb_msgdesc_t wippersnapper_servo_v1_ServoWriteRequest_msg; - -/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define wippersnapper_servo_v1_ServoAttachRequest_fields &wippersnapper_servo_v1_ServoAttachRequest_msg -#define wippersnapper_servo_v1_ServoAttachResponse_fields &wippersnapper_servo_v1_ServoAttachResponse_msg -#define wippersnapper_servo_v1_ServoDetachRequest_fields &wippersnapper_servo_v1_ServoDetachRequest_msg -#define wippersnapper_servo_v1_ServoWriteRequest_fields &wippersnapper_servo_v1_ServoWriteRequest_msg - -/* Maximum encoded size of messages (where known) */ -#define wippersnapper_servo_v1_ServoAttachRequest_size 40 -#define wippersnapper_servo_v1_ServoAttachResponse_size 9 -#define wippersnapper_servo_v1_ServoDetachRequest_size 6 -#define wippersnapper_servo_v1_ServoWriteRequest_size 17 - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/wippersnapper/signal/v1/signal.pb.c b/src/wippersnapper/signal/v1/signal.pb.c deleted file mode 100644 index e793af832..000000000 --- a/src/wippersnapper/signal/v1/signal.pb.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#include "wippersnapper/signal/v1/signal.pb.h" -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -PB_BIND(wippersnapper_signal_v1_UARTRequest, wippersnapper_signal_v1_UARTRequest, AUTO) - - -PB_BIND(wippersnapper_signal_v1_UARTResponse, wippersnapper_signal_v1_UARTResponse, AUTO) - - -PB_BIND(wippersnapper_signal_v1_Ds18x20Request, wippersnapper_signal_v1_Ds18x20Request, AUTO) - - -PB_BIND(wippersnapper_signal_v1_Ds18x20Response, wippersnapper_signal_v1_Ds18x20Response, AUTO) - - -PB_BIND(wippersnapper_signal_v1_I2CRequest, wippersnapper_signal_v1_I2CRequest, AUTO) - - -PB_BIND(wippersnapper_signal_v1_I2CResponse, wippersnapper_signal_v1_I2CResponse, 2) - - -PB_BIND(wippersnapper_signal_v1_ServoRequest, wippersnapper_signal_v1_ServoRequest, AUTO) - - -PB_BIND(wippersnapper_signal_v1_ServoResponse, wippersnapper_signal_v1_ServoResponse, AUTO) - - -PB_BIND(wippersnapper_signal_v1_PixelsRequest, wippersnapper_signal_v1_PixelsRequest, AUTO) - - -PB_BIND(wippersnapper_signal_v1_PixelsResponse, wippersnapper_signal_v1_PixelsResponse, AUTO) - - -PB_BIND(wippersnapper_signal_v1_CreateSignalRequest, wippersnapper_signal_v1_CreateSignalRequest, AUTO) - - -PB_BIND(wippersnapper_signal_v1_SignalResponse, wippersnapper_signal_v1_SignalResponse, AUTO) - - -PB_BIND(wippersnapper_signal_v1_PWMRequest, wippersnapper_signal_v1_PWMRequest, AUTO) - - -PB_BIND(wippersnapper_signal_v1_PWMResponse, wippersnapper_signal_v1_PWMResponse, AUTO) - - - diff --git a/src/wippersnapper/signal/v1/signal.pb.h b/src/wippersnapper/signal/v1/signal.pb.h deleted file mode 100644 index 328fd3757..000000000 --- a/src/wippersnapper/signal/v1/signal.pb.h +++ /dev/null @@ -1,416 +0,0 @@ -/* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#ifndef PB_WIPPERSNAPPER_SIGNAL_V1_WIPPERSNAPPER_SIGNAL_V1_SIGNAL_PB_H_INCLUDED -#define PB_WIPPERSNAPPER_SIGNAL_V1_WIPPERSNAPPER_SIGNAL_V1_SIGNAL_PB_H_INCLUDED -#include -#include "nanopb/nanopb.pb.h" -#include "wippersnapper/pin/v1/pin.pb.h" -#include "wippersnapper/i2c/v1/i2c.pb.h" -#include "wippersnapper/servo/v1/servo.pb.h" -#include "wippersnapper/pwm/v1/pwm.pb.h" -#include "wippersnapper/ds18x20/v1/ds18x20.pb.h" -#include "wippersnapper/pixels/v1/pixels.pb.h" -#include "wippersnapper/uart/v1/uart.pb.h" - -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -/* Struct definitions */ -typedef struct _wippersnapper_signal_v1_CreateSignalRequest { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_pin_v1_ConfigurePinRequests pin_configs; - wippersnapper_pin_v1_PinEvents pin_events; - wippersnapper_pin_v1_PinEvent pin_event; - } payload; -} wippersnapper_signal_v1_CreateSignalRequest; - -typedef struct _wippersnapper_signal_v1_Ds18x20Request { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_ds18x20_v1_Ds18x20InitRequest req_ds18x20_init; - wippersnapper_ds18x20_v1_Ds18x20DeInitRequest req_ds18x20_deinit; - } payload; -} wippersnapper_signal_v1_Ds18x20Request; - -typedef struct _wippersnapper_signal_v1_Ds18x20Response { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_ds18x20_v1_Ds18x20InitResponse resp_ds18x20_init; - wippersnapper_ds18x20_v1_Ds18x20DeviceEvent resp_ds18x20_event; - } payload; -} wippersnapper_signal_v1_Ds18x20Response; - -typedef struct _wippersnapper_signal_v1_I2CRequest { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_i2c_v1_I2CBusScanRequest req_i2c_scan; - wippersnapper_i2c_v1_I2CBusSetFrequency req_i2c_set_freq; - wippersnapper_i2c_v1_I2CDeviceInitRequest req_i2c_device_init; - wippersnapper_i2c_v1_I2CDeviceDeinitRequest req_i2c_device_deinit; - wippersnapper_i2c_v1_I2CDeviceUpdateRequest req_i2c_device_update; - wippersnapper_i2c_v1_I2CDeviceInitRequests req_i2c_device_init_requests; - } payload; -} wippersnapper_signal_v1_I2CRequest; - -typedef struct _wippersnapper_signal_v1_I2CResponse { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_i2c_v1_I2CBusScanResponse resp_i2c_scan; - wippersnapper_i2c_v1_I2CDeviceInitResponse resp_i2c_device_init; - wippersnapper_i2c_v1_I2CDeviceDeinitResponse resp_i2c_device_deinit; - wippersnapper_i2c_v1_I2CDeviceUpdateResponse resp_i2c_device_update; - wippersnapper_i2c_v1_I2CDeviceEvent resp_i2c_device_event; - } payload; -} wippersnapper_signal_v1_I2CResponse; - -typedef struct _wippersnapper_signal_v1_PWMRequest { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_pwm_v1_PWMAttachRequest attach_request; - wippersnapper_pwm_v1_PWMDetachRequest detach_request; - wippersnapper_pwm_v1_PWMWriteDutyCycleRequest write_duty_request; - wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest write_duty_multi_request; - wippersnapper_pwm_v1_PWMWriteFrequencyRequest write_freq_request; - } payload; -} wippersnapper_signal_v1_PWMRequest; - -typedef struct _wippersnapper_signal_v1_PWMResponse { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_pwm_v1_PWMAttachResponse attach_response; - } payload; -} wippersnapper_signal_v1_PWMResponse; - -typedef struct _wippersnapper_signal_v1_PixelsRequest { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_pixels_v1_PixelsCreateRequest req_pixels_create; - wippersnapper_pixels_v1_PixelsDeleteRequest req_pixels_delete; - wippersnapper_pixels_v1_PixelsWriteRequest req_pixels_write; - } payload; -} wippersnapper_signal_v1_PixelsRequest; - -typedef struct _wippersnapper_signal_v1_PixelsResponse { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_pixels_v1_PixelsCreateResponse resp_pixels_create; - } payload; -} wippersnapper_signal_v1_PixelsResponse; - -typedef struct _wippersnapper_signal_v1_ServoRequest { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_servo_v1_ServoAttachRequest servo_attach; - wippersnapper_servo_v1_ServoDetachRequest servo_detach; - wippersnapper_servo_v1_ServoWriteRequest servo_write; - } payload; -} wippersnapper_signal_v1_ServoRequest; - -typedef struct _wippersnapper_signal_v1_ServoResponse { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_servo_v1_ServoAttachResponse servo_attach_resp; - } payload; -} wippersnapper_signal_v1_ServoResponse; - -typedef struct _wippersnapper_signal_v1_SignalResponse { - pb_size_t which_payload; - union { - bool configuration_complete; - } payload; -} wippersnapper_signal_v1_SignalResponse; - -typedef struct _wippersnapper_signal_v1_UARTRequest { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_uart_v1_UARTDeviceAttachRequest req_uart_device_attach; - wippersnapper_uart_v1_UARTDeviceDetachRequest req_uart_device_detach; - } payload; -} wippersnapper_signal_v1_UARTRequest; - -typedef struct _wippersnapper_signal_v1_UARTResponse { - pb_callback_t cb_payload; - pb_size_t which_payload; - union { - wippersnapper_uart_v1_UARTDeviceAttachResponse resp_uart_device_attach; - wippersnapper_uart_v1_UARTDeviceEvent resp_uart_device_event; - } payload; -} wippersnapper_signal_v1_UARTResponse; - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Initializer values for message structs */ -#define wippersnapper_signal_v1_UARTRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_uart_v1_UARTDeviceAttachRequest_init_default}} -#define wippersnapper_signal_v1_UARTResponse_init_default {{{NULL}, NULL}, 0, {wippersnapper_uart_v1_UARTDeviceAttachResponse_init_default}} -#define wippersnapper_signal_v1_Ds18x20Request_init_default {{{NULL}, NULL}, 0, {wippersnapper_ds18x20_v1_Ds18x20InitRequest_init_default}} -#define wippersnapper_signal_v1_Ds18x20Response_init_default {{{NULL}, NULL}, 0, {wippersnapper_ds18x20_v1_Ds18x20InitResponse_init_default}} -#define wippersnapper_signal_v1_I2CRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_i2c_v1_I2CBusScanRequest_init_default}} -#define wippersnapper_signal_v1_I2CResponse_init_default {{{NULL}, NULL}, 0, {wippersnapper_i2c_v1_I2CBusScanResponse_init_default}} -#define wippersnapper_signal_v1_ServoRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_servo_v1_ServoAttachRequest_init_default}} -#define wippersnapper_signal_v1_ServoResponse_init_default {{{NULL}, NULL}, 0, {wippersnapper_servo_v1_ServoAttachResponse_init_default}} -#define wippersnapper_signal_v1_PixelsRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_pixels_v1_PixelsCreateRequest_init_default}} -#define wippersnapper_signal_v1_PixelsResponse_init_default {{{NULL}, NULL}, 0, {wippersnapper_pixels_v1_PixelsCreateResponse_init_default}} -#define wippersnapper_signal_v1_CreateSignalRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_pin_v1_ConfigurePinRequests_init_default}} -#define wippersnapper_signal_v1_SignalResponse_init_default {0, {0}} -#define wippersnapper_signal_v1_PWMRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_pwm_v1_PWMAttachRequest_init_default}} -#define wippersnapper_signal_v1_PWMResponse_init_default {{{NULL}, NULL}, 0, {wippersnapper_pwm_v1_PWMAttachResponse_init_default}} -#define wippersnapper_signal_v1_UARTRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_uart_v1_UARTDeviceAttachRequest_init_zero}} -#define wippersnapper_signal_v1_UARTResponse_init_zero {{{NULL}, NULL}, 0, {wippersnapper_uart_v1_UARTDeviceAttachResponse_init_zero}} -#define wippersnapper_signal_v1_Ds18x20Request_init_zero {{{NULL}, NULL}, 0, {wippersnapper_ds18x20_v1_Ds18x20InitRequest_init_zero}} -#define wippersnapper_signal_v1_Ds18x20Response_init_zero {{{NULL}, NULL}, 0, {wippersnapper_ds18x20_v1_Ds18x20InitResponse_init_zero}} -#define wippersnapper_signal_v1_I2CRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_i2c_v1_I2CBusScanRequest_init_zero}} -#define wippersnapper_signal_v1_I2CResponse_init_zero {{{NULL}, NULL}, 0, {wippersnapper_i2c_v1_I2CBusScanResponse_init_zero}} -#define wippersnapper_signal_v1_ServoRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_servo_v1_ServoAttachRequest_init_zero}} -#define wippersnapper_signal_v1_ServoResponse_init_zero {{{NULL}, NULL}, 0, {wippersnapper_servo_v1_ServoAttachResponse_init_zero}} -#define wippersnapper_signal_v1_PixelsRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_pixels_v1_PixelsCreateRequest_init_zero}} -#define wippersnapper_signal_v1_PixelsResponse_init_zero {{{NULL}, NULL}, 0, {wippersnapper_pixels_v1_PixelsCreateResponse_init_zero}} -#define wippersnapper_signal_v1_CreateSignalRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_pin_v1_ConfigurePinRequests_init_zero}} -#define wippersnapper_signal_v1_SignalResponse_init_zero {0, {0}} -#define wippersnapper_signal_v1_PWMRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_pwm_v1_PWMAttachRequest_init_zero}} -#define wippersnapper_signal_v1_PWMResponse_init_zero {{{NULL}, NULL}, 0, {wippersnapper_pwm_v1_PWMAttachResponse_init_zero}} - -/* Field tags (for use in manual encoding/decoding) */ -#define wippersnapper_signal_v1_CreateSignalRequest_pin_configs_tag 6 -#define wippersnapper_signal_v1_CreateSignalRequest_pin_events_tag 7 -#define wippersnapper_signal_v1_CreateSignalRequest_pin_event_tag 15 -#define wippersnapper_signal_v1_Ds18x20Request_req_ds18x20_init_tag 1 -#define wippersnapper_signal_v1_Ds18x20Request_req_ds18x20_deinit_tag 2 -#define wippersnapper_signal_v1_Ds18x20Response_resp_ds18x20_init_tag 1 -#define wippersnapper_signal_v1_Ds18x20Response_resp_ds18x20_event_tag 2 -#define wippersnapper_signal_v1_I2CRequest_req_i2c_scan_tag 2 -#define wippersnapper_signal_v1_I2CRequest_req_i2c_set_freq_tag 3 -#define wippersnapper_signal_v1_I2CRequest_req_i2c_device_init_tag 4 -#define wippersnapper_signal_v1_I2CRequest_req_i2c_device_deinit_tag 5 -#define wippersnapper_signal_v1_I2CRequest_req_i2c_device_update_tag 6 -#define wippersnapper_signal_v1_I2CRequest_req_i2c_device_init_requests_tag 7 -#define wippersnapper_signal_v1_I2CResponse_resp_i2c_scan_tag 2 -#define wippersnapper_signal_v1_I2CResponse_resp_i2c_device_init_tag 3 -#define wippersnapper_signal_v1_I2CResponse_resp_i2c_device_deinit_tag 4 -#define wippersnapper_signal_v1_I2CResponse_resp_i2c_device_update_tag 5 -#define wippersnapper_signal_v1_I2CResponse_resp_i2c_device_event_tag 6 -#define wippersnapper_signal_v1_PWMRequest_attach_request_tag 1 -#define wippersnapper_signal_v1_PWMRequest_detach_request_tag 2 -#define wippersnapper_signal_v1_PWMRequest_write_duty_request_tag 3 -#define wippersnapper_signal_v1_PWMRequest_write_duty_multi_request_tag 4 -#define wippersnapper_signal_v1_PWMRequest_write_freq_request_tag 5 -#define wippersnapper_signal_v1_PWMResponse_attach_response_tag 1 -#define wippersnapper_signal_v1_PixelsRequest_req_pixels_create_tag 1 -#define wippersnapper_signal_v1_PixelsRequest_req_pixels_delete_tag 2 -#define wippersnapper_signal_v1_PixelsRequest_req_pixels_write_tag 3 -#define wippersnapper_signal_v1_PixelsResponse_resp_pixels_create_tag 1 -#define wippersnapper_signal_v1_ServoRequest_servo_attach_tag 1 -#define wippersnapper_signal_v1_ServoRequest_servo_detach_tag 2 -#define wippersnapper_signal_v1_ServoRequest_servo_write_tag 3 -#define wippersnapper_signal_v1_ServoResponse_servo_attach_resp_tag 1 -#define wippersnapper_signal_v1_SignalResponse_configuration_complete_tag 1 -#define wippersnapper_signal_v1_UARTRequest_req_uart_device_attach_tag 1 -#define wippersnapper_signal_v1_UARTRequest_req_uart_device_detach_tag 2 -#define wippersnapper_signal_v1_UARTResponse_resp_uart_device_attach_tag 1 -#define wippersnapper_signal_v1_UARTResponse_resp_uart_device_event_tag 2 - -/* Struct field encoding specification for nanopb */ -#define wippersnapper_signal_v1_UARTRequest_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_uart_device_attach,payload.req_uart_device_attach), 1) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_uart_device_detach,payload.req_uart_device_detach), 2) -#define wippersnapper_signal_v1_UARTRequest_CALLBACK NULL -#define wippersnapper_signal_v1_UARTRequest_DEFAULT NULL -#define wippersnapper_signal_v1_UARTRequest_payload_req_uart_device_attach_MSGTYPE wippersnapper_uart_v1_UARTDeviceAttachRequest -#define wippersnapper_signal_v1_UARTRequest_payload_req_uart_device_detach_MSGTYPE wippersnapper_uart_v1_UARTDeviceDetachRequest - -#define wippersnapper_signal_v1_UARTResponse_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,resp_uart_device_attach,payload.resp_uart_device_attach), 1) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,resp_uart_device_event,payload.resp_uart_device_event), 2) -#define wippersnapper_signal_v1_UARTResponse_CALLBACK NULL -#define wippersnapper_signal_v1_UARTResponse_DEFAULT NULL -#define wippersnapper_signal_v1_UARTResponse_payload_resp_uart_device_attach_MSGTYPE wippersnapper_uart_v1_UARTDeviceAttachResponse -#define wippersnapper_signal_v1_UARTResponse_payload_resp_uart_device_event_MSGTYPE wippersnapper_uart_v1_UARTDeviceEvent - -#define wippersnapper_signal_v1_Ds18x20Request_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_ds18x20_init,payload.req_ds18x20_init), 1) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_ds18x20_deinit,payload.req_ds18x20_deinit), 2) -#define wippersnapper_signal_v1_Ds18x20Request_CALLBACK NULL -#define wippersnapper_signal_v1_Ds18x20Request_DEFAULT NULL -#define wippersnapper_signal_v1_Ds18x20Request_payload_req_ds18x20_init_MSGTYPE wippersnapper_ds18x20_v1_Ds18x20InitRequest -#define wippersnapper_signal_v1_Ds18x20Request_payload_req_ds18x20_deinit_MSGTYPE wippersnapper_ds18x20_v1_Ds18x20DeInitRequest - -#define wippersnapper_signal_v1_Ds18x20Response_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,resp_ds18x20_init,payload.resp_ds18x20_init), 1) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,resp_ds18x20_event,payload.resp_ds18x20_event), 2) -#define wippersnapper_signal_v1_Ds18x20Response_CALLBACK NULL -#define wippersnapper_signal_v1_Ds18x20Response_DEFAULT NULL -#define wippersnapper_signal_v1_Ds18x20Response_payload_resp_ds18x20_init_MSGTYPE wippersnapper_ds18x20_v1_Ds18x20InitResponse -#define wippersnapper_signal_v1_Ds18x20Response_payload_resp_ds18x20_event_MSGTYPE wippersnapper_ds18x20_v1_Ds18x20DeviceEvent - -#define wippersnapper_signal_v1_I2CRequest_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_i2c_scan,payload.req_i2c_scan), 2) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_i2c_set_freq,payload.req_i2c_set_freq), 3) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_i2c_device_init,payload.req_i2c_device_init), 4) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_i2c_device_deinit,payload.req_i2c_device_deinit), 5) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_i2c_device_update,payload.req_i2c_device_update), 6) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_i2c_device_init_requests,payload.req_i2c_device_init_requests), 7) -#define wippersnapper_signal_v1_I2CRequest_CALLBACK NULL -#define wippersnapper_signal_v1_I2CRequest_DEFAULT NULL -#define wippersnapper_signal_v1_I2CRequest_payload_req_i2c_scan_MSGTYPE wippersnapper_i2c_v1_I2CBusScanRequest -#define wippersnapper_signal_v1_I2CRequest_payload_req_i2c_set_freq_MSGTYPE wippersnapper_i2c_v1_I2CBusSetFrequency -#define wippersnapper_signal_v1_I2CRequest_payload_req_i2c_device_init_MSGTYPE wippersnapper_i2c_v1_I2CDeviceInitRequest -#define wippersnapper_signal_v1_I2CRequest_payload_req_i2c_device_deinit_MSGTYPE wippersnapper_i2c_v1_I2CDeviceDeinitRequest -#define wippersnapper_signal_v1_I2CRequest_payload_req_i2c_device_update_MSGTYPE wippersnapper_i2c_v1_I2CDeviceUpdateRequest -#define wippersnapper_signal_v1_I2CRequest_payload_req_i2c_device_init_requests_MSGTYPE wippersnapper_i2c_v1_I2CDeviceInitRequests - -#define wippersnapper_signal_v1_I2CResponse_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,resp_i2c_scan,payload.resp_i2c_scan), 2) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,resp_i2c_device_init,payload.resp_i2c_device_init), 3) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,resp_i2c_device_deinit,payload.resp_i2c_device_deinit), 4) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,resp_i2c_device_update,payload.resp_i2c_device_update), 5) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,resp_i2c_device_event,payload.resp_i2c_device_event), 6) -#define wippersnapper_signal_v1_I2CResponse_CALLBACK NULL -#define wippersnapper_signal_v1_I2CResponse_DEFAULT NULL -#define wippersnapper_signal_v1_I2CResponse_payload_resp_i2c_scan_MSGTYPE wippersnapper_i2c_v1_I2CBusScanResponse -#define wippersnapper_signal_v1_I2CResponse_payload_resp_i2c_device_init_MSGTYPE wippersnapper_i2c_v1_I2CDeviceInitResponse -#define wippersnapper_signal_v1_I2CResponse_payload_resp_i2c_device_deinit_MSGTYPE wippersnapper_i2c_v1_I2CDeviceDeinitResponse -#define wippersnapper_signal_v1_I2CResponse_payload_resp_i2c_device_update_MSGTYPE wippersnapper_i2c_v1_I2CDeviceUpdateResponse -#define wippersnapper_signal_v1_I2CResponse_payload_resp_i2c_device_event_MSGTYPE wippersnapper_i2c_v1_I2CDeviceEvent - -#define wippersnapper_signal_v1_ServoRequest_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,servo_attach,payload.servo_attach), 1) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,servo_detach,payload.servo_detach), 2) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,servo_write,payload.servo_write), 3) -#define wippersnapper_signal_v1_ServoRequest_CALLBACK NULL -#define wippersnapper_signal_v1_ServoRequest_DEFAULT NULL -#define wippersnapper_signal_v1_ServoRequest_payload_servo_attach_MSGTYPE wippersnapper_servo_v1_ServoAttachRequest -#define wippersnapper_signal_v1_ServoRequest_payload_servo_detach_MSGTYPE wippersnapper_servo_v1_ServoDetachRequest -#define wippersnapper_signal_v1_ServoRequest_payload_servo_write_MSGTYPE wippersnapper_servo_v1_ServoWriteRequest - -#define wippersnapper_signal_v1_ServoResponse_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,servo_attach_resp,payload.servo_attach_resp), 1) -#define wippersnapper_signal_v1_ServoResponse_CALLBACK NULL -#define wippersnapper_signal_v1_ServoResponse_DEFAULT NULL -#define wippersnapper_signal_v1_ServoResponse_payload_servo_attach_resp_MSGTYPE wippersnapper_servo_v1_ServoAttachResponse - -#define wippersnapper_signal_v1_PixelsRequest_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_pixels_create,payload.req_pixels_create), 1) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_pixels_delete,payload.req_pixels_delete), 2) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,req_pixels_write,payload.req_pixels_write), 3) -#define wippersnapper_signal_v1_PixelsRequest_CALLBACK NULL -#define wippersnapper_signal_v1_PixelsRequest_DEFAULT NULL -#define wippersnapper_signal_v1_PixelsRequest_payload_req_pixels_create_MSGTYPE wippersnapper_pixels_v1_PixelsCreateRequest -#define wippersnapper_signal_v1_PixelsRequest_payload_req_pixels_delete_MSGTYPE wippersnapper_pixels_v1_PixelsDeleteRequest -#define wippersnapper_signal_v1_PixelsRequest_payload_req_pixels_write_MSGTYPE wippersnapper_pixels_v1_PixelsWriteRequest - -#define wippersnapper_signal_v1_PixelsResponse_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,resp_pixels_create,payload.resp_pixels_create), 1) -#define wippersnapper_signal_v1_PixelsResponse_CALLBACK NULL -#define wippersnapper_signal_v1_PixelsResponse_DEFAULT NULL -#define wippersnapper_signal_v1_PixelsResponse_payload_resp_pixels_create_MSGTYPE wippersnapper_pixels_v1_PixelsCreateResponse - -#define wippersnapper_signal_v1_CreateSignalRequest_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,pin_configs,payload.pin_configs), 6) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,pin_events,payload.pin_events), 7) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,pin_event,payload.pin_event), 15) -#define wippersnapper_signal_v1_CreateSignalRequest_CALLBACK NULL -#define wippersnapper_signal_v1_CreateSignalRequest_DEFAULT NULL -#define wippersnapper_signal_v1_CreateSignalRequest_payload_pin_configs_MSGTYPE wippersnapper_pin_v1_ConfigurePinRequests -#define wippersnapper_signal_v1_CreateSignalRequest_payload_pin_events_MSGTYPE wippersnapper_pin_v1_PinEvents -#define wippersnapper_signal_v1_CreateSignalRequest_payload_pin_event_MSGTYPE wippersnapper_pin_v1_PinEvent - -#define wippersnapper_signal_v1_SignalResponse_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, BOOL, (payload,configuration_complete,payload.configuration_complete), 1) -#define wippersnapper_signal_v1_SignalResponse_CALLBACK NULL -#define wippersnapper_signal_v1_SignalResponse_DEFAULT NULL - -#define wippersnapper_signal_v1_PWMRequest_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,attach_request,payload.attach_request), 1) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,detach_request,payload.detach_request), 2) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,write_duty_request,payload.write_duty_request), 3) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,write_duty_multi_request,payload.write_duty_multi_request), 4) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,write_freq_request,payload.write_freq_request), 5) -#define wippersnapper_signal_v1_PWMRequest_CALLBACK NULL -#define wippersnapper_signal_v1_PWMRequest_DEFAULT NULL -#define wippersnapper_signal_v1_PWMRequest_payload_attach_request_MSGTYPE wippersnapper_pwm_v1_PWMAttachRequest -#define wippersnapper_signal_v1_PWMRequest_payload_detach_request_MSGTYPE wippersnapper_pwm_v1_PWMDetachRequest -#define wippersnapper_signal_v1_PWMRequest_payload_write_duty_request_MSGTYPE wippersnapper_pwm_v1_PWMWriteDutyCycleRequest -#define wippersnapper_signal_v1_PWMRequest_payload_write_duty_multi_request_MSGTYPE wippersnapper_pwm_v1_PWMWriteDutyCycleMultiRequest -#define wippersnapper_signal_v1_PWMRequest_payload_write_freq_request_MSGTYPE wippersnapper_pwm_v1_PWMWriteFrequencyRequest - -#define wippersnapper_signal_v1_PWMResponse_FIELDLIST(X, a) \ -X(a, STATIC, ONEOF, MSG_W_CB, (payload,attach_response,payload.attach_response), 1) -#define wippersnapper_signal_v1_PWMResponse_CALLBACK NULL -#define wippersnapper_signal_v1_PWMResponse_DEFAULT NULL -#define wippersnapper_signal_v1_PWMResponse_payload_attach_response_MSGTYPE wippersnapper_pwm_v1_PWMAttachResponse - -extern const pb_msgdesc_t wippersnapper_signal_v1_UARTRequest_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_UARTResponse_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_Ds18x20Request_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_Ds18x20Response_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_I2CRequest_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_I2CResponse_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_ServoRequest_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_ServoResponse_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_PixelsRequest_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_PixelsResponse_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_CreateSignalRequest_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_SignalResponse_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_PWMRequest_msg; -extern const pb_msgdesc_t wippersnapper_signal_v1_PWMResponse_msg; - -/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define wippersnapper_signal_v1_UARTRequest_fields &wippersnapper_signal_v1_UARTRequest_msg -#define wippersnapper_signal_v1_UARTResponse_fields &wippersnapper_signal_v1_UARTResponse_msg -#define wippersnapper_signal_v1_Ds18x20Request_fields &wippersnapper_signal_v1_Ds18x20Request_msg -#define wippersnapper_signal_v1_Ds18x20Response_fields &wippersnapper_signal_v1_Ds18x20Response_msg -#define wippersnapper_signal_v1_I2CRequest_fields &wippersnapper_signal_v1_I2CRequest_msg -#define wippersnapper_signal_v1_I2CResponse_fields &wippersnapper_signal_v1_I2CResponse_msg -#define wippersnapper_signal_v1_ServoRequest_fields &wippersnapper_signal_v1_ServoRequest_msg -#define wippersnapper_signal_v1_ServoResponse_fields &wippersnapper_signal_v1_ServoResponse_msg -#define wippersnapper_signal_v1_PixelsRequest_fields &wippersnapper_signal_v1_PixelsRequest_msg -#define wippersnapper_signal_v1_PixelsResponse_fields &wippersnapper_signal_v1_PixelsResponse_msg -#define wippersnapper_signal_v1_CreateSignalRequest_fields &wippersnapper_signal_v1_CreateSignalRequest_msg -#define wippersnapper_signal_v1_SignalResponse_fields &wippersnapper_signal_v1_SignalResponse_msg -#define wippersnapper_signal_v1_PWMRequest_fields &wippersnapper_signal_v1_PWMRequest_msg -#define wippersnapper_signal_v1_PWMResponse_fields &wippersnapper_signal_v1_PWMResponse_msg - -/* Maximum encoded size of messages (where known) */ -#define wippersnapper_signal_v1_UARTRequest_size 58 -#define wippersnapper_signal_v1_UARTResponse_size 154 -#define wippersnapper_signal_v1_Ds18x20Request_size 39 -#define wippersnapper_signal_v1_Ds18x20Response_size 26 -#if defined(wippersnapper_i2c_v1_I2CDeviceInitRequests_size) -union wippersnapper_signal_v1_I2CRequest_payload_size_union {char f7[(6 + wippersnapper_i2c_v1_I2CDeviceInitRequests_size)]; char f0[227];}; -#define wippersnapper_signal_v1_I2CRequest_size (0 + sizeof(union wippersnapper_signal_v1_I2CRequest_payload_size_union)) -#endif -#define wippersnapper_signal_v1_I2CResponse_size 725 -#define wippersnapper_signal_v1_ServoRequest_size 42 -#define wippersnapper_signal_v1_ServoResponse_size 11 -#define wippersnapper_signal_v1_PixelsRequest_size 39 -#define wippersnapper_signal_v1_PixelsResponse_size 11 -#if defined(wippersnapper_pin_v1_ConfigurePinRequests_size) && defined(wippersnapper_pin_v1_PinEvents_size) -union wippersnapper_signal_v1_CreateSignalRequest_payload_size_union {char f6[(6 + wippersnapper_pin_v1_ConfigurePinRequests_size)]; char f7[(6 + wippersnapper_pin_v1_PinEvents_size)]; char f0[21];}; -#define wippersnapper_signal_v1_CreateSignalRequest_size (0 + sizeof(union wippersnapper_signal_v1_CreateSignalRequest_payload_size_union)) -#endif -#define wippersnapper_signal_v1_SignalResponse_size 2 -#define wippersnapper_signal_v1_PWMRequest_size 82 -#define wippersnapper_signal_v1_PWMResponse_size 11 - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/wippersnapper/uart/v1/uart.pb.c b/src/wippersnapper/uart/v1/uart.pb.c deleted file mode 100644 index b58470741..000000000 --- a/src/wippersnapper/uart/v1/uart.pb.c +++ /dev/null @@ -1,24 +0,0 @@ -/* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#include "wippersnapper/uart/v1/uart.pb.h" -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -PB_BIND(wippersnapper_uart_v1_UARTBusData, wippersnapper_uart_v1_UARTBusData, AUTO) - - -PB_BIND(wippersnapper_uart_v1_UARTDeviceAttachRequest, wippersnapper_uart_v1_UARTDeviceAttachRequest, AUTO) - - -PB_BIND(wippersnapper_uart_v1_UARTDeviceAttachResponse, wippersnapper_uart_v1_UARTDeviceAttachResponse, AUTO) - - -PB_BIND(wippersnapper_uart_v1_UARTDeviceDetachRequest, wippersnapper_uart_v1_UARTDeviceDetachRequest, AUTO) - - -PB_BIND(wippersnapper_uart_v1_UARTDeviceEvent, wippersnapper_uart_v1_UARTDeviceEvent, AUTO) - - - diff --git a/src/wippersnapper/uart/v1/uart.pb.h b/src/wippersnapper/uart/v1/uart.pb.h deleted file mode 100644 index fc197c4c2..000000000 --- a/src/wippersnapper/uart/v1/uart.pb.h +++ /dev/null @@ -1,134 +0,0 @@ -/* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.5-dev at Wed Sep 6 18:22:09 2023. */ - -#ifndef PB_WIPPERSNAPPER_UART_V1_WIPPERSNAPPER_UART_V1_UART_PB_H_INCLUDED -#define PB_WIPPERSNAPPER_UART_V1_WIPPERSNAPPER_UART_V1_UART_PB_H_INCLUDED -#include -#include "nanopb/nanopb.pb.h" -#include "wippersnapper/i2c/v1/i2c.pb.h" - -#if PB_PROTO_HEADER_VERSION != 40 -#error Regenerate this file with the current version of nanopb generator. -#endif - -/* Struct definitions */ -typedef struct _wippersnapper_uart_v1_UARTBusData { - int32_t baudrate; - char pin_rx[6]; - char pin_tx[6]; - bool is_invert; -} wippersnapper_uart_v1_UARTBusData; - -typedef struct _wippersnapper_uart_v1_UARTDeviceAttachResponse { - char device_id[15]; - bool is_success; -} wippersnapper_uart_v1_UARTDeviceAttachResponse; - -typedef struct _wippersnapper_uart_v1_UARTDeviceDetachRequest { - char device_id[15]; -} wippersnapper_uart_v1_UARTDeviceDetachRequest; - -typedef struct _wippersnapper_uart_v1_UARTDeviceEvent { - char device_id[15]; - pb_size_t sensor_event_count; - wippersnapper_i2c_v1_SensorEvent sensor_event[15]; -} wippersnapper_uart_v1_UARTDeviceEvent; - -typedef struct _wippersnapper_uart_v1_UARTDeviceAttachRequest { - bool has_bus_info; - wippersnapper_uart_v1_UARTBusData bus_info; - char device_id[15]; - int32_t polling_interval; -} wippersnapper_uart_v1_UARTDeviceAttachRequest; - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Initializer values for message structs */ -#define wippersnapper_uart_v1_UARTBusData_init_default {0, "", "", 0} -#define wippersnapper_uart_v1_UARTDeviceAttachRequest_init_default {false, wippersnapper_uart_v1_UARTBusData_init_default, "", 0} -#define wippersnapper_uart_v1_UARTDeviceAttachResponse_init_default {"", 0} -#define wippersnapper_uart_v1_UARTDeviceDetachRequest_init_default {""} -#define wippersnapper_uart_v1_UARTDeviceEvent_init_default {"", 0, {wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default, wippersnapper_i2c_v1_SensorEvent_init_default}} -#define wippersnapper_uart_v1_UARTBusData_init_zero {0, "", "", 0} -#define wippersnapper_uart_v1_UARTDeviceAttachRequest_init_zero {false, wippersnapper_uart_v1_UARTBusData_init_zero, "", 0} -#define wippersnapper_uart_v1_UARTDeviceAttachResponse_init_zero {"", 0} -#define wippersnapper_uart_v1_UARTDeviceDetachRequest_init_zero {""} -#define wippersnapper_uart_v1_UARTDeviceEvent_init_zero {"", 0, {wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero, wippersnapper_i2c_v1_SensorEvent_init_zero}} - -/* Field tags (for use in manual encoding/decoding) */ -#define wippersnapper_uart_v1_UARTBusData_baudrate_tag 1 -#define wippersnapper_uart_v1_UARTBusData_pin_rx_tag 2 -#define wippersnapper_uart_v1_UARTBusData_pin_tx_tag 3 -#define wippersnapper_uart_v1_UARTBusData_is_invert_tag 4 -#define wippersnapper_uart_v1_UARTDeviceAttachResponse_device_id_tag 1 -#define wippersnapper_uart_v1_UARTDeviceAttachResponse_is_success_tag 2 -#define wippersnapper_uart_v1_UARTDeviceDetachRequest_device_id_tag 1 -#define wippersnapper_uart_v1_UARTDeviceEvent_device_id_tag 1 -#define wippersnapper_uart_v1_UARTDeviceEvent_sensor_event_tag 2 -#define wippersnapper_uart_v1_UARTDeviceAttachRequest_bus_info_tag 1 -#define wippersnapper_uart_v1_UARTDeviceAttachRequest_device_id_tag 2 -#define wippersnapper_uart_v1_UARTDeviceAttachRequest_polling_interval_tag 3 - -/* Struct field encoding specification for nanopb */ -#define wippersnapper_uart_v1_UARTBusData_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, INT32, baudrate, 1) \ -X(a, STATIC, SINGULAR, STRING, pin_rx, 2) \ -X(a, STATIC, SINGULAR, STRING, pin_tx, 3) \ -X(a, STATIC, SINGULAR, BOOL, is_invert, 4) -#define wippersnapper_uart_v1_UARTBusData_CALLBACK NULL -#define wippersnapper_uart_v1_UARTBusData_DEFAULT NULL - -#define wippersnapper_uart_v1_UARTDeviceAttachRequest_FIELDLIST(X, a) \ -X(a, STATIC, OPTIONAL, MESSAGE, bus_info, 1) \ -X(a, STATIC, SINGULAR, STRING, device_id, 2) \ -X(a, STATIC, SINGULAR, INT32, polling_interval, 3) -#define wippersnapper_uart_v1_UARTDeviceAttachRequest_CALLBACK NULL -#define wippersnapper_uart_v1_UARTDeviceAttachRequest_DEFAULT NULL -#define wippersnapper_uart_v1_UARTDeviceAttachRequest_bus_info_MSGTYPE wippersnapper_uart_v1_UARTBusData - -#define wippersnapper_uart_v1_UARTDeviceAttachResponse_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, device_id, 1) \ -X(a, STATIC, SINGULAR, BOOL, is_success, 2) -#define wippersnapper_uart_v1_UARTDeviceAttachResponse_CALLBACK NULL -#define wippersnapper_uart_v1_UARTDeviceAttachResponse_DEFAULT NULL - -#define wippersnapper_uart_v1_UARTDeviceDetachRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, device_id, 1) -#define wippersnapper_uart_v1_UARTDeviceDetachRequest_CALLBACK NULL -#define wippersnapper_uart_v1_UARTDeviceDetachRequest_DEFAULT NULL - -#define wippersnapper_uart_v1_UARTDeviceEvent_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, STRING, device_id, 1) \ -X(a, STATIC, REPEATED, MESSAGE, sensor_event, 2) -#define wippersnapper_uart_v1_UARTDeviceEvent_CALLBACK NULL -#define wippersnapper_uart_v1_UARTDeviceEvent_DEFAULT NULL -#define wippersnapper_uart_v1_UARTDeviceEvent_sensor_event_MSGTYPE wippersnapper_i2c_v1_SensorEvent - -extern const pb_msgdesc_t wippersnapper_uart_v1_UARTBusData_msg; -extern const pb_msgdesc_t wippersnapper_uart_v1_UARTDeviceAttachRequest_msg; -extern const pb_msgdesc_t wippersnapper_uart_v1_UARTDeviceAttachResponse_msg; -extern const pb_msgdesc_t wippersnapper_uart_v1_UARTDeviceDetachRequest_msg; -extern const pb_msgdesc_t wippersnapper_uart_v1_UARTDeviceEvent_msg; - -/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define wippersnapper_uart_v1_UARTBusData_fields &wippersnapper_uart_v1_UARTBusData_msg -#define wippersnapper_uart_v1_UARTDeviceAttachRequest_fields &wippersnapper_uart_v1_UARTDeviceAttachRequest_msg -#define wippersnapper_uart_v1_UARTDeviceAttachResponse_fields &wippersnapper_uart_v1_UARTDeviceAttachResponse_msg -#define wippersnapper_uart_v1_UARTDeviceDetachRequest_fields &wippersnapper_uart_v1_UARTDeviceDetachRequest_msg -#define wippersnapper_uart_v1_UARTDeviceEvent_fields &wippersnapper_uart_v1_UARTDeviceEvent_msg - -/* Maximum encoded size of messages (where known) */ -#define wippersnapper_uart_v1_UARTBusData_size 27 -#define wippersnapper_uart_v1_UARTDeviceAttachRequest_size 56 -#define wippersnapper_uart_v1_UARTDeviceAttachResponse_size 18 -#define wippersnapper_uart_v1_UARTDeviceDetachRequest_size 16 -#define wippersnapper_uart_v1_UARTDeviceEvent_size 151 - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/ws_adapters.h b/src/ws_adapters.h new file mode 100644 index 000000000..72bba5072 --- /dev/null +++ b/src/ws_adapters.h @@ -0,0 +1,56 @@ +/*! + * @file ws_adapters.h + * + * This file includes the adapter interfaces at compile-time. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2020-2025 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ + +#ifndef WS_ADAPTERS_H +#define WS_ADAPTERS_H +/** + * The following are adapters for use with WiFi modules. + */ +// Adafruit AirLift (ESP32) networking adapter +#if defined(ADAFRUIT_METRO_M4_EXPRESS) || \ + defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE) || defined(ADAFRUIT_PYPORTAL) || \ + defined(ADAFRUIT_PYPORTAL_M4_TITANO) || defined(USE_AIRLIFT) +#include "adapters/wifi/ws_wifi_airlift.h" +typedef ws_wifi_airlift ws_adapter_wifi; +// ESP8266 networking adapter +#elif defined(ARDUINO_ARCH_ESP8266) +#include "adapters/wifi/ws_wifi_esp8266.h" +typedef ws_wifi_esp8266 ws_adapter_wifi; +// ESP32 networking adapter +#elif defined(ARDUINO_ARCH_ESP32) +#include "adapters/wifi/ws_wifi_esp32.h" +typedef ws_wifi_esp32 ws_adapter_wifi; +// Networking adapters for Raspberry Pi Pico W-series +#elif defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include "adapters/wifi/ws_wifi_pico.h" +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) +#include "adapters/wifi/ws_wifi_ninafw.h" +typedef ws_wifi_ninafw ws_adapter_wifi; +/** + * The following are adapters for use without networking functionality. + */ +#elif defined(ARDUINO_RASPBERRY_PI_PICO_2) || \ + defined(ARDUINO_RASPBERRY_PI_PICO) || \ + defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER) || \ + defined(ARDUINO_ADAFRUIT_METRO_RP2350) +#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 + +#endif // WS_ADAPTERS_H \ No newline at end of file diff --git a/tests/bin/offline/firmware.elf b/tests/bin/offline/firmware.elf new file mode 100755 index 000000000..21c458943 Binary files /dev/null and b/tests/bin/offline/firmware.elf differ diff --git a/tests/diagram.json b/tests/diagram.json new file mode 100644 index 000000000..fa86f30fd --- /dev/null +++ b/tests/diagram.json @@ -0,0 +1,160 @@ +{ + "version": 1, + "author": "Uri Shaked", + "editor": "wokwi", + "parts": [ + { "type": "wokwi-breadboard", "id": "bb1", "top": -89.4, "left": -266, "attrs": {} }, + { + "type": "wokwi-esp32-devkit-v1", + "id": "esp", + "top": -91.9, + "left": -208.2, + "rotate": 90, + "attrs": {} + }, + { + "type": "wokwi-microsd-card", + "id": "sd1", + "top": -112.63, + "left": -50.93, + "rotate": 90, + "attrs": {} + }, + { + "type": "wokwi-ds1307", + "id": "rtc1", + "top": -119.9, + "left": 26, + "rotate": 270, + "attrs": {} + }, + { "type": "wokwi-potentiometer", "id": "pot1", "top": -87.7, "left": 143.8, "attrs": {} }, + { "type": "wokwi-potentiometer", "id": "pot2", "top": -1.3, "left": 143.8, "attrs": {} }, + { + "type": "wokwi-pushbutton", + "id": "btn1", + "top": 9.2, + "left": 74, + "rotate": 270, + "attrs": { "bounce": "0", "color": "green" } + }, + { "type": "board-ds18b20", "id": "temp1", "top": -87.53, "left": 272.88, "attrs": {} }, + { + "type": "wokwi-resistor", + "id": "r1", + "top": 4.8, + "left": 277.85, + "rotate": 90, + "attrs": { "value": "7400" } + }, + { "type": "board-ds18b20", "id": "temp2", "top": -87.53, "left": 234.48, "attrs": {} }, + { + "type": "wokwi-resistor", + "id": "r2", + "top": -6.2, + "left": 239.15, + "rotate": 270, + "attrs": { "value": "7400" } + } + ], + "connections": [ + [ "esp:TX0", "$serialMonitor:RX", "", [] ], + [ "esp:RX0", "$serialMonitor:TX", "", [] ], + [ "sd1:CS", "esp:D15", "gold", [ "v144", "h-144.26" ] ], + [ "sd1:DI", "esp:D23", "blue", [ "v0" ] ], + [ "sd1:SCK", "esp:D18", "violet", [ "v153.6", "h-115.19" ] ], + [ "sd1:DO", "esp:D19", "orange", [ "v124.8", "h-125.01" ] ], + [ "rtc1:SDA", "esp:D21", "blue", [ "v115.2", "h-183.1" ] ], + [ "rtc1:SCL", "esp:D22", "green", [ "v105.6", "h-163.7" ] ], + [ "pot2:SIG", "esp:D27", "green", [ "h-0.4", "v76.8", "h-345.9" ] ], + [ "esp:3V3", "bb1:bp.1", "red", [ "h-9.6", "v39" ] ], + [ "sd1:VCC", "bb1:bp.18", "red", [ "v0" ] ], + [ "rtc1:GND", "bb1:bn.25", "black", [ "v0" ] ], + [ "esp:GND.1", "bb1:bn.3", "black", [ "v0" ] ], + [ "bb1:33b.h", "bb1:33b.g", "green", [ "v0" ] ], + [ "rtc1:5V", "esp:VIN", "red", [ "v-19.2", "h-269.2" ] ], + [ "pot1:SIG", "esp:D14", "blue", [ "v9.6", "h-48.4", "v144", "h-316.8", "v-172.8" ] ], + [ "btn1:1.l", "esp:D4", "orange", [ "v57.6", "h-268.7" ] ], + [ "temp1:GND", "bb1:bn.48", "black", [ "v0" ] ], + [ "temp1:DQ", "r1:1", "green", [ "v0" ] ], + [ "temp1:VCC", "r1:2", "red", [ "v0" ] ], + [ "r1:1", "esp:D12", "green", [ "v-124.8", "h-490.3" ] ], + [ "temp2:GND", "bb1:bn.36", "black", [ "v0" ] ], + [ "temp2:DQ", "r2:2", "violet", [ "v0" ] ], + [ "temp2:VCC", "r2:1", "red", [ "v0" ] ], + [ "esp:D25", "r2:2", "violet", [ "v-96", "h412.8" ] ], + [ "sd1:GND", "bb1:bn.21", "black", [ "v0" ] ], + [ "btn1:2.r", "bb1:tn.31", "black", [ "h9.8", "v-67.3" ] ], + [ "pot1:GND", "bb1:tn.32", "black", [ "h-38.4", "v-47.9" ] ], + [ "pot1:VCC", "bb1:bp.39", "red", [ "h18.4", "v116.1" ] ], + [ "pot2:GND", "bb1:bn.35", "black", [ "v0" ] ], + [ "pot2:VCC", "bb1:bp.37", "red", [ "v0" ] ], + [ "r2:1", "bb1:bp.44", "red", [ "h0" ] ], + [ "r1:2", "bb1:bp.47", "red", [ "h0" ] ], + [ "esp:VIN", "bb1:4t.a", "", [ "$bb" ] ], + [ "esp:GND.2", "bb1:5t.a", "", [ "$bb" ] ], + [ "esp:D13", "bb1:6t.a", "", [ "$bb" ] ], + [ "esp:D12", "bb1:7t.a", "", [ "$bb" ] ], + [ "esp:D14", "bb1:8t.a", "", [ "$bb" ] ], + [ "esp:D27", "bb1:9t.a", "", [ "$bb" ] ], + [ "esp:D26", "bb1:10t.a", "", [ "$bb" ] ], + [ "esp:D25", "bb1:11t.a", "", [ "$bb" ] ], + [ "esp:D33", "bb1:12t.a", "", [ "$bb" ] ], + [ "esp:D32", "bb1:13t.a", "", [ "$bb" ] ], + [ "esp:D35", "bb1:14t.a", "", [ "$bb" ] ], + [ "esp:D34", "bb1:15t.a", "", [ "$bb" ] ], + [ "esp:VN", "bb1:16t.a", "", [ "$bb" ] ], + [ "esp:VP", "bb1:17t.a", "", [ "$bb" ] ], + [ "esp:EN", "bb1:18t.a", "", [ "$bb" ] ], + [ "esp:3V3", "bb1:4b.i", "", [ "$bb" ] ], + [ "esp:GND.1", "bb1:5b.i", "", [ "$bb" ] ], + [ "esp:D15", "bb1:6b.i", "", [ "$bb" ] ], + [ "esp:D2", "bb1:7b.i", "", [ "$bb" ] ], + [ "esp:D4", "bb1:8b.i", "", [ "$bb" ] ], + [ "esp:RX2", "bb1:9b.i", "", [ "$bb" ] ], + [ "esp:TX2", "bb1:10b.i", "", [ "$bb" ] ], + [ "esp:D5", "bb1:11b.i", "", [ "$bb" ] ], + [ "esp:D18", "bb1:12b.i", "", [ "$bb" ] ], + [ "esp:D19", "bb1:13b.i", "", [ "$bb" ] ], + [ "esp:D21", "bb1:14b.i", "", [ "$bb" ] ], + [ "esp:RX0", "bb1:15b.i", "", [ "$bb" ] ], + [ "esp:TX0", "bb1:16b.i", "", [ "$bb" ] ], + [ "esp:D22", "bb1:17b.i", "", [ "$bb" ] ], + [ "esp:D23", "bb1:18b.i", "", [ "$bb" ] ], + [ "sd1:CD", "bb1:28t.a", "", [ "$bb" ] ], + [ "sd1:DO", "bb1:27t.a", "", [ "$bb" ] ], + [ "sd1:GND", "bb1:26t.a", "", [ "$bb" ] ], + [ "sd1:SCK", "bb1:25t.a", "", [ "$bb" ] ], + [ "sd1:VCC", "bb1:24t.a", "", [ "$bb" ] ], + [ "sd1:DI", "bb1:23t.a", "", [ "$bb" ] ], + [ "sd1:CS", "bb1:22t.a", "", [ "$bb" ] ], + [ "rtc1:GND", "bb1:31t.a", "", [ "$bb" ] ], + [ "rtc1:5V", "bb1:32t.a", "", [ "$bb" ] ], + [ "rtc1:SDA", "bb1:33t.a", "", [ "$bb" ] ], + [ "rtc1:SCL", "bb1:34t.a", "", [ "$bb" ] ], + [ "rtc1:SQW", "bb1:35t.a", "", [ "$bb" ] ], + [ "pot1:GND", "bb1:44t.c", "", [ "$bb" ] ], + [ "pot1:SIG", "bb1:45t.c", "", [ "$bb" ] ], + [ "pot1:VCC", "bb1:46t.c", "", [ "$bb" ] ], + [ "pot2:GND", "bb1:44b.j", "", [ "$bb" ] ], + [ "pot2:SIG", "bb1:45b.j", "", [ "$bb" ] ], + [ "pot2:VCC", "bb1:46b.j", "", [ "$bb" ] ], + [ "btn1:1.l", "bb1:36b.j", "", [ "$bb" ] ], + [ "btn1:2.l", "bb1:38b.j", "", [ "$bb" ] ], + [ "btn1:1.r", "bb1:36t.e", "", [ "$bb" ] ], + [ "btn1:2.r", "bb1:38t.e", "", [ "$bb" ] ], + [ "r1:1", "bb1:58t.c", "", [ "$bb" ] ], + [ "r1:2", "bb1:58b.g", "", [ "$bb" ] ], + [ "r2:1", "bb1:54b.f", "", [ "$bb" ] ], + [ "r2:2", "bb1:54t.b", "", [ "$bb" ] ], + [ "temp1:GND", "bb1:55t.a", "", [ "$bb" ] ], + [ "temp1:DQ", "bb1:56t.a", "", [ "$bb" ] ], + [ "temp1:VCC", "bb1:57t.a", "", [ "$bb" ] ], + [ "temp2:GND", "bb1:51t.a", "", [ "$bb" ] ], + [ "temp2:DQ", "bb1:52t.a", "", [ "$bb" ] ], + [ "temp2:VCC", "bb1:53t.a", "", [ "$bb" ] ], + [ "esp:GND.2", "bb1:tn.3", "black", [ "v0" ] ] + ], + "serialMonitor": { "display": "terminal", "newline": "lf" }, + "dependencies": {} +} \ No newline at end of file diff --git a/tests/diagrams/offline.json b/tests/diagrams/offline.json new file mode 100644 index 000000000..e10e11fa3 --- /dev/null +++ b/tests/diagrams/offline.json @@ -0,0 +1,160 @@ +{ + "version": 1, + "author": "Uri Shaked", + "editor": "wokwi", + "parts": [ + { "type": "wokwi-breadboard", "id": "bb1", "top": -89.4, "left": -266, "attrs": {} }, + { + "type": "wokwi-esp32-devkit-v1", + "id": "esp", + "top": -91.9, + "left": -208.2, + "rotate": 90, + "attrs": {} + }, + { + "type": "wokwi-microsd-card", + "id": "sd1", + "top": -112.63, + "left": -50.93, + "rotate": 90, + "attrs": {} + }, + { + "type": "wokwi-ds1307", + "id": "rtc1", + "top": -119.9, + "left": 26, + "rotate": 270, + "attrs": {} + }, + { "type": "wokwi-potentiometer", "id": "pot1", "top": -87.7, "left": 143.8, "attrs": {} }, + { "type": "wokwi-potentiometer", "id": "pot2", "top": -1.3, "left": 143.8, "attrs": {} }, + { + "type": "wokwi-pushbutton", + "id": "btn1", + "top": 9.2, + "left": 74, + "rotate": 270, + "attrs": { "color": "green" } + }, + { "type": "board-ds18b20", "id": "temp1", "top": -87.53, "left": 272.88, "attrs": {} }, + { + "type": "wokwi-resistor", + "id": "r1", + "top": 4.8, + "left": 277.85, + "rotate": 90, + "attrs": { "value": "7400" } + }, + { "type": "board-ds18b20", "id": "temp2", "top": -87.53, "left": 234.48, "attrs": {} }, + { + "type": "wokwi-resistor", + "id": "r2", + "top": -6.2, + "left": 239.15, + "rotate": 270, + "attrs": { "value": "7400" } + } + ], + "connections": [ + [ "esp:TX0", "$serialMonitor:RX", "", [] ], + [ "esp:RX0", "$serialMonitor:TX", "", [] ], + [ "sd1:CS", "esp:D15", "gold", [ "v144", "h-144.26" ] ], + [ "sd1:DI", "esp:D23", "blue", [ "v0" ] ], + [ "sd1:SCK", "esp:D18", "violet", [ "v153.6", "h-115.19" ] ], + [ "sd1:DO", "esp:D19", "orange", [ "v124.8", "h-125.01" ] ], + [ "rtc1:SDA", "esp:D21", "blue", [ "v115.2", "h-183.1" ] ], + [ "rtc1:SCL", "esp:D22", "green", [ "v105.6", "h-163.7" ] ], + [ "pot2:SIG", "esp:D27", "green", [ "h-0.4", "v76.8", "h-345.9" ] ], + [ "esp:3V3", "bb1:bp.1", "red", [ "h-9.6", "v39" ] ], + [ "sd1:VCC", "bb1:bp.18", "red", [ "v0" ] ], + [ "rtc1:GND", "bb1:bn.25", "black", [ "v0" ] ], + [ "esp:GND.1", "bb1:bn.3", "black", [ "v0" ] ], + [ "bb1:33b.h", "bb1:33b.g", "green", [ "v0" ] ], + [ "rtc1:5V", "esp:VIN", "red", [ "v-19.2", "h-269.2" ] ], + [ "pot1:SIG", "esp:D14", "blue", [ "v9.6", "h-48.4", "v144", "h-316.8", "v-172.8" ] ], + [ "btn1:1.l", "esp:D4", "orange", [ "v57.6", "h-268.7" ] ], + [ "temp1:GND", "bb1:bn.48", "black", [ "v0" ] ], + [ "temp1:DQ", "r1:1", "green", [ "v0" ] ], + [ "temp1:VCC", "r1:2", "red", [ "v0" ] ], + [ "r1:1", "esp:D12", "green", [ "v-124.8", "h-490.3" ] ], + [ "temp2:GND", "bb1:bn.36", "black", [ "v0" ] ], + [ "temp2:DQ", "r2:2", "violet", [ "v0" ] ], + [ "temp2:VCC", "r2:1", "red", [ "v0" ] ], + [ "esp:D25", "r2:2", "violet", [ "v-96", "h412.8" ] ], + [ "sd1:GND", "bb1:bn.21", "black", [ "v0" ] ], + [ "btn1:2.r", "bb1:tn.31", "black", [ "h9.8", "v-67.3" ] ], + [ "pot1:GND", "bb1:tn.32", "black", [ "h-38.4", "v-47.9" ] ], + [ "pot1:VCC", "bb1:bp.39", "red", [ "h18.4", "v116.1" ] ], + [ "pot2:GND", "bb1:bn.35", "black", [ "v0" ] ], + [ "pot2:VCC", "bb1:bp.37", "red", [ "v0" ] ], + [ "r2:1", "bb1:bp.44", "red", [ "h0" ] ], + [ "r1:2", "bb1:bp.47", "red", [ "h0" ] ], + [ "esp:VIN", "bb1:4t.a", "", [ "$bb" ] ], + [ "esp:GND.2", "bb1:5t.a", "", [ "$bb" ] ], + [ "esp:D13", "bb1:6t.a", "", [ "$bb" ] ], + [ "esp:D12", "bb1:7t.a", "", [ "$bb" ] ], + [ "esp:D14", "bb1:8t.a", "", [ "$bb" ] ], + [ "esp:D27", "bb1:9t.a", "", [ "$bb" ] ], + [ "esp:D26", "bb1:10t.a", "", [ "$bb" ] ], + [ "esp:D25", "bb1:11t.a", "", [ "$bb" ] ], + [ "esp:D33", "bb1:12t.a", "", [ "$bb" ] ], + [ "esp:D32", "bb1:13t.a", "", [ "$bb" ] ], + [ "esp:D35", "bb1:14t.a", "", [ "$bb" ] ], + [ "esp:D34", "bb1:15t.a", "", [ "$bb" ] ], + [ "esp:VN", "bb1:16t.a", "", [ "$bb" ] ], + [ "esp:VP", "bb1:17t.a", "", [ "$bb" ] ], + [ "esp:EN", "bb1:18t.a", "", [ "$bb" ] ], + [ "esp:3V3", "bb1:4b.i", "", [ "$bb" ] ], + [ "esp:GND.1", "bb1:5b.i", "", [ "$bb" ] ], + [ "esp:D15", "bb1:6b.i", "", [ "$bb" ] ], + [ "esp:D2", "bb1:7b.i", "", [ "$bb" ] ], + [ "esp:D4", "bb1:8b.i", "", [ "$bb" ] ], + [ "esp:RX2", "bb1:9b.i", "", [ "$bb" ] ], + [ "esp:TX2", "bb1:10b.i", "", [ "$bb" ] ], + [ "esp:D5", "bb1:11b.i", "", [ "$bb" ] ], + [ "esp:D18", "bb1:12b.i", "", [ "$bb" ] ], + [ "esp:D19", "bb1:13b.i", "", [ "$bb" ] ], + [ "esp:D21", "bb1:14b.i", "", [ "$bb" ] ], + [ "esp:RX0", "bb1:15b.i", "", [ "$bb" ] ], + [ "esp:TX0", "bb1:16b.i", "", [ "$bb" ] ], + [ "esp:D22", "bb1:17b.i", "", [ "$bb" ] ], + [ "esp:D23", "bb1:18b.i", "", [ "$bb" ] ], + [ "sd1:CD", "bb1:28t.a", "", [ "$bb" ] ], + [ "sd1:DO", "bb1:27t.a", "", [ "$bb" ] ], + [ "sd1:GND", "bb1:26t.a", "", [ "$bb" ] ], + [ "sd1:SCK", "bb1:25t.a", "", [ "$bb" ] ], + [ "sd1:VCC", "bb1:24t.a", "", [ "$bb" ] ], + [ "sd1:DI", "bb1:23t.a", "", [ "$bb" ] ], + [ "sd1:CS", "bb1:22t.a", "", [ "$bb" ] ], + [ "rtc1:GND", "bb1:31t.a", "", [ "$bb" ] ], + [ "rtc1:5V", "bb1:32t.a", "", [ "$bb" ] ], + [ "rtc1:SDA", "bb1:33t.a", "", [ "$bb" ] ], + [ "rtc1:SCL", "bb1:34t.a", "", [ "$bb" ] ], + [ "rtc1:SQW", "bb1:35t.a", "", [ "$bb" ] ], + [ "pot1:GND", "bb1:44t.c", "", [ "$bb" ] ], + [ "pot1:SIG", "bb1:45t.c", "", [ "$bb" ] ], + [ "pot1:VCC", "bb1:46t.c", "", [ "$bb" ] ], + [ "pot2:GND", "bb1:44b.j", "", [ "$bb" ] ], + [ "pot2:SIG", "bb1:45b.j", "", [ "$bb" ] ], + [ "pot2:VCC", "bb1:46b.j", "", [ "$bb" ] ], + [ "btn1:1.l", "bb1:36b.j", "", [ "$bb" ] ], + [ "btn1:2.l", "bb1:38b.j", "", [ "$bb" ] ], + [ "btn1:1.r", "bb1:36t.e", "", [ "$bb" ] ], + [ "btn1:2.r", "bb1:38t.e", "", [ "$bb" ] ], + [ "r1:1", "bb1:58t.c", "", [ "$bb" ] ], + [ "r1:2", "bb1:58b.g", "", [ "$bb" ] ], + [ "r2:1", "bb1:54b.f", "", [ "$bb" ] ], + [ "r2:2", "bb1:54t.b", "", [ "$bb" ] ], + [ "temp1:GND", "bb1:55t.a", "", [ "$bb" ] ], + [ "temp1:DQ", "bb1:56t.a", "", [ "$bb" ] ], + [ "temp1:VCC", "bb1:57t.a", "", [ "$bb" ] ], + [ "temp2:GND", "bb1:51t.a", "", [ "$bb" ] ], + [ "temp2:DQ", "bb1:52t.a", "", [ "$bb" ] ], + [ "temp2:VCC", "bb1:53t.a", "", [ "$bb" ] ], + [ "esp:GND.2", "bb1:tn.3", "black", [ "v0" ] ] + ], + "serialMonitor": { "display": "terminal", "newline": "lf" }, + "dependencies": {} + } \ No newline at end of file diff --git a/tests/report.xml b/tests/report.xml new file mode 100644 index 000000000..07d7c851b --- /dev/null +++ b/tests/report.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/requirements.txt b/tests/requirements.txt new file mode 100644 index 000000000..f4e034370 --- /dev/null +++ b/tests/requirements.txt @@ -0,0 +1,2 @@ +platformio +pytest \ No newline at end of file diff --git a/tests/scenarios/offline/test-invalid-checksum.scenario.yaml b/tests/scenarios/offline/test-invalid-checksum.scenario.yaml new file mode 100644 index 000000000..bf7d8a9b1 --- /dev/null +++ b/tests/scenarios/offline/test-invalid-checksum.scenario.yaml @@ -0,0 +1,9 @@ +name: Offline Mode - Invalid Checksum Value +version: 1 +author: Brent Rubell for Adafruit Industries + +steps: + - wait-serial: '[SD] Waiting for incoming JSON string...' + - write-serial: '{"exportVersion": "1.0.0", "exportedBy": "wokwi", "exportedAt": "2024-10-28T18:58:23.976Z", "exportedFromDevice": {"board": "metroesp32s3", "firmwareVersion": "1.0.0-beta.93", "referenceVoltage": 2.6, "totalGPIOPins": 11, "totalAnalogPins": 6}, "components": [{"componentAPI": "analogio", "name": "Analog Pin", "pinName": "D14", "type": "analog_pin", "mode": "ANALOG", "direction": "INPUT", "sampleMode": "TIMER", "analogReadMode": "PIN_VALUE", "period": 5, "isPin": true}], "checksum": 5}' + - write-serial: '\n' + - wait-serial: '[SD] Checksum mismatch, file has been modified from its original state!' \ No newline at end of file diff --git a/tests/scenarios/offline/test-invalid-json.scenario.yaml b/tests/scenarios/offline/test-invalid-json.scenario.yaml new file mode 100644 index 000000000..dc12905f7 --- /dev/null +++ b/tests/scenarios/offline/test-invalid-json.scenario.yaml @@ -0,0 +1,9 @@ +name: Offline Mode - Invalid JSON +version: 1 +author: Brent Rubell for Adafruit Industries + +steps: + - wait-serial: '[SD] Waiting for incoming JSON string...' + - write-serial: '{"exportVersion":"1.0.0",' + - write-serial: '\n' + - wait-serial: '[SD] Runtime Error: Unable to deserialize config.json' \ No newline at end of file diff --git a/tests/scenarios/offline/test-log-analogin.scenario.yaml b/tests/scenarios/offline/test-log-analogin.scenario.yaml new file mode 100644 index 000000000..aee02b43c --- /dev/null +++ b/tests/scenarios/offline/test-log-analogin.scenario.yaml @@ -0,0 +1,20 @@ +name: Offline Mode - Analog Input +version: 1 +author: Brent Rubell for Adafruit Industries + +steps: + - wait-serial: '[SD] Waiting for incoming JSON string...' + - write-serial: '{"exportVersion": "1.0.0", "exportedBy": "wokwi", "exportedAt": "2024-10-28T18:58:23.976Z", "exportedFromDevice": {"board": "metroesp32s3", "firmwareVersion": "1.0.0-beta.93", "referenceVoltage": 2.6, "totalGPIOPins": 11, "totalAnalogPins": 6}, "components": [{"componentAPI": "analogio", "name": "Analog Pin", "pinName": "D14", "type": "analog_pin", "mode": "ANALOG", "direction": "INPUT", "sampleMode": "TIMER", "analogReadMode": "raw", "period": 5, "isPin": true}], "checksum": 149}' + - write-serial: '\n' + - wait-serial: '[analogio] Added new pin:' + - wait-serial: 'Pin Name: 14' + - wait-serial: 'Period: 5000.00' + - wait-serial: 'Read Mode: 18' + - delay: 5s + - wait-serial: '{"timestamp":0,"pin":"A14","value":0,"si_unit":"none"}' + - set-control: + part-id: pot1 + control: position + value: 0.5 + - delay: 3s + - wait-serial: '{"timestamp":0,"pin":"A14","value":16384,"si_unit":"none"}' \ No newline at end of file diff --git a/tests/scenarios/offline/test-log-digital-in.scenario.yaml b/tests/scenarios/offline/test-log-digital-in.scenario.yaml new file mode 100644 index 000000000..6471c1f52 --- /dev/null +++ b/tests/scenarios/offline/test-log-digital-in.scenario.yaml @@ -0,0 +1,20 @@ +name: Offline Mode - Digital Input +version: 1 +author: Brent Rubell for Adafruit Industries + +steps: + - wait-serial: '[SD] Waiting for incoming JSON string...' + - write-serial: '{"checksum":183,"components":[{"componentAPI":"digitalio","direction":"INPUT","isPin":true,"mode":"DIGITAL","name":"Button (D4)","period":5,"pinName":"D4","pull":"UP","sampleMode":"TIMER","type":"push_button"}],"exportVersion":"1.0.0","exportedAt":"2024-10-28T18:58:23.976Z","exportedBy":"wokwi","exportedFromDevice":{"board":"metroesp32s3","firmwareVersion":"1.0.0-beta.93","referenceVoltage":2.6,"totalAnalogPins":6,"totalGPIOPins":11}}' + - write-serial: '\n' + - wait-serial: '[SD] JSON string received!' + - wait-serial: '[digitalio] Added new pin:' + - wait-serial: 'Pin Name: 4' + - wait-serial: 'Period: 5000' + - wait-serial: 'Sample Mode: 1' + - wait-serial: 'Direction: 2' + - wait-serial: '{"timestamp":0,"pin":"D4","value":true,"si_unit":"boolean"}' + - set-control: + part-id: btn1 + control: pressed + value: 1 + - wait-serial: '{"timestamp":0,"pin":"D4","value":false,"si_unit":"boolean"}' \ No newline at end of file diff --git a/tests/scenarios/offline/test-log-ds18b20.scenario.yaml b/tests/scenarios/offline/test-log-ds18b20.scenario.yaml new file mode 100644 index 000000000..1b8148bba --- /dev/null +++ b/tests/scenarios/offline/test-log-ds18b20.scenario.yaml @@ -0,0 +1,10 @@ +name: Offline Mode - DS18b20 +version: 1 +author: Brent Rubell for Adafruit Industries + +steps: + - wait-serial: '[SD] Waiting for incoming JSON string...' + - write-serial: '{"exportVersion": "1.0.0", "exportedBy": "wokwi", "exportedAt": "2024-10-28T18:58:23.976Z", "exportedFromDevice": {"board": "metroesp32s3", "firmwareVersion": "1.0.0-beta.93", "referenceVoltage": 2.6, "totalGPIOPins": 11, "totalAnalogPins": 6}, "components": [{"componentAPI": "ds18x20", "name": "DS18B20: Temperature Sensor", "sensorTypeCount": 2, "sensorType1": "object-temp-fahrenheit", "sensorType2": "object-temp", "pinName": "D6", "sensorResolution": 12, "period": 5}], "checksum": 34}' + - write-serial: '\n' + - wait-serial: '{"timestamp":0,"pin":"D6","value":0,"si_unit":"C"}' + - wait-serial: '{"timestamp":0,"pin":"D6","value":32,"si_unit":"F"}' \ No newline at end of file diff --git a/tests/scenarios/offline/test-valid-checksum.scenario.yaml b/tests/scenarios/offline/test-valid-checksum.scenario.yaml new file mode 100644 index 000000000..f02118e06 --- /dev/null +++ b/tests/scenarios/offline/test-valid-checksum.scenario.yaml @@ -0,0 +1,9 @@ +name: Offline Mode - Invalid Checksum Value +version: 1 +author: Brent Rubell for Adafruit Industries + +steps: + - wait-serial: '[SD] Waiting for incoming JSON string...' + - write-serial: '{"exportVersion": "1.0.0", "exportedBy": "wokwi", "exportedAt": "2024-10-28T18:58:23.976Z", "exportedFromDevice": {"board": "metroesp32s3", "firmwareVersion": "1.0.0-beta.93", "referenceVoltage": 2.6, "totalGPIOPins": 11, "totalAnalogPins": 6}, "components": [{"componentAPI": "analogio", "name": "Analog Pin", "pinName": "D14", "type": "analog_pin", "mode": "ANALOG", "direction": "INPUT", "sampleMode": "TIMER", "analogReadMode": "raw", "period": 5, "isPin": true}], "checksum": 28}' + - write-serial: '\n' + - wait-serial: '[SD] Checksum OK!' \ No newline at end of file diff --git a/tests/scenarios/test_netfsm_establish_wifi.scenario.yaml b/tests/scenarios/test_netfsm_establish_wifi.scenario.yaml new file mode 100644 index 000000000..1250ad9be --- /dev/null +++ b/tests/scenarios/test_netfsm_establish_wifi.scenario.yaml @@ -0,0 +1,10 @@ +name: NetFSM - Establish WiFi Connection +version: 1 +author: Brent Rubell for Adafruit Industries + +steps: + - wait-serial: 'Adafruit.io WipperSnapper' + - wait-serial: 'Establishing network connection...' + - wait-serial: 'Connecting to WiFi (attempt #0)' + - wait-serial: 'Connected to WiFi!' + - wait-serial: 'Connecting to AIO MQTT (attempt #0)' \ No newline at end of file diff --git a/tests/test_offline.py b/tests/test_offline.py new file mode 100644 index 000000000..06ccf4a00 --- /dev/null +++ b/tests/test_offline.py @@ -0,0 +1,49 @@ +# SPDX-FileCopyrightText: 2024-2025, Brent Rubell for Adafruit Industries +# SPDX-License-Identifier: MIT +# SPDX-FileDescription: Unit tests for WipperSnapper Offline Mode Functionality +import pytest +import subprocess + +def run_wokwi_cli(binary, timeout, scenario, diagram): + result = subprocess.run( + [ + "wokwi-cli", + "--elf", + binary, + "--timeout", + timeout, + "--scenario", + scenario, + "--diagram-file", + diagram, + ] + ) + return result + +def test_digital_input(): + result = run_wokwi_cli(f"tests/bin/offline/firmware.elf", "120000", f"tests/scenarios/offline/test-log-digital-in.scenario.yaml", f"tests/diagrams/offline.json") + assert result.returncode == 0 + + +def test_analog_input(): + result = run_wokwi_cli(f"tests/bin/offline/firmware.elf", "120000", f"tests/scenarios/offline/test-log-analogin.scenario.yaml", f"tests/diagrams/offline.json") + assert result.returncode == 0 + + +def test_ds18b20(): + result = run_wokwi_cli(f"tests/bin/offline/firmware.elf", "120000", f"tests/scenarios/offline/test-log-ds18b20.scenario.yaml", f"tests/diagrams/offline.json") + assert result.returncode == 0 + +def test_invalid_json(): + result = run_wokwi_cli(f"tests/bin/offline/firmware.elf", "120000", f"tests/scenarios/offline/test-invalid-json.scenario.yaml", f"tests/diagrams/offline.json") + assert result.returncode == 0 + + +def test_invalid_checksum(): + result = run_wokwi_cli(f"tests/bin/offline/firmware.elf", "120000", f"tests/scenarios/offline/test-invalid-checksum.scenario.yaml", f"tests/diagrams/offline.json") + assert result.returncode == 0 + + +def test_valid_checksum(): + result = run_wokwi_cli(f"tests/bin/offline/firmware.elf", "120000", f"tests/scenarios/offline/test-valid-checksum.scenario.yaml", f"tests/diagrams/offline.json") + assert result.returncode == 0 \ No newline at end of file diff --git a/tests/wokwi.toml b/tests/wokwi.toml new file mode 100644 index 000000000..646b42181 --- /dev/null +++ b/tests/wokwi.toml @@ -0,0 +1,6 @@ +[wokwi] +version = 1 +elf = "../.pio/build/esp32dev/firmware.elf" +firmware = "../.pio/build/esp32dev/firmware.bin" +gdbServerPort=3333 +rfc2217ServerPort = 4000 \ No newline at end of file diff --git a/tinyuf2-partitions-4MB-noota.csv b/tinyuf2-partitions-4MB-noota.csv new file mode 100644 index 000000000..ab7fa8669 --- /dev/null +++ b/tinyuf2-partitions-4MB-noota.csv @@ -0,0 +1,10 @@ +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +# bootloader.bin,, 0x1000, 32K +# partition table, 0x8000, 4K + +nvs, data, nvs, 0x9000, 20K, +otadata, data, ota, 0xe000, 8K, +ota_0, app, ota_0, 0x10000, 2816K, +uf2, app, factory,0x2d0000, 256K, +ffat, data, fat, 0x310000, 960K, diff --git a/tinyuf2-partitions-4MB.csv b/tinyuf2-partitions-4MB.csv new file mode 100644 index 000000000..f3112a23b --- /dev/null +++ b/tinyuf2-partitions-4MB.csv @@ -0,0 +1,11 @@ +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +# bootloader.bin,, 0x1000, 32K +# partition table, 0x8000, 4K + +nvs, data, nvs, 0x9000, 20K, +otadata, data, ota, 0xe000, 8K, +ota_0, app, ota_0, 0x10000, 1408K, +ota_1, app, ota_1, 0x170000, 1408K, +uf2, app, factory,0x2d0000, 256K, +ffat, data, fat, 0x310000, 960K, diff --git a/upload_no_build.py b/upload_no_build.py new file mode 100644 index 000000000..092d08f42 --- /dev/null +++ b/upload_no_build.py @@ -0,0 +1,8 @@ +Import("env") +env.AddCustomTarget( + "uploadnobuild", + None, + 'pio run -e %s -t nobuild -t upload' % + env["PIOENV"], + title="Uploads without building" +) \ No newline at end of file