diff --git a/.github/workflows/arduino-esp-v2-build-check.yml b/.github/workflows/arduino-esp-v2-build-check.yml index 313a864..4ce8b52 100644 --- a/.github/workflows/arduino-esp-v2-build-check.yml +++ b/.github/workflows/arduino-esp-v2-build-check.yml @@ -2,7 +2,7 @@ name: Build(arduino-esp32:2.x) env: SKETCH_NAMES_FIND_START: ./examples/UnitUnified - REQUIRED_LIBRARIES: M5Unified,M5UnitUnified,BME68x Sensor library,Bsec2 + REQUIRED_LIBRARIES: M5Unified,M5UnitUnified,BME68x Sensor library,bsec2 on: push: @@ -48,11 +48,11 @@ jobs: build: name: ${{ matrix.unit }}:${{ matrix.sketch }}:${{matrix.board}}@${{matrix.platform-version}} runs-on: ubuntu-latest - timeout-minutes: 5 + timeout-minutes: 12 strategy: fail-fast: false - #max-parallel: 1 + max-parallel: 20 matrix: platform-url: - https://espressif.github.io/arduino-esp32/package_esp32_index.json @@ -89,8 +89,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} # Build - name: Compile examples diff --git a/.github/workflows/arduino-esp-v3-build-check.yml b/.github/workflows/arduino-esp-v3-build-check.yml index b75ebf8..bfbad5b 100644 --- a/.github/workflows/arduino-esp-v3-build-check.yml +++ b/.github/workflows/arduino-esp-v3-build-check.yml @@ -48,11 +48,11 @@ jobs: build: name: ${{ matrix.unit }}:${{ matrix.sketch }}:${{matrix.board}}@${{matrix.platform-version}} runs-on: ubuntu-latest - timeout-minutes: 5 + timeout-minutes: 12 strategy: fail-fast: false - #max-parallel: 1 + max-parallel: 20 matrix: platform-url: - https://espressif.github.io/arduino-esp32/package_esp32_index.json @@ -69,15 +69,17 @@ jobs: - UnitENVPro board: + - arduino_nesso_n1 - m5stack_atom - m5stack_atoms3 - m5stack_capsule -# - m5stack_cardputer + - m5stack_cardputer - m5stack_core - m5stack_core2 - m5stack_coreink - m5stack_cores3 - m5stack_dial + - m5stack_dinmeter - m5stack_fire - m5stack_nanoc6 - m5stack_paper @@ -89,13 +91,14 @@ jobs: # - m5stack_stickc - m5stack_stickc_plus - m5stack_stickc_plus2 + - m5stack_tab5 # - m5stack_timer_cam # - m5stack_tough # - m5stack_unit_cam # - m5stack_unit_cams3 platform-version: - - 3.0.4 + - 3.3.6 platform: - esp32 @@ -103,11 +106,20 @@ jobs: archi: - esp32 + include: + # Specific sketches + # Paper + - sketch: Paper + platform-url: https://espressif.github.io/arduino-esp32/package_esp32_index.json + platform: esp32 + archi: esp32 + platform-version: 3.3.6 + board: m5stack_paper + unit: '' + steps: - name: Checkout uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} # Build - name: Compile examples diff --git a/.github/workflows/arduino-m5-build-check.yml b/.github/workflows/arduino-m5-build-check.yml index 207da75..7ce94ec 100644 --- a/.github/workflows/arduino-m5-build-check.yml +++ b/.github/workflows/arduino-m5-build-check.yml @@ -48,11 +48,11 @@ jobs: build: name: ${{ matrix.unit }}:${{ matrix.sketch }}:${{matrix.board}}@${{matrix.platform-version}} runs-on: ubuntu-latest - timeout-minutes: 5 + timeout-minutes: 12 strategy: fail-fast: false -# max-parallel: 1 + max-parallel: 20 matrix: platform-url: - https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json @@ -69,11 +69,13 @@ jobs: - UnitENVPro board: + - arduino_nesso_n1 - m5stack_atom - m5stack_atoms3 - m5stack_atoms3r - m5stack_capsule -# - m5stack_cardputer + - m5stack_cardputer +# - m5stack_chain_dualkey - m5stack_core - m5stack_core2 - m5stack_coreink @@ -81,22 +83,30 @@ jobs: - m5stack_dial - m5stack_dinmeter - m5stack_fire + - m5stack_nano_c6 +# - m5stack_nano_h2 - m5stack_paper + - m5stack_papers3 # - m5stack_poe_cam +# - m5stack_powerhub # - m5stack_stamp_c3 # - m5stack_stamp_pico - m5stack_stamp_s3 +# - m5stack_stamplc # - m5stack_station -# - m5stack_stickc + - m5stack_stickc - m5stack_stickc_plus - m5stack_stickc_plus2 + - m5stack_sticks3 + - m5stack_tab5 # - m5stack_timer_cam # - m5stack_tough +# - m5stack_unit_c6l # - m5stack_unit_cam # - m5stack_unit_cams3 platform-version: - - 3.2.1 + - 3.2.5 platform: - m5stack @@ -104,11 +114,20 @@ jobs: archi: - esp32 + include: + # Specific sketches + # Paper + - sketch: Paper + platform-url: https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json + platform: m5stack + archi: esp32 + platform-version: 3.2.5 + board: m5stack_paper + unit: '' + steps: - name: Checkout uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} # Build - name: Compile examples diff --git a/.github/workflows/clang-format-check.yml b/.github/workflows/clang-format-check.yml index 3453b52..9fbec79 100644 --- a/.github/workflows/clang-format-check.yml +++ b/.github/workflows/clang-format-check.yml @@ -56,11 +56,9 @@ jobs: steps: - name: Checkout # When pull_request is used, include it in the checkout https://zenn.dev/hkusu/articles/c731862051438b uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - name: Run clang-format style check for C/C++/Protobuf programs. - uses: jidicula/clang-format-action@v4.10.2 # Using include-regex 10.x or later + uses: jidicula/clang-format-action@v4.16.0 # Using include-regex 10.x or later with: clang-format-version: '13' check-path: ${{ matrix.path['check'] }} diff --git a/.github/workflows/doxygen-gh-pages.yml b/.github/workflows/doxygen-gh-pages.yml index 83c1c96..59c8172 100644 --- a/.github/workflows/doxygen-gh-pages.yml +++ b/.github/workflows/doxygen-gh-pages.yml @@ -1,8 +1,10 @@ -name: Deploy Doxygen docuemnt on GitHub Pages +name: Deploy Doxygen document on GitHub Pages on: [release, workflow_dispatch] # branches: # - main # - master +permissions: + contents: write defaults: run: shell: bash diff --git a/.github/workflows/platformio-build-check.yml b/.github/workflows/platformio-build-check.yml index 41f67fc..0b8c48f 100644 --- a/.github/workflows/platformio-build-check.yml +++ b/.github/workflows/platformio-build-check.yml @@ -46,11 +46,11 @@ jobs: build: name: ${{ matrix.unit }}:${{ matrix.example }}@${{ matrix.board }}:${{ matrix.framework }}:${{ matrix.espressif32 }} runs-on: ubuntu-latest - timeout-minutes: 5 + timeout-minutes: 12 strategy: fail-fast: false - #max-parallel: 1 + max-parallel: 20 matrix: example: @@ -61,8 +61,8 @@ jobs: - UnitCO2L - UnitENVIII - UnitENVIV - - UnitTVOC - UnitENVPro + - UnitTVOC board: - Core @@ -71,58 +71,39 @@ jobs: - Fire - StampS3 - Dial - - AtomMatrix + - Atom - AtomS3 - AtomS3R - NanoC6 - StickCPlus - StickCPlus2 + - StickS3 - Paper - CoreInk + - Cardputer + - Tab5 + - NessoN1 framework: - Arduino espressif32: - latest -# - '5_4_0' -# - '4_4_0' -# exclude: -# - board: CoreS3 -# espressif32: '5_4_0' -# - board: CoreS3 -# espressif32: '4_4_0' -# - board: StampS3 -# espressif32: '5_4_0' -# - board: StampS3 -# espressif32: '4_4_0' -# - board: AtomS3 -# espressif32: '5_4_0' -# - board: AtomS3 -# espressif32: '4_4_0' -# - board: Dial -# espressif32: '5_4_0' -# - board: Dial -# espressif32: '4_4_0' -# - board: NanoC6 -# espressif32: '5_4_0' -# - board: NanoC6 -# espressif32: '4_4_0' -# - board: StickCPlus -# espressif32: '5_4_0' -# - board: StickCPlus -# espressif32: '4_4_0' -# - board: Paper -# espressif32: '5_4_0' -# - board: Paper -# espressif32: '4_4_0' + + include: + # Specific sketches + # Paper + - example: Paper + unit: BuiltinSHT30 + board: Paper + framework: Arduino + espressif32: latest + steps: - name: Checkout uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - name: Build examples uses: karniv00l/platformio-run-action@v1 diff --git a/README.md b/README.md index 8a55e5b..c8f9269 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,14 @@ CO2 is a photoacoustic Carbon Dioxide (CO2) Unit that will tell you the CO2 PPM ## Related Link -- [Unit ENVIV - Document & Datasheet](https://docs.m5stack.com/en/unit/ENV%E2%85%A3%20Unit) +- [Unit ENVIV - Document & Datasheet](https://docs.m5stack.com/en/unit/Unit_ENV-IV) - [Unit ENVIII - Document & Datasheet](https://docs.m5stack.com/en/unit/envIII) - [Unit ENVII - Document & Datasheet](https://docs.m5stack.com/en/unit/envII) - [Unit ENV - Document & Datasheet](https://docs.m5stack.com/en/unit/env) - [Hat ENVIII - Document & Datasheet](https://docs.m5stack.com/en/hat/hat_envIII) - [Hat ENVII - Document & Datasheet](https://docs.m5stack.com/en/hat/hat_envII) - [Unit BPS - Document & Datasheet](https://docs.m5stack.com/en/unit/bps) -- [Unit BPS(QMP6988) - Document & Datasheet](https://docs.m5stack.com/en/unit/BPS(QMP6988)) +- [Unit BPS(QMP6988) - Document & Datasheet](https://docs.m5stack.com/en/unit/BPS%28QMP6988%29) - [Unit CO2 - Document & Datasheet](https://docs.m5stack.com/en/unit/co2) ## Required Libraries: @@ -56,7 +56,7 @@ M5UnitUnified is a library for unified handling of various M5 units products. TVOC/eCO2 mini Unit is a digital multi-pixel gas sensor unit with integrated SGP30. -It mainly measures various VOC (volatile organic compounds) and H2 in the air. It can be programmed to detect TVOC (total volatile organic compounds) and eCO2 (equivalent carbon dioxide reading)Concentration measurement. +It mainly measures various VOC (volatile organic compounds) and H2 in the air. It can be programmed to detect TVOC (total volatile organic compounds) and eCO2 (equivalent carbon dioxide reading) Concentration measurement. Typical measurement accuracy is 15% within the measurement range, the SGP30 reading is internally calibrated and output, which can maintain long-term stability. SGP30 uses I2C protocol communication with on-chip humidity compensation function, which can be turned on through an external humidity sensor. diff --git a/docs/Doxyfile b/docs/Doxyfile index ea43d72..9b11d9f 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -42,7 +42,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = M5Unit-ENV +PROJECT_NAME = "M5Unit-ENV" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version diff --git a/docs/doxy.sh b/docs/doxy.sh index 064edd0..d4492c9 100755 --- a/docs/doxy.sh +++ b/docs/doxy.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Please execute on repositry root +# Please execute on repository root ## Get version from library.properties ## Get git rev of HEAD diff --git a/examples/UnitUnified/Paper/Paper.ino b/examples/UnitUnified/Paper/Paper.ino new file mode 100644 index 0000000..954cb58 --- /dev/null +++ b/examples/UnitUnified/Paper/Paper.ino @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD + * + * SPDX-License-Identifier: MIT + */ +/* + Example of Using the M5UnitUnified for SHT30 Built into M5Paper +*/ +#include "main/Paper.cpp" diff --git a/examples/UnitUnified/Paper/main/Paper.cpp b/examples/UnitUnified/Paper/main/Paper.cpp new file mode 100644 index 0000000..e5e94af --- /dev/null +++ b/examples/UnitUnified/Paper/main/Paper.cpp @@ -0,0 +1,134 @@ +/* + * SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD + * + * SPDX-License-Identifier: MIT + */ +/* + Example of Using the M5UnitUnified for SHT30 Built into M5Paper +*/ +#include +#include +#include +#include + +namespace { +auto& lcd = M5.Display; +m5::unit::UnitUnified Units; +m5::unit::UnitSHT30 sht30; +float latest_temperature{}; +float latest_humidity{}; +bool has_measurement{}; +uint32_t last_lcd_update_ms{}; + +void draw_dashboard(const float temperature, const float humidity) +{ + char temp_text[32]; + char hum_text[32]; + std::snprintf(temp_text, sizeof(temp_text), "%7.2f C ", temperature); + std::snprintf(hum_text, sizeof(hum_text), "%7.2f %% ", humidity); + + const int w = lcd.width(); + const int h = lcd.height(); + + constexpr int value_x = 220; + constexpr int temp_value_y = 130; + const int humid_value_y = h / 2 + 58; + + static bool initialized{}; + lcd.startWrite(); + if (!initialized) { + lcd.fillScreen(TFT_WHITE); + lcd.drawRoundRect(12, 12, w - 24, h - 24, 16, TFT_BLACK); + lcd.drawFastHLine(28, 88, w - 56, TFT_BLACK); + lcd.drawFastHLine(28, h / 2 + 20, w - 56, TFT_BLACK); + + lcd.setTextColor(TFT_BLACK, TFT_WHITE); + lcd.setTextSize(1); + lcd.setCursor(40, 28); + lcd.print("M5PAPER SHT30 MONITOR"); + + lcd.setCursor(40, 116); + lcd.print("TEMP"); + lcd.setCursor(40, h / 2 + 44); + lcd.print("HUMID"); + + lcd.setTextSize(1); + lcd.setCursor(w - 440, h - 44); + lcd.print("refresh:touch or 60s"); + initialized = true; + } + + lcd.setTextColor(TFT_BLACK, TFT_WHITE); + lcd.setTextSize(3.5f); + lcd.setCursor(value_x, temp_value_y); + lcd.print(temp_text); + lcd.setCursor(value_x, humid_value_y); + lcd.print(hum_text); + lcd.endWrite(); +} +} // namespace + +void setup() +{ + { + auto cfg = sht30.config(); + cfg.mps = m5::unit::sht30::MPS::Half; // 0.5Hz (about every 2 seconds) + sht30.config(cfg); + } + + M5.begin(); + if (M5.getBoard() != m5::board_t::board_M5Paper) { + M5_LOGE("This example is for the SHT30 sensor built into the M5Paper"); + lcd.fillScreen(TFT_RED); + while (true) { + m5::utility::delay(10000); + } + } + + M5.setTouchButtonHeightByRatio(100); + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } + lcd.setFont(&fonts::Orbitron_Light_32); + + // The built-in SHT30 is used via M5.In_I2C + if (!Units.add(sht30, M5.In_I2C) || !Units.begin()) { + M5_LOGE("Failed to begin"); + M5_LOGW("%s", Units.debugInfo().c_str()); + lcd.fillScreen(TFT_RED); + while (true) { + m5::utility::delay(10000); + } + } + + M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("%s", Units.debugInfo().c_str()); + lcd.fillScreen(TFT_WHITE); + last_lcd_update_ms = m5::utility::millis() - 60 * 1000U; +} + +void loop() +{ + M5.update(); + Units.update(); + const auto now = m5::utility::millis(); + bool touch_redraw{}; + + if (M5.Touch.getCount()) { + const auto td = M5.Touch.getDetail(0); + touch_redraw = td.wasPressed() || td.wasClicked(); + } + + if (sht30.updated()) { + latest_temperature = sht30.temperature(); + latest_humidity = sht30.humidity(); + has_measurement = true; + M5.Log.printf(">SHT30Temp:%2.2f\n>Humidity:%2.2f\n", latest_temperature, latest_humidity); + } + + if (has_measurement && (now - last_lcd_update_ms >= 60 * 1000U || touch_redraw)) { + draw_dashboard(latest_temperature, latest_humidity); + last_lcd_update_ms = now; + } +} diff --git a/examples/UnitUnified/UnitCO2/PlotToSerial/main/PlotToSerial.cpp b/examples/UnitUnified/UnitCO2/PlotToSerial/main/PlotToSerial.cpp index 1af26ad..4490899 100644 --- a/examples/UnitUnified/UnitCO2/PlotToSerial/main/PlotToSerial.cpp +++ b/examples/UnitUnified/UnitCO2/PlotToSerial/main/PlotToSerial.cpp @@ -6,10 +6,10 @@ /* Example using M5UnitUnified for UnitCO2 */ -// #define USING_M5HAL // When using M5HAL #include #include #include +#include // For NessoN1 namespace { auto& lcd = M5.Display; @@ -20,38 +20,51 @@ m5::unit::UnitCO2 unit; void setup() { M5.begin(); + M5.setTouchButtonHeightByRatio(100); + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + auto board = M5.getBoard(); -#if defined(USING_M5HAL) -#pragma message "Using M5HAL" - // Using M5HAL - m5::hal::bus::I2CBusConfig i2c_cfg; - i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); - i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); - auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); - if (!Units.add(unit, i2c_bus ? i2c_bus.value() : nullptr) || !Units.begin()) { - M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); - while (true) { - m5::utility::delay(10000); - } + // NessoN1: Arduino Wire (I2C_NUM_0) cannot be used for GROVE port. + // Wire is used by M5Unified In_I2C for internal devices (IOExpander etc.). + // Solution: Use SoftwareI2C via M5HAL (bit-banging) for the GROVE port. + // NanoC6: Wire.begin() on GROVE pins conflicts with m5::I2C_Class registered by Ex_I2C.setPort() + // on the same I2C_NUM_0, causing sporadic NACK errors. + // Solution: Use M5.Ex_I2C (m5::I2C_Class) directly instead of Arduino Wire. + bool unit_ready{}; + if (board == m5::board_t::board_ArduinoNessoN1) { + // NessoN1: GROVE is on port_b (GPIO 5/4), not port_a (which maps to Wire pins 8/10) + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_b_out); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_b_in); + M5_LOGI("getPin(M5HAL): SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + m5::hal::bus::I2CBusConfig i2c_cfg; + i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); + i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); + auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); + M5_LOGI("Bus:%d", i2c_bus.has_value()); + unit_ready = Units.add(unit, i2c_bus ? i2c_bus.value() : nullptr) && Units.begin(); + } else if (board == m5::board_t::board_M5NanoC6) { + // NanoC6: Use M5.Ex_I2C (m5::I2C_Class, not Arduino Wire) + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + Wire.end(); + Wire.begin(pin_num_sda, pin_num_scl, 400 * 1000U); + unit_ready = Units.add(unit, Wire) && Units.begin(); } -#else -#pragma message "Using Wire" - // Using TwoWire - Wire.end(); - Wire.begin(pin_num_sda, pin_num_scl, 400000U); - if (!Units.add(unit, Wire) || !Units.begin()) { + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } } -#endif M5_LOGI("M5UnitUnified has been begun"); M5_LOGI("%s", Units.debugInfo().c_str()); @@ -78,13 +91,13 @@ void setup() offset, altitude, pressure, asc, ppm); if (!ret) { - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } } } - lcd.clear(TFT_DARKGREEN); + lcd.fillScreen(TFT_DARKGREEN); } void loop() @@ -95,5 +108,10 @@ void loop() // Can be checked e.g. by serial plotters M5.Log.printf(">CO2:%u\n>Temperature:%2.2f\n>Humidity:%2.2f\n", unit.co2(), unit.temperature(), unit.humidity()); + lcd.startWrite(); + lcd.fillRect(0, 0, lcd.width(), lcd.fontHeight() * 3, TFT_BLACK); + lcd.setCursor(0, 0); + lcd.printf("CO2:%u\nTemperature:%2.2f\nHumidity:%2.2f", unit.co2(), unit.temperature(), unit.humidity()); + lcd.endWrite(); } } diff --git a/examples/UnitUnified/UnitCO2L/PlotToSerial/main/PlotToSerial.cpp b/examples/UnitUnified/UnitCO2L/PlotToSerial/main/PlotToSerial.cpp index 5cd33c6..875d255 100644 --- a/examples/UnitUnified/UnitCO2L/PlotToSerial/main/PlotToSerial.cpp +++ b/examples/UnitUnified/UnitCO2L/PlotToSerial/main/PlotToSerial.cpp @@ -6,10 +6,10 @@ /* Example using M5UnitUnified for UnitCO2L */ -// #define USING_M5HAL // When using M5HAL #include #include #include +#include // For NessoN1 namespace { auto& lcd = M5.Display; @@ -23,38 +23,51 @@ using namespace m5::unit::scd4x; void setup() { M5.begin(); + M5.setTouchButtonHeightByRatio(100); + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + auto board = M5.getBoard(); -#if defined(USING_M5HAL) -#pragma message "Using M5HAL" - // Using M5HAL - m5::hal::bus::I2CBusConfig i2c_cfg; - i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); - i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); - auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); - if (!Units.add(unit, i2c_bus ? i2c_bus.value() : nullptr) || !Units.begin()) { - M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); - while (true) { - m5::utility::delay(10000); - } + // NessoN1: Arduino Wire (I2C_NUM_0) cannot be used for GROVE port. + // Wire is used by M5Unified In_I2C for internal devices (IOExpander etc.). + // Solution: Use SoftwareI2C via M5HAL (bit-banging) for the GROVE port. + // NanoC6: Wire.begin() on GROVE pins conflicts with m5::I2C_Class registered by Ex_I2C.setPort() + // on the same I2C_NUM_0, causing sporadic NACK errors. + // Solution: Use M5.Ex_I2C (m5::I2C_Class) directly instead of Arduino Wire. + bool unit_ready{}; + if (board == m5::board_t::board_ArduinoNessoN1) { + // NessoN1: GROVE is on port_b (GPIO 5/4), not port_a (which maps to Wire pins 8/10) + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_b_out); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_b_in); + M5_LOGI("getPin(M5HAL): SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + m5::hal::bus::I2CBusConfig i2c_cfg; + i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); + i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); + auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); + M5_LOGI("Bus:%d", i2c_bus.has_value()); + unit_ready = Units.add(unit, i2c_bus ? i2c_bus.value() : nullptr) && Units.begin(); + } else if (board == m5::board_t::board_M5NanoC6) { + // NanoC6: Use M5.Ex_I2C (m5::I2C_Class, not Arduino Wire) + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + Wire.end(); + Wire.begin(pin_num_sda, pin_num_scl, 400 * 1000U); + unit_ready = Units.add(unit, Wire) && Units.begin(); } -#else -#pragma message "Using Wire" - // Using TwoWire - Wire.end(); - Wire.begin(pin_num_sda, pin_num_scl, 400000U); - if (!Units.add(unit, Wire) || !Units.begin()) { + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } } -#endif M5_LOGI("M5UnitUnified has been begun"); M5_LOGI("%s", Units.debugInfo().c_str()); @@ -87,19 +100,18 @@ void setup() offset, altitude, pressure, asc, ppm, initialPeriod, standardPeriod); if (!ret) { - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(1000); } } } - lcd.clear(TFT_DARKGREEN); + lcd.fillScreen(TFT_DARKGREEN); } void loop() { M5.update(); - auto touch = M5.Touch.getDetail(); // Periodic Units.update(); @@ -107,10 +119,15 @@ void loop() // Can be checked e.g. by serial plotters M5.Log.printf(">CO2:%u\n>Temperature:%2.2f\n>Humidity:%2.2f\n", unit.co2(), unit.temperature(), unit.humidity()); + lcd.startWrite(); + lcd.fillRect(0, 0, lcd.width(), lcd.fontHeight() * 3, TFT_BLACK); + lcd.setCursor(0, 0); + lcd.printf("CO2:%u\nTemperature:%2.2f\nHumidity:%2.2f", unit.co2(), unit.temperature(), unit.humidity()); + lcd.endWrite(); } // Single shot - if (M5.BtnA.wasClicked() || touch.wasClicked()) { + if (M5.BtnA.wasClicked()) { static bool all{}; // false: RHT only all = !all; M5.Log.printf("Try single shot %u, waiting measurement...\n", all); @@ -118,11 +135,11 @@ void loop() Data d{}; if (all) { if (unit.measureSingleshot(d)) { - M5.Log.printf(" SingleAll: %u/%2.2f/%2.2f\n", d.co2(), d.temperature(), d.humidity()); + M5.Log.printf(" SingleAll: CO2:%u T:%2.2f H:%2.2f\n", d.co2(), d.temperature(), d.humidity()); } } else { if (unit.measureSingleshotRHT(d)) { - M5.Log.printf(" SingleRHT: %2.2f/%2.2f", d.temperature(), d.humidity()); + M5.Log.printf(" SingleRHT: T:%2.2f H:%2.2f\n", d.temperature(), d.humidity()); } } unit.startPeriodicMeasurement(); diff --git a/examples/UnitUnified/UnitENVIII/PlotToSerial/main/PlotToSerial.cpp b/examples/UnitUnified/UnitENVIII/PlotToSerial/main/PlotToSerial.cpp index 3956e0e..a2f39d7 100644 --- a/examples/UnitUnified/UnitENVIII/PlotToSerial/main/PlotToSerial.cpp +++ b/examples/UnitUnified/UnitENVIII/PlotToSerial/main/PlotToSerial.cpp @@ -9,11 +9,7 @@ #include #include #include - -// #define USING_M5HAL // When using M5HAL - -// Using single shot measurement If defined -// #define USING_SINGLE_SHOT +#include // For NessoN1 // Using combined unit if defined #define USING_ENV3 @@ -43,87 +39,69 @@ auto& qmp6988 = unitQMP6988; void setup() { M5.begin(); - - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); - -#if defined(USING_SINGLE_SHOT) - { - auto cfg = sht30.config(); - cfg.start_periodic = false; - sht30.config(cfg); + M5.setTouchButtonHeightByRatio(100); + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); } - { - auto cfg = qmp6988.config(); - cfg.start_periodic = false; - qmp6988.config(cfg); - } -#endif + auto board = M5.getBoard(); + + // NessoN1: Arduino Wire (I2C_NUM_0) cannot be used for GROVE port. + // Wire is used by M5Unified In_I2C for internal devices (IOExpander etc.). + // Solution: Use SoftwareI2C via M5HAL (bit-banging) for the GROVE port. + // NanoC6: Wire.begin() on GROVE pins conflicts with m5::I2C_Class registered by Ex_I2C.setPort() + // on the same I2C_NUM_0, causing sporadic NACK errors. + // Solution: Use M5.Ex_I2C (m5::I2C_Class) directly instead of Arduino Wire. + bool unit_ready{}; + if (board == m5::board_t::board_ArduinoNessoN1) { + // NessoN1: GROVE is on port_b (GPIO 5/4), not port_a (which maps to Wire pins 8/10) + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_b_out); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_b_in); + M5_LOGI("getPin(M5HAL): SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + m5::hal::bus::I2CBusConfig i2c_cfg; + i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); + i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); + auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); + M5_LOGI("Bus:%d", i2c_bus.has_value()); #if defined(USING_ENV3) -#if defined(USING_M5HAL) -#pragma message "Using M5HAL" - m5::hal::bus::I2CBusConfig i2c_cfg; - i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); - i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); - auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); - if (!Units.add(unitENV3, i2c_bus ? i2c_bus.value() : nullptr) || !Units.begin()) { - M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); - while (true) { - m5::utility::delay(10000); - } - } + unit_ready = Units.add(unitENV3, i2c_bus ? i2c_bus.value() : nullptr) && Units.begin(); #else -#pragma message "Using Wire" - Wire.end(); - Wire.begin(pin_num_sda, pin_num_scl, 400000U); - - if (!Units.add(unitENV3, Wire) || !Units.begin()) { - M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); - while (true) { - m5::utility::delay(10000); - } - } + unit_ready = Units.add(unitSHT30, i2c_bus ? i2c_bus.value() : nullptr) && + Units.add(unitQMP6988, i2c_bus ? i2c_bus.value() : nullptr) && Units.begin(); #endif - + } else if (board == m5::board_t::board_M5NanoC6) { + // NanoC6: Use M5.Ex_I2C (m5::I2C_Class, not Arduino Wire) + M5_LOGI("Using M5.Ex_I2C"); +#if defined(USING_ENV3) + unit_ready = Units.add(unitENV3, M5.Ex_I2C) && Units.begin(); #else - -#if defined(USING_M5HAL) -#pragma message "Using M5HAL" - m5::hal::bus::I2CBusConfig i2c_cfg; - i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); - i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); - auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); - if (!Units.add(unitSHT30, i2c_bus ? i2c_bus.value() : nullptr) || - !Units.add(unitQMP6988, i2c_bus ? i2c_bus.value() : nullptr) || !Units.begin()) { - M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); - while (true) { - m5::utility::delay(10000); - } - } + unit_ready = Units.add(unitSHT30, M5.Ex_I2C) && Units.add(unitQMP6988, M5.Ex_I2C) && Units.begin(); +#endif + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + Wire.end(); + Wire.begin(pin_num_sda, pin_num_scl, 400 * 1000U); +#if defined(USING_ENV3) + unit_ready = Units.add(unitENV3, Wire) && Units.begin(); #else -#pragma message "Using Wire" - Wire.begin(pin_num_sda, pin_num_scl, 400000U); - if (!Units.add(unitSHT30, Wire) || !Units.add(unitQMP6988, Wire) || !Units.begin()) { + unit_ready = Units.add(unitSHT30, Wire) && Units.add(unitQMP6988, Wire) && Units.begin(); +#endif + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + M5_LOGW("%s", Units.debugInfo().c_str()); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } } -#endif -#endif M5_LOGI("M5UnitUnified has been begun"); M5_LOGI("%s", Units.debugInfo().c_str()); -#if defined(USING_SINGLE_SHOT) - M5_LOGI("\n>>> Click BtnA to single shot measurement"); -#endif - lcd.clear(TFT_DARKGREEN); + lcd.fillScreen(TFT_DARKGREEN); } void loop() @@ -131,23 +109,41 @@ void loop() M5.update(); Units.update(); -#if defined(USING_SINGLE_SHOT) + if (sht30.updated()) { + M5.Log.printf(">SHT30Temp:%2.2f\n>Humidity:%2.2f\n", sht30.temperature(), sht30.humidity()); + lcd.startWrite(); + lcd.fillRect(0, 0, lcd.width(), lcd.fontHeight() * 3, TFT_BLACK); + lcd.setCursor(0, 0); + lcd.printf("SHT30\nTemp:%2.2f\nHumidity:%2.2f", sht30.temperature(), sht30.humidity()); + lcd.endWrite(); + } + if (qmp6988.updated()) { + M5.Log.printf(">QMP6988Temp:%2.2f\n>Pressure:%.2f\n", qmp6988.temperature(), qmp6988.pressure() * 0.01f); + lcd.startWrite(); + lcd.fillRect(0, lcd.fontHeight() * 3, lcd.width(), lcd.fontHeight() * 3, TFT_BLACK); + lcd.setCursor(0, lcd.fontHeight() * 3); + lcd.printf("QMP6988\nTemp:%2.2f\nPressure:%.2f", qmp6988.temperature(), qmp6988.pressure() * 0.01f); + lcd.endWrite(); + } + if (M5.BtnA.wasClicked()) { + sht30.stopPeriodicMeasurement(); + qmp6988.stopPeriodicMeasurement(); + m5::unit::sht30::Data ds{}; if (sht30.measureSingleshot(ds)) { - M5.Log.printf(">SHT30Temp:%2.2f\n>Humidity:%2.2f\n", ds.temperature(), ds.humidity()); + M5.Log.printf("== Singleshot SHT30 Temp:%2.2f Humidity:%2.2f\n", ds.temperature(), ds.humidity()); + } else { + M5_LOGW("Single SHT30 failed"); } m5::unit::qmp6988::Data dq{}; if (qmp6988.measureSingleshot(dq)) { - M5.Log.printf(">QMP6988Temp:%2.2f\n>Pressure:%.2f\n", dq.temperature(), dq.pressure() * 0.01f); + M5.Log.printf("== Singleshot QMP6988 Temp:%2.2f Pressure:%.2f\n", dq.temperature(), dq.pressure() * 0.01f); + } else { + M5_LOGW("Single QMP failed"); } + + sht30.startPeriodicMeasurement(); + qmp6988.startPeriodicMeasurement(); } -#else - if (sht30.updated()) { - M5.Log.printf(">SHT30Temp:%2.2f\n>Humidity:%2.2f\n", sht30.temperature(), sht30.humidity()); - } - if (qmp6988.updated()) { - M5.Log.printf(">QMP6988Temp:%2.2f\n>Pressure:%.2f\n", qmp6988.temperature(), qmp6988.pressure() * 0.01f); - } -#endif } diff --git a/examples/UnitUnified/UnitENVIV/PlotToSerial/main/PlotToSerial.cpp b/examples/UnitUnified/UnitENVIV/PlotToSerial/main/PlotToSerial.cpp index 00b05b9..44fedd5 100644 --- a/examples/UnitUnified/UnitENVIV/PlotToSerial/main/PlotToSerial.cpp +++ b/examples/UnitUnified/UnitENVIV/PlotToSerial/main/PlotToSerial.cpp @@ -9,8 +9,10 @@ #include #include #include +#include // For NessoN1 #include +// Using combined unit if defined #define USING_ENV4 namespace { @@ -44,10 +46,11 @@ float calculate_altitude(const float pressure, const float seaLvhPa = 1013.25f) void setup() { M5.begin(); - - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + M5.setTouchButtonHeightByRatio(100); + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } { using namespace m5::unit::bmp280; @@ -59,32 +62,62 @@ void setup() bmp280.config(cfg); } -#if defined(USING_ENV4) - Wire.end(); - Wire.begin(pin_num_sda, pin_num_scl, 400000U); + auto board = M5.getBoard(); - if (!Units.add(unitENV4, Wire) || !Units.begin()) { - M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); - while (true) { - m5::utility::delay(10000); - } - } + // NessoN1: Arduino Wire (I2C_NUM_0) cannot be used for GROVE port. + // Wire is used by M5Unified In_I2C for internal devices (IOExpander etc.). + // Solution: Use SoftwareI2C via M5HAL (bit-banging) for the GROVE port. + // NanoC6: Wire.begin() on GROVE pins conflicts with m5::I2C_Class registered by Ex_I2C.setPort() + // on the same I2C_NUM_0, causing sporadic NACK errors. + // Solution: Use M5.Ex_I2C (m5::I2C_Class) directly instead of Arduino Wire. + bool unit_ready{}; + if (board == m5::board_t::board_ArduinoNessoN1) { + // NessoN1: GROVE is on port_b (GPIO 5/4), not port_a (which maps to Wire pins 8/10) + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_b_out); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_b_in); + M5_LOGI("getPin(M5HAL): SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + m5::hal::bus::I2CBusConfig i2c_cfg; + i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); + i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); + auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); + M5_LOGI("Bus:%d", i2c_bus.has_value()); +#if defined(USING_ENV4) + unit_ready = Units.add(unitENV4, i2c_bus ? i2c_bus.value() : nullptr) && Units.begin(); +#else + unit_ready = Units.add(unitSHT40, i2c_bus ? i2c_bus.value() : nullptr) && + Units.add(unitBMP280, i2c_bus ? i2c_bus.value() : nullptr) && Units.begin(); +#endif + } else if (board == m5::board_t::board_M5NanoC6) { + // NanoC6: Use M5.Ex_I2C (m5::I2C_Class, not Arduino Wire) + M5_LOGI("Using M5.Ex_I2C"); +#if defined(USING_ENV4) + unit_ready = Units.add(unitENV4, M5.Ex_I2C) && Units.begin(); +#else + unit_ready = Units.add(unitSHT40, M5.Ex_I2C) && Units.add(unitBMP280, M5.Ex_I2C) && Units.begin(); +#endif + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + Wire.end(); + Wire.begin(pin_num_sda, pin_num_scl, 400 * 1000U); +#if defined(USING_ENV4) + unit_ready = Units.add(unitENV4, Wire) && Units.begin(); #else - Wire.end(); - Wire.begin(pin_num_sda, pin_num_scl, 400000U); - if (!Units.add(unitSHT40, Wire) || !Units.add(unitBMP280, Wire) || !Units.begin()) { + unit_ready = Units.add(unitSHT40, Wire) && Units.add(unitBMP280, Wire) && Units.begin(); +#endif + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } } -#endif M5_LOGI("M5UnitUnified has been begun"); M5_LOGI("%s", Units.debugInfo().c_str()); - lcd.clear(TFT_DARKGREEN); + lcd.fillScreen(TFT_DARKGREEN); } void loop() @@ -97,6 +130,16 @@ void loop() ">SHT40Temp:%.4f\n" ">Humidity:%.4f\n", sht40.temperature(), sht40.humidity()); + + lcd.startWrite(); + lcd.fillRect(0, 0, lcd.width(), lcd.fontHeight() * 3, TFT_BLACK); + lcd.setCursor(0, 0); + lcd.printf( + "SHT40\n" + "Temp:%.4f\n" + "Humidity:%.4f", + sht40.temperature(), sht40.humidity()); + lcd.endWrite(); } if (bmp280.updated()) { auto p = bmp280.pressure(); @@ -105,5 +148,37 @@ void loop() ">Pressure:%.4f\n" ">Altitude:%.4f\n", bmp280.temperature(), p * 0.01f /* To hPa */, calculate_altitude(p)); + + lcd.startWrite(); + lcd.fillRect(0, lcd.fontHeight() * 3, lcd.width(), lcd.fontHeight() * 4, TFT_BLACK); + lcd.setCursor(0, lcd.fontHeight() * 3); + lcd.printf( + "BMP280\n" + "Temp:%.4f\n" + "Pressure:%.4f\n" + "Altitude:%.4f", + bmp280.temperature(), p * 0.01f /* To hPa */, calculate_altitude(p)); + lcd.endWrite(); + } + + if (M5.BtnA.wasClicked()) { + sht40.stopPeriodicMeasurement(); + bmp280.stopPeriodicMeasurement(); + + m5::unit::sht40::Data ds{}; + if (sht40.measureSingleshot(ds)) { + M5.Log.printf("== Singleshot SHT40 Temp:%.4f Humidity:%.4f\n", ds.temperature(), ds.humidity()); + } else { + M5_LOGW("Single SHT40 failed"); + } + m5::unit::bmp280::Data db{}; + if (bmp280.measureSingleshot(db)) { + M5.Log.printf("== Singleshot BMP280 Temp:%.4f Pressure:%.4f\n", db.temperature(), db.pressure() * 0.01f); + } else { + M5_LOGW("Single BMP280 failed"); + } + + sht40.startPeriodicMeasurement(); + bmp280.startPeriodicMeasurement(); } } diff --git a/examples/UnitUnified/UnitENVPro/PlotToSerial/main/PlotToSerial.cpp b/examples/UnitUnified/UnitENVPro/PlotToSerial/main/PlotToSerial.cpp index a7ff756..895eba1 100644 --- a/examples/UnitUnified/UnitENVPro/PlotToSerial/main/PlotToSerial.cpp +++ b/examples/UnitUnified/UnitENVPro/PlotToSerial/main/PlotToSerial.cpp @@ -9,6 +9,7 @@ #include #include #include +#include // For NessoN1 namespace { auto& lcd = M5.Display; @@ -19,16 +20,47 @@ m5::unit::UnitENVPro unit; void setup() { M5.begin(); + M5.setTouchButtonHeightByRatio(100); + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); - Wire.end(); - Wire.begin(pin_num_sda, pin_num_scl, 400 * 1000U); + auto board = M5.getBoard(); - if (!Units.add(unit, Wire) || !Units.begin()) { + // NessoN1: Arduino Wire (I2C_NUM_0) cannot be used for GROVE port. + // Wire is used by M5Unified In_I2C for internal devices (IOExpander etc.). + // Solution: Use SoftwareI2C via M5HAL (bit-banging) for the GROVE port. + // NanoC6: Wire.begin() on GROVE pins conflicts with m5::I2C_Class registered by Ex_I2C.setPort() + // on the same I2C_NUM_0, causing sporadic NACK errors. + // Solution: Use M5.Ex_I2C (m5::I2C_Class) directly instead of Arduino Wire. + bool unit_ready{}; + if (board == m5::board_t::board_ArduinoNessoN1) { + // NessoN1: GROVE is on port_b (GPIO 5/4), not port_a (which maps to Wire pins 8/10) + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_b_out); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_b_in); + M5_LOGI("getPin(M5HAL): SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + m5::hal::bus::I2CBusConfig i2c_cfg; + i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); + i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); + auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); + M5_LOGI("Bus:%d", i2c_bus.has_value()); + unit_ready = Units.add(unit, i2c_bus ? i2c_bus.value() : nullptr) && Units.begin(); + } else if (board == m5::board_t::board_M5NanoC6) { + // NanoC6: Use M5.Ex_I2C (m5::I2C_Class, not Arduino Wire) + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + Wire.end(); + Wire.begin(pin_num_sda, pin_num_scl, 400 * 1000U); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -36,7 +68,7 @@ void setup() M5_LOGI("M5UnitUnified has been begun"); M5_LOGI("%s", Units.debugInfo().c_str()); - lcd.clear(TFT_DARKGREEN); + lcd.fillScreen(TFT_DARKGREEN); } void loop() @@ -47,10 +79,22 @@ void loop() #if defined(UNIT_BME688_USING_BSEC2) M5.Log.printf(">IAQ:%.2f\n>Temperature:%.2f\n>Pressure:%.2f\n>Humidity:%.2f\n>GAS:%.2f\n", unit.iaq(), unit.temperature(), unit.pressure(), unit.humidity(), unit.gas()); + lcd.startWrite(); + lcd.fillRect(0, 0, lcd.width(), lcd.fontHeight() * 5, TFT_BLACK); + lcd.setCursor(0, 0); + lcd.printf("IAQ:%.2f\nTemperature:%.2f\nPressure:%.2f\nHumidity:%.2f\nGAS:%.2f", unit.iaq(), unit.temperature(), + unit.pressure(), unit.humidity(), unit.gas()); + lcd.endWrite(); #else M5.Log.printf(">Temperature:%.2f\n>Pressure:%.2f\n>Humidity:%.2f\n>GAS:%.2f\n", unit.temperature(), unit.pressure(), unit.humidity(), unit.gas()); - m5::utility::delay(1000); + lcd.startWrite(); + lcd.fillRect(0, 0, lcd.width(), lcd.fontHeight() * 4, TFT_BLACK); + lcd.setCursor(0, 0); + lcd.printf("Temperature:%.2f\nPressure:%.2f\nHumidity:%.2f\nGAS:%.2f", unit.temperature(), unit.pressure(), + unit.humidity(), unit.gas()); + lcd.endWrite(); + // m5::utility::delay(1000); #endif } } diff --git a/examples/UnitUnified/UnitTVOC/PlotToSerial/main/PlotToSerial.cpp b/examples/UnitUnified/UnitTVOC/PlotToSerial/main/PlotToSerial.cpp index 2564b25..981885e 100644 --- a/examples/UnitUnified/UnitTVOC/PlotToSerial/main/PlotToSerial.cpp +++ b/examples/UnitUnified/UnitTVOC/PlotToSerial/main/PlotToSerial.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include // For NessoN1 namespace { auto& lcd = M5.Display; @@ -21,16 +21,47 @@ m5::unit::UnitTVOC unit; void setup() { M5.begin(); + M5.setTouchButtonHeightByRatio(100); + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); - Wire.end(); - Wire.begin(pin_num_sda, pin_num_scl, 400 * 1000U); + auto board = M5.getBoard(); - if (!Units.add(unit, Wire) || !Units.begin()) { + // NessoN1: Arduino Wire (I2C_NUM_0) cannot be used for GROVE port. + // Wire is used by M5Unified In_I2C for internal devices (IOExpander etc.). + // Solution: Use SoftwareI2C via M5HAL (bit-banging) for the GROVE port. + // NanoC6: Wire.begin() on GROVE pins conflicts with m5::I2C_Class registered by Ex_I2C.setPort() + // on the same I2C_NUM_0, causing sporadic NACK errors. + // Solution: Use M5.Ex_I2C (m5::I2C_Class) directly instead of Arduino Wire. + bool unit_ready{}; + if (board == m5::board_t::board_ArduinoNessoN1) { + // NessoN1: GROVE is on port_b (GPIO 5/4), not port_a (which maps to Wire pins 8/10) + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_b_out); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_b_in); + M5_LOGI("getPin(M5HAL): SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + m5::hal::bus::I2CBusConfig i2c_cfg; + i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); + i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); + auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); + M5_LOGI("Bus:%d", i2c_bus.has_value()); + unit_ready = Units.add(unit, i2c_bus ? i2c_bus.value() : nullptr) && Units.begin(); + } else if (board == m5::board_t::board_M5NanoC6) { + // NanoC6: Use M5.Ex_I2C (m5::I2C_Class, not Arduino Wire) + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); + Wire.end(); + Wire.begin(pin_num_sda, pin_num_scl, 400 * 1000U); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -38,9 +69,10 @@ void setup() M5_LOGI("M5UnitUnified has been begun"); M5_LOGI("%s", Units.debugInfo().c_str()); - M5_LOGW("SGP30 measurement starts 15 seconds after begin"); - lcd.clear(TFT_DARKGREEN); + lcd.fillScreen(TFT_DARKGREEN); + M5.Log.printf("SGP30 measurement starts 15 seconds after begin\n"); + lcd.printf("SGP30 measurement starts 15 seconds after begin"); } void loop() @@ -51,6 +83,11 @@ void loop() // SGP30 measurement starts 15 seconds after begin. if (unit.updated()) { // Can be checked on serial plotters - M5.Log.printf("\n>CO2eq:%u\n>TVOC:%u", unit.co2eq(), unit.tvoc()); + M5.Log.printf(">CO2eq:%u\n>TVOC:%u\n", unit.co2eq(), unit.tvoc()); + lcd.startWrite(); + lcd.fillRect(0, 0, lcd.width(), lcd.fontHeight() * 2, TFT_BLACK); + lcd.setCursor(0, 0); + lcd.printf("CO2eq:%u\nTVOC:%u", unit.co2eq(), unit.tvoc()); + lcd.endWrite(); } } diff --git a/library.json b/library.json index 170f611..1b87428 100644 --- a/library.json +++ b/library.json @@ -11,11 +11,11 @@ "url": "https://github.com/m5stack/M5Unit-ENV.git" }, "dependencies": { - "m5stack/M5UnitUnified": ">=0.1.0", + "m5stack/M5UnitUnified": ">=0.4.1", "boschsensortec/BME68x Sensor library": ">=1.3.40408", "boschsensortec/bsec2": ">=1.10.2610" }, - "version": "1.3.1", + "version": "1.3.2", "frameworks": [ "arduino" ], diff --git a/library.properties b/library.properties index b0930ce..bcdc5ad 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=M5Unit-ENV -version=1.3.1 +version=1.3.2 author=M5Stack maintainer=M5Stack sentence=Library for M5Stack UNIT ENV diff --git a/platformio.ini b/platformio.ini index a1aca77..3402975 100644 --- a/platformio.ini +++ b/platformio.ini @@ -11,7 +11,7 @@ lib_ldf_mode = deep test_framework = googletest test_build_src = true lib_deps=m5stack/M5Unified - m5stack/M5UnitUnified + m5stack/M5UnitUnified@>=0.4.1 boschsensortec/BME68x Sensor library@>=1.3.40408 ; -------------------------------- @@ -27,10 +27,7 @@ test_ignore= native/* [Core] extends = m5base -board = m5stack-grey -;m5stack-grey -;m5stack-core-esp32-16M ;;6.8.0 or later -;m5stack-core-esp32 +board = m5stack-core-esp32-16M lib_deps = ${env.lib_deps} ${bsec2.lib_deps} @@ -66,13 +63,15 @@ lib_deps = ${env.lib_deps} ${bsec2.lib_deps} m5stack/M5Dial -[AtomMatrix] +[Atom] +;include AtomMatrix,AtomLite,AtomU extends = m5base board = m5stack-atom lib_deps = ${env.lib_deps} ${bsec2.lib_deps} [AtomS3] +;include AtomEchoS3R,AtomS3Lite,AtomS3U extends = m5base board = m5stack-atoms3 lib_deps = ${env.lib_deps} @@ -89,12 +88,8 @@ lib_deps = ${env.lib_deps} [NanoC6] extends = m5base board = m5stack-nanoc6 -platform = https://github.com/platformio/platform-espressif32.git -platform_packages = - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.7 - platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 -board_build.partitions = default.csv lib_deps = ${env.lib_deps} +board_build.partitions = default.csv [StickCPlus] extends = m5base @@ -109,6 +104,21 @@ board = m5stick-cplus2 lib_deps = ${env.lib_deps} ${bsec2.lib_deps} +[StickS3] +extends = m5base +board = esp32-s3-devkitc-1 +board_build.arduino.partitions = default_8MB.csv +board_build.arduino.memory_type = qio_opi +build_flags = + -DESP32S3 + -DBOARD_HAS_PSRAM + -mfix-esp32-psram-cache-issue + -DARDUINO_USB_CDC_ON_BOOT=1 + -DARDUINO_USB_MODE=1 +lib_deps = ${env.lib_deps} + ${bsec2.lib_deps} + + [Paper] extends = m5base board = m5stack-fire @@ -121,6 +131,34 @@ board = m5stack-coreink lib_deps = ${env.lib_deps} ${bsec2.lib_deps} +[Cardputer] +extends = m5base +board = esp32-s3-devkitc-1 +build_flags = + -DESP32S3 + -DARDUINO_USB_CDC_ON_BOOT=1 + -DARDUINO_USB_MODE=1 +lib_deps = ${env.lib_deps} + ${bsec2.lib_deps} + + +[Tab5] +extends = m5base +board = esp32-p4-evboard +board_build.mcu = esp32p4 +board_build.flash_mode = qio +build_flags = + -DBOARD_HAS_PSRAM + -DARDUINO_USB_CDC_ON_BOOT=1 + -DARDUINO_USB_MODE=1 +lib_deps = ${env.lib_deps} + +[NessoN1] +extends = m5base +board = arduino_nesso_n1 +lib_deps = ${env.lib_deps} + + [sdl] build_flags = -O3 -xc++ -std=c++14 -lSDL2 -arch arm64 ; for arm mac @@ -136,6 +174,10 @@ lib_deps = ${env.lib_deps} ; -------------------------------- ;Choose framework [arduino_latest] +platform = espressif32 @ 6.12.0 +framework = arduino + +[arduino_6_8_1] platform = espressif32 @ 6.8.1 framework = arduino @@ -147,17 +189,21 @@ framework = arduino platform = espressif32 @ 6.0.1 framework = arduino -[arduino_5_4_0] -platform = espressif32 @ 5.4.0 +;[arduino_3_5_0] +;platform = espressif32 @ 3.5.0 +;framework = arduino + +[nanoc6_latest] +platform = espressif32 @ 6.12.0 +platform_packages = + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.7 + platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 framework = arduino -[arduino_4_4_0] -platform = espressif32 @ 4.4.0 +[pioarduino_latest] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.36/platform-espressif32.zip framework = arduino -;[arduino_3_5_0] -;platform = espressif32 @ 3.5.0 -;framework = arduino [esp-idf] platform = espressif32 @ 6.8.1 @@ -197,7 +243,6 @@ build_flags = ${env.build_flags} -DM5_LOG_LEVEL=0 -Wl,-Map,output.map -; Require at leaset C++14 after 1.13.0 +; Require at least C++14 after 1.13.0 [test_fw] lib_deps = google/googletest@1.12.1 - diff --git a/src/idf_component.yml b/src/idf_component.yml new file mode 100644 index 0000000..d752765 --- /dev/null +++ b/src/idf_component.yml @@ -0,0 +1,2 @@ +dependencies: + idf: '>=5.1' diff --git a/src/idf_component.yml.orig b/src/idf_component.yml.orig new file mode 100644 index 0000000..d752765 --- /dev/null +++ b/src/idf_component.yml.orig @@ -0,0 +1,2 @@ +dependencies: + idf: '>=5.1' diff --git a/src/unit/unit_BME688.cpp b/src/unit/unit_BME688.cpp index 6e3b32e..3c43954 100644 --- a/src/unit/unit_BME688.cpp +++ b/src/unit/unit_BME688.cpp @@ -278,7 +278,7 @@ void UnitBME688::update(const bool force) } #if defined(UNIT_BME688_USING_BSEC2) -// Using BSEC2 library and configration and state +// Using BSEC2 library and configuration and state void UnitBME688::update_bsec2(const bool force) { auto now = m5::utility::millis(); @@ -527,8 +527,8 @@ bool UnitBME688::writeCalibration(const bme688::bme68xCalibration& c) array2[CALIBRATION_RES_HEAT_VAL - CALIBRATION_GROUP_2] = c.res_heat_val; return writeRegister(CALIBRATION_GROUP_0, array0.data(), array0.size()) && - writeRegister(CALIBRATION_GROUP_1, array0.data(), array1.size()) && - writeRegister(CALIBRATION_GROUP_2, array0.data(), array2.size()); + writeRegister(CALIBRATION_GROUP_1, array1.data(), array1.size()) && + writeRegister(CALIBRATION_GROUP_2, array2.data(), array2.size()); } bool UnitBME688::readTPHSetting(bme688::bme68xConf& s) @@ -955,7 +955,7 @@ bool UnitBME688::fetch_data() bool UnitBME688::process_data(bsecOutputs& outputs, const int64_t ns, const bme688::bme68xData& data) { - bsec_input_t inputs[BSEC_MAX_PHYSICAL_SENSOR]{}; /* Temp, Pres, Hum & Gas */ + bsec_input_t inputs[BSEC_MAX_PHYSICAL_SENSOR]{}; /* Temp, Pressure, Hum & Gas */ uint8_t nInputs{0}; /* Checks all the required sensor inputs, required for the BSEC library for * the requested outputs */ diff --git a/src/unit/unit_BME688.hpp b/src/unit/unit_BME688.hpp index dff9c50..df81c2e 100644 --- a/src/unit/unit_BME688.hpp +++ b/src/unit/unit_BME688.hpp @@ -90,7 +90,7 @@ using bme68xCalibration = struct bme68x_calib_data; ///@} /*! - @enum Oversamping + @enum Oversampling @brief Sampling setting */ enum class Oversampling : uint8_t { @@ -171,7 +171,7 @@ struct GasWait { } ///@} - //! @brief Conversion from duration to register value for Force/Sequencial + //! @brief Conversion from duration to register value for Force/Sequential //! mode static uint8_t from(const uint16_t duration) { @@ -183,7 +183,7 @@ struct GasWait { } return (f <= 0x03) ? ((uint8_t)d | (f << 6)) : 0xFF; } - //! @brief Conversion from register value to duration for Force/Sequencial + //! @brief Conversion from register value to duration for Force/Sequential //! mode static uint16_t to(const uint8_t v) { @@ -205,7 +205,7 @@ enum class SampleRate : uint8_t { Disabled, //!< Sample rate of a disabled sensor LowPower, //!< Sample rate in case of Low Power Mode (0.33Hz) interval 3 sec. UltraLowPower, //!< Sample rate in case of Ultra Low Power Mode (3.3 mHz) interval 300 sec. - UltraLowPowerMeasurementOnDemand, //!< Input value used to trigger an extra measurment (ULP plus) (0.33Hz + UltraLowPowerMeasurementOnDemand, //!< Input value used to trigger an extra measurement (ULP plus) (0.33Hz //!< [T,p,h] 3.3mHz [IAQ]) Scan, //!< Sample rate in case of scan mode (1/10.8 s) Continuous, //!< Sample rate in case of Continuous Mode (1Hz) interval 1 sec. @@ -429,12 +429,12 @@ class UnitBME688 : public Component, public PeriodicMeasurementAdapter #include @@ -99,7 +99,7 @@ enum class UseCase : uint8_t { }; /*! - @union Trimmming + @union Trimming @brief Trimming parameter */ union Trimming { @@ -184,12 +184,12 @@ class UnitBMP280 : public Component, public PeriodicMeasurementAdapter::startPeriodicMeasurement( osrsPressure, osrsTemperature, filter, st); } - //! @brief Start periodic measurement using current settings + /*! + @brief Start periodic measurement using current register settings + @return True if successful + @note Reads the current standby time from sensor registers and sets PowerMode to Normal + */ inline bool startPeriodicMeasurement() { return PeriodicMeasurementAdapter::startPeriodicMeasurement(); @@ -258,7 +262,7 @@ class UnitBMP280 : public Component, public PeriodicMeasurementAdapter UnitENV3::ensure_adapter(const uint8_t ch) { - if (ch > 2) { + if (ch >= 2) { M5_LIB_LOGE("Invalid channel %u", ch); return std::make_shared(); // Empty adapter } diff --git a/src/unit/unit_ENV4.cpp b/src/unit/unit_ENV4.cpp index 75c63d9..7a0da9a 100644 --- a/src/unit/unit_ENV4.cpp +++ b/src/unit/unit_ENV4.cpp @@ -31,7 +31,7 @@ UnitENV4::UnitENV4(const uint8_t addr) : Component(addr) std::shared_ptr UnitENV4::ensure_adapter(const uint8_t ch) { - if (ch > 2) { + if (ch >= 2) { M5_LIB_LOGE("Invalid channel %u", ch); return std::make_shared(); // Empty adapter } diff --git a/src/unit/unit_QMP6988.cpp b/src/unit/unit_QMP6988.cpp index f317df3..b1c62f4 100644 --- a/src/unit/unit_QMP6988.cpp +++ b/src/unit/unit_QMP6988.cpp @@ -20,8 +20,8 @@ using namespace m5::unit::qmp6988::command; namespace { constexpr uint8_t chip_id{0x5C}; -constexpr size_t calibration_length{25}; -constexpr uint32_t sub_raw{8388608}; // 2^23 +constexpr size_t CALIBRATION_LENGTH{25}; +constexpr uint32_t SUB_RAW{8388608}; // 2^23 constexpr Oversampling osrss_table[][2] = { // Pressure, Temperature @@ -51,7 +51,7 @@ constexpr UseCaseSetting uc_table[] = { {OversamplingSetting::LowPower, Filter::Off}, {OversamplingSetting::Standard, Filter::Coeff4}, {OversamplingSetting::HighAccuracy, Filter::Coeff8}, - {OversamplingSetting::UltraHightAccuracy, Filter::Coeff32}, + {OversamplingSetting::UltraHighAccuracy, Filter::Coeff32}, }; #if 1 @@ -129,8 +129,6 @@ int32_t convert_pressure16(const int32_t dp, const int16_t tx, const Calibration return p16; } -} // namespace - struct CtrlMeas { Oversampling osrs_t() const { @@ -171,6 +169,8 @@ struct IOSetup { uint8_t value{}; }; +} // namespace + namespace m5 { namespace unit { @@ -179,7 +179,7 @@ float Data::celsius() const { uint32_t rt = (((uint32_t)raw[3]) << 16) | (((uint32_t)raw[4]) << 8) | ((uint32_t)raw[5]); if (calib && rt) { - int32_t dt = (int32_t)(rt - sub_raw); + int32_t dt = (int32_t)(rt - SUB_RAW); int16_t t256 = convert_temperature256(dt, *calib); return (float)t256 / 256.f; } @@ -197,15 +197,15 @@ float Data::pressure() const uint32_t rp = (((uint32_t)raw[0]) << 16) | (((uint32_t)raw[1]) << 8) | ((uint32_t)raw[2]); if (calib && rt && rp) { - int32_t dt = (int32_t)(rt - sub_raw); + int32_t dt = (int32_t)(rt - SUB_RAW); int16_t t256 = convert_temperature256(dt, *calib); - int32_t dp = (int32_t)(rp - sub_raw); + int32_t dp = (int32_t)(rp - SUB_RAW); int32_t p16 = convert_pressure16(dp, t256, *calib); return (float)p16 / 16.0f; } return std::numeric_limits::quiet_NaN(); } -}; // namespace qmp6988 +} // namespace qmp6988 // const char UnitQMP6988::name[] = "UnitQMP6988"; @@ -249,6 +249,7 @@ bool UnitQMP6988::begin() M5_LIB_LOGE("This unit is NOT QMP6988 %x", id); return false; } + M5_LIB_LOGE("ChipID:%02X", id); if (!softReset()) { M5_LIB_LOGE("Failed to reset"); @@ -336,6 +337,7 @@ bool UnitQMP6988::measureSingleshot(qmp6988::Data& d, const qmp6988::Oversamplin // Need temperature for measure pressure (Only temperature measurement is acceptable) if (osrsTemperature == Oversampling::Skipped) { + M5_LIB_LOGW("osrsTemperature == Oversampling::Skipped cannot measure"); return false; } return writeOversampling(osrsPressure, osrsTemperature) && writeFilter(f) && measureSingleshot(d); @@ -514,14 +516,18 @@ bool UnitQMP6988::softReset() { constexpr uint8_t v{0xE6}; // When inputting "E6h", a soft-reset will be occurred - auto ret = writeRegister8(SOFT_RESET, v); - M5_LIB_LOGD("Reset causes a NO ACK or timeout error, but ignore it"); - (void)ret; + // Reset causes a NO ACK or timeout error, but ignore it + (void)writeRegister8(SOFT_RESET, v); m5::utility::delay(10); // Need delay - if (writeRegister(SOFT_RESET, 0x00)) { - _periodic = false; - return true; - } + + auto timeout_at = m5::utility::millis() + 1000; + do { + uint8_t id{}; + if (readRegister8(CHIP_ID, id, 0) && id == chip_id) { + return true; + } + m5::utility::delay(1); + } while (m5::utility::millis() <= timeout_at); return false; } @@ -551,7 +557,8 @@ bool UnitQMP6988::read_calibration(qmp6988::Calibration& c) using namespace m5::utility; // unsigned_to_signed using namespace m5::types; // big_uint16_t - uint8_t rbuf[calibration_length]{}; + uint8_t rbuf[CALIBRATION_LENGTH]{}; + if (!readRegister(READ_COMPENSATION_COEFFICIENT, rbuf, sizeof(rbuf), 0)) { return false; } diff --git a/src/unit/unit_QMP6988.hpp b/src/unit/unit_QMP6988.hpp index 44f11a3..95de375 100644 --- a/src/unit/unit_QMP6988.hpp +++ b/src/unit/unit_QMP6988.hpp @@ -32,7 +32,6 @@ enum class PowerMode : uint8_t { /*! @enum Oversampling @brief Oversampling value - @warning */ enum class Oversampling : uint8_t { Skipped, //!< Skipped (No measurements are performed) @@ -50,16 +49,18 @@ enum class Oversampling : uint8_t { @brief Oversampling Settings */ enum class OversamplingSetting : uint8_t { - HighSpeed, //!< osrsP:X2 osrsT:X1 - LowPower, //!< osrsP:X4 osrsT:X1 - Standard, //!< osrsP:X8 osrsT:X1 - HighAccuracy, //!< osrsP:X16 osrsT:X2 - UltraHightAccuracy, //!< osrsP:X32 osrsT:X4 + HighSpeed, //!< osrsP:X2 osrsT:X1 + LowPower, //!< osrsP:X4 osrsT:X1 + Standard, //!< osrsP:X8 osrsT:X1 + HighAccuracy, //!< osrsP:X16 osrsT:X2 + UltraHighAccuracy, //!< osrsP:X32 osrsT:X4 + //! @deprecated Use UltraHighAccuracy instead + UltraHightAccuracy [[deprecated("Use UltraHighAccuracy")]] = UltraHighAccuracy, }; /*! @enum Filter - @brief Filtter setting + @brief Filter setting */ enum class Filter : uint8_t { Off, //!< Off filter @@ -122,7 +123,7 @@ struct Data { const Calibration* calib{}; }; -}; // namespace qmp6988 +} // namespace qmp6988 /*! @class UnitQMP6988 @@ -153,7 +154,8 @@ class UnitQMP6988 : public Component, public PeriodicMeasurementAdapter(1)} { auto ccfg = component_config(); - ccfg.clock = 400 * 1000U; + ccfg.clock = 100 * 1000U; + // QMP6988 datasheet: if bus >400 kbit/s and shared, wait >=1 ms before access component_config(ccfg); } virtual ~UnitQMP6988() @@ -165,12 +167,12 @@ class UnitQMP6988 : public Component, public PeriodicMeasurementAdapter::startPeriodicMeasurement(osrsPressure, osrsTemperature, f, st); } - //! @brief Start periodic measurement using current settings + /*! + @brief Start periodic measurement using current register settings + @return True if successful + @note Reads the current standby time from sensor registers and sets PowerMode to Normal + */ inline bool startPeriodicMeasurement() { return PeriodicMeasurementAdapter::startPeriodicMeasurement(); @@ -238,7 +244,7 @@ class UnitQMP6988 : public Component, public PeriodicMeasurementAdapter 3 minutes in an environment with homogenous and constant CO2 + // shot) for > 3 minutes in an environment with homogeneous and constant CO2 // concentration. // 2. Issue stop_periodic_measurement. Wait 500 ms for the stop command to // complete. @@ -492,8 +492,9 @@ bool UnitSCD40::read_measurement(Data& d, const bool all) bool UnitSCD40::read_register(const uint16_t reg, uint8_t* rbuf, const uint32_t rlen, const uint32_t duration) { - uint8_t tmp[rlen + 1]{}; - if (!rbuf || !rlen || !readRegister(reg, tmp, sizeof(tmp), duration)) { + constexpr uint32_t BUF_SIZE{16}; + uint8_t tmp[BUF_SIZE + 1]{}; + if (!rbuf || !rlen || rlen > BUF_SIZE || !readRegister(reg, tmp, rlen + 1, duration)) { return false; } @@ -509,15 +510,16 @@ bool UnitSCD40::read_register(const uint16_t reg, uint8_t* rbuf, const uint32_t bool UnitSCD40::write_register(const uint16_t reg, uint8_t* wbuf, const uint32_t wlen) { - uint8_t buf[wlen + 1]{}; - if (!wbuf || !wlen) { + constexpr uint32_t BUF_SIZE{16}; + uint8_t buf[BUF_SIZE + 1]{}; + if (!wbuf || !wlen || wlen > BUF_SIZE) { return false; } memcpy(buf, wbuf, wlen); m5::utility::CRC8_Checksum crc{}; auto crc8 = crc.range(wbuf, wlen); buf[wlen] = crc8; - return writeRegister(reg, buf, sizeof(buf)); + return writeRegister(reg, buf, wlen + 1); } bool UnitSCD40::delay_true(const uint32_t duration) diff --git a/src/unit/unit_SCD40.hpp b/src/unit/unit_SCD40.hpp index 59acc4f..2eee392 100644 --- a/src/unit/unit_SCD40.hpp +++ b/src/unit/unit_SCD40.hpp @@ -111,12 +111,12 @@ class UnitSCD40 : public Component, public PeriodicMeasurementAdapter>>>>> %u", inceptive_tvoc); - m5::utility::CRC8_Checksum crc; std::array buf{}; m5::types::big_uint16_t tt(inceptive_tvoc); diff --git a/src/unit/unit_SGP30.hpp b/src/unit/unit_SGP30.hpp index 019bdd6..24c056a 100644 --- a/src/unit/unit_SGP30.hpp +++ b/src/unit/unit_SGP30.hpp @@ -51,9 +51,9 @@ struct Feature { } /*! @brief product version - @note Please note that the last 5 bits of the productversion (bits 12-16 + @note Please note that the last 5 bits of the product version (bits 12-16 of the LSB) are subject to change - @note This is used to track new features added tothe SGP multi-pixel + @note This is used to track new features added to the SGP multi-pixel platform */ uint8_t productVersion() const @@ -70,7 +70,7 @@ struct Feature { struct Data { std::array raw{}; //!< RAW data uint16_t co2eq() const; //!< Co2Eq (ppm) - uint16_t tvoc() const; //!< TVOC (pbb) + uint16_t tvoc() const; //!< TVOC (ppb) }; } // namespace sgp30 @@ -94,7 +94,7 @@ class UnitSGP30 : public Component, public PeriodicMeasurementAdapter +#include #include // NaN #include @@ -25,8 +26,8 @@ struct Temperature { } }; -// After sending a command to the sensor a minimalwaiting time of 1ms is needed -// before another commandcan be received by the sensor. +// After sending a command to the sensor a minimal waiting time of 1ms is needed +// before another command can be received by the sensor. bool delay1() { m5::utility::delay(1); @@ -122,6 +123,9 @@ bool UnitSHT30::begin() M5_LIB_LOGE("Failed to heater %d", _cfg.start_heater); return false; } + + _mps = _cfg.mps; + _rep = _cfg.repeatability; return _cfg.start_periodic ? startPeriodicMeasurement(_cfg.mps, _cfg.repeatability) : true; } @@ -167,6 +171,15 @@ bool UnitSHT30::measureSingleshot(Data& d, const sht30::Repeatability rep, const return false; } + // m5::I2C_Class does not support clock stretching + if (stretch) { + auto ad = asAdapter(Adapter::Type::I2C); + if (ad && ad->implType() == AdapterI2C::ImplType::I2CClass) { + M5_LIB_LOGE("Clock stretching is not supported with I2C_Class"); + return false; + } + } + uint32_t idx = m5::stl::to_underlying(rep) + (stretch ? 0 : 3); if (idx >= m5::stl::size(cmd)) { M5_LIB_LOGE("Invalid arg : %u", (int)rep); @@ -189,6 +202,8 @@ bool UnitSHT30::start_periodic_measurement(const sht30::MPS mps, const sht30::Re _periodic = writeRegister(periodic_cmd[m5::stl::to_underlying(mps) * 3 + m5::stl::to_underlying(rep)]); if (_periodic) { + _mps = mps; + _rep = rep; _interval = interval_table[m5::stl::to_underlying(mps)]; m5::utility::delay(16); return true; diff --git a/src/unit/unit_SHT30.hpp b/src/unit/unit_SHT30.hpp index c0bfd97..5edbfb0 100644 --- a/src/unit/unit_SHT30.hpp +++ b/src/unit/unit_SHT30.hpp @@ -73,7 +73,7 @@ struct Status { { return value & (1U << 4); } - //! @brief Command staus + //! @brief Command status inline bool command() const { return value & (1U << 1); @@ -143,12 +143,12 @@ class UnitSHT30 : public Component, public PeriodicMeasurementAdapter::startPeriodicMeasurement(mps, rep); } + /*! + @brief Start periodic measurement using previous settings + @return True if successful + @note Uses the MPS and repeatability settings from the last successful startPeriodicMeasurement or begin + */ + inline bool startPeriodicMeasurement() + { + return PeriodicMeasurementAdapter::startPeriodicMeasurement(); + } /*! @brief Stop periodic measurement @return True if successful @@ -205,16 +214,18 @@ class UnitSHT30 : public Component, public PeriodicMeasurementAdapter> _data{}; config_t _cfg{}; + sht30::MPS _mps{}; + sht30::Repeatability _rep{}; }; ///@cond diff --git a/src/unit/unit_SHT40.cpp b/src/unit/unit_SHT40.cpp index 16a6808..dec63b1 100644 --- a/src/unit/unit_SHT40.cpp +++ b/src/unit/unit_SHT40.cpp @@ -85,17 +85,20 @@ bool UnitSHT40::begin() } } - if (!softReset()) { - M5_LIB_LOGE("Failed to reset"); - return false; - } - uint32_t sn{}; if (!readSerialNumber(sn)) { M5_LIB_LOGE("Failed to readSerialNumber %x", sn); return false; } + if (!softReset()) { + M5_LIB_LOGE("Failed to reset"); + return false; + } + + _precision = _cfg.precision; + _heater = _cfg.heater; + _duty = _cfg.heater_duty; return _cfg.start_periodic ? startPeriodicMeasurement(_cfg.precision, _cfg.heater, _cfg.heater_duty) : true; } @@ -139,7 +142,7 @@ bool UnitSHT40::start_periodic_measurement(const sht40::Precision precision, con return false; } if (duty <= 0.0f || duty > MAX_HEATER_DUTY) { - M5_LIB_LOGW("duty range is invalid %f. duty (0.0, 0.05]"); + M5_LIB_LOGW("duty range is invalid %f. duty (0.0, 0.05]", duty); return false; } @@ -148,6 +151,9 @@ bool UnitSHT40::start_periodic_measurement(const sht40::Precision precision, con _periodic = writeRegister(_cmd); if (_periodic) { + _precision = precision; + _heater = heater; + _duty = duty; _duration_heater = interval_table[m5::stl::to_underlying(precision) * 3 + m5::stl::to_underlying(heater)]; _duration_measure = interval_table[m5::stl::to_underlying(precision) * 3 + m5::stl::to_underlying(Heater::None)]; diff --git a/src/unit/unit_SHT40.hpp b/src/unit/unit_SHT40.hpp index 2061507..d86a4c0 100644 --- a/src/unit/unit_SHT40.hpp +++ b/src/unit/unit_SHT40.hpp @@ -102,12 +102,12 @@ class UnitSHT40 : public Component, public PeriodicMeasurementAdapter::startPeriodicMeasurement(precision, heater, duty); } + /*! + @brief Start periodic measurement using previous settings + @return True if successful + @note Uses the precision, heater, and duty settings from the last successful startPeriodicMeasurement or begin + */ + inline bool startPeriodicMeasurement() + { + return startPeriodicMeasurement(_precision, _heater, _duty); + } /*! @brief Stop periodic measurement @return True if successful @@ -168,7 +177,7 @@ class UnitSHT40 : public Component, public PeriodicMeasurementAdapter> _data{}; - config_t _cfg{}; uint8_t _cmd{}, _measureCmd{}; types::elapsed_time_t _latest_heater{}, _interval_heater{}; uint32_t _duration_measure{}, _duration_heater{}; + +private: + config_t _cfg{}; + sht40::Precision _precision{sht40::Precision::High}; + sht40::Heater _heater{sht40::Heater::None}; + float _duty{0.05f}; }; ///@cond diff --git a/test/embedded/scd4x_test.inl b/test/embedded/scd4x_test.inl index 9ce601c..92758af 100644 --- a/test/embedded/scd4x_test.inl +++ b/test/embedded/scd4x_test.inl @@ -14,49 +14,10 @@ constexpr uint16_t float_to_uint16(const float f) return f * 65536 / 175; } -constexpr Mode mode_table[] = {Mode::Normal, Mode::LowPower}; -constexpr uint32_t interval_table[] = { - 5 * 1000, - 30 * 1000, -}; - -template -elapsed_time_t test_periodic(U* unit, const uint32_t times, const uint32_t measure_duration = 0) -{ - auto tm = unit->interval(); - auto timeout_at = m5::utility::millis() + 10 * 1000; - - do { - unit->update(); - if (unit->updated()) { - break; - } - std::this_thread::yield(); - } while (!unit->updated() && m5::utility::millis() <= timeout_at); - // timeout - if (!unit->updated()) { - return 0; - } - - // - uint32_t measured{}; - auto start_at = m5::utility::millis(); - timeout_at = start_at + (times * (tm + measure_duration) * 2); - - do { - unit->update(); - measured += unit->updated() ? 1 : 0; - if (measured >= times) { - break; - } - m5::utility::delay(1); - - } while (measured < times && m5::utility::millis() <= timeout_at); - return (measured == times) ? m5::utility::millis() - start_at : 0; -} +constexpr Mode mode_table[] = {Mode::Normal, Mode::LowPower}; } // namespace -TEST_P(TestSCD4x, BasicCommand) +TEST_F(TestSCD4x, BasicCommand) { SCOPED_TRACE(ustr); @@ -119,7 +80,7 @@ TEST_P(TestSCD4x, BasicCommand) } } -TEST_P(TestSCD4x, OnChipOutputSignalCompensation) +TEST_F(TestSCD4x, OnChipOutputSignalCompensation) { SCOPED_TRACE(ustr); @@ -159,7 +120,7 @@ TEST_P(TestSCD4x, OnChipOutputSignalCompensation) } } -TEST_P(TestSCD4x, FieldCalibration) +TEST_F(TestSCD4x, FieldCalibration) { SCOPED_TRACE(ustr); @@ -188,7 +149,7 @@ TEST_P(TestSCD4x, FieldCalibration) } } -TEST_P(TestSCD4x, AdvancedFeatures) +TEST_F(TestSCD4x, AdvancedFeatures) { SCOPED_TRACE(ustr); @@ -284,13 +245,12 @@ TEST_P(TestSCD4x, AdvancedFeatures) EXPECT_TRUE(enabled); } -TEST_P(TestSCD4x, Periodic) +TEST_F(TestSCD4x, Periodic) { SCOPED_TRACE(ustr); EXPECT_TRUE(unit->performFactoryReset()); // Reset EEPROM - uint32_t idx{}; for (auto&& m : mode_table) { auto s = m5::utility::formatString("Mode:%u", m); SCOPED_TRACE(s); @@ -301,14 +261,14 @@ TEST_P(TestSCD4x, Periodic) EXPECT_TRUE(unit->inPeriodic()); EXPECT_EQ(unit->updatedMillis(), 0); - auto it = interval_table[idx]; - auto elapsed = test_periodic(unit.get(), STORED_SIZE, it); + auto r = collect_periodic_measurements(unit.get(), STORED_SIZE); EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); - EXPECT_NE(elapsed, 0); - EXPECT_GE(elapsed, STORED_SIZE * it); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, STORED_SIZE); + EXPECT_LE(r.median(), r.expected_interval + 1); // EXPECT_EQ(unit->available(), STORED_SIZE); diff --git a/test/embedded/test_bme688/bme688_test.cpp b/test/embedded/test_bme688/bme688_test.cpp index a98ae15..cab7d21 100644 --- a/test/embedded/test_bme688/bme688_test.cpp +++ b/test/embedded/test_bme688/bme688_test.cpp @@ -24,9 +24,7 @@ using namespace m5::unit::bme688; using namespace m5::unit::bme688::bsec2; #endif -const ::testing::Environment* global_fixture = ::testing::AddGlobalTestEnvironment(new GlobalFixture<400000U>()); - -class TestBME688 : public ComponentTestBase { +class TestBME688 : public I2CComponentTestBase { protected: virtual UnitBME688* get_instance() override { @@ -36,21 +34,11 @@ class TestBME688 : public ComponentTestBase { ptr->component_config(ccfg); return ptr; } - virtual bool is_using_hal() const override - { - return GetParam(); - }; }; -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestBME688, -// ::testing::Values(false, true)); -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestBME688, ::testing::Values(true)); -INSTANTIATE_TEST_SUITE_P(ParamValues, TestBME688, ::testing::Values(false)); - namespace { constexpr Oversampling os_table[] = { - Oversampling::None, Oversampling::x1, Oversampling::x1, Oversampling::x2, - Oversampling::x4, Oversampling::x8, Oversampling::x16, + Oversampling::None, Oversampling::x1, Oversampling::x2, Oversampling::x4, Oversampling::x8, Oversampling::x16, }; constexpr Filter filter_table[] = { Filter::None, Filter::Coeff_1, Filter::Coeff_3, Filter::Coeff_7, @@ -104,7 +92,7 @@ void check_measurement_values(UnitBME688* u) } // namespace -TEST_P(TestBME688, Misc) +TEST_F(TestBME688, Misc) { #if defined(UNIT_BME688_USING_BSEC2) for (auto&& v : vs_table) { @@ -132,7 +120,7 @@ TEST_P(TestBME688, Misc) #endif } -TEST_P(TestBME688, Settings) +TEST_F(TestBME688, Settings) { SCOPED_TRACE(ustr); @@ -223,7 +211,7 @@ TEST_P(TestBME688, Settings) } #if defined(UNIT_BME688_USING_BSEC2) -TEST_P(TestBME688, BSEC2) +TEST_F(TestBME688, BSEC2) { SCOPED_TRACE(ustr); @@ -290,7 +278,13 @@ TEST_P(TestBME688, BSEC2) EXPECT_EQ(unit->bsec2Subscription(), bits); #if 1 - test_periodic_measurement(unit.get(), 8, 8, (unit->interval() * 2) * 8, check_measurement_values, false); + { + auto timeout = (unit->interval() * 2) * 8; + auto r = collect_periodic_measurements(unit.get(), 8, timeout, check_measurement_values); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, 8U); + EXPECT_LE(r.median(), r.expected_interval + 8); + } EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); @@ -415,7 +409,7 @@ TEST_P(TestBME688, BSEC2) } #endif -TEST_P(TestBME688, SingleShot) +TEST_F(TestBME688, SingleShot) { SCOPED_TRACE(ustr); @@ -456,7 +450,7 @@ TEST_P(TestBME688, SingleShot) #endif } -TEST_P(TestBME688, PeriodicForced) +TEST_F(TestBME688, PeriodicForced) { SCOPED_TRACE(ustr); @@ -490,7 +484,13 @@ TEST_P(TestBME688, PeriodicForced) EXPECT_TRUE(unit->empty()); EXPECT_FALSE(unit->full()); - test_periodic_measurement(unit.get(), 8, 8, (unit->interval() * 2) * 8, check_measurement_values, false); + { + auto timeout = (unit->interval() * 2) * 8; + auto r = collect_periodic_measurements(unit.get(), 8, timeout, check_measurement_values); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, 8U); + EXPECT_LE(r.median(), r.expected_interval + 8); + } EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); @@ -521,7 +521,7 @@ TEST_P(TestBME688, PeriodicForced) EXPECT_FALSE(unit->full()); } -TEST_P(TestBME688, PeriodicParallel) +TEST_F(TestBME688, PeriodicParallel) { SCOPED_TRACE(ustr); @@ -560,7 +560,13 @@ TEST_P(TestBME688, PeriodicParallel) EXPECT_FALSE(unit->full()); // TODO : What are the measurement intervals in the parallel mode datasheet? - test_periodic_measurement(unit.get(), 8, 1, (unit->interval() * 10) * 10, check_measurement_values, false); + { + auto timeout = (unit->interval() * 10) * 10; + auto r = collect_periodic_measurements(unit.get(), 8, timeout, check_measurement_values); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, 8U); + EXPECT_LE(r.median(), r.expected_interval + 1); + } EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); @@ -591,7 +597,7 @@ TEST_P(TestBME688, PeriodicParallel) EXPECT_FALSE(unit->full()); } -TEST_P(TestBME688, PeriodiSequential) +TEST_F(TestBME688, PeriodicSequential) { SCOPED_TRACE(ustr); @@ -624,14 +630,20 @@ TEST_P(TestBME688, PeriodiSequential) EXPECT_TRUE(unit->inPeriodic()); EXPECT_EQ(unit->mode(), Mode::Sequential); - test_periodic_measurement(unit.get(), 8, 1, (unit->interval() * 2) * 8, check_measurement_values, false); + { + auto timeout = (unit->interval() * 2) * 8; + auto r = collect_periodic_measurements(unit.get(), 8, timeout, check_measurement_values); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, 8U); + EXPECT_LE(r.median(), r.expected_interval + 1); + } EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); EXPECT_EQ(unit->mode(), Mode::Sleep); } -TEST_P(TestBME688, SelfTest) +TEST_F(TestBME688, SelfTest) { SCOPED_TRACE(ustr); EXPECT_TRUE(unit->selfTest()); diff --git a/test/embedded/test_bmp280/bmp280_test.cpp b/test/embedded/test_bmp280/bmp280_test.cpp index 74817e5..43fc4da 100644 --- a/test/embedded/test_bmp280/bmp280_test.cpp +++ b/test/embedded/test_bmp280/bmp280_test.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -25,9 +26,7 @@ using m5::unit::types::elapsed_time_t; constexpr uint32_t STORED_SIZE{8}; -const ::testing::Environment* global_fixture = ::testing::AddGlobalTestEnvironment(new GlobalFixture<400000U>()); - -class TestBMP280 : public ComponentTestBase { +class TestBMP280 : public I2CComponentTestBase { protected: virtual UnitBMP280* get_instance() override { @@ -37,10 +36,6 @@ class TestBMP280 : public ComponentTestBase { ptr->component_config(ccfg); return ptr; } - virtual bool is_using_hal() const override - { - return GetParam(); - }; void print_ctrl_measurement(const char* msg = "") { @@ -56,11 +51,6 @@ class TestBMP280 : public ComponentTestBase { } }; -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestBMP280, -// ::testing::Values(false, true)); -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestBMP280, ::testing::Values(true)); -INSTANTIATE_TEST_SUITE_P(ParamValues, TestBMP280, ::testing::Values(false)); - namespace { constexpr Oversampling os_table[] = { @@ -115,44 +105,6 @@ constexpr UseCaseSetting uc_val_table[] = { {OversamplingSetting::UltraHighResolution, Filter::Coeff16, Standby::Time0_5ms}, }; -template -elapsed_time_t test_periodic(U* unit, const uint32_t times, const uint32_t measure_duration = 0) -{ - auto tm = unit->interval(); - auto timeout_at = m5::utility::millis() + 10 * 1000; - - do { - unit->update(); - if (unit->updated()) { - break; - } - std::this_thread::yield(); - } while (!unit->updated() && m5::utility::millis() <= timeout_at); - // timeout - if (!unit->updated()) { - return 0; - } - - // - uint32_t measured{}; - auto start_at = m5::utility::millis(); - timeout_at = start_at + (times * (tm + measure_duration) * 2); - - do { - unit->update(); - measured += unit->updated() ? 1 : 0; - if (measured >= times) { - break; - } - std::this_thread::yield(); - // m5::utility::delay(1); - - } while (measured < times && m5::utility::millis() <= timeout_at); - return (measured == times) ? m5::utility::millis() - start_at : 0; - - // return (measured == times) ? unit->updatedMillis() - start_at : 0; -} - uint32_t calculate_measure_time(const Oversampling osrsP, const Oversampling osrsT, const Filter f) { uint32_t px = ((1U << m5::stl::to_underlying(osrsP) >> 1)); @@ -173,7 +125,7 @@ uint32_t calculate_measure_time(const Oversampling osrsP, const Oversampling osr } // namespace -TEST_P(TestBMP280, Settings) +TEST_F(TestBMP280, Settings) { SCOPED_TRACE(ustr); @@ -322,7 +274,7 @@ TEST_P(TestBMP280, Settings) } } -TEST_P(TestBMP280, UseCase) +TEST_F(TestBMP280, UseCase) { SCOPED_TRACE(ustr); EXPECT_TRUE(unit->inPeriodic()); @@ -360,7 +312,7 @@ TEST_P(TestBMP280, UseCase) } } -TEST_P(TestBMP280, Reset) +TEST_F(TestBMP280, Reset) { SCOPED_TRACE(ustr); @@ -395,7 +347,7 @@ TEST_P(TestBMP280, Reset) EXPECT_EQ(pm, PowerMode::Sleep); } -TEST_P(TestBMP280, SingleShot) +TEST_F(TestBMP280, SingleShot) { SCOPED_TRACE(ustr); @@ -461,10 +413,13 @@ TEST_P(TestBMP280, SingleShot) } } -TEST_P(TestBMP280, Periodic) +TEST_F(TestBMP280, Periodic) { SCOPED_TRACE(ustr); + auto ad = unit->asAdapter(m5::unit::Adapter::Type::I2C); + bool is_bus = ad && ad->implType() == m5::unit::AdapterI2C::ImplType::Bus; + EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); @@ -482,20 +437,23 @@ TEST_P(TestBMP280, Periodic) tm = standby_time_table[m5::stl::to_underlying(val.st)]; } + M5_LOGI("Periodic: %s interval:%lu ms", s.c_str(), (unsigned long)tm); + EXPECT_TRUE(unit->writeUseCaseSetting(uc)); EXPECT_TRUE(unit->startPeriodicMeasurement()); EXPECT_TRUE(unit->inPeriodic()); - auto elapsed = test_periodic(unit.get(), STORED_SIZE, tm); + // interval() can be 0 for short standby; use actual cycle time to ensure non-zero timeout + uint32_t cycle = std::max(tm, unit->interval()); + uint32_t timeout = is_bus ? std::max(cycle, (uint32_t)500) * (STORED_SIZE + 1) * 4 : cycle * (STORED_SIZE + 1); + auto r = collect_periodic_measurements(unit.get(), STORED_SIZE, timeout); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, STORED_SIZE); + EXPECT_LE(r.median(), cycle + (is_bus ? 5U : 1U)); EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); - // M5_LOGW("E:%ld tm:%ld/%ld", elapsed, tm, tm * STORED_SIZE); - - EXPECT_NE(elapsed, 0); - EXPECT_LE(elapsed, STORED_SIZE * tm); - // EXPECT_EQ(unit->available(), STORED_SIZE); EXPECT_FALSE(unit->empty()); diff --git a/test/embedded/test_qmp6988/qmp6988_test.cpp b/test/embedded/test_qmp6988/qmp6988_test.cpp index ad8f315..33a6a7d 100644 --- a/test/embedded/test_qmp6988/qmp6988_test.cpp +++ b/test/embedded/test_qmp6988/qmp6988_test.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -23,11 +24,9 @@ using namespace m5::unit::qmp6988; using namespace m5::unit::qmp6988::command; using m5::unit::types::elapsed_time_t; -const ::testing::Environment* global_fixture = ::testing::AddGlobalTestEnvironment(new GlobalFixture<400000U>()); - constexpr uint32_t STORED_SIZE{8}; -class TestQMP6988 : public ComponentTestBase { +class TestQMP6988 : public I2CComponentTestBase { protected: virtual UnitQMP6988* get_instance() override { @@ -37,17 +36,8 @@ class TestQMP6988 : public ComponentTestBase { ptr->component_config(ccfg); return ptr; } - virtual bool is_using_hal() const override - { - return GetParam(); - }; }; -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestQMP6988, -// ::testing::Values(false, true)); -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestQMP6988, ::testing::Values(true)); -INSTANTIATE_TEST_SUITE_P(ParamValues, TestQMP6988, ::testing::Values(false)); - namespace { constexpr Oversampling os_table[] = { Oversampling::Skipped, Oversampling::X1, Oversampling::X2, Oversampling::X4, @@ -55,8 +45,8 @@ constexpr Oversampling os_table[] = { }; constexpr OversamplingSetting oss_table[] = { - OversamplingSetting::HighSpeed, OversamplingSetting::LowPower, OversamplingSetting::Standard, - OversamplingSetting::HighAccuracy, OversamplingSetting::UltraHightAccuracy, + OversamplingSetting::HighSpeed, OversamplingSetting::LowPower, OversamplingSetting::Standard, + OversamplingSetting::HighAccuracy, OversamplingSetting::UltraHighAccuracy, }; constexpr Oversampling osrss_table[][2] = { @@ -95,52 +85,12 @@ constexpr UseCaseSetting uc_val_table[] = { {OversamplingSetting::LowPower, Filter::Off}, {OversamplingSetting::Standard, Filter::Coeff4}, {OversamplingSetting::HighAccuracy, Filter::Coeff8}, - {OversamplingSetting::UltraHightAccuracy, Filter::Coeff32}, + {OversamplingSetting::UltraHighAccuracy, Filter::Coeff32}, }; -template -elapsed_time_t test_periodic(U* unit, const uint32_t times, const uint32_t measure_duration = 0) -{ - auto tm = unit->interval(); - auto timeout_at = m5::utility::millis() + 8 * 1000; - // First measured - do { - unit->update(); - if (unit->updated()) { - break; - } - std::this_thread::yield(); - } while (!unit->updated() && m5::utility::millis() <= timeout_at); - // timeout - if (!unit->updated()) { - return 0; - } - - // - uint32_t measured{}; - auto start_at = m5::utility::millis(); - timeout_at = start_at + (times * (tm + measure_duration) * 2); - do { - unit->update(); - measured += unit->updated() ? 1 : 0; - if (measured >= times) { - break; - } - std::this_thread::yield(); - // m5::utility::delay(1); - - } while (measured < times && m5::utility::millis() <= timeout_at); - - if (measured == times) { - return m5::utility::millis() - start_at; - } - M5_LOGE("measured:%u", measured); - return -1; -} - } // namespace -TEST_P(TestQMP6988, Settings) +TEST_F(TestQMP6988, Settings) { SCOPED_TRACE(ustr); @@ -289,7 +239,7 @@ TEST_P(TestQMP6988, Settings) } } -TEST_P(TestQMP6988, UseCase) +TEST_F(TestQMP6988, UseCase) { SCOPED_TRACE(ustr); EXPECT_TRUE(unit->inPeriodic()); @@ -324,7 +274,7 @@ TEST_P(TestQMP6988, UseCase) } } -TEST_P(TestQMP6988, Reset) +TEST_F(TestQMP6988, Reset) { SCOPED_TRACE(ustr); @@ -359,7 +309,7 @@ TEST_P(TestQMP6988, Reset) EXPECT_EQ(pm, PowerMode::Sleep); } -TEST_P(TestQMP6988, SingleShot) +TEST_F(TestQMP6988, SingleShot) { SCOPED_TRACE(ustr); @@ -424,10 +374,13 @@ TEST_P(TestQMP6988, SingleShot) } } -TEST_P(TestQMP6988, Periodic) +TEST_F(TestQMP6988, Periodic) { SCOPED_TRACE(ustr); + auto ad = unit->asAdapter(m5::unit::Adapter::Type::I2C); + bool is_bus = ad && ad->implType() == m5::unit::AdapterI2C::ImplType::Bus; + EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); @@ -436,8 +389,6 @@ TEST_P(TestQMP6988, Periodic) auto s = m5::utility::formatString("UC:%u ST:%u", uc, st); SCOPED_TRACE(s); - // M5_LOGW("%s", s.c_str()); - const auto& val = uc_val_table[m5::stl::to_underlying(uc)]; const auto& osrrs = osrss_table[m5::stl::to_underlying(val.osrss)]; @@ -445,17 +396,19 @@ TEST_P(TestQMP6988, Periodic) EXPECT_TRUE(unit->writeStandbyTime(st)); EXPECT_TRUE(unit->startPeriodicMeasurement()); EXPECT_TRUE(unit->inPeriodic()); - auto tm = unit->interval(); - auto elapsed = test_periodic(unit.get(), STORED_SIZE, (int)st == 0 ? ((uint32_t)uc + 1) * 2 : 0); + + // interval() can be as small as 1ms for short standby + M5_LOGI("Periodic: %s interval:%lu ms", s.c_str(), unit->interval()); + uint32_t timeout = is_bus ? std::max(unit->interval(), 500) * (STORED_SIZE + 1) * 4 + : unit->interval() * (STORED_SIZE + 1); + auto r = collect_periodic_measurements(unit.get(), STORED_SIZE, timeout); EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); - // M5_LOGW("E:(%u) %ld", tm == 1 ? (uint32_t)uc * 2 : 0, elapsed); - - EXPECT_NE(elapsed, 0); - EXPECT_NE(elapsed, -1); - EXPECT_GE(elapsed, STORED_SIZE * tm - 1); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, STORED_SIZE); + EXPECT_LE(r.median(), r.expected_interval + (is_bus ? 5U : 1U)); Oversampling t; Oversampling p; diff --git a/test/embedded/test_scd40/scd40_test.cpp b/test/embedded/test_scd40/scd40_test.cpp index 8304d28..366e924 100644 --- a/test/embedded/test_scd40/scd40_test.cpp +++ b/test/embedded/test_scd40/scd40_test.cpp @@ -21,11 +21,9 @@ using namespace m5::unit; using namespace m5::unit::scd4x; using m5::unit::types::elapsed_time_t; -const ::testing::Environment* global_fixture = ::testing::AddGlobalTestEnvironment(new GlobalFixture<400000U>()); - constexpr uint32_t STORED_SIZE{4}; -class TestSCD4x : public ComponentTestBase { +class TestSCD4x : public I2CComponentTestBase { protected: virtual UnitSCD40* get_instance() override { @@ -38,16 +36,8 @@ class TestSCD4x : public ComponentTestBase { ptr->config(cfg); return ptr; } - virtual bool is_using_hal() const override - { - return GetParam(); - }; }; -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestSCD4x, ::testing::Values(false, true)); -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestSCD4x, ::testing::Values(true)); -INSTANTIATE_TEST_SUITE_P(ParamValues, TestSCD4x, ::testing::Values(false)); - namespace { } // namespace diff --git a/test/embedded/test_scd41/scd41_test.cpp b/test/embedded/test_scd41/scd41_test.cpp index 741c7b0..d464600 100644 --- a/test/embedded/test_scd41/scd41_test.cpp +++ b/test/embedded/test_scd41/scd41_test.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -20,11 +21,9 @@ using namespace m5::unit; using namespace m5::unit::scd4x; using m5::unit::types::elapsed_time_t; -const ::testing::Environment* global_fixture = ::testing::AddGlobalTestEnvironment(new GlobalFixture<400000U>()); - constexpr uint32_t STORED_SIZE{4}; -class TestSCD4x : public ComponentTestBase { +class TestSCD4x : public I2CComponentTestBase { protected: virtual UnitSCD41* get_instance() override { @@ -37,22 +36,14 @@ class TestSCD4x : public ComponentTestBase { ptr->config(cfg); return ptr; } - virtual bool is_using_hal() const override - { - return GetParam(); - }; }; -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestSCD4x, ::testing::Values(false, true)); -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestSCD4x, ::testing::Values(true)); -INSTANTIATE_TEST_SUITE_P(ParamValues, TestSCD4x, ::testing::Values(false)); - namespace { } // namespace #include "../scd4x_test.inl" -TEST_P(TestSCD4x, Singleshot) +TEST_F(TestSCD4x, Singleshot) { SCOPED_TRACE(ustr); { @@ -93,7 +84,7 @@ TEST_P(TestSCD4x, Singleshot) } } -TEST_P(TestSCD4x, PowerMode) +TEST_F(TestSCD4x, PowerMode) { SCOPED_TRACE(ustr); @@ -115,7 +106,7 @@ TEST_P(TestSCD4x, PowerMode) EXPECT_TRUE(unit->reInit()); } -TEST_P(TestSCD4x, ASC) +TEST_F(TestSCD4x, ASC) { SCOPED_TRACE(ustr); diff --git a/test/embedded/test_sgp30/sgp30_test.cpp b/test/embedded/test_sgp30/sgp30_test.cpp index b12eaf0..1660617 100644 --- a/test/embedded/test_sgp30/sgp30_test.cpp +++ b/test/embedded/test_sgp30/sgp30_test.cpp @@ -13,14 +13,13 @@ #include #include #include +#include using namespace m5::unit::googletest; using namespace m5::unit; using namespace m5::unit::sgp30; -const ::testing::Environment* global_fixture = ::testing::AddGlobalTestEnvironment(new GlobalFixture<400000U>()); - -class TestSGP30 : public ComponentTestBase { +class TestSGP30 : public I2CComponentTestBase { protected: virtual UnitSGP30* get_instance() override { @@ -36,16 +35,8 @@ class TestSGP30 : public ComponentTestBase { } return ptr; } - virtual bool is_using_hal() const override - { - return GetParam(); - }; }; -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestSGP30, ::testing::Values(false, true)); -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestSGP30, ::testing::Values(true)); -INSTANTIATE_TEST_SUITE_P(ParamValues, TestSGP30, ::testing::Values(false)); - namespace { void check_measurement_values(UnitSGP30* u) { @@ -69,7 +60,7 @@ void wait15sec() } // namespace -TEST_P(TestSGP30, FeatureSet) +TEST_F(TestSGP30, FeatureSet) { SCOPED_TRACE(ustr); @@ -84,7 +75,7 @@ TEST_P(TestSGP30, FeatureSet) EXPECT_EQ(unit->productVersion(), f.productVersion()); } -TEST_P(TestSGP30, selfTest) +TEST_F(TestSGP30, selfTest) { SCOPED_TRACE(ustr); @@ -93,7 +84,7 @@ TEST_P(TestSGP30, selfTest) EXPECT_EQ(result, 0xD400); } -TEST_P(TestSGP30, serialNumber) +TEST_F(TestSGP30, serialNumber) { SCOPED_TRACE(ustr); // Read direct [MSB] SNB_3, SNB_2, CRC, SNB_1, SNB_0, CRC [LSB] @@ -128,10 +119,18 @@ TEST_P(TestSGP30, serialNumber) EXPECT_STREQ(s.c_str(), ssno); } -TEST_P(TestSGP30, generalReset) +TEST_F(TestSGP30, generalReset) { SCOPED_TRACE(ustr); + // I2C_Class hangs on generalReset (bus stuck after general call reset) + auto ad = unit->asAdapter(m5::unit::Adapter::Type::I2C); + bool is_i2cclass = ad && ad->implType() == m5::unit::AdapterI2C::ImplType::I2CClass; + if (is_i2cclass) { + M5_LOGW("Skip GeneralReset: I2C_Class does not recover from general call reset"); + GTEST_SKIP(); + } + EXPECT_TRUE(unit->startPeriodicMeasurement(0x1234, 0x5678, 0x9ABC)); M5_LOGW("SGP30 measurement starts 15 seconds after begin"); EXPECT_TRUE(unit->inPeriodic()); @@ -158,7 +157,7 @@ TEST_P(TestSGP30, generalReset) // EXPECT_EQ(inceptive_tvoc, 0x0000); } -TEST_P(TestSGP30, Periodic) +TEST_F(TestSGP30, Periodic) { SCOPED_TRACE(ustr); @@ -177,7 +176,12 @@ TEST_P(TestSGP30, Periodic) EXPECT_TRUE(unit->inPeriodic()); wait15sec(); - test_periodic_measurement(unit.get(), 4, check_measurement_values); + { + auto r = collect_periodic_measurements(unit.get(), 4, 0, check_measurement_values); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, 4U); + EXPECT_LE(r.median(), r.expected_interval + 1); + } EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); diff --git a/test/embedded/test_sht30/sht30_test.cpp b/test/embedded/test_sht30/sht30_test.cpp index e0e6310..79c9ca9 100644 --- a/test/embedded/test_sht30/sht30_test.cpp +++ b/test/embedded/test_sht30/sht30_test.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -25,9 +26,7 @@ using namespace m5::unit::sht30::command; constexpr size_t STORED_SIZE{4}; -const ::testing::Environment* global_fixture = ::testing::AddGlobalTestEnvironment(new GlobalFixture<400000U>()); - -class TestSHT30 : public ComponentTestBase { +class TestSHT30 : public I2CComponentTestBase { protected: virtual UnitSHT30* get_instance() override { @@ -37,17 +36,8 @@ class TestSHT30 : public ComponentTestBase { ptr->component_config(ccfg); return ptr; } - virtual bool is_using_hal() const override - { - return GetParam(); - }; }; -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestSHT30, -// ::testing::Values(false, true)); -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestSHT30, ::testing::Values(true)); -INSTANTIATE_TEST_SUITE_P(ParamValues, TestSHT30, ::testing::Values(false)); - namespace { // flot t uu int16 (temperature) constexpr uint16_t float_to_uint16(const float f) @@ -70,11 +60,14 @@ void check_measurement_values(UnitSHT30* u) } // namespace -TEST_P(TestSHT30, SingleShot) +TEST_F(TestSHT30, SingleShot) { SCOPED_TRACE(ustr); EXPECT_TRUE(unit->stopPeriodicMeasurement()); + auto ad = unit->asAdapter(m5::unit::Adapter::Type::I2C); + bool is_i2cclass = ad && ad->implType() == m5::unit::AdapterI2C::ImplType::I2CClass; + for (auto&& e : ss_table) { const char* s{}; Repeatability rep; @@ -82,20 +75,29 @@ TEST_P(TestSHT30, SingleShot) std::tie(s, rep, stretch) = e; SCOPED_TRACE(s); - int cnt{10}; // repeat 10 times - while (cnt--) { + if (stretch && is_i2cclass) { + // I2C_Class does not support clock stretching sht30::Data d{}; - EXPECT_TRUE(unit->measureSingleshot(d, rep, stretch)) << (int)rep << " : " << stretch; - EXPECT_TRUE(std::isfinite(d.temperature())); - EXPECT_TRUE(std::isfinite(d.humidity())); + EXPECT_FALSE(unit->measureSingleshot(d, rep, stretch)); + } else { + int cnt{10}; // repeat 10 times + while (cnt--) { + sht30::Data d{}; + EXPECT_TRUE(unit->measureSingleshot(d, rep, stretch)) << (int)rep << " : " << stretch; + EXPECT_TRUE(std::isfinite(d.temperature())); + EXPECT_TRUE(std::isfinite(d.humidity())); + } } } } -TEST_P(TestSHT30, Periodic) +TEST_F(TestSHT30, Periodic) { SCOPED_TRACE(ustr); + auto ad = unit->asAdapter(m5::unit::Adapter::Type::I2C); + bool is_bus = ad && ad->implType() == m5::unit::AdapterI2C::ImplType::Bus; + EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); @@ -132,6 +134,8 @@ TEST_P(TestSHT30, Periodic) EXPECT_TRUE(unit->startPeriodicMeasurement(mps, rep)); EXPECT_TRUE(unit->inPeriodic()); + M5_LOGI("Periodic: %s interval:%lu ms", s, unit->interval()); + // Cannot call all singleshot in periodic for (auto&& e : ss_table) { const char* s{}; @@ -143,7 +147,14 @@ TEST_P(TestSHT30, Periodic) SCOPED_TRACE(s); EXPECT_FALSE(unit->measureSingleshot(d, rep, stretch)); } - test_periodic_measurement(unit.get(), 4, 1, check_measurement_values); + { + uint32_t timeout = + is_bus ? std::max(unit->interval(), 500) * (4 + 1) * 4 : unit->interval() * (4 + 1); + auto r = collect_periodic_measurements(unit.get(), 4, timeout, check_measurement_values); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, 4U); + EXPECT_LE(r.median(), r.expected_interval + (is_bus ? 5U : 1U)); + } EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); @@ -196,7 +207,15 @@ TEST_P(TestSHT30, Periodic) EXPECT_FALSE(unit->measureSingleshot(d, rep, stretch)); } - test_periodic_measurement(unit.get(), 4, 1, check_measurement_values); + { + // ART = 4 mps = 250ms interval + uint32_t timeout = + is_bus ? std::max(unit->interval(), 500) * (4 + 1) * 4 : unit->interval() * (4 + 1); + auto r = collect_periodic_measurements(unit.get(), 4, timeout, check_measurement_values); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, 4U); + EXPECT_LE(r.median(), r.expected_interval + (is_bus ? 5U : 1U)); + } EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); @@ -217,13 +236,36 @@ TEST_P(TestSHT30, Periodic) EXPECT_TRUE(unit->empty()); EXPECT_FALSE(unit->full()); + // startPeriodicMeasurement() no-arg: uses cached MPS and Repeatability + { + EXPECT_TRUE(unit->startPeriodicMeasurement(MPS::Four, Repeatability::Low)); + EXPECT_TRUE(unit->inPeriodic()); + EXPECT_TRUE(unit->stopPeriodicMeasurement()); + EXPECT_FALSE(unit->inPeriodic()); + + // No-arg version should use cached settings (Four, Low) + EXPECT_TRUE(unit->startPeriodicMeasurement()); + EXPECT_TRUE(unit->inPeriodic()); + + uint32_t timeout = + is_bus ? std::max(unit->interval(), 500) * (4 + 1) * 4 : unit->interval() * (4 + 1); + auto r = collect_periodic_measurements(unit.get(), 4, timeout, check_measurement_values); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, 4U); + // Four = 250ms interval + EXPECT_LE(r.median(), 250 + (is_bus ? 5U : 1U)); + EXPECT_GE(r.median(), 250 - 50); + + EXPECT_TRUE(unit->stopPeriodicMeasurement()); + EXPECT_FALSE(unit->inPeriodic()); + } + // startPeriodicMeasurement after ART (ART is disabled) EXPECT_TRUE(unit->startPeriodicMeasurement(MPS::Two, Repeatability::High)); // 2 mps EXPECT_TRUE(unit->inPeriodic()); EXPECT_EQ(unit->updatedMillis(), 0); - std::array rbuf{}; types::elapsed_time_t timeout_at{}, now{}, at[2]{}; uint32_t idx{}; timeout_at = m5::utility::millis() + 1100; @@ -252,7 +294,7 @@ void printStatus(const Status& s) } } // namespace -TEST_P(TestSHT30, HeaterAndStatus) +TEST_F(TestSHT30, HeaterAndStatus) { SCOPED_TRACE(ustr); @@ -277,7 +319,7 @@ TEST_P(TestSHT30, HeaterAndStatus) EXPECT_FALSE(s.heater()); } -TEST_P(TestSHT30, SoftReset) +TEST_F(TestSHT30, SoftReset) { SCOPED_TRACE(ustr); @@ -303,18 +345,25 @@ TEST_P(TestSHT30, SoftReset) EXPECT_FALSE(s.checksum()); } -TEST_P(TestSHT30, GeneralReset) +TEST_F(TestSHT30, GeneralReset) { SCOPED_TRACE(ustr); + // I2C_Class hangs on generalReset (bus stuck after general call reset) + auto ad = unit->asAdapter(m5::unit::Adapter::Type::I2C); + bool is_i2cclass = ad && ad->implType() == m5::unit::AdapterI2C::ImplType::I2CClass; + if (is_i2cclass) { + M5_LOGW("Skip GeneralReset: I2C_Class does not recover from general call reset"); + GTEST_SKIP(); + } + EXPECT_TRUE(unit->startHeater()); EXPECT_TRUE(unit->generalReset()); Status s{}; EXPECT_TRUE(unit->readStatus(s)); - // The ALERT pin will also become active (high) after powerup and after - // resets + // The ALERT pin will also become active (high) after powerup and after resets EXPECT_TRUE(s.alertPending()); EXPECT_FALSE(s.heater()); EXPECT_FALSE(s.trackingAlertRH()); @@ -324,7 +373,7 @@ TEST_P(TestSHT30, GeneralReset) EXPECT_FALSE(s.checksum()); } -TEST_P(TestSHT30, SerialNumber) +TEST_F(TestSHT30, SerialNumber) { SCOPED_TRACE(ustr); diff --git a/test/embedded/test_sht40/sht40_test.cpp b/test/embedded/test_sht40/sht40_test.cpp index 7c668f4..d836122 100644 --- a/test/embedded/test_sht40/sht40_test.cpp +++ b/test/embedded/test_sht40/sht40_test.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -25,9 +26,7 @@ using m5::unit::types::elapsed_time_t; constexpr size_t STORED_SIZE{4}; -const ::testing::Environment* global_fixture = ::testing::AddGlobalTestEnvironment(new GlobalFixture<400000U>()); - -class TestSHT40 : public ComponentTestBase { +class TestSHT40 : public I2CComponentTestBase { protected: virtual UnitSHT40* get_instance() override { @@ -37,48 +36,10 @@ class TestSHT40 : public ComponentTestBase { ptr->component_config(ccfg); return ptr; } - virtual bool is_using_hal() const override - { - return GetParam(); - }; }; -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestSHT40, -// ::testing::Values(false, true)); -// INSTANTIATE_TEST_SUITE_P(ParamValues, TestSHT40, ::testing::Values(true)); -INSTANTIATE_TEST_SUITE_P(ParamValues, TestSHT40, ::testing::Values(false)); - namespace { -template -elapsed_time_t test_periodic(U* unit, const uint32_t times) -{ - auto timeout_at = m5::utility::millis() + (times * unit->interval() * 2); - - // First read - while (!unit->updated() && m5::utility::millis() < timeout_at) { - std::this_thread::yield(); - unit->update(); - } - // timeout - if (!unit->updated()) { - return 0; - } - - // - uint32_t measured{}; - auto start_at = m5::utility::millis(); - unit->update(); - - do { - m5::utility::delay(1); - unit->update(); - measured += unit->updated() ? 1 : 0; - } while (measured < times && m5::utility::millis() < timeout_at); - - return (measured == times) ? m5::utility::millis() - start_at : 0; -} - std::tuple sm_table[] = { // {"HighLong", Precision::High, Heater::Long, 9}, @@ -96,7 +57,7 @@ std::tuple sm_table[] = { } // namespace -TEST_P(TestSHT40, SoftReset) +TEST_F(TestSHT40, SoftReset) { SCOPED_TRACE(ustr); // Soft reset is only possible in standby mode. @@ -106,13 +67,22 @@ TEST_P(TestSHT40, SoftReset) EXPECT_TRUE(unit->softReset()); } -TEST_P(TestSHT40, GeneralReset) +TEST_F(TestSHT40, GeneralReset) { SCOPED_TRACE(ustr); + + // I2C_Class hangs on generalReset (bus stuck after general call reset) + auto ad = unit->asAdapter(m5::unit::Adapter::Type::I2C); + bool is_i2cclass = ad && ad->implType() == m5::unit::AdapterI2C::ImplType::I2CClass; + if (is_i2cclass) { + M5_LOGW("Skip GeneralReset: I2C_Class does not recover from general call reset"); + GTEST_SKIP(); + } + EXPECT_TRUE(unit->generalReset()); } -TEST_P(TestSHT40, SerialNumber) +TEST_F(TestSHT40, SerialNumber) { SCOPED_TRACE(ustr); @@ -143,7 +113,7 @@ TEST_P(TestSHT40, SerialNumber) } } -TEST_P(TestSHT40, SingleShot) +TEST_F(TestSHT40, SingleShot) { SCOPED_TRACE(ustr); @@ -170,10 +140,13 @@ TEST_P(TestSHT40, SingleShot) } } -TEST_P(TestSHT40, Periodic) +TEST_F(TestSHT40, Periodic) { SCOPED_TRACE(ustr); + auto ad = unit->asAdapter(m5::unit::Adapter::Type::I2C); + bool is_bus = ad && ad->implType() == m5::unit::AdapterI2C::ImplType::Bus; + EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); @@ -185,6 +158,7 @@ TEST_P(TestSHT40, Periodic) std::tie(s, p, h, tm) = e; SCOPED_TRACE(s); + M5_LOGI("Periodic: %s interval:%lu ms", s, (unsigned long)tm); EXPECT_TRUE(unit->startPeriodicMeasurement(p, h)); EXPECT_TRUE(unit->inPeriodic()); @@ -206,10 +180,14 @@ TEST_P(TestSHT40, Periodic) EXPECT_TRUE(unit->startPeriodicMeasurement(p, h)); EXPECT_TRUE(unit->inPeriodic()); - auto elapsed = test_periodic(unit.get(), STORED_SIZE); - EXPECT_NE(elapsed, 0); - EXPECT_GE(elapsed, STORED_SIZE * tm); - EXPECT_LE(elapsed, STORED_SIZE * tm + 1); + // interval() can be small (2-9ms); use actual cycle time to ensure non-zero timeout + uint32_t cycle = std::max(tm, unit->interval()); + uint32_t timeout = is_bus ? std::max(cycle, (uint32_t)500) * (STORED_SIZE + 1) * 4 : cycle * (STORED_SIZE + 1); + uint32_t tolerance = is_bus ? 5 : 1; + auto r = collect_periodic_measurements(unit.get(), STORED_SIZE, timeout); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, STORED_SIZE); + EXPECT_LE(r.median(), r.expected_interval + tolerance); // M5_LOGW("[%s] %lu %zu", s, elapsed, unit->available()); @@ -242,4 +220,27 @@ TEST_P(TestSHT40, Periodic) EXPECT_FALSE(std::isfinite(unit->temperature())); EXPECT_FALSE(std::isfinite(unit->humidity())); } + + // startPeriodicMeasurement() no-arg: uses cached Precision, Heater, and duty + { + EXPECT_TRUE(unit->startPeriodicMeasurement(Precision::High, Heater::None)); + EXPECT_TRUE(unit->inPeriodic()); + EXPECT_TRUE(unit->stopPeriodicMeasurement()); + EXPECT_FALSE(unit->inPeriodic()); + + // No-arg version should use cached settings (High, None) + EXPECT_TRUE(unit->startPeriodicMeasurement()); + EXPECT_TRUE(unit->inPeriodic()); + + uint32_t timeout2 = is_bus ? std::max(unit->interval(), 500) * (STORED_SIZE + 1) * 4 + : unit->interval() * (STORED_SIZE + 1); + auto r = collect_periodic_measurements(unit.get(), STORED_SIZE, timeout2); + EXPECT_FALSE(r.timed_out); + EXPECT_EQ(r.update_count, STORED_SIZE); + // High/None = 9ms interval + EXPECT_LE(r.median(), 9 + (is_bus ? 5U : 1U)); + + EXPECT_TRUE(unit->stopPeriodicMeasurement()); + EXPECT_FALSE(unit->inPeriodic()); + } } diff --git a/unit_co2_env.ini b/unit_co2_env.ini index 429e069..bcb195e 100644 --- a/unit_co2_env.ini +++ b/unit_co2_env.ini @@ -33,15 +33,14 @@ lib_deps = ${StampS3.lib_deps} test_filter= embedded/test_scd40 [env:test_SCD40_Dial] -extends=StampS3, option_release, arduino_latest -lib_deps = ${StampS3.lib_deps} - ${test_fw.lib_deps} - m5stack/M5Dial +extends=Dial, option_release, arduino_latest +lib_deps = ${Dial.lib_deps} + ${test_fw.lib_deps} test_filter= embedded/test_scd40 -[env:test_SCD40_AtomMatrix] -extends=AtomMatrix, option_release, arduino_latest -lib_deps = ${AtomMatrix.lib_deps} +[env:test_SCD40_Atom] +extends=Atom, option_release, arduino_latest +lib_deps = ${Atom.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_scd40 @@ -58,7 +57,7 @@ lib_deps = ${AtomS3R.lib_deps} test_filter= embedded/test_scd40 [env:test_SCD40_NanoC6] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest lib_deps = ${NanoC6.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_scd40 @@ -75,6 +74,14 @@ lib_deps = ${StickCPlus2.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_scd40 +[env:test_SCD40_StickS3] +extends=StickS3, option_release, arduino_latest +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} +lib_deps = ${StickS3.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_scd40 + [env:test_SCD40_Paper] extends=Paper, option_release, arduino_latest lib_deps = ${Paper.lib_deps} @@ -87,6 +94,28 @@ lib_deps = ${CoreInk.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_scd40 +[env:test_SCD40_Cardputer] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} +lib_deps = ${Cardputer.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_scd40 + +[env:test_SCD40_Tab5] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} +lib_deps = ${Tab5.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_scd40 + +[env:test_SCD40_NessoN1] +extends=NessoN1, option_release, pioarduino_latest +lib_deps = ${NessoN1.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_scd40 + ; SCD41 [env:test_SCD41_Core] extends=Core, option_release, arduino_latest @@ -119,15 +148,14 @@ lib_deps = ${StampS3.lib_deps} test_filter= embedded/test_scd41 [env:test_SCD41_Dial] -extends=StampS3, option_release, arduino_latest -lib_deps = ${StampS3.lib_deps} - ${test_fw.lib_deps} - m5stack/M5Dial +extends=Dial, option_release, arduino_latest +lib_deps = ${Dial.lib_deps} + ${test_fw.lib_deps} test_filter= embedded/test_scd41 -[env:test_SCD41_AtomMatrix] -extends=AtomMatrix, option_release, arduino_latest -lib_deps = ${AtomMatrix.lib_deps} +[env:test_SCD41_Atom] +extends=Atom, option_release, arduino_latest +lib_deps = ${Atom.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_scd41 @@ -144,7 +172,7 @@ lib_deps = ${AtomS3R.lib_deps} test_filter= embedded/test_scd41 [env:test_SCD41_NanoC6] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest lib_deps = ${NanoC6.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_scd41 @@ -161,6 +189,14 @@ lib_deps = ${StickCPlus2.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_scd41 +[env:test_SCD41_StickS3] +extends=StickS3, option_release, arduino_latest +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} +lib_deps = ${StickS3.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_scd41 + [env:test_SCD41_Paper] extends=Paper, option_release, arduino_latest lib_deps = ${Paper.lib_deps} @@ -173,32 +209,39 @@ lib_deps = ${CoreInk.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_scd41 +[env:test_SCD41_Cardputer] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} +lib_deps = ${Cardputer.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_scd41 + +[env:test_SCD41_Tab5] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} +lib_deps = ${Tab5.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_scd41 + +[env:test_SCD41_NessoN1] +extends=NessoN1, option_release, pioarduino_latest +lib_deps = ${NessoN1.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_scd41 + + ;Examples ; UnitCO2 [env:UnitCO2_PlotToSerial_Core_Arduino_latest] extends=Core, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> -[env:UnitCO2_PlotToSerial_Core_Arduino_5_4_0] -extends=Core, option_release, arduino_5_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> - -[env:UnitCO2_PlotToSerial_Core_Arduino_4_4_0] -extends=Core, option_release, arduino_4_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> - [env:UnitCO2_PlotToSerial_Core2_Arduino_latest] extends=Core2, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> -[env:UnitCO2_PlotToSerial_Core2_Arduino_5_4_0] -extends=Core2, option_release, arduino_5_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> - -[env:UnitCO2_PlotToSerial_Core2_Arduino_4_4_0] -extends=Core2, option_release, arduino_4_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> - [env:UnitCO2_PlotToSerial_CoreS3_Arduino_latest] extends=CoreS3, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> @@ -207,8 +250,8 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/Plot extends=StampS3, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> -[env:UnitCO2_PlotToSerial_AtomMatrix_Arduino_latest] -extends=AtomMatrix, option_release, arduino_latest +[env:UnitCO2_PlotToSerial_Atom_Arduino_latest] +extends=Atom, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> [env:UnitCO2_PlotToSerial_AtomS3_Arduino_latest] @@ -224,7 +267,7 @@ extends=Dial, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> [env:UnitCO2_PlotToSerial_NanoC6_Arduino_latest] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> [env:UnitCO2_PlotToSerial_StickCPlus_Arduino_latest] @@ -235,6 +278,12 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/Plot extends=StickCPlus2, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> +[env:UnitCO2_PlotToSerial_StickS3_Arduino_latest] +extends=StickS3, option_release, arduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} + [env:UnitCO2_PlotToSerial_Paper_Arduino_latest] extends=Paper, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> @@ -247,39 +296,32 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/Plot extends=Fire, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> -[env:UnitCO2_PlotToSerial_Fire_Arduino_5_4_0] -extends=Fire, option_release, arduino_5_4_0 +[env:UnitCO2_PlotToSerial_Cardputer_Arduino_latest] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> + +[env:UnitCO2_PlotToSerial_Tab5_Arduino_latest] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> -[env:UnitCO2_PlotToSerial_Fire_Arduino_4_4_0] -extends=Fire, option_release, arduino_4_4_0 +[env:UnitCO2_PlotToSerial_NessoN1_Arduino_latest] +extends=NessoN1, option_release, pioarduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2/PlotToSerial> + ; UnitCO2L [env:UnitCO2L_PlotToSerial_Core_Arduino_latest] extends=Core, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> -[env:UnitCO2L_PlotToSerial_Core_Arduino_5_4_0] -extends=Core, option_release, arduino_5_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> - -[env:UnitCO2L_PlotToSerial_Core_Arduino_4_4_0] -extends=Core, option_release, arduino_4_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> - [env:UnitCO2L_PlotToSerial_Core2_Arduino_latest] extends=Core2, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> -[env:UnitCO2L_PlotToSerial_Core2_Arduino_5_4_0] -extends=Core2, option_release, arduino_5_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> - -[env:UnitCO2L_PlotToSerial_Core2_Arduino_4_4_0] -extends=Core2, option_release, arduino_4_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> - [env:UnitCO2L_PlotToSerial_CoreS3_Arduino_latest] extends=CoreS3, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> @@ -288,8 +330,8 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/Plo extends=StampS3, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> -[env:UnitCO2L_PlotToSerial_AtomMatrix_Arduino_latest] -extends=AtomMatrix, option_release, arduino_latest +[env:UnitCO2L_PlotToSerial_Atom_Arduino_latest] +extends=Atom, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> [env:UnitCO2L_PlotToSerial_AtomS3_Arduino_latest] @@ -305,7 +347,7 @@ extends=Dial, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> [env:UnitCO2L_PlotToSerial_NanoC6_Arduino_latest] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> [env:UnitCO2L_PlotToSerial_StickCPlus_Arduino_latest] @@ -316,6 +358,12 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/Plo extends=StickCPlus2, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> +[env:UnitCO2L_PlotToSerial_StickS3_Arduino_latest] +extends=StickS3, option_release, arduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} + [env:UnitCO2L_PlotToSerial_Paper_Arduino_latest] extends=Paper, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> @@ -328,10 +376,19 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/Plo extends=Fire, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> -[env:UnitCO2L_PlotToSerial_Fire_Arduino_5_4_0] -extends=Fire, option_release, arduino_5_4_0 +[env:UnitCO2L_PlotToSerial_Cardputer_Arduino_latest] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> -[env:UnitCO2L_PlotToSerial_Fire_Arduino_4_4_0] -extends=Fire, option_release, arduino_4_4_0 +[env:UnitCO2L_PlotToSerial_Tab5_Arduino_latest] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> + +[env:UnitCO2L_PlotToSerial_NessoN1_Arduino_latest] +extends=NessoN1, option_release, pioarduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitCO2L/PlotToSerial> + diff --git a/unit_env3_env.ini b/unit_env3_env.ini index 4472049..8460862 100644 --- a/unit_env3_env.ini +++ b/unit_env3_env.ini @@ -33,15 +33,14 @@ lib_deps = ${StampS3.lib_deps} test_filter= embedded/test_sht30 [env:test_SHT30_Dial] -extends=StampS3, option_release, arduino_latest -lib_deps = ${StampS3.lib_deps} - ${test_fw.lib_deps} - m5stack/M5Dial +extends=Dial, option_release, arduino_latest +lib_deps = ${Dial.lib_deps} + ${test_fw.lib_deps} test_filter= embedded/test_sht30 -[env:test_SHT30_AtomMatrix] -extends=AtomMatrix, option_release, arduino_latest -lib_deps = ${AtomMatrix.lib_deps} +[env:test_SHT30_Atom] +extends=Atom, option_release, arduino_latest +lib_deps = ${Atom.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_sht30 @@ -58,7 +57,7 @@ lib_deps = ${AtomS3R.lib_deps} test_filter= embedded/test_sht30 [env:test_SHT30_NanoC6] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest lib_deps = ${NanoC6.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_sht30 @@ -75,6 +74,14 @@ lib_deps = ${StickCPlus2.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_sht30 +[env:test_SHT30_StickS3] +extends=StickS3, option_release, arduino_latest +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} +lib_deps = ${StickS3.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_sht30 + [env:test_SHT30_Paper] extends=Paper, option_release, arduino_latest lib_deps = ${Paper.lib_deps} @@ -87,6 +94,28 @@ lib_deps = ${CoreInk.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_sht30 +[env:test_SHT30_Cardputer] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} +lib_deps = ${Cardputer.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_sht30 + +[env:test_SHT30_Tab5] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} +lib_deps = ${Tab5.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_sht30 + +[env:test_SHT30_NessoN1] +extends=NessoN1, option_release, pioarduino_latest +lib_deps = ${NessoN1.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_sht30 + ; QMP6988 [env:test_QMP6988_Core] extends=Core, option_release, arduino_latest @@ -119,15 +148,14 @@ lib_deps = ${StampS3.lib_deps} test_filter= embedded/test_qmp6988 [env:test_QMP6988_Dial] -extends=StampS3, option_release, arduino_latest -lib_deps = ${StampS3.lib_deps} - ${test_fw.lib_deps} - m5stack/M5Dial +extends=Dial, option_release, arduino_latest +lib_deps = ${Dial.lib_deps} + ${test_fw.lib_deps} test_filter= embedded/test_qmp6988 -[env:test_QMP6988_AtomMatrix] -extends=AtomMatrix, option_release, arduino_latest -lib_deps = ${AtomMatrix.lib_deps} +[env:test_QMP6988_Atom] +extends=Atom, option_release, arduino_latest +lib_deps = ${Atom.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_qmp6988 @@ -144,7 +172,7 @@ lib_deps = ${AtomS3R.lib_deps} test_filter= embedded/test_qmp6988 [env:test_QMP6988_NanoC6] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest lib_deps = ${NanoC6.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_qmp6988 @@ -161,6 +189,14 @@ lib_deps = ${StickCPlus2.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_qmp6988 +[env:test_QMP6988_StickS3] +extends=StickS3, option_release, arduino_latest +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} +lib_deps = ${StickS3.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_qmp6988 + [env:test_QMP6988_Paper] extends=Paper, option_release, arduino_latest lib_deps = ${Paper.lib_deps} @@ -173,32 +209,38 @@ lib_deps = ${CoreInk.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_qmp6988 +[env:test_QMP6988_Cardputer] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} +lib_deps = ${Cardputer.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_qmp6988 + +[env:test_QMP6988_Tab5] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} +lib_deps = ${Tab5.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_qmp6988 + +[env:test_QMP6988_NessoN1] +extends=NessoN1, option_release, pioarduino_latest +lib_deps = ${NessoN1.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_qmp6988 + ;Examples ;;Unit ENVIII [env:UnitENVIII_PlotToSerial_Core_Arduino_latest] extends=Core, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> -[env:UnitENVIII_PlotToSerial_Core_Arduino_5_4_0] -extends=Core, option_release, arduino_5_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> - -[env:UnitENVIII_PlotToSerial_Core_Arduino_4_4_0] -extends=Core, option_release, arduino_4_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> - [env:UnitENVIII_PlotToSerial_Core2_Arduino_latest] extends=Core2, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> -[env:UnitENVIII_PlotToSerial_Core2_Arduino_5_4_0] -extends=Core2, option_release, arduino_5_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> - -[env:UnitENVIII_PlotToSerial_Core2_Arduino_4_4_0] -extends=Core2, option_release, arduino_4_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> - [env:UnitENVIII_PlotToSerial_CoreS3_Arduino_latest] extends=CoreS3, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> @@ -207,8 +249,8 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/P extends=StampS3, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> -[env:UnitENVIII_PlotToSerial_AtomMatrix_Arduino_latest] -extends=AtomMatrix, option_release, arduino_latest +[env:UnitENVIII_PlotToSerial_Atom_Arduino_latest] +extends=Atom, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> [env:UnitENVIII_PlotToSerial_AtomS3_Arduino_latest] @@ -224,7 +266,7 @@ extends=Dial, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> [env:UnitENVIII_PlotToSerial_NanoC6_Arduino_latest] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> [env:UnitENVIII_PlotToSerial_StickCPlus_Arduino_latest] @@ -235,6 +277,12 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/P extends=StickCPlus2, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> +[env:UnitENVIII_PlotToSerial_StickS3_Arduino_latest] +extends=StickS3, option_release, arduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} + [env:UnitENVIII_PlotToSerial_Paper_Arduino_latest] extends=Paper, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> @@ -247,10 +295,23 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/P extends=Fire, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> -[env:UnitENVIII_PlotToSerial_Fire_Arduino_5_4_0] -extends=Fire, option_release, arduino_5_4_0 +[env:UnitENVIII_PlotToSerial_Cardputer_Arduino_latest] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> + +[env:UnitENVIII_PlotToSerial_Tab5_Arduino_latest] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> -[env:UnitENVIII_PlotToSerial_Fire_Arduino_4_4_0] -extends=Fire, option_release, arduino_4_4_0 +[env:UnitENVIII_PlotToSerial_NessoN1_Arduino_latest] +extends=NessoN1, option_release, pioarduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIII/PlotToSerial> + +; This example is for the SHT30 sensor built into the M5Paper +[env:BuiltinSHT30_Paper_Paper_Arduino_latest] +extends=Paper, option_release, arduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/Paper> diff --git a/unit_env4_env.ini b/unit_env4_env.ini index d2bd905..2efdcb1 100644 --- a/unit_env4_env.ini +++ b/unit_env4_env.ini @@ -33,15 +33,14 @@ lib_deps = ${StampS3.lib_deps} test_filter= embedded/test_sht40 [env:test_SHT40_Dial] -extends=StampS3, option_release, arduino_latest -lib_deps = ${StampS3.lib_deps} - ${test_fw.lib_deps} - m5stack/M5Dial +extends=Dial, option_release, arduino_latest +lib_deps = ${Dial.lib_deps} + ${test_fw.lib_deps} test_filter= embedded/test_sht40 -[env:test_SHT40_AtomMatrix] -extends=AtomMatrix, option_release, arduino_latest -lib_deps = ${AtomMatrix.lib_deps} +[env:test_SHT40_Atom] +extends=Atom, option_release, arduino_latest +lib_deps = ${Atom.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_sht40 @@ -58,9 +57,9 @@ lib_deps = ${AtomS3R.lib_deps} test_filter= embedded/test_sht40 [env:test_SHT40_NanoC6] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest lib_deps = ${NanoC6.lib_deps} - ${test_fw.lib_deps} + ${test_fw.lib_deps} test_filter= embedded/test_sht40 [env:test_SHT40_StickCPlus] @@ -75,6 +74,14 @@ lib_deps = ${StickCPlus2.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_sht40 +[env:test_SHT40_StickS3] +extends=StickS3, option_release, arduino_latest +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} +lib_deps = ${StickS3.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_sht40 + [env:test_SHT40_Paper] extends=Paper, option_release, arduino_latest lib_deps = ${Paper.lib_deps} @@ -83,8 +90,30 @@ test_filter= embedded/test_sht40 [env:test_SHT40_CoreInk] extends=CoreInk, option_release, arduino_latest -lib_deps = ${CoreInk.lib_deps} - ${test_fw.lib_deps} +lib_deps = ${CoreInk.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_sht40 + +[env:test_SHT40_Cardputer] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} +lib_deps = ${Cardputer.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_sht40 + +[env:test_SHT40_Tab5] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} +lib_deps = ${Tab5.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_sht40 + +[env:test_SHT40_NessoN1] +extends=NessoN1, option_release, pioarduino_latest +lib_deps = ${NessoN1.lib_deps} + ${test_fw.lib_deps} test_filter= embedded/test_sht40 ; BMP280 @@ -119,15 +148,14 @@ lib_deps = ${StampS3.lib_deps} test_filter= embedded/test_bmp280 [env:test_BMP280_Dial] -extends=StampS3, option_release, arduino_latest -lib_deps = ${StampS3.lib_deps} - ${test_fw.lib_deps} - m5stack/M5Dial +extends=Dial, option_release, arduino_latest +lib_deps = ${Dial.lib_deps} + ${test_fw.lib_deps} test_filter= embedded/test_bmp280 -[env:test_BMP280_AtomMatrix] -extends=AtomMatrix, option_release, arduino_latest -lib_deps = ${AtomMatrix.lib_deps} +[env:test_BMP280_Atom] +extends=Atom, option_release, arduino_latest +lib_deps = ${Atom.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_bmp280 @@ -144,7 +172,7 @@ lib_deps = ${AtomS3R.lib_deps} test_filter= embedded/test_bmp280 [env:test_BMP280_NanoC6] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest lib_deps = ${NanoC6.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_bmp280 @@ -161,6 +189,14 @@ lib_deps = ${StickCPlus2.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_bmp280 +[env:test_BMP280_StickS3] +extends=StickS3, option_release, arduino_latest +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} +lib_deps = ${StickS3.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_bmp280 + [env:test_BMP280_Paper] extends=Paper, option_release, arduino_latest lib_deps = ${Paper.lib_deps} @@ -173,31 +209,37 @@ lib_deps = ${CoreInk.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_bmp280 +[env:test_BMP280_Cardputer] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} +lib_deps = ${Cardputer.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_bmp280 + +[env:test_BMP280_Tab5] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} +lib_deps = ${Tab5.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_bmp280 + +[env:test_BMP280_NessoN1] +extends=NessoN1, option_release, pioarduino_latest +lib_deps = ${NessoN1.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_bmp280 + ;Examples [env:UnitENVIV_PlotToSerial_Core_Arduino_latest] extends=Core, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> -[env:UnitENVIV_PlotToSerial_Core_Arduino_5_4_0] -extends=Core, option_release, arduino_5_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> - -[env:UnitENVIV_PlotToSerial_Core_Arduino_4_4_0] -extends=Core, option_release, arduino_4_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> - [env:UnitENVIV_PlotToSerial_Core2_Arduino_latest] extends=Core2, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> -[env:UnitENVIV_PlotToSerial_Core2_Arduino_5_4_0] -extends=Core2, option_release, arduino_5_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> - -[env:UnitENVIV_PlotToSerial_Core2_Arduino_4_4_0] -extends=Core2, option_release, arduino_4_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> - [env:UnitENVIV_PlotToSerial_CoreS3_Arduino_latest] extends=CoreS3, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> @@ -206,8 +248,8 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/Pl extends=StampS3, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> -[env:UnitENVIV_PlotToSerial_AtomMatrix_Arduino_latest] -extends=AtomMatrix, option_release, arduino_latest +[env:UnitENVIV_PlotToSerial_Atom_Arduino_latest] +extends=Atom, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> [env:UnitENVIV_PlotToSerial_AtomS3_Arduino_latest] @@ -223,7 +265,7 @@ extends=Dial, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> [env:UnitENVIV_PlotToSerial_NanoC6_Arduino_latest] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> [env:UnitENVIV_PlotToSerial_StickCPlus_Arduino_latest] @@ -234,6 +276,12 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/Pl extends=StickCPlus2, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> +[env:UnitENVIV_PlotToSerial_StickS3_Arduino_latest] +extends=StickS3, option_release, arduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} + [env:UnitENVIV_PlotToSerial_Paper_Arduino_latest] extends=Paper, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> @@ -246,11 +294,19 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/Pl extends=Fire, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> -[env:UnitENVIV_PlotToSerial_Fire_Arduino_5_4_0] -extends=Fire, option_release, arduino_5_4_0 +[env:UnitENVIV_PlotToSerial_Cardputer_Arduino_latest] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> + +[env:UnitENVIV_PlotToSerial_Tab5_Arduino_latest] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> -[env:UnitENVIV_PlotToSerial_Fire_Arduino_4_4_0] -extends=Fire, option_release, arduino_4_4_0 +[env:UnitENVIV_PlotToSerial_NessoN1_Arduino_latest] +extends=NessoN1, option_release, pioarduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVIV/PlotToSerial> diff --git a/unit_envpro_env.ini b/unit_envpro_env.ini index e189bef..cde2c13 100644 --- a/unit_envpro_env.ini +++ b/unit_envpro_env.ini @@ -33,15 +33,14 @@ lib_deps = ${StampS3.lib_deps} test_filter= embedded/test_bme688 [env:test_BME688_Dial] -extends=StampS3, option_release, arduino_latest -lib_deps = ${StampS3.lib_deps} - ${test_fw.lib_deps} - m5stack/M5Dial +extends=Dial, option_release, arduino_latest +lib_deps = ${Dial.lib_deps} + ${test_fw.lib_deps} test_filter= embedded/test_bme688 -[env:test_BME688_AtomMatrix] -extends=AtomMatrix, option_release, arduino_latest -lib_deps = ${AtomMatrix.lib_deps} +[env:test_BME688_Atom] +extends=Atom, option_release, arduino_latest +lib_deps = ${Atom.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_bme688 @@ -58,7 +57,7 @@ lib_deps = ${AtomS3R.lib_deps} test_filter= embedded/test_bme688 [env:test_BME688_NanoC6] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest lib_deps = ${NanoC6.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_bme688 @@ -75,6 +74,14 @@ lib_deps = ${StickCPlus2.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_bme688 +[env:test_BME688_StickS3] +extends=StickS3, option_release, arduino_latest +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} +lib_deps = ${StickS3.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_bme688 + [env:test_BME688_Paper] extends=Paper, option_release, arduino_latest lib_deps = ${Paper.lib_deps} @@ -87,32 +94,38 @@ lib_deps = ${CoreInk.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_bme688 +[env:test_BME688_Cardputer] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} +lib_deps = ${Cardputer.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_bme688 + +[env:test_BME688_Tab5] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} +lib_deps = ${Tab5.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_bme688 + +[env:test_BME688_NessoN1] +extends=NessoN1, option_release, pioarduino_latest +lib_deps = ${NessoN1.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_bme688 + ;Examples ; UnitENVPro [env:UnitENVPro_PlotToSerial_Core_Arduino_latest] extends=Core, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> -[env:UnitENVPro_PlotToSerial_Core_Arduino_5_4_0] -extends=Core, option_release, arduino_5_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> - -[env:UnitENVPro_PlotToSerial_Core_Arduino_4_4_0] -extends=Core, option_release, arduino_4_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> - [env:UnitENVPro_PlotToSerial_Core2_Arduino_latest] extends=Core2, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> -[env:UnitENVPro_PlotToSerial_Core2_Arduino_5_4_0] -extends=Core2, option_release, arduino_5_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> - -[env:UnitENVPro_PlotToSerial_Core2_Arduino_4_4_0] -extends=Core2, option_release, arduino_4_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> - [env:UnitENVPro_PlotToSerial_CoreS3_Arduino_latest] extends=CoreS3, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> @@ -121,8 +134,8 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/P extends=StampS3, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> -[env:UnitENVPro_PlotToSerial_AtomMatrix_Arduino_latest] -extends=AtomMatrix, option_release, arduino_latest +[env:UnitENVPro_PlotToSerial_Atom_Arduino_latest] +extends=Atom, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> [env:UnitENVPro_PlotToSerial_AtomS3_Arduino_latest] @@ -138,7 +151,7 @@ extends=Dial, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> [env:UnitENVPro_PlotToSerial_NanoC6_Arduino_latest] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> [env:UnitENVPro_PlotToSerial_StickCPlus_Arduino_latest] @@ -149,6 +162,12 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/P extends=StickCPlus2, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> +[env:UnitENVPro_PlotToSerial_StickS3_Arduino_latest] +extends=StickS3, option_release, arduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} + [env:UnitENVPro_PlotToSerial_Paper_Arduino_latest] extends=Paper, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> @@ -161,10 +180,19 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/P extends=Fire, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> -[env:UnitENVPro_PlotToSerial_Fire_Arduino_5_4_0] -extends=Fire, option_release, arduino_5_4_0 +[env:UnitENVPro_PlotToSerial_Cardputer_Arduino_latest] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> -[env:UnitENVPro_PlotToSerial_Fire_Arduino_4_4_0] -extends=Fire, option_release, arduino_4_4_0 +[env:UnitENVPro_PlotToSerial_Tab5_Arduino_latest] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> + +[env:UnitENVPro_PlotToSerial_NessoN1_Arduino_latest] +extends=NessoN1, option_release, pioarduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitENVPro/PlotToSerial> + diff --git a/unit_tvoc_env.ini b/unit_tvoc_env.ini index 8b1f0f7..0482af4 100644 --- a/unit_tvoc_env.ini +++ b/unit_tvoc_env.ini @@ -37,9 +37,9 @@ lib_deps = ${Dial.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_sgp30 -[env:test_SGP30_AtomMatrix] -extends=AtomMatrix, option_release, arduino_latest -lib_deps = ${AtomMatrix.lib_deps} +[env:test_SGP30_Atom] +extends=Atom, option_release, arduino_latest +lib_deps = ${Atom.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_sgp30 @@ -56,7 +56,7 @@ lib_deps = ${AtomS3R.lib_deps} test_filter= embedded/test_sgp30 [env:test_SGP30_NanoC6] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest lib_deps = ${NanoC6.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_sgp30 @@ -73,6 +73,14 @@ lib_deps = ${StickCPlus2.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_sgp30 +[env:test_SGP30_StickS3] +extends=StickS3, option_release, arduino_latest +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} +lib_deps = ${StickS3.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_sgp30 + [env:test_SGP30_Paper] extends=Paper, option_release, arduino_latest lib_deps = ${Paper.lib_deps} @@ -85,31 +93,37 @@ lib_deps = ${CoreInk.lib_deps} ${test_fw.lib_deps} test_filter= embedded/test_sgp30 +[env:test_SGP30_Cardputer] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} +lib_deps = ${Cardputer.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_sgp30 + +[env:test_SGP30_Tab5] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} +lib_deps = ${Tab5.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_sgp30 + +[env:test_SGP30_NessoN1] +extends=NessoN1, option_release, pioarduino_latest +lib_deps = ${NessoN1.lib_deps} + ${test_fw.lib_deps} +test_filter= embedded/test_sgp30 + ;Examples [env:UnitTVOC_PlotToSerial_Core_Arduino_latest] extends=Core, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> -[env:UnitTVOC_PlotToSerial_Core_Arduino_5_4_0] -extends=Core, option_release, arduino_5_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> - -[env:UnitTVOC_PlotToSerial_Core_Arduino_4_4_0] -extends=Core, option_release, arduino_4_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> - [env:UnitTVOC_PlotToSerial_Core2_Arduino_latest] extends=Core2, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> -[env:UnitTVOC_PlotToSerial_Core2_Arduino_5_4_0] -extends=Core2, option_release, arduino_5_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> - -[env:UnitTVOC_PlotToSerial_Core2_Arduino_4_4_0] -extends=Core2, option_release, arduino_4_4_0 -build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> - [env:UnitTVOC_PlotToSerial_CoreS3_Arduino_latest] extends=CoreS3, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> @@ -118,8 +132,8 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/Plo extends=StampS3, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> -[env:UnitTVOC_PlotToSerial_AtomMatrix_Arduino_latest] -extends=AtomMatrix, option_release, arduino_latest +[env:UnitTVOC_PlotToSerial_Atom_Arduino_latest] +extends=Atom, option_release, arduino_latest build_flags = ${option_release.build_flags} -DARDUINO_USB_CDC_ON_BOOT=0 build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> @@ -137,7 +151,7 @@ extends=Dial, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> [env:UnitTVOC_PlotToSerial_NanoC6_Arduino_latest] -extends=NanoC6, option_release, arduino_latest +extends=NanoC6, option_release, nanoc6_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> [env:UnitTVOC_PlotToSerial_StickCPlus_Arduino_latest] @@ -148,6 +162,12 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/Plo extends=StickCPlus2, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> +[env:UnitTVOC_PlotToSerial_StickS3_Arduino_latest] +extends=StickS3, option_release, arduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> +build_flags = ${StickS3.build_flags} + ${option_release.build_flags} + [env:UnitTVOC_PlotToSerial_Paper_Arduino_latest] extends=Paper, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> @@ -160,11 +180,19 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/Plo extends=Fire, option_release, arduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> -[env:UnitTVOC_PlotToSerial_Fire_Arduino_5_4_0] -extends=Fire, option_release, arduino_5_4_0 +[env:UnitTVOC_PlotToSerial_Cardputer_Arduino_latest] +extends=Cardputer, option_release, arduino_latest +build_flags = ${Cardputer.build_flags} + ${option_release.build_flags} +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> + +[env:UnitTVOC_PlotToSerial_Tab5_Arduino_latest] +extends=Tab5, option_release, pioarduino_latest +build_flags = ${Tab5.build_flags} + ${option_release.build_flags} build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial> -[env:UnitTVOC_PlotToSerial_Fire_Arduino_4_4_0] -extends=Fire, option_release, arduino_4_4_0 +[env:UnitTVOC_PlotToSerial_NessoN1_Arduino_latest] +extends=NessoN1, option_release, pioarduino_latest build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/UnitTVOC/PlotToSerial>