├── .clang-format ├── .github ├── ISSUE_TEMPLATE │ └── bug-report.yml └── workflows │ ├── Arduino-Lint-Check.yml │ ├── arduino-esp-v2-build-check.yml │ ├── arduino-esp-v3-build-check.yml │ ├── arduino-m5-build-check.yml │ ├── clang-format-check.yml │ ├── doxygen-gh-pages.yml │ └── platformio-build-check.yml ├── .gitignore ├── LICENSE ├── README.md ├── boards ├── m5stack-atoms3r.json ├── m5stack-nanoc6.json └── m5stick-cplus2.json ├── custom_script.py ├── docs ├── Doxyfile └── doxy.sh ├── examples ├── ENV │ └── ENV.ino ├── ENV_II │ └── ENV_II.ino ├── ENV_III │ └── ENV_III.ino ├── ENV_IV │ └── ENV_IV.ino ├── ENV_PRO │ └── ENV_PRO.ino ├── Hat_ENVIII_M5StickC │ └── Hat_ENVIII_M5StickC.ino ├── Hat_ENVIII_M5StickCPlus │ └── Hat_ENVIII_M5StickCPlus.ino ├── Hat_ENVII_M5StickC │ └── Hat_ENVII_M5StickC.ino ├── Hat_ENVII_M5StickCPlus │ └── Hat_ENVII_M5StickCPlus.ino ├── UnitUnified │ ├── UnitCO2 │ │ └── PlotToSerial │ │ │ ├── PlotToSerial.ino │ │ │ └── main │ │ │ └── PlotToSerial.cpp │ ├── UnitCO2L │ │ └── PlotToSerial │ │ │ ├── PlotToSerial.ino │ │ │ └── main │ │ │ └── PlotToSerial.cpp │ ├── UnitENVIII │ │ └── PlotToSerial │ │ │ ├── PlotToSerial.ino │ │ │ └── main │ │ │ └── PlotToSerial.cpp │ ├── UnitENVIV │ │ └── PlotToSerial │ │ │ ├── PlotToSerial.ino │ │ │ └── main │ │ │ └── PlotToSerial.cpp │ ├── UnitENVPro │ │ └── PlotToSerial │ │ │ ├── PlotToSerial.ino │ │ │ └── main │ │ │ └── PlotToSerial.cpp │ └── UnitTVOC │ │ └── PlotToSerial │ │ ├── PlotToSerial.ino │ │ └── main │ │ └── PlotToSerial.cpp ├── Unit_BPS1.1_M5Atom │ └── Unit_BPS1.1_M5Atom.ino ├── Unit_BPS1.1_M5AtomS3 │ └── Unit_BPS1.1_M5AtomS3.ino ├── Unit_BPS1.1_M5AtomS3Lite │ └── Unit_BPS1.1_M5AtomS3Lite.ino ├── Unit_BPS1.1_M5Core │ └── Unit_BPS1.1_M5Core.ino ├── Unit_BPS1.1_M5Core2 │ └── Unit_BPS1.1_M5Core2.ino ├── Unit_BPS1.1_M5StickC │ └── Unit_BPS1.1_M5StickC.ino ├── Unit_BPS1.1_M5StickCPlus │ └── Unit_BPS1.1_M5StickCPlus.ino ├── Unit_BPS_M5Atom │ └── Unit_BPS_M5Atom.ino ├── Unit_BPS_M5AtomS3 │ └── Unit_BPS_M5AtomS3.ino ├── Unit_BPS_M5AtomS3Lite │ └── Unit_BPS_M5AtomS3Lite.ino ├── Unit_BPS_M5Core │ └── Unit_BPS_M5Core.ino ├── Unit_BPS_M5Core2 │ └── Unit_BPS_M5Core2.ino ├── Unit_BPS_M5StickC │ └── Unit_BPS_M5StickC.ino ├── Unit_BPS_M5StickCPlus │ └── Unit_BPS_M5StickCPlus.ino ├── Unit_CO2_M5Atom │ └── Unit_CO2_M5Atom.ino ├── Unit_CO2_M5AtomS3 │ └── Unit_CO2_M5AtomS3.ino ├── Unit_CO2_M5AtomS3Lite │ └── Unit_CO2_M5AtomS3Lite.ino ├── Unit_CO2_M5Core │ └── Unit_CO2_M5Core.ino ├── Unit_CO2_M5Core2 │ └── Unit_CO2_M5Core2.ino ├── Unit_CO2_M5StickC │ └── Unit_CO2_M5StickC.ino ├── Unit_CO2_M5StickCPlus │ └── Unit_CO2_M5StickCPlus.ino ├── Unit_ENVIII_M5Atom │ └── Unit_ENVIII_M5Atom.ino ├── Unit_ENVIII_M5AtomS3 │ └── Unit_ENVIII_M5AtomS3.ino ├── Unit_ENVIII_M5AtomS3Lite │ └── Unit_ENVIII_M5AtomS3Lite.ino ├── Unit_ENVIII_M5Core │ └── Unit_ENVIII_M5Core.ino ├── Unit_ENVIII_M5Core2 │ └── Unit_ENVIII_M5Core2.ino ├── Unit_ENVIII_M5Station │ └── Unit_ENVIII_M5Station.ino ├── Unit_ENVIII_M5StickC │ └── Unit_ENVIII_M5StickC.ino ├── Unit_ENVIII_M5StickCPlus │ └── Unit_ENVIII_M5StickCPlus.ino ├── Unit_ENVII_M5Atom │ └── Unit_ENVII_M5Atom.ino ├── Unit_ENVII_M5AtomS3 │ └── Unit_ENVII_M5AtomS3.ino ├── Unit_ENVII_M5AtomS3Lite │ └── Unit_ENVII_M5AtomS3Lite.ino ├── Unit_ENVII_M5Core │ └── Unit_ENVII_M5Core.ino ├── Unit_ENVII_M5Core2 │ └── Unit_ENVII_M5Core2.ino ├── Unit_ENVII_M5StickC │ └── Unit_ENVII_M5StickC.ino ├── Unit_ENVII_M5StickCPlus │ └── Unit_ENVII_M5StickCPlus.ino ├── Unit_ENVIV_M5Core │ └── Unit_ENVIV_M5Core.ino ├── Unit_ENVIV_M5Core2 │ └── Unit_ENVIV_M5Core2.ino ├── Unit_ENV_M5Atom │ └── Unit_ENV_M5Atom.ino ├── Unit_ENV_M5AtomS3 │ └── Unit_ENV_M5AtomS3.ino ├── Unit_ENV_M5AtomS3Lite │ └── Unit_ENV_M5AtomS3Lite.ino ├── Unit_ENV_M5Core │ └── Unit_ENV_M5Core.ino ├── Unit_ENV_M5Core2 │ └── Unit_ENV_M5Core2.ino ├── Unit_ENV_M5StickC │ └── Unit_ENV_M5StickC.ino └── Unit_ENV_M5StickCPlus │ └── Unit_ENV_M5StickCPlus.ino ├── library.json ├── library.properties ├── platformio.ini ├── src ├── BMP280.cpp ├── BMP280.h ├── DHT12.cpp ├── DHT12.h ├── I2C_Class.cpp ├── I2C_Class.h ├── M5UnitENV.h ├── M5UnitUnifiedENV.h ├── M5UnitUnifiedENV.hpp ├── QMP6988.cpp ├── QMP6988.h ├── SCD4X.cpp ├── SCD4X.h ├── SHT3X.cpp ├── SHT3X.h ├── SHT4X.cpp ├── SHT4X.h ├── unit │ ├── unit_BME688.cpp │ ├── unit_BME688.hpp │ ├── unit_BMP280.cpp │ ├── unit_BMP280.hpp │ ├── unit_ENV3.cpp │ ├── unit_ENV3.hpp │ ├── unit_ENV4.cpp │ ├── unit_ENV4.hpp │ ├── unit_QMP6988.cpp │ ├── unit_QMP6988.hpp │ ├── unit_SCD40.cpp │ ├── unit_SCD40.hpp │ ├── unit_SCD41.cpp │ ├── unit_SCD41.hpp │ ├── unit_SGP30.cpp │ ├── unit_SGP30.hpp │ ├── unit_SHT30.cpp │ ├── unit_SHT30.hpp │ ├── unit_SHT40.cpp │ └── unit_SHT40.hpp ├── utility.cpp └── utility.h ├── test ├── common_main.cpp ├── embedded │ ├── embedded_main.cpp │ ├── scd4x_test.inl │ ├── test_bme688 │ │ └── bme688_test.cpp │ ├── test_bmp280 │ │ └── bmp280_test.cpp │ ├── test_qmp6988 │ │ └── qmp6988_test.cpp │ ├── test_scd40 │ │ └── scd40_test.cpp │ ├── test_scd41 │ │ └── scd41_test.cpp │ ├── test_sgp30 │ │ └── sgp30_test.cpp │ ├── test_sht30 │ │ └── sht30_test.cpp │ └── test_sht40 │ │ └── sht40_test.cpp └── native │ └── test_dummy │ └── .keep ├── unit_co2_env.ini ├── unit_env3_env.ini ├── unit_env4_env.ini ├── unit_envpro_env.ini └── unit_tvoc_env.ini /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: Google 4 | AccessModifierOffset: -4 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveMacros: true 7 | AlignConsecutiveAssignments: true 8 | AlignConsecutiveDeclarations: false 9 | AlignEscapedNewlines: Left 10 | AlignOperands: true 11 | AlignTrailingComments: true 12 | AllowAllArgumentsOnNextLine: true 13 | AllowAllConstructorInitializersOnNextLine: true 14 | AllowAllParametersOfDeclarationOnNextLine: true 15 | AllowShortBlocksOnASingleLine: Never 16 | AllowShortCaseLabelsOnASingleLine: false 17 | AllowShortFunctionsOnASingleLine: false 18 | AllowShortLambdasOnASingleLine: All 19 | AllowShortIfStatementsOnASingleLine: WithoutElse 20 | AllowShortLoopsOnASingleLine: true 21 | AlwaysBreakAfterDefinitionReturnType: None 22 | AlwaysBreakAfterReturnType: None 23 | AlwaysBreakBeforeMultilineStrings: true 24 | AlwaysBreakTemplateDeclarations: Yes 25 | BinPackArguments: true 26 | BinPackParameters: true 27 | BraceWrapping: 28 | AfterCaseLabel: false 29 | AfterClass: false 30 | AfterControlStatement: false 31 | AfterEnum: false 32 | AfterFunction: true 33 | AfterNamespace: false 34 | AfterObjCDeclaration: false 35 | AfterStruct: false 36 | AfterUnion: false 37 | AfterExternBlock: false 38 | BeforeCatch: false 39 | BeforeElse: false 40 | IndentBraces: false 41 | SplitEmptyFunction: true 42 | SplitEmptyRecord: true 43 | SplitEmptyNamespace: true 44 | BreakBeforeBinaryOperators: None 45 | BreakBeforeBraces: Custom 46 | BreakBeforeInheritanceComma: false 47 | BreakInheritanceList: BeforeColon 48 | BreakBeforeTernaryOperators: true 49 | BreakConstructorInitializersBeforeComma: false 50 | BreakConstructorInitializers: BeforeColon 51 | BreakAfterJavaFieldAnnotations: false 52 | BreakStringLiterals: true 53 | ColumnLimit: 120 54 | CommentPragmas: '^ IWYU pragma:' 55 | CompactNamespaces: false 56 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 57 | ConstructorInitializerIndentWidth: 4 58 | ContinuationIndentWidth: 4 59 | Cpp11BracedListStyle: true 60 | DeriveLineEnding: true 61 | DerivePointerAlignment: true 62 | DisableFormat: false 63 | ExperimentalAutoDetectBinPacking: false 64 | FixNamespaceComments: true 65 | ForEachMacros: 66 | - foreach 67 | - Q_FOREACH 68 | - BOOST_FOREACH 69 | IncludeBlocks: Regroup 70 | IncludeCategories: 71 | - Regex: '^' 72 | Priority: 2 73 | SortPriority: 0 74 | - Regex: '^<.*\.h>' 75 | Priority: 1 76 | SortPriority: 0 77 | - Regex: '^<.*' 78 | Priority: 2 79 | SortPriority: 0 80 | - Regex: '.*' 81 | Priority: 3 82 | SortPriority: 0 83 | IncludeIsMainRegex: '([-_](test|unittest))?$' 84 | IncludeIsMainSourceRegex: '' 85 | IndentCaseLabels: true 86 | IndentGotoLabels: true 87 | IndentPPDirectives: None 88 | IndentWidth: 4 89 | IndentWrappedFunctionNames: false 90 | JavaScriptQuotes: Leave 91 | JavaScriptWrapImports: true 92 | KeepEmptyLinesAtTheStartOfBlocks: false 93 | MacroBlockBegin: '' 94 | MacroBlockEnd: '' 95 | MaxEmptyLinesToKeep: 1 96 | NamespaceIndentation: None 97 | ObjCBinPackProtocolList: Never 98 | ObjCBlockIndentWidth: 2 99 | ObjCSpaceAfterProperty: false 100 | ObjCSpaceBeforeProtocolList: true 101 | PenaltyBreakAssignment: 2 102 | PenaltyBreakBeforeFirstCallParameter: 1 103 | PenaltyBreakComment: 300 104 | PenaltyBreakFirstLessLess: 120 105 | PenaltyBreakString: 1000 106 | PenaltyBreakTemplateDeclaration: 10 107 | PenaltyExcessCharacter: 1000000 108 | PenaltyReturnTypeOnItsOwnLine: 200 109 | PointerAlignment: Left 110 | RawStringFormats: 111 | - Language: Cpp 112 | Delimiters: 113 | - cc 114 | - CC 115 | - cpp 116 | - Cpp 117 | - CPP 118 | - 'c++' 119 | - 'C++' 120 | CanonicalDelimiter: '' 121 | BasedOnStyle: google 122 | - Language: TextProto 123 | Delimiters: 124 | - pb 125 | - PB 126 | - proto 127 | - PROTO 128 | EnclosingFunctions: 129 | - EqualsProto 130 | - EquivToProto 131 | - PARSE_PARTIAL_TEXT_PROTO 132 | - PARSE_TEST_PROTO 133 | - PARSE_TEXT_PROTO 134 | - ParseTextOrDie 135 | - ParseTextProtoOrDie 136 | CanonicalDelimiter: '' 137 | BasedOnStyle: google 138 | ReflowComments: true 139 | SortIncludes: false 140 | SortUsingDeclarations: true 141 | SpaceAfterCStyleCast: false 142 | SpaceAfterLogicalNot: false 143 | SpaceAfterTemplateKeyword: true 144 | SpaceBeforeAssignmentOperators: true 145 | SpaceBeforeCpp11BracedList: false 146 | SpaceBeforeCtorInitializerColon: true 147 | SpaceBeforeInheritanceColon: true 148 | SpaceBeforeParens: ControlStatements 149 | SpaceBeforeRangeBasedForLoopColon: true 150 | SpaceInEmptyBlock: false 151 | SpaceInEmptyParentheses: false 152 | SpacesBeforeTrailingComments: 2 153 | SpacesInAngles: false 154 | SpacesInConditionalStatement: false 155 | SpacesInContainerLiterals: true 156 | SpacesInCStyleCastParentheses: false 157 | SpacesInParentheses: false 158 | SpacesInSquareBrackets: false 159 | SpaceBeforeSquareBrackets: false 160 | Standard: Auto 161 | StatementMacros: 162 | - Q_UNUSED 163 | - QT_REQUIRE_VERSION 164 | TabWidth: 4 165 | UseCRLF: false 166 | UseTab: Never 167 | ... 168 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | # Source: 2 | # https://github.com/Tinyu-Zhao/M5-Depends/blob/main/.github/ISSUE_TEMPLATE/bug-report.yml 3 | # See: 4 | # https://docs.github.com/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms 5 | 6 | name: Bug report 7 | description: Report a problem with the code in this repository. 8 | labels: 9 | - "type: bug" 10 | body: 11 | - type: markdown 12 | attributes: 13 | value: "Thank you for opening an issue on an M5Stack Arduino library repository.\n\ 14 | To improve the speed of resolution please review the following guidelines and common troubleshooting steps below before creating the issue:\n\ 15 | If you have any UIFLOW questions you can ask in the [special board](https://community.m5stack.com/category/5/uiflow), there will be many enthusiastic friends to help you.\n\ 16 | Do not use GitHub issues for troubleshooting projects and issues. Instead use the forums at https://community.m5stack.com to ask questions and troubleshoot why something isn't working as expected. In many cases the problem is a common issue that you will more quickly receive help from the forum community. GitHub issues are meant for known defects in the code. If you don't know if there is a defect in the code then start with troubleshooting on the forum first." 17 | - type: textarea 18 | id: description 19 | attributes: 20 | label: Describe the bug 21 | description: A clear and concise description of what the bug is. 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: reproduce 26 | attributes: 27 | label: To reproduce 28 | description: Provide the specific set of steps we can follow to reproduce the problem. 29 | placeholder: | 30 | 1. In this environment... 31 | 2. With this config... 32 | 3. Run '...' 33 | 4. See error... 34 | validations: 35 | required: true 36 | - type: textarea 37 | id: expected 38 | attributes: 39 | label: Expected behavior 40 | description: What would you expect to happen after following those instructions? 41 | validations: 42 | required: true 43 | - type: textarea 44 | id: screenshots 45 | attributes: 46 | label: Screenshots 47 | description: If applicable, add screenshots to help explain your problem. 48 | validations: 49 | required: false 50 | - type: textarea 51 | id: information 52 | attributes: 53 | label: Environment 54 | description: | 55 | If applicable, add screenshots to help explain your problem. 56 | examples: 57 | - **OS**: Ubuntu 20.04 58 | - **IDE & IDE Version**: Arduino 1.8.19 Or Platform IO v2.5.0 59 | - **Repository Version**: 0.4.0 60 | value: | 61 | - OS: 62 | - IDE &IDE Version: 63 | - Repository Version: 64 | validations: 65 | required: false 66 | - type: textarea 67 | id: additional 68 | attributes: 69 | label: Additional context 70 | description: Add any additional information here. 71 | validations: 72 | required: false 73 | - type: checkboxes 74 | id: checklist 75 | attributes: 76 | label: Issue checklist 77 | description: Please double-check that you have done each of the following things before submitting the issue. 78 | options: 79 | - label: I searched for previous reports in [the issue tracker](https://github.com/m5stack/M5Unit-ENV/issues?q=) 80 | required: true 81 | - label: My report contains all necessary details 82 | required: true 83 | -------------------------------------------------------------------------------- /.github/workflows/Arduino-Lint-Check.yml: -------------------------------------------------------------------------------- 1 | name: Arduino Lint Check 2 | on: 3 | push: 4 | branches: [ master, main ] 5 | pull_request: 6 | branches: [ master, main ] 7 | workflow_dispatch: 8 | 9 | defaults: 10 | run: 11 | shell: bash 12 | 13 | concurrency: 14 | group: ${{ github.workflow }}-${{ github.ref }} 15 | cancel-in-progress: true 16 | 17 | jobs: 18 | lint: 19 | name: Lint Check 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@v4 23 | - uses: arduino/arduino-lint-action@v2 24 | with: 25 | library-manager: update 26 | compliance: strict 27 | project-type: all 28 | -------------------------------------------------------------------------------- /.github/workflows/arduino-esp-v2-build-check.yml: -------------------------------------------------------------------------------- 1 | name: Build(arduino-esp32:2.x) 2 | 3 | env: 4 | SKETCH_NAMES_FIND_START: ./examples/UnitUnified 5 | REQUIRED_LIBRARIES: M5Unified,M5UnitUnified,BME68x Sensor library,Bsec2 6 | 7 | on: 8 | push: 9 | tags-ignore: 10 | - '*.*.*' 11 | - 'v*.*.*' 12 | branches: 13 | - '*' 14 | paths: 15 | - 'src/unit/**.cpp' 16 | - 'src/unit/**.hpp' 17 | - 'src/unit/**.h' 18 | - 'src/unit/**.c' 19 | - 'examples/UnitUnified/**.ino' 20 | - 'examples/UnitUnified/**.cpp' 21 | - 'examples/UnitUnified/**.hpp' 22 | - 'examples/UnitUnified/**.h' 23 | - 'examples/UnitUnified/**.c' 24 | - '**arduino-esp-v2-build-check.yml' 25 | pull_request: 26 | paths: 27 | - 'src/unit/**.cpp' 28 | - 'src/unit/**.hpp' 29 | - 'src/unit/**.h' 30 | - 'src/unit/**.c' 31 | - 'examples/UnitUnified/**.ino' 32 | - 'examples/UnitUnified/**.cpp' 33 | - 'examples/UnitUnified/**.hpp' 34 | - 'examples/UnitUnified/**.h' 35 | - 'examples/UnitUnified/**.c' 36 | - '**arduino-esp-v2-build-check.yml' 37 | workflow_dispatch: 38 | 39 | defaults: 40 | run: 41 | shell: bash 42 | 43 | concurrency: 44 | group: ${{ github.workflow }}-${{ github.ref }} 45 | cancel-in-progress: true 46 | 47 | jobs: 48 | build: 49 | name: ${{ matrix.unit }}:${{ matrix.sketch }}:${{matrix.board}}@${{matrix.platform-version}} 50 | runs-on: ubuntu-latest 51 | timeout-minutes: 5 52 | 53 | strategy: 54 | fail-fast: false 55 | #max-parallel: 1 56 | matrix: 57 | platform-url: 58 | - https://espressif.github.io/arduino-esp32/package_esp32_index.json 59 | 60 | sketch: 61 | - PlotToSerial 62 | 63 | unit: 64 | - UnitCO2 65 | - UnitCO2L 66 | - UnitENVIII 67 | - UnitENVIV 68 | - UnitTVOC 69 | - UnitENVPro 70 | 71 | board: 72 | - m5stack-atom 73 | - m5stack-atoms3 74 | - m5stack-core-esp32 75 | - m5stack-core2 76 | - m5stack-coreink 77 | - m5stack-cores3 78 | - m5stack-fire 79 | 80 | platform-version: 81 | - 2.0.17 82 | 83 | platform: 84 | - esp32 85 | 86 | archi: 87 | - esp32 88 | 89 | steps: 90 | - name: Checkout 91 | uses: actions/checkout@v4 92 | with: 93 | ref: ${{ github.event.pull_request.head.sha }} 94 | 95 | # Build 96 | - name: Compile examples 97 | uses: ArminJo/arduino-test-compile@master 98 | with: 99 | arduino-board-fqbn: ${{ matrix.platform }}:${{ matrix.archi }}:${{ matrix.board }} 100 | arduino-platform: ${{ matrix.platform }}:${{ matrix.archi }}@${{ matrix.platform-version }} 101 | platform-url: ${{ matrix.platform-url }} 102 | required-libraries: ${{ env.REQUIRED_LIBRARIES }} 103 | extra-arduino-cli-args: ${{ matrix.cli-args }} 104 | #build-properties: ${{ toJson(matrix.build-properties) }} 105 | sketch-names: ${{ matrix.sketch }}.ino 106 | sketch-names-find-start: ${{ env.SKETCH_NAMES_FIND_START }}/${{ matrix.unit }} 107 | #sketches-exclude: ${{ matrix.sketches-exclude }} 108 | -------------------------------------------------------------------------------- /.github/workflows/arduino-esp-v3-build-check.yml: -------------------------------------------------------------------------------- 1 | name: Build(arduino-esp32:3.x) 2 | 3 | env: 4 | SKETCH_NAMES_FIND_START: ./examples/UnitUnified 5 | REQUIRED_LIBRARIES: M5Unified,M5UnitUnified,BME68x Sensor library,bsec2 6 | 7 | on: 8 | push: 9 | tags-ignore: 10 | - '*.*.*' 11 | - 'v*.*.*' 12 | branches: 13 | - '*' 14 | paths: 15 | - 'src/unit/**.cpp' 16 | - 'src/unit/**.hpp' 17 | - 'src/unit/**.h' 18 | - 'src/unit/**.c' 19 | - 'examples/UnitUnified/**.ino' 20 | - 'examples/UnitUnified/**.cpp' 21 | - 'examples/UnitUnified/**.hpp' 22 | - 'examples/UnitUnified/**.h' 23 | - 'examples/UnitUnified/**.c' 24 | - '**arduino-esp-v3-build-check.yml' 25 | pull_request: 26 | paths: 27 | - 'src/unit/**.cpp' 28 | - 'src/unit/**.hpp' 29 | - 'src/unit/**.h' 30 | - 'src/unit/**.c' 31 | - 'examples/UnitUnified/**.ino' 32 | - 'examples/UnitUnified/**.cpp' 33 | - 'examples/UnitUnified/**.hpp' 34 | - 'examples/UnitUnified/**.h' 35 | - 'examples/UnitUnified/**.c' 36 | - '**arduino-esp-v3-build-check.yml' 37 | workflow_dispatch: 38 | 39 | defaults: 40 | run: 41 | shell: bash 42 | 43 | concurrency: 44 | group: ${{ github.workflow }}-${{ github.ref }} 45 | cancel-in-progress: true 46 | 47 | jobs: 48 | build: 49 | name: ${{ matrix.unit }}:${{ matrix.sketch }}:${{matrix.board}}@${{matrix.platform-version}} 50 | runs-on: ubuntu-latest 51 | timeout-minutes: 5 52 | 53 | strategy: 54 | fail-fast: false 55 | #max-parallel: 1 56 | matrix: 57 | platform-url: 58 | - https://espressif.github.io/arduino-esp32/package_esp32_index.json 59 | 60 | sketch: 61 | - PlotToSerial 62 | 63 | unit: 64 | - UnitCO2 65 | - UnitCO2L 66 | - UnitENVIII 67 | - UnitENVIV 68 | - UnitTVOC 69 | - UnitENVPro 70 | 71 | board: 72 | - m5stack_atom 73 | - m5stack_atoms3 74 | - m5stack_capsule 75 | # - m5stack_cardputer 76 | - m5stack_core 77 | - m5stack_core2 78 | - m5stack_coreink 79 | - m5stack_cores3 80 | - m5stack_dial 81 | - m5stack_fire 82 | - m5stack_nanoc6 83 | - m5stack_paper 84 | # - m5stack_poe_cam 85 | # - m5stack_stamp_c3 86 | # - m5stack_stamp_pico 87 | - m5stack_stamp_s3 88 | # - m5stack_station 89 | # - m5stack_stickc 90 | - m5stack_stickc_plus 91 | - m5stack_stickc_plus2 92 | # - m5stack_timer_cam 93 | # - m5stack_tough 94 | # - m5stack_unit_cam 95 | # - m5stack_unit_cams3 96 | 97 | platform-version: 98 | - 3.0.4 99 | 100 | platform: 101 | - esp32 102 | 103 | archi: 104 | - esp32 105 | 106 | steps: 107 | - name: Checkout 108 | uses: actions/checkout@v4 109 | with: 110 | ref: ${{ github.event.pull_request.head.sha }} 111 | 112 | # Build 113 | - name: Compile examples 114 | uses: ArminJo/arduino-test-compile@master 115 | with: 116 | arduino-board-fqbn: ${{ matrix.platform }}:${{ matrix.archi }}:${{ matrix.board }} 117 | arduino-platform: ${{ matrix.platform }}:${{ matrix.archi }}@${{ matrix.platform-version }} 118 | platform-url: ${{ matrix.platform-url }} 119 | required-libraries: ${{ env.REQUIRED_LIBRARIES }} 120 | # required-libraries: ${{ matrix.board == 'm5stack_nanoc6' && env.REQUIRED_LIBRARIES_NANOC6 || env.REQUIRED_LIBRARIES }} 121 | extra-arduino-cli-args: ${{ matrix.cli-args }} 122 | #build-properties: ${{ toJson(matrix.build-properties) }} 123 | sketch-names: ${{ matrix.sketch }}.ino 124 | sketch-names-find-start: ${{ env.SKETCH_NAMES_FIND_START }}/${{ matrix.unit }} 125 | #sketches-exclude: ${{ matrix.sketches-exclude }} 126 | -------------------------------------------------------------------------------- /.github/workflows/arduino-m5-build-check.yml: -------------------------------------------------------------------------------- 1 | name: Build(arduino-m5stack) 2 | 3 | env: 4 | SKETCH_NAMES_FIND_START: ./examples/UnitUnified 5 | REQUIRED_LIBRARIES: M5Unified,M5UnitUnified,BME68x Sensor library,bsec2 6 | 7 | on: 8 | push: 9 | tags-ignore: 10 | - '*.*.*' 11 | - 'v*.*.*' 12 | branches: 13 | - '*' 14 | paths: 15 | - 'src/unit/**.cpp' 16 | - 'src/unit/**.hpp' 17 | - 'src/unit/**.h' 18 | - 'src/unit/**.c' 19 | - 'examples/UnitUnified/**.ino' 20 | - 'examples/UnitUnified/**.cpp' 21 | - 'examples/UnitUnified/**.hpp' 22 | - 'examples/UnitUnified/**.h' 23 | - 'examples/UnitUnified/**.c' 24 | - '**arduino-m5-build-check.yml' 25 | pull_request: 26 | paths: 27 | - 'src/unit/**.cpp' 28 | - 'src/unit/**.hpp' 29 | - 'src/unit/**.h' 30 | - 'src/unit/**.c' 31 | - 'examples/UnitUnified/**.ino' 32 | - 'examples/UnitUnified/**.cpp' 33 | - 'examples/UnitUnified/**.hpp' 34 | - 'examples/UnitUnified/**.h' 35 | - 'examples/UnitUnified/**.c' 36 | - '**arduino-m5-build-check.yml' 37 | workflow_dispatch: 38 | 39 | defaults: 40 | run: 41 | shell: bash 42 | 43 | concurrency: 44 | group: ${{ github.workflow }}-${{ github.ref }} 45 | cancel-in-progress: true 46 | 47 | jobs: 48 | build: 49 | name: ${{ matrix.unit }}:${{ matrix.sketch }}:${{matrix.board}}@${{matrix.platform-version}} 50 | runs-on: ubuntu-latest 51 | timeout-minutes: 5 52 | 53 | strategy: 54 | fail-fast: false 55 | # max-parallel: 1 56 | matrix: 57 | platform-url: 58 | - https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json 59 | 60 | sketch: 61 | - PlotToSerial 62 | 63 | unit: 64 | - UnitCO2 65 | - UnitCO2L 66 | - UnitENVIII 67 | - UnitENVIV 68 | - UnitTVOC 69 | - UnitENVPro 70 | 71 | board: 72 | - m5stack_atom 73 | - m5stack_atoms3 74 | - m5stack_atoms3r 75 | - m5stack_capsule 76 | # - m5stack_cardputer 77 | - m5stack_core 78 | - m5stack_core2 79 | - m5stack_coreink 80 | - m5stack_cores3 81 | - m5stack_dial 82 | - m5stack_dinmeter 83 | - m5stack_fire 84 | - m5stack_paper 85 | # - m5stack_poe_cam 86 | # - m5stack_stamp_c3 87 | # - m5stack_stamp_pico 88 | - m5stack_stamp_s3 89 | # - m5stack_station 90 | # - m5stack_stickc 91 | - m5stack_stickc_plus 92 | - m5stack_stickc_plus2 93 | # - m5stack_timer_cam 94 | # - m5stack_tough 95 | # - m5stack_unit_cam 96 | # - m5stack_unit_cams3 97 | 98 | platform-version: 99 | - 2.1.2 100 | 101 | platform: 102 | - m5stack 103 | 104 | archi: 105 | - esp32 106 | 107 | steps: 108 | - name: Checkout 109 | uses: actions/checkout@v4 110 | with: 111 | ref: ${{ github.event.pull_request.head.sha }} 112 | 113 | # Build 114 | - name: Compile examples 115 | uses: ArminJo/arduino-test-compile@master 116 | with: 117 | arduino-board-fqbn: ${{ matrix.platform }}:${{ matrix.archi }}:${{ matrix.board }} 118 | arduino-platform: ${{ matrix.platform }}:${{ matrix.archi }}@${{ matrix.platform-version }} 119 | platform-url: ${{ matrix.platform-url }} 120 | required-libraries: ${{ env.REQUIRED_LIBRARIES }} 121 | extra-arduino-cli-args: ${{ matrix.cli-args }} 122 | #build-properties: ${{ toJson(matrix.build-properties) }} 123 | sketch-names: ${{ matrix.sketch }}.ino 124 | sketch-names-find-start: ${{ env.SKETCH_NAMES_FIND_START }}/${{ matrix.unit }} 125 | #sketches-exclude: ${{ matrix.sketches-exclude }} 126 | 127 | -------------------------------------------------------------------------------- /.github/workflows/clang-format-check.yml: -------------------------------------------------------------------------------- 1 | name: clang-format Check 2 | 3 | env: 4 | INCLUDE_REGEX: ^.*\.((((c|C)(c|pp|xx|\+\+)?$)|((h|H)h?(pp|xx|\+\+)?$))|(inl|ino|pde|proto|cu))$ 5 | 6 | on: 7 | push: 8 | tags-ignore: 9 | - '*.*.*' 10 | - 'v*.*.*' 11 | branches: 12 | - '*' 13 | paths: 14 | - '**.ino' 15 | - '**.cpp' 16 | - '**.hpp' 17 | - '**.h' 18 | - '**.c' 19 | - '**.inl' 20 | - '**clang-format-check.yml' 21 | - '**.clang-format' 22 | pull_request: 23 | paths: 24 | - '**.ino' 25 | - '**.cpp' 26 | - '**.hpp' 27 | - '**.h' 28 | - '**.c' 29 | - '**.inl' 30 | - '**clang-format-check.yml' 31 | - '**.clang-format' 32 | workflow_dispatch: 33 | 34 | defaults: 35 | run: 36 | shell: bash 37 | 38 | concurrency: 39 | group: ${{ github.workflow }}-${{ github.ref }} 40 | cancel-in-progress: true 41 | 42 | jobs: 43 | formatting-check: 44 | name: Formatting Check 45 | runs-on: ubuntu-latest 46 | strategy: 47 | matrix: 48 | path: 49 | - check: 'src' 50 | exclude: '^.*[\/](BMP280|DHT12|I2C_Class|M5UnitENV|QMP6988|SCD4X|SHT3X|SHT4X|utility)\.(cpp|h|hpp)$' 51 | - check: 'test' 52 | exclude: '' 53 | - check: 'examples/UnitUnified' 54 | exclude: '' 55 | 56 | steps: 57 | - name: Checkout # When pull_request is used, include it in the checkout https://zenn.dev/hkusu/articles/c731862051438b 58 | uses: actions/checkout@v4 59 | with: 60 | ref: ${{ github.event.pull_request.head.sha }} 61 | 62 | - name: Run clang-format style check for C/C++/Protobuf programs. 63 | uses: jidicula/clang-format-action@v4.10.2 # Using include-regex 10.x or later 64 | with: 65 | clang-format-version: '13' 66 | check-path: ${{ matrix.path['check'] }} 67 | exclude-regex: ${{ matrix.path['exclude'] }} 68 | include-regex: ${{ env.INCLUDE_REGEX }} 69 | -------------------------------------------------------------------------------- /.github/workflows/doxygen-gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Doxygen docuemnt on GitHub Pages 2 | on: [release, workflow_dispatch] 3 | # branches: 4 | # - main 5 | # - master 6 | defaults: 7 | run: 8 | shell: bash 9 | 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.ref }} 12 | cancel-in-progress: true 13 | 14 | jobs: 15 | deploy: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Make document 19 | uses: m5stack/M5Utility/.github/actions/doxygen@develop 20 | with: 21 | doxygen_version: 1.11.0 22 | github_token: ${{ secrets.GITHUB_TOKEN }} 23 | branch: gh-pages 24 | folder: docs/html 25 | config_file: docs/Doxyfile 26 | -------------------------------------------------------------------------------- /.github/workflows/platformio-build-check.yml: -------------------------------------------------------------------------------- 1 | name: Build(platformio) 2 | 3 | on: 4 | push: 5 | tags-ignore: 6 | - '*.*.*' 7 | - 'v*.*.*' 8 | branches: 9 | - '*' 10 | paths: 11 | - 'src/unit/**.cpp' 12 | - 'src/unit/**.hpp' 13 | - 'src/unit/**.h' 14 | - 'src/unit/**.c' 15 | - 'examples/UnitUnified/**.ino' 16 | - 'examples/UnitUnified/**.cpp' 17 | - 'examples/UnitUnified/**.hpp' 18 | - 'examples/UnitUnified/**.h' 19 | - 'examples/UnitUnified/**.c' 20 | - '**/platformio-build-check.yml' 21 | - '**platformio.ini' 22 | pull_request: 23 | paths: 24 | - 'src/unit/**.cpp' 25 | - 'src/unit/**.hpp' 26 | - 'src/unit/**.h' 27 | - 'src/unit/**.c' 28 | - 'examples/UnitUnified/**.ino' 29 | - 'examples/UnitUnified/**.cpp' 30 | - 'examples/UnitUnified/**.hpp' 31 | - 'examples/UnitUnified/**.h' 32 | - 'examples/UnitUnified/**.c' 33 | - '**/platformio-build-check.yml' 34 | - '**platformio.ini' 35 | workflow_dispatch: 36 | 37 | defaults: 38 | run: 39 | shell: bash 40 | 41 | concurrency: 42 | group: ${{ github.workflow }}-${{ github.ref }} 43 | cancel-in-progress: true 44 | 45 | jobs: 46 | build: 47 | name: ${{ matrix.unit }}:${{ matrix.example }}@${{ matrix.board }}:${{ matrix.framework }}:${{ matrix.espressif32 }} 48 | runs-on: ubuntu-latest 49 | timeout-minutes: 5 50 | 51 | strategy: 52 | fail-fast: false 53 | #max-parallel: 1 54 | 55 | matrix: 56 | example: 57 | - PlotToSerial 58 | 59 | unit: 60 | - UnitCO2 61 | - UnitCO2L 62 | - UnitENVIII 63 | - UnitENVIV 64 | - UnitTVOC 65 | - UnitENVPro 66 | 67 | board: 68 | - Core 69 | - Core2 70 | - CoreS3 71 | - Fire 72 | - StampS3 73 | - Dial 74 | - AtomMatrix 75 | - AtomS3 76 | - AtomS3R 77 | - NanoC6 78 | - StickCPlus 79 | - StickCPlus2 80 | - Paper 81 | - CoreInk 82 | 83 | framework: 84 | - Arduino 85 | 86 | espressif32: 87 | - latest 88 | # - '5_4_0' 89 | # - '4_4_0' 90 | 91 | # exclude: 92 | # - board: CoreS3 93 | # espressif32: '5_4_0' 94 | # - board: CoreS3 95 | # espressif32: '4_4_0' 96 | # - board: StampS3 97 | # espressif32: '5_4_0' 98 | # - board: StampS3 99 | # espressif32: '4_4_0' 100 | # - board: AtomS3 101 | # espressif32: '5_4_0' 102 | # - board: AtomS3 103 | # espressif32: '4_4_0' 104 | # - board: Dial 105 | # espressif32: '5_4_0' 106 | # - board: Dial 107 | # espressif32: '4_4_0' 108 | # - board: NanoC6 109 | # espressif32: '5_4_0' 110 | # - board: NanoC6 111 | # espressif32: '4_4_0' 112 | # - board: StickCPlus 113 | # espressif32: '5_4_0' 114 | # - board: StickCPlus 115 | # espressif32: '4_4_0' 116 | # - board: Paper 117 | # espressif32: '5_4_0' 118 | # - board: Paper 119 | # espressif32: '4_4_0' 120 | 121 | steps: 122 | - name: Checkout 123 | uses: actions/checkout@v4 124 | with: 125 | ref: ${{ github.event.pull_request.head.sha }} 126 | 127 | - name: Build examples 128 | uses: karniv00l/platformio-run-action@v1 129 | with: 130 | environments: ${{ matrix.unit != '' && format('{0}_{1}_{2}_{3}_{4}', matrix.unit, matrix.example, matrix.board, matrix.framework, matrix.espressif32) || format('{0}_{1}_{2}_{3}', matrix.example, matrix.board, matrix.framework, matrix.espressif32) }} 131 | # targets: 132 | project-dir: "./" 133 | project-conf: "./platformio.ini" 134 | # jobs: 6 135 | # silent: false 136 | # verbose: true 137 | # disable-auto-clean: false 138 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 M5Stack 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # M5Unit - ENV 2 | 3 | ## Overview 4 | 5 | ### SKU:U001 & U001-B & U001-C & U090 & U053-B & U053-D & U103 6 | 7 | Contains M5Stack-**UNIT ENV & Hat ENV & UNIT BPS & UNIT CO2** series related case programs. 8 | 9 | ENV is an environmental sensor with integrated SHT30 and QMP6988 internally to detect temperature, humidity, and atmospheric pressure data. 10 | 11 | BPS is a barometer unit, which integrates the Bosch BMP280 pressure sensor to measure atmospheric pressure and estimate the altitude. 12 | 13 | BPS(QMP6988) Unit is a barometer unit that uses QMP6988 barometric pressure sensor to measure atmospheric pressure and altitude estimation 14 | 15 | CO2 is a photoacoustic Carbon Dioxide (CO2) Unit that will tell you the CO2 PPM (parts-per-million) composition of ambient air. 16 | 17 | ## Related Link 18 | 19 | - [Unit ENVIV - Document & Datasheet](https://docs.m5stack.com/en/unit/ENV%E2%85%A3%20Unit) 20 | - [Unit ENVIII - Document & Datasheet](https://docs.m5stack.com/en/unit/envIII) 21 | - [Unit ENVII - Document & Datasheet](https://docs.m5stack.com/en/unit/envII) 22 | - [Unit ENV - Document & Datasheet](https://docs.m5stack.com/en/unit/env) 23 | - [Hat ENVIII - Document & Datasheet](https://docs.m5stack.com/en/hat/hat_envIII) 24 | - [Hat ENVII - Document & Datasheet](https://docs.m5stack.com/en/hat/hat_envII) 25 | - [Unit BPS - Document & Datasheet](https://docs.m5stack.com/en/unit/bps) 26 | - [Unit BPS(QMP6988) - Document & Datasheet](https://docs.m5stack.com/en/unit/BPS(QMP6988)) 27 | - [Unit CO2 - Document & Datasheet](https://docs.m5stack.com/en/unit/co2) 28 | 29 | ## Required Libraries: 30 | 31 | - [Adafruit_BMP280_Library](https://github.com/adafruit/Adafruit_BMP280_Library) 32 | - [Adafruit_Sensor](https://github.com/adafruit/Adafruit_Sensor) 33 | - [Sensirion I2C SCD4x](https://github.com/Sensirion/arduino-i2c-scd4x) 34 | - [Sensirion I2C SHT4x](https://github.com/Sensirion/arduino-i2c-sht4x) 35 | - [Sensirion Core](https://github.com/Sensirion/arduino-core) 36 | 37 | ## License 38 | 39 | - [M5Unit-ENV - MIT](LICENSE) 40 | 41 | --- 42 | 43 | ## M5UnitUnified 44 | Library for Unit ENV using [M5UnitUnified](https://github.com/m5stack/M5UnitUnified). 45 | M5UnitUnified is a library for unified handling of various M5 units products. 46 | 47 | ### Supported units 48 | - Unit CO2 (SKU:U103) 49 | - Unit CO2L (SKU:U104) 50 | - Unit ENVIII (SKU:U001-C) 51 | - Unit ENVIV (SKU:U001-D) 52 | - Unit ENVPro (SKU:U169) 53 | - Unit TVOC (SKU:U088) 54 | 55 | ### SKU:U088 56 | 57 | TVOC/eCO2 mini Unit is a digital multi-pixel gas sensor unit with integrated SGP30. 58 | 59 | 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. 60 | 61 | 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. 62 | 63 | If you need to obtain accurate results, you need to calibrate according to a known measurement source. SGP30 has a built-in calibration function. In addition, eCO2 is calculated based on the concentration of H2 and cannot completely replace "true" CO2 sensors for laboratory use. 64 | 65 | ## Related Link 66 | See also examples using conventional methods here. 67 | 68 | - [UnitTVOC/eCO2 & Datasheet](https://docs.m5stack.com/en/unit/tvoc) 69 | 70 | 71 | ### Include file 72 | ```cpp 73 | #include // For UnitUnified 74 | //#include // When using M5UnitUnified, do not use it at the same time as conventional libraries 75 | ``` 76 | Supported units will be added in the future. 77 | 78 | ### Required Libraries: 79 | - [M5UnitUnified](https://github.com/m5stack/M5UnitUnified) 80 | - [M5Utility](https://github.com/m5stack/M5Utility) 81 | - [M5HAL](https://github.com/m5stack/M5HAL) 82 | 83 | The Bosch library is required by ENVPro to obtain values that cannot be obtained without using the Bosch library. 84 | - [Bosch-BME68x-Library](https://github.com/boschsensortec/Bosch-BME68x-Library) 85 | - [Bosch-BSEC2-Library](https://github.com/boschsensortec/Bosch-BSEC2-Library) (Excluding NanoC6) 86 | 87 | ### Examples 88 | See also [examples/UnitUnified](examples/UnitUnified) 89 | 90 | ### Doxygen document 91 | [GitHub Pages](https://m5stack.github.io/M5Unit-ENV/) 92 | 93 | If you want to generate documents on your local machine, execute the following command 94 | 95 | ``` 96 | bash docs/doxy.sh 97 | ``` 98 | 99 | It will output it under docs/html 100 | If you want to output Git commit hashes to html, do it for the git cloned folder. 101 | 102 | #### Required 103 | - [Doxyegn](https://www.doxygen.nl/) 104 | - [pcregrep](https://formulae.brew.sh/formula/pcre2) 105 | - [Git](https://git-scm.com/) (Output commit hash to html) 106 | -------------------------------------------------------------------------------- /boards/m5stack-atoms3r.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino": { 4 | "memory_type": "qio_opi", 5 | "ldscript": "esp32s3_out.ld", 6 | "partitions": "default_8MB.csv" 7 | }, 8 | "core": "esp32", 9 | "extra_flags": [ 10 | "-DARDUINO_M5STACK_ATOMS3R", 11 | "-DBOARD_HAS_PSRAM", 12 | "-DARDUINO_USB_MODE=1", 13 | "-DARDUINO_USB_CDC_ON_BOOT=1", 14 | "-DARDUINO_RUNNING_CORE=1", 15 | "-DARDUINO_EVENT_RUNNING_CORE=1" 16 | ], 17 | "f_cpu": "240000000L", 18 | "f_flash": "80000000L", 19 | "flash_mode": "dio", 20 | "mcu": "esp32s3", 21 | "variant": "m5stack_atoms3" 22 | }, 23 | "connectivity": [ 24 | "bluetooth", 25 | "wifi" 26 | ], 27 | "frameworks": [ 28 | "arduino", 29 | "espidf" 30 | ], 31 | "name": "M5Stack AtomS3R", 32 | "upload": { 33 | "flash_size": "8MB", 34 | "maximum_ram_size": 327680, 35 | "maximum_size": 8388608, 36 | "require_upload_port": true, 37 | "speed": 460800 38 | }, 39 | "url": "https://docs.m5stack.com/en/core/AtomS3R", 40 | "vendor": "M5Stack" 41 | } 42 | -------------------------------------------------------------------------------- /boards/m5stack-nanoc6.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "core": "esp32", 4 | "extra_flags": [ 5 | "-DARDUINO_M5STACK_NANOC6" 6 | ], 7 | "f_cpu": "160000000L", 8 | "f_flash": "80000000L", 9 | "flash_mode": "qio", 10 | "mcu": "esp32c6", 11 | "variant": "esp32c6" 12 | }, 13 | "connectivity": [ 14 | "wifi" 15 | ], 16 | "debug": { 17 | "openocd_target": "esp32c6.cfg" 18 | }, 19 | "frameworks": [ 20 | "arduino", 21 | "espidf" 22 | ], 23 | "name": "M5Stack NanoC6", 24 | "upload": { 25 | "flash_size": "4MB", 26 | "maximum_ram_size": 327680, 27 | "maximum_size": 4194384, 28 | "require_upload_port": true, 29 | "speed": 460800 30 | }, 31 | "url": "https://docs.m5stack.com/en/core/M5NanoC6", 32 | "vendor": "M5Stack" 33 | } 34 | -------------------------------------------------------------------------------- /boards/m5stick-cplus2.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino":{ 4 | "ldscript": "esp32_out.ld", 5 | "partitions": "default_8MB.csv" 6 | }, 7 | "core": "esp32", 8 | "extra_flags": [ 9 | "-DM5STACK_M5STICK_CPLUS2", 10 | "-DBOARD_HAS_PSRAM", 11 | "-mfix-esp32-psram-cache-issue", 12 | "-mfix-esp32-psram-cache-strategy=memw", 13 | "-DARDUINO_RUNNING_CORE=1", 14 | "-DARDUINO_EVENT_RUNNING_CORE=1" 15 | ], 16 | "f_cpu": "240000000L", 17 | "f_flash": "80000000L", 18 | "flash_mode": "dio", 19 | "mcu": "esp32", 20 | "variant": "m5stick_c" 21 | }, 22 | "connectivity": [ 23 | "wifi", 24 | "bluetooth" 25 | ], 26 | "frameworks": [ 27 | "arduino", 28 | "espidf" 29 | ], 30 | "name": "M5Stick-CPlus2", 31 | "upload": { 32 | "flash_size": "8MB", 33 | "maximum_ram_size": 327680, 34 | "maximum_size": 8388608, 35 | "require_upload_port": true, 36 | "speed": 1500000 37 | }, 38 | "url": "https://docs.m5stack.com/en/core/M5StickC%20PLUS2", 39 | "vendor": "M5Stack" 40 | } 41 | -------------------------------------------------------------------------------- /custom_script.py: -------------------------------------------------------------------------------- 1 | Import("env") 2 | 3 | EXCLUDE_FILES = (env.GetProjectOption("custom_exclude_src_files") or []).split(' ') 4 | print(EXCLUDE_FILES) 5 | 6 | def skip_from_build(node): 7 | np = node.get_path() 8 | if any(ef in np for ef in EXCLUDE_FILES): 9 | return None 10 | return node 11 | 12 | env.AddBuildMiddleware(skip_from_build, "*") 13 | -------------------------------------------------------------------------------- /docs/doxy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Please execute on repositry root 4 | 5 | ## Get version from library.properties 6 | ## Get git rev of HEAD 7 | LIB_VERSION="$(pcregrep -o1 "^\s*version\s*=\s*(\*|\d+(\.\d+){0,3}(\.\*)?)" library.properties)" 8 | #echo ${DOXYGEN_PROJECT_NUMBER} 9 | DOXYGEN_PROJECT_NUMBER="${LIB_VERSION} git rev:$(git rev-parse --short HEAD)" doxygen docs/Doxyfile 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/ENV/ENV.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core + Unit ENV 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | DHT12 dht; 18 | BMP280 bmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | if (!dht.begin(&Wire, DHT12_I2C_ADDR, 21, 22, 400000U)) { 23 | Serial.println("Couldn't find DHT12"); 24 | while (1) delay(1); 25 | } 26 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 21, 22, 400000U)) { 27 | Serial.println("Couldn't find BMP280"); 28 | while (1) delay(1); 29 | } 30 | /* Default settings from datasheet. */ 31 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 32 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 33 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 34 | BMP280::FILTER_X16, /* Filtering. */ 35 | BMP280::STANDBY_MS_500); /* Standby time. */ 36 | } 37 | 38 | void loop() { 39 | if (dht.update()) { 40 | Serial.println("-----DHT12-----"); 41 | Serial.print("Temperature: "); 42 | Serial.print(dht.cTemp); 43 | Serial.println(" degrees C"); 44 | Serial.print("Humidity: "); 45 | Serial.print(dht.humidity); 46 | Serial.println("% rH"); 47 | Serial.println("-------------\r\n"); 48 | } 49 | 50 | if (bmp.update()) { 51 | Serial.println("-----BMP280-----"); 52 | Serial.print(F("Temperature: ")); 53 | Serial.print(bmp.cTemp); 54 | Serial.println(" degrees C"); 55 | Serial.print(F("Pressure: ")); 56 | Serial.print(bmp.pressure); 57 | Serial.println(" Pa"); 58 | Serial.print(F("Approx altitude: ")); 59 | Serial.print(bmp.altitude); 60 | Serial.println(" m"); 61 | Serial.println("-------------\r\n"); 62 | } 63 | delay(1000); 64 | } 65 | -------------------------------------------------------------------------------- /examples/ENV_II/ENV_II.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV_II.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core + Unit ENV_II 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | SHT3X sht3x; 18 | BMP280 bmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | 23 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 21, 22, 400000U)) { 24 | Serial.println("Couldn't find SHT3X"); 25 | while (1) delay(1); 26 | } 27 | 28 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 21, 22, 400000U)) { 29 | Serial.println("Couldn't find BMP280"); 30 | while (1) delay(1); 31 | } 32 | /* Default settings from datasheet. */ 33 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 34 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 35 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 36 | BMP280::FILTER_X16, /* Filtering. */ 37 | BMP280::STANDBY_MS_500); /* Standby time. */ 38 | } 39 | 40 | void loop() { 41 | if (sht3x.update()) { 42 | Serial.println("-----SHT3X-----"); 43 | Serial.print("Temperature: "); 44 | Serial.print(sht3x.cTemp); 45 | Serial.println(" degrees C"); 46 | Serial.print("Humidity: "); 47 | Serial.print(sht3x.humidity); 48 | Serial.println("% rH"); 49 | Serial.println("-------------\r\n"); 50 | } 51 | 52 | if (bmp.update()) { 53 | Serial.println("-----BMP280-----"); 54 | Serial.print(F("Temperature: ")); 55 | Serial.print(bmp.cTemp); 56 | Serial.println(" degrees C"); 57 | Serial.print(F("Pressure: ")); 58 | Serial.print(bmp.pressure); 59 | Serial.println(" Pa"); 60 | Serial.print(F("Approx altitude: ")); 61 | Serial.print(bmp.altitude); 62 | Serial.println(" m"); 63 | Serial.println("-------------\r\n"); 64 | } 65 | delay(1000); 66 | } 67 | -------------------------------------------------------------------------------- /examples/ENV_III/ENV_III.ino: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @file ENV_III.ino 4 | * @author SeanKwok (shaoxiang@m5stack.com) 5 | * @brief 6 | * @version 0.1 7 | * @date 2024-01-30 8 | * 9 | * 10 | * @Hardwares: M5Core + Unit ENV_III 11 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 12 | * @Dependent Library: 13 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 14 | */ 15 | 16 | #include "M5UnitENV.h" 17 | 18 | SHT3X sht3x; 19 | QMP6988 qmp; 20 | 21 | void setup() { 22 | Serial.begin(115200); 23 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 21, 22, 400000U)) { 24 | Serial.println("Couldn't find QMP6988"); 25 | while (1) delay(1); 26 | } 27 | 28 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 21, 22, 400000U)) { 29 | Serial.println("Couldn't find SHT3X"); 30 | while (1) delay(1); 31 | } 32 | } 33 | 34 | void loop() { 35 | if (sht3x.update()) { 36 | Serial.println("-----SHT3X-----"); 37 | Serial.print("Temperature: "); 38 | Serial.print(sht3x.cTemp); 39 | Serial.println(" degrees C"); 40 | Serial.print("Humidity: "); 41 | Serial.print(sht3x.humidity); 42 | Serial.println("% rH"); 43 | Serial.println("-------------\r\n"); 44 | } 45 | 46 | if (qmp.update()) { 47 | Serial.println("-----QMP6988-----"); 48 | Serial.print(F("Temperature: ")); 49 | Serial.print(qmp.cTemp); 50 | Serial.println(" *C"); 51 | Serial.print(F("Pressure: ")); 52 | Serial.print(qmp.pressure); 53 | Serial.println(" Pa"); 54 | Serial.print(F("Approx altitude: ")); 55 | Serial.print(qmp.altitude); 56 | Serial.println(" m"); 57 | Serial.println("-------------\r\n"); 58 | } 59 | delay(1000); 60 | } 61 | -------------------------------------------------------------------------------- /examples/ENV_IV/ENV_IV.ino: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @file ENV_IV.ino 4 | * @author SeanKwok (shaoxiang@m5stack.com) 5 | * @brief 6 | * @version 0.1 7 | * @date 2024-01-30 8 | * 9 | * 10 | * @Hardwares: M5Core + Unit ENV_IV 11 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 12 | * @Dependent Library: 13 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 14 | */ 15 | 16 | #include "M5UnitENV.h" 17 | 18 | SHT4X sht4; 19 | BMP280 bmp; 20 | 21 | void setup() { 22 | Serial.begin(115200); 23 | 24 | if (!sht4.begin(&Wire, SHT40_I2C_ADDR_44, 21, 22, 400000U)) { 25 | Serial.println("Couldn't find SHT4x"); 26 | while (1) delay(1); 27 | } 28 | 29 | // You can have 3 different precisions, higher precision takes longer 30 | sht4.setPrecision(SHT4X_HIGH_PRECISION); 31 | sht4.setHeater(SHT4X_NO_HEATER); 32 | 33 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 21, 22, 400000U)) { 34 | Serial.println("Couldn't find BMP280"); 35 | while (1) delay(1); 36 | } 37 | /* Default settings from datasheet. */ 38 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 39 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 40 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 41 | BMP280::FILTER_X16, /* Filtering. */ 42 | BMP280::STANDBY_MS_500); /* Standby time. */ 43 | } 44 | 45 | void loop() { 46 | if (sht4.update()) { 47 | Serial.println("-----SHT4X-----"); 48 | Serial.print("Temperature: "); 49 | Serial.print(sht4.cTemp); 50 | Serial.println(" degrees C"); 51 | Serial.print("Humidity: "); 52 | Serial.print(sht4.humidity); 53 | Serial.println("% rH"); 54 | Serial.println("-------------\r\n"); 55 | } 56 | 57 | if (bmp.update()) { 58 | Serial.println("-----BMP280-----"); 59 | Serial.print(F("Temperature: ")); 60 | Serial.print(bmp.cTemp); 61 | Serial.println(" degrees C"); 62 | Serial.print(F("Pressure: ")); 63 | Serial.print(bmp.pressure); 64 | Serial.println(" Pa"); 65 | Serial.print(F("Approx altitude: ")); 66 | Serial.print(bmp.altitude); 67 | Serial.println(" m"); 68 | Serial.println("-------------\r\n"); 69 | } 70 | delay(1000); 71 | } 72 | -------------------------------------------------------------------------------- /examples/ENV_PRO/ENV_PRO.ino: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @file ENV_PRO.ino 4 | * @author SeanKwok (shaoxiang@m5stack.com) 5 | * @brief 6 | * @version 0.1 7 | * @date 2024-01-30 8 | * 9 | * 10 | * @Hardwares: M5Core + Unit ENV_PRO 11 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 12 | * @Dependent Library: 13 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 14 | * BME68x Sensor library: https://github.com/boschsensortec/Bosch-BME68x-Library 15 | * BSEC2 Software Library: https://github.com/boschsensortec/Bosch-BSEC2-Library 16 | */ 17 | 18 | #include 19 | 20 | /** 21 | * @brief : This function checks the BSEC status, prints the respective error 22 | * code. Halts in case of error 23 | * @param[in] bsec : Bsec2 class object 24 | */ 25 | void checkBsecStatus(Bsec2 bsec); 26 | 27 | /** 28 | * @brief : This function is called by the BSEC library when a new output is 29 | * available 30 | * @param[in] input : BME68X sensor data before processing 31 | * @param[in] outputs : Processed BSEC BSEC output data 32 | * @param[in] bsec : Instance of BSEC2 calling the callback 33 | */ 34 | void newDataCallback(const bme68xData data, const bsecOutputs outputs, 35 | Bsec2 bsec); 36 | 37 | /* Create an object of the class Bsec2 */ 38 | Bsec2 envSensor; 39 | 40 | /* Entry point for the example */ 41 | void setup(void) { 42 | /* Desired subscription list of BSEC2 outputs */ 43 | bsecSensor sensorList[] = { 44 | BSEC_OUTPUT_IAQ, BSEC_OUTPUT_RAW_TEMPERATURE, 45 | BSEC_OUTPUT_RAW_PRESSURE, BSEC_OUTPUT_RAW_HUMIDITY, 46 | BSEC_OUTPUT_RAW_GAS, BSEC_OUTPUT_STABILIZATION_STATUS, 47 | BSEC_OUTPUT_RUN_IN_STATUS}; 48 | 49 | /* Initialize the communication interfaces */ 50 | Serial.begin(115200); 51 | Wire.begin(21, 22); 52 | 53 | /* Valid for boards with USB-COM. Wait until the port is open */ 54 | while (!Serial) delay(10); 55 | 56 | /* Initialize the library and interfaces */ 57 | if (!envSensor.begin(BME68X_I2C_ADDR_HIGH, Wire)) { 58 | checkBsecStatus(envSensor); 59 | } 60 | 61 | /* Subsribe to the desired BSEC2 outputs */ 62 | if (!envSensor.updateSubscription(sensorList, ARRAY_LEN(sensorList), 63 | BSEC_SAMPLE_RATE_LP)) { 64 | checkBsecStatus(envSensor); 65 | } 66 | 67 | /* Whenever new data is available call the newDataCallback function */ 68 | envSensor.attachCallback(newDataCallback); 69 | 70 | Serial.println("BSEC library version " + String(envSensor.version.major) + 71 | "." + String(envSensor.version.minor) + "." + 72 | String(envSensor.version.major_bugfix) + "." + 73 | String(envSensor.version.minor_bugfix)); 74 | } 75 | 76 | /* Function that is looped forever */ 77 | void loop(void) { 78 | /* Call the run function often so that the library can 79 | * check if it is time to read new data from the sensor 80 | * and process it. 81 | */ 82 | if (!envSensor.run()) { 83 | checkBsecStatus(envSensor); 84 | } 85 | } 86 | 87 | void newDataCallback(const bme68xData data, const bsecOutputs outputs, 88 | Bsec2 bsec) { 89 | if (!outputs.nOutputs) { 90 | return; 91 | } 92 | 93 | Serial.println( 94 | "BSEC outputs:\n\ttimestamp = " + 95 | String((int)(outputs.output[0].time_stamp / INT64_C(1000000)))); 96 | for (uint8_t i = 0; i < outputs.nOutputs; i++) { 97 | const bsecData output = outputs.output[i]; 98 | switch (output.sensor_id) { 99 | case BSEC_OUTPUT_IAQ: 100 | Serial.println("\tiaq = " + String(output.signal)); 101 | Serial.println("\tiaq accuracy = " + 102 | String((int)output.accuracy)); 103 | break; 104 | case BSEC_OUTPUT_RAW_TEMPERATURE: 105 | Serial.println("\ttemperature = " + String(output.signal)); 106 | break; 107 | case BSEC_OUTPUT_RAW_PRESSURE: 108 | Serial.println("\tpressure = " + String(output.signal)); 109 | break; 110 | case BSEC_OUTPUT_RAW_HUMIDITY: 111 | Serial.println("\thumidity = " + String(output.signal)); 112 | break; 113 | case BSEC_OUTPUT_RAW_GAS: 114 | Serial.println("\tgas resistance = " + String(output.signal)); 115 | break; 116 | case BSEC_OUTPUT_STABILIZATION_STATUS: 117 | Serial.println("\tstabilization status = " + 118 | String(output.signal)); 119 | break; 120 | case BSEC_OUTPUT_RUN_IN_STATUS: 121 | Serial.println("\trun in status = " + String(output.signal)); 122 | break; 123 | default: 124 | break; 125 | } 126 | } 127 | } 128 | 129 | void checkBsecStatus(Bsec2 bsec) { 130 | if (bsec.status < BSEC_OK) { 131 | Serial.println("BSEC error code : " + String(bsec.status)); 132 | 133 | } else if (bsec.status > BSEC_OK) { 134 | Serial.println("BSEC warning code : " + String(bsec.status)); 135 | } 136 | 137 | if (bsec.sensor.status < BME68X_OK) { 138 | Serial.println("BME68X error code : " + String(bsec.sensor.status)); 139 | } else if (bsec.sensor.status > BME68X_OK) { 140 | Serial.println("BME68X warning code : " + String(bsec.sensor.status)); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /examples/Hat_ENVIII_M5StickC/Hat_ENVIII_M5StickC.ino: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @file Hat_ENVIII_M5StickC.ino 4 | * @author SeanKwok (shaoxiang@m5stack.com) 5 | * @brief 6 | * @version 0.1 7 | * @date 2024-01-30 8 | * 9 | * 10 | * @Hardwares: M5StickC + Hat_ENVIII 11 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 12 | * @Dependent Library: 13 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 14 | * M5Unified: https://github.com/m5stack/M5Unified 15 | */ 16 | 17 | #include 18 | #include "M5UnitENV.h" 19 | 20 | SHT3X sht3x; 21 | QMP6988 qmp; 22 | 23 | void setup() { 24 | M5.begin(); 25 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 0, 26, 400000U)) { 26 | Serial.println("Couldn't find QMP6988"); 27 | while (1) delay(1); 28 | } 29 | 30 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 0, 26, 400000U)) { 31 | Serial.println("Couldn't find SHT3X"); 32 | while (1) delay(1); 33 | } 34 | } 35 | 36 | void loop() { 37 | if (sht3x.update()) { 38 | Serial.println("-----SHT3X-----"); 39 | Serial.print("Temperature: "); 40 | Serial.print(sht3x.cTemp); 41 | Serial.println(" degrees C"); 42 | Serial.print("Humidity: "); 43 | Serial.print(sht3x.humidity); 44 | Serial.println("% rH"); 45 | Serial.println("-------------\r\n"); 46 | } 47 | 48 | if (qmp.update()) { 49 | Serial.println("-----QMP6988-----"); 50 | Serial.print(F("Temperature: ")); 51 | Serial.print(qmp.cTemp); 52 | Serial.println(" *C"); 53 | Serial.print(F("Pressure: ")); 54 | Serial.print(qmp.pressure); 55 | Serial.println(" Pa"); 56 | Serial.print(F("Approx altitude: ")); 57 | Serial.print(qmp.altitude); 58 | Serial.println(" m"); 59 | Serial.println("-------------\r\n"); 60 | } 61 | delay(1000); 62 | } 63 | -------------------------------------------------------------------------------- /examples/Hat_ENVIII_M5StickCPlus/Hat_ENVIII_M5StickCPlus.ino: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @file Hat_ENVIII_M5StickCPlus.ino 4 | * @author SeanKwok (shaoxiang@m5stack.com) 5 | * @brief 6 | * @version 0.1 7 | * @date 2024-01-30 8 | * 9 | * 10 | * @Hardwares: M5StickCPlus + Hat_ENVIII 11 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 12 | * @Dependent Library: 13 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 14 | * M5Unified: https://github.com/m5stack/M5Unified 15 | */ 16 | 17 | #include 18 | #include "M5UnitENV.h" 19 | 20 | SHT3X sht3x; 21 | QMP6988 qmp; 22 | 23 | void setup() { 24 | M5.begin(); 25 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 0, 26, 400000U)) { 26 | Serial.println("Couldn't find QMP6988"); 27 | while (1) delay(1); 28 | } 29 | 30 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 0, 26, 400000U)) { 31 | Serial.println("Couldn't find SHT3X"); 32 | while (1) delay(1); 33 | } 34 | } 35 | 36 | void loop() { 37 | if (sht3x.update()) { 38 | Serial.println("-----SHT3X-----"); 39 | Serial.print("Temperature: "); 40 | Serial.print(sht3x.cTemp); 41 | Serial.println(" degrees C"); 42 | Serial.print("Humidity: "); 43 | Serial.print(sht3x.humidity); 44 | Serial.println("% rH"); 45 | Serial.println("-------------\r\n"); 46 | } 47 | 48 | if (qmp.update()) { 49 | Serial.println("-----QMP6988-----"); 50 | Serial.print(F("Temperature: ")); 51 | Serial.print(qmp.cTemp); 52 | Serial.println(" *C"); 53 | Serial.print(F("Pressure: ")); 54 | Serial.print(qmp.pressure); 55 | Serial.println(" Pa"); 56 | Serial.print(F("Approx altitude: ")); 57 | Serial.print(qmp.altitude); 58 | Serial.println(" m"); 59 | Serial.println("-------------\r\n"); 60 | } 61 | delay(1000); 62 | } 63 | -------------------------------------------------------------------------------- /examples/Hat_ENVII_M5StickC/Hat_ENVII_M5StickC.ino: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @file Hat_ENVII_M5StickC.ino 4 | * @author SeanKwok (shaoxiang@m5stack.com) 5 | * @brief 6 | * @version 0.1 7 | * @date 2024-01-30 8 | * 9 | * 10 | * @Hardwares: M5StickC + Hat_ENVII 11 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 12 | * @Dependent Library: 13 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 14 | * M5Unified: https://github.com/m5stack/M5Unified 15 | */ 16 | 17 | #include 18 | #include "M5UnitENV.h" 19 | 20 | SHT3X sht3x; 21 | BMP280 bmp; 22 | 23 | void setup() { 24 | M5.begin(); 25 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 0, 26, 400000U)) { 26 | Serial.println("Couldn't find SHT3X"); 27 | while (1) delay(1); 28 | } 29 | 30 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 0, 26, 400000U)) { 31 | Serial.println("Couldn't find BMP280"); 32 | while (1) delay(1); 33 | } 34 | /* Default settings from datasheet. */ 35 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 36 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 37 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 38 | BMP280::FILTER_X16, /* Filtering. */ 39 | BMP280::STANDBY_MS_500); /* Standby time. */ 40 | } 41 | 42 | void loop() { 43 | if (sht3x.update()) { 44 | Serial.println("-----SHT3X-----"); 45 | Serial.print("Temperature: "); 46 | Serial.print(sht3x.cTemp); 47 | Serial.println(" degrees C"); 48 | Serial.print("Humidity: "); 49 | Serial.print(sht3x.humidity); 50 | Serial.println("% rH"); 51 | Serial.println("-------------\r\n"); 52 | } 53 | 54 | if (bmp.update()) { 55 | Serial.println("-----BMP280-----"); 56 | Serial.print(F("Temperature: ")); 57 | Serial.print(bmp.cTemp); 58 | Serial.println(" degrees C"); 59 | Serial.print(F("Pressure: ")); 60 | Serial.print(bmp.pressure); 61 | Serial.println(" Pa"); 62 | Serial.print(F("Approx altitude: ")); 63 | Serial.print(bmp.altitude); 64 | Serial.println(" m"); 65 | Serial.println("-------------\r\n"); 66 | } 67 | delay(1000); 68 | } 69 | -------------------------------------------------------------------------------- /examples/Hat_ENVII_M5StickCPlus/Hat_ENVII_M5StickCPlus.ino: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @file Hat_ENVII_M5StickCPlus.ino 4 | * @author SeanKwok (shaoxiang@m5stack.com) 5 | * @brief 6 | * @version 0.1 7 | * @date 2024-01-30 8 | * 9 | * 10 | * @Hardwares: M5StickCPlus + Hat_ENVII 11 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 12 | * @Dependent Library: 13 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 14 | * M5Unified: https://github.com/m5stack/M5Unified 15 | */ 16 | 17 | #include 18 | #include "M5UnitENV.h" 19 | 20 | SHT3X sht3x; 21 | BMP280 bmp; 22 | 23 | void setup() { 24 | M5.begin(); 25 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 0, 26, 400000U)) { 26 | Serial.println("Couldn't find SHT3X"); 27 | while (1) delay(1); 28 | } 29 | 30 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 0, 26, 400000U)) { 31 | Serial.println("Couldn't find BMP280"); 32 | while (1) delay(1); 33 | } 34 | /* Default settings from datasheet. */ 35 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 36 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 37 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 38 | BMP280::FILTER_X16, /* Filtering. */ 39 | BMP280::STANDBY_MS_500); /* Standby time. */ 40 | } 41 | 42 | void loop() { 43 | if (sht3x.update()) { 44 | Serial.println("-----SHT3X-----"); 45 | Serial.print("Temperature: "); 46 | Serial.print(sht3x.cTemp); 47 | Serial.println(" degrees C"); 48 | Serial.print("Humidity: "); 49 | Serial.print(sht3x.humidity); 50 | Serial.println("% rH"); 51 | Serial.println("-------------\r\n"); 52 | } 53 | 54 | if (bmp.update()) { 55 | Serial.println("-----BMP280-----"); 56 | Serial.print(F("Temperature: ")); 57 | Serial.print(bmp.cTemp); 58 | Serial.println(" degrees C"); 59 | Serial.print(F("Pressure: ")); 60 | Serial.print(bmp.pressure); 61 | Serial.println(" Pa"); 62 | Serial.print(F("Approx altitude: ")); 63 | Serial.print(bmp.altitude); 64 | Serial.println(" m"); 65 | Serial.println("-------------\r\n"); 66 | } 67 | delay(1000); 68 | } 69 | -------------------------------------------------------------------------------- /examples/UnitUnified/UnitCO2/PlotToSerial/PlotToSerial.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | Example using M5UnitUnified for UnitCO2 8 | Required 9 | - M5Unified: https://github.com/m5stack/M5Unified 10 | */ 11 | #include "main/PlotToSerial.cpp" 12 | -------------------------------------------------------------------------------- /examples/UnitUnified/UnitCO2/PlotToSerial/main/PlotToSerial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | Example using M5UnitUnified for UnitCO2 8 | */ 9 | // #define USING_M5HAL // When using M5HAL 10 | #include 11 | #include 12 | #include 13 | 14 | namespace { 15 | auto& lcd = M5.Display; 16 | m5::unit::UnitUnified Units; 17 | m5::unit::UnitCO2 unit; 18 | } // namespace 19 | 20 | void setup() 21 | { 22 | M5.begin(); 23 | 24 | auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); 25 | auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); 26 | M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); 27 | 28 | #if defined(USING_M5HAL) 29 | #pragma message "Using M5HAL" 30 | // Using M5HAL 31 | m5::hal::bus::I2CBusConfig i2c_cfg; 32 | i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); 33 | i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); 34 | auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); 35 | if (!Units.add(unit, i2c_bus ? i2c_bus.value() : nullptr) || !Units.begin()) { 36 | M5_LOGE("Failed to begin"); 37 | lcd.clear(TFT_RED); 38 | while (true) { 39 | m5::utility::delay(10000); 40 | } 41 | } 42 | #else 43 | #pragma message "Using Wire" 44 | // Using TwoWire 45 | Wire.end(); 46 | Wire.begin(pin_num_sda, pin_num_scl, 400000U); 47 | if (!Units.add(unit, Wire) || !Units.begin()) { 48 | M5_LOGE("Failed to begin"); 49 | lcd.clear(TFT_RED); 50 | while (true) { 51 | m5::utility::delay(10000); 52 | } 53 | } 54 | #endif 55 | M5_LOGI("M5UnitUnified has been begun"); 56 | M5_LOGI("%s", Units.debugInfo().c_str()); 57 | 58 | { 59 | auto ret = unit.stopPeriodicMeasurement(); 60 | float offset{}; 61 | ret &= unit.readTemperatureOffset(offset); 62 | uint16_t altitude{}; 63 | ret &= unit.readSensorAltitude(altitude); 64 | uint16_t pressure{}; 65 | ret &= unit.readAmbientPressure(pressure); 66 | bool asc{}; 67 | ret &= unit.readAutomaticSelfCalibrationEnabled(asc); 68 | uint16_t ppm{}; 69 | ret &= unit.readAutomaticSelfCalibrationTarget(ppm); 70 | ret &= unit.startPeriodicMeasurement(); 71 | 72 | M5.Log.printf( 73 | " temp offset:%f\n" 74 | " sensor altitude:%u\n" 75 | "ambient pressure:%u\n" 76 | " ASC enabled:%u\n" 77 | " ASC target:%u\n", 78 | offset, altitude, pressure, asc, ppm); 79 | 80 | if (!ret) { 81 | lcd.clear(TFT_RED); 82 | while (true) { 83 | m5::utility::delay(10000); 84 | } 85 | } 86 | } 87 | lcd.clear(TFT_DARKGREEN); 88 | } 89 | 90 | void loop() 91 | { 92 | M5.update(); 93 | Units.update(); 94 | if (unit.updated()) { 95 | // Can be checked e.g. by serial plotters 96 | M5.Log.printf(">CO2:%u\n>Temperature:%2.2f\n>Humidity:%2.2f\n", unit.co2(), unit.temperature(), 97 | unit.humidity()); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /examples/UnitUnified/UnitCO2L/PlotToSerial/PlotToSerial.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | Example using M5UnitUnified for UnitCO2L 8 | Required 9 | - M5Unified: https://github.com/m5stack/M5Unified 10 | */ 11 | #include "main/PlotToSerial.cpp" 12 | -------------------------------------------------------------------------------- /examples/UnitUnified/UnitCO2L/PlotToSerial/main/PlotToSerial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | Example using M5UnitUnified for UnitCO2L 8 | */ 9 | // #define USING_M5HAL // When using M5HAL 10 | #include 11 | #include 12 | #include 13 | 14 | namespace { 15 | auto& lcd = M5.Display; 16 | m5::unit::UnitUnified Units; 17 | m5::unit::UnitCO2L unit; 18 | 19 | } // namespace 20 | 21 | using namespace m5::unit::scd4x; 22 | 23 | void setup() 24 | { 25 | M5.begin(); 26 | 27 | auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); 28 | auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); 29 | M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); 30 | 31 | #if defined(USING_M5HAL) 32 | #pragma message "Using M5HAL" 33 | // Using M5HAL 34 | m5::hal::bus::I2CBusConfig i2c_cfg; 35 | i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); 36 | i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); 37 | auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); 38 | if (!Units.add(unit, i2c_bus ? i2c_bus.value() : nullptr) || !Units.begin()) { 39 | M5_LOGE("Failed to begin"); 40 | lcd.clear(TFT_RED); 41 | while (true) { 42 | m5::utility::delay(10000); 43 | } 44 | } 45 | #else 46 | #pragma message "Using Wire" 47 | // Using TwoWire 48 | Wire.end(); 49 | Wire.begin(pin_num_sda, pin_num_scl, 400000U); 50 | if (!Units.add(unit, Wire) || !Units.begin()) { 51 | M5_LOGE("Failed to begin"); 52 | lcd.clear(TFT_RED); 53 | while (true) { 54 | m5::utility::delay(10000); 55 | } 56 | } 57 | #endif 58 | M5_LOGI("M5UnitUnified has been begun"); 59 | M5_LOGI("%s", Units.debugInfo().c_str()); 60 | 61 | { 62 | auto ret = unit.stopPeriodicMeasurement(); 63 | float offset{}; 64 | ret &= unit.readTemperatureOffset(offset); 65 | uint16_t altitude{}; 66 | ret &= unit.readSensorAltitude(altitude); 67 | uint16_t pressure{}; 68 | ret &= unit.readAmbientPressure(pressure); 69 | bool asc{}; 70 | ret &= unit.readAutomaticSelfCalibrationEnabled(asc); 71 | uint16_t ppm{}; 72 | ret &= unit.readAutomaticSelfCalibrationTarget(ppm); 73 | uint16_t initialPeriod{}, standardPeriod{}; 74 | ret &= unit.readAutomaticSelfCalibrationInitialPeriod(initialPeriod); 75 | ret &= unit.readAutomaticSelfCalibrationStandardPeriod(standardPeriod); 76 | 77 | ret &= unit.startPeriodicMeasurement(); 78 | 79 | M5.Log.printf( 80 | " temp offset:%f\n" 81 | " sensor altitude:%u\n" 82 | "ambient pressure:%u\n" 83 | " ASC enabled:%u\n" 84 | " ASC target:%u\n" 85 | " initial period:%u\n" 86 | " standard period:%u\n", 87 | offset, altitude, pressure, asc, ppm, initialPeriod, standardPeriod); 88 | 89 | if (!ret) { 90 | lcd.clear(TFT_RED); 91 | while (true) { 92 | m5::utility::delay(1000); 93 | } 94 | } 95 | } 96 | lcd.clear(TFT_DARKGREEN); 97 | } 98 | 99 | void loop() 100 | { 101 | M5.update(); 102 | auto touch = M5.Touch.getDetail(); 103 | 104 | // Periodic 105 | Units.update(); 106 | if (unit.updated()) { 107 | // Can be checked e.g. by serial plotters 108 | M5.Log.printf(">CO2:%u\n>Temperature:%2.2f\n>Humidity:%2.2f\n", unit.co2(), unit.temperature(), 109 | unit.humidity()); 110 | } 111 | 112 | // Single shot 113 | if (M5.BtnA.wasClicked() || touch.wasClicked()) { 114 | static bool all{}; // false: RHT only 115 | all = !all; 116 | M5.Log.printf("Try single shot %u, waiting measurement...\n", all); 117 | unit.stopPeriodicMeasurement(); 118 | Data d{}; 119 | if (all) { 120 | if (unit.measureSingleshot(d)) { 121 | M5.Log.printf(" SingleAll: %u/%2.2f/%2.2f\n", d.co2(), d.temperature(), d.humidity()); 122 | } 123 | } else { 124 | if (unit.measureSingleshotRHT(d)) { 125 | M5.Log.printf(" SingleRHT: %2.2f/%2.2f", d.temperature(), d.humidity()); 126 | } 127 | } 128 | unit.startPeriodicMeasurement(); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /examples/UnitUnified/UnitENVIII/PlotToSerial/PlotToSerial.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | Example using M5UnitUnified for UnitENVIII 8 | Required 9 | - M5Unified: https://github.com/m5stack/M5Unified 10 | */ 11 | #include "main/PlotToSerial.cpp" 12 | -------------------------------------------------------------------------------- /examples/UnitUnified/UnitENVIII/PlotToSerial/main/PlotToSerial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | Example using M5UnitUnified for UnitENVIII 8 | */ 9 | #include 10 | #include 11 | #include 12 | 13 | // #define USING_M5HAL // When using M5HAL 14 | 15 | // Using single shot measurement If defined 16 | // #define USING_SINGLE_SHOT 17 | 18 | // Using combined unit if defined 19 | #define USING_ENV3 20 | 21 | namespace { 22 | auto& lcd = M5.Display; 23 | m5::unit::UnitUnified Units; 24 | 25 | #if defined(USING_ENV3) 26 | #pragma message "Using combined unit(ENV3)" 27 | m5::unit::UnitENV3 unitENV3; 28 | #else 29 | #pragma message "Using each unit" 30 | m5::unit::UnitSHT30 unitSHT30; 31 | m5::unit::UnitQMP6988 unitQMP6988; 32 | #endif 33 | 34 | #if defined(USING_ENV3) 35 | auto& sht30 = unitENV3.sht30; 36 | auto& qmp6988 = unitENV3.qmp6988; 37 | #else 38 | auto& sht30 = unitSHT30; 39 | auto& qmp6988 = unitQMP6988; 40 | #endif 41 | } // namespace 42 | 43 | void setup() 44 | { 45 | M5.begin(); 46 | 47 | auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); 48 | auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); 49 | M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); 50 | 51 | #if defined(USING_SINGLE_SHOT) 52 | { 53 | auto cfg = sht30.config(); 54 | cfg.start_periodic = false; 55 | sht30.config(cfg); 56 | } 57 | { 58 | auto cfg = qmp6988.config(); 59 | cfg.start_periodic = false; 60 | qmp6988.config(cfg); 61 | } 62 | #endif 63 | 64 | #if defined(USING_ENV3) 65 | #if defined(USING_M5HAL) 66 | #pragma message "Using M5HAL" 67 | m5::hal::bus::I2CBusConfig i2c_cfg; 68 | i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); 69 | i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); 70 | auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); 71 | if (!Units.add(unitENV3, i2c_bus ? i2c_bus.value() : nullptr) || !Units.begin()) { 72 | M5_LOGE("Failed to begin"); 73 | lcd.clear(TFT_RED); 74 | while (true) { 75 | m5::utility::delay(10000); 76 | } 77 | } 78 | #else 79 | #pragma message "Using Wire" 80 | Wire.end(); 81 | Wire.begin(pin_num_sda, pin_num_scl, 400000U); 82 | 83 | if (!Units.add(unitENV3, Wire) || !Units.begin()) { 84 | M5_LOGE("Failed to begin"); 85 | lcd.clear(TFT_RED); 86 | while (true) { 87 | m5::utility::delay(10000); 88 | } 89 | } 90 | #endif 91 | 92 | #else 93 | 94 | #if defined(USING_M5HAL) 95 | #pragma message "Using M5HAL" 96 | m5::hal::bus::I2CBusConfig i2c_cfg; 97 | i2c_cfg.pin_sda = m5::hal::gpio::getPin(pin_num_sda); 98 | i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl); 99 | auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg); 100 | if (!Units.add(unitSHT30, i2c_bus ? i2c_bus.value() : nullptr) || 101 | !Units.add(unitQMP6988, i2c_bus ? i2c_bus.value() : nullptr) || !Units.begin()) { 102 | M5_LOGE("Failed to begin"); 103 | lcd.clear(TFT_RED); 104 | while (true) { 105 | m5::utility::delay(10000); 106 | } 107 | } 108 | #else 109 | #pragma message "Using Wire" 110 | Wire.begin(pin_num_sda, pin_num_scl, 400000U); 111 | if (!Units.add(unitSHT30, Wire) || !Units.add(unitQMP6988, Wire) || !Units.begin()) { 112 | M5_LOGE("Failed to begin"); 113 | lcd.clear(TFT_RED); 114 | while (true) { 115 | m5::utility::delay(10000); 116 | } 117 | } 118 | #endif 119 | #endif 120 | 121 | M5_LOGI("M5UnitUnified has been begun"); 122 | M5_LOGI("%s", Units.debugInfo().c_str()); 123 | #if defined(USING_SINGLE_SHOT) 124 | M5_LOGI("\n>>> Click BtnA to single shot measurement"); 125 | #endif 126 | lcd.clear(TFT_DARKGREEN); 127 | } 128 | 129 | void loop() 130 | { 131 | M5.update(); 132 | Units.update(); 133 | 134 | #if defined(USING_SINGLE_SHOT) 135 | if (M5.BtnA.wasClicked()) { 136 | m5::unit::sht30::Data ds{}; 137 | if (sht30.measureSingleshot(ds)) { 138 | M5.Log.printf(">SHT30Temp:%2.2f\n>Humidity:%2.2f\n", ds.temperature(), ds.humidity()); 139 | } 140 | m5::unit::qmp6988::Data dq{}; 141 | if (qmp6988.measureSingleshot(dq)) { 142 | M5.Log.printf(">QMP6988Temp:%2.2f\n>Pressure:%.2f\n", dq.temperature(), dq.pressure() * 0.01f); 143 | } 144 | } 145 | #else 146 | if (sht30.updated()) { 147 | M5.Log.printf(">SHT30Temp:%2.2f\n>Humidity:%2.2f\n", sht30.temperature(), sht30.humidity()); 148 | } 149 | if (qmp6988.updated()) { 150 | M5.Log.printf(">QMP6988Temp:%2.2f\n>Pressure:%.2f\n", qmp6988.temperature(), qmp6988.pressure() * 0.01f); 151 | } 152 | #endif 153 | } 154 | -------------------------------------------------------------------------------- /examples/UnitUnified/UnitENVIV/PlotToSerial/PlotToSerial.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | Example using M5UnitUnified for UnitENVIV 8 | Required 9 | - M5Unified: https://github.com/m5stack/M5Unified 10 | */ 11 | #include "main/PlotToSerial.cpp" 12 | -------------------------------------------------------------------------------- /examples/UnitUnified/UnitENVIV/PlotToSerial/main/PlotToSerial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | Example using M5UnitUnified for UnitENVIV 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define USING_ENV4 15 | 16 | namespace { 17 | auto& lcd = M5.Display; 18 | m5::unit::UnitUnified Units; 19 | 20 | #if defined(USING_ENV4) 21 | #pragma message "Using combined unit(ENV4)" 22 | m5::unit::UnitENV4 unitENV4; 23 | #else 24 | #pragma message "Using each unit" 25 | m5::unit::UnitSHT40 unitSHT40; 26 | m5::unit::UnitBMP280 unitBMP280; 27 | #endif 28 | 29 | #if defined(USING_ENV4) 30 | auto& sht40 = unitENV4.sht40; 31 | auto& bmp280 = unitENV4.bmp280; 32 | #else 33 | auto& sht40 = unitSHT40; 34 | auto& bmp280 = unitBMP280; 35 | #endif 36 | 37 | float calculate_altitude(const float pressure, const float seaLvhPa = 1013.25f) 38 | { 39 | return 44330.f * (1.0f - pow((pressure / 100.f) / seaLvhPa, 0.1903f)); 40 | } 41 | 42 | } // namespace 43 | 44 | void setup() 45 | { 46 | M5.begin(); 47 | 48 | auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); 49 | auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); 50 | M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); 51 | 52 | { 53 | using namespace m5::unit::bmp280; 54 | auto cfg = bmp280.config(); 55 | cfg.osrs_pressure = Oversampling::X16; 56 | cfg.osrs_temperature = Oversampling::X2; 57 | cfg.filter = Filter::Coeff16; 58 | cfg.standby = Standby::Time500ms; 59 | bmp280.config(cfg); 60 | } 61 | 62 | #if defined(USING_ENV4) 63 | Wire.end(); 64 | Wire.begin(pin_num_sda, pin_num_scl, 400000U); 65 | 66 | if (!Units.add(unitENV4, Wire) || !Units.begin()) { 67 | M5_LOGE("Failed to begin"); 68 | lcd.clear(TFT_RED); 69 | while (true) { 70 | m5::utility::delay(10000); 71 | } 72 | } 73 | #else 74 | Wire.end(); 75 | Wire.begin(pin_num_sda, pin_num_scl, 400000U); 76 | if (!Units.add(unitSHT40, Wire) || !Units.add(unitBMP280, Wire) || !Units.begin()) { 77 | M5_LOGE("Failed to begin"); 78 | lcd.clear(TFT_RED); 79 | while (true) { 80 | m5::utility::delay(10000); 81 | } 82 | } 83 | #endif 84 | 85 | M5_LOGI("M5UnitUnified has been begun"); 86 | M5_LOGI("%s", Units.debugInfo().c_str()); 87 | lcd.clear(TFT_DARKGREEN); 88 | } 89 | 90 | void loop() 91 | { 92 | M5.update(); 93 | Units.update(); 94 | 95 | if (sht40.updated()) { 96 | M5.Log.printf( 97 | ">SHT40Temp:%.4f\n" 98 | ">Humidity:%.4f\n", 99 | sht40.temperature(), sht40.humidity()); 100 | } 101 | if (bmp280.updated()) { 102 | auto p = bmp280.pressure(); 103 | M5.Log.printf( 104 | ">BMP280Temp:%.4f\n" 105 | ">Pressure:%.4f\n" 106 | ">Altitude:%.4f\n", 107 | bmp280.temperature(), p * 0.01f /* To hPa */, calculate_altitude(p)); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /examples/UnitUnified/UnitENVPro/PlotToSerial/PlotToSerial.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | Example using M5UnitUnified for UnitENVPro 8 | Required 9 | - M5Unified: https://github.com/m5stack/M5Unified 10 | */ 11 | #include "main/PlotToSerial.cpp" 12 | -------------------------------------------------------------------------------- /examples/UnitUnified/UnitENVPro/PlotToSerial/main/PlotToSerial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | Example using M5UnitUnified for UnitENVPro 8 | */ 9 | #include 10 | #include 11 | #include 12 | 13 | namespace { 14 | auto& lcd = M5.Display; 15 | m5::unit::UnitUnified Units; 16 | m5::unit::UnitENVPro unit; 17 | } // namespace 18 | 19 | void setup() 20 | { 21 | M5.begin(); 22 | 23 | auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); 24 | auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); 25 | M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); 26 | Wire.end(); 27 | Wire.begin(pin_num_sda, pin_num_scl, 400 * 1000U); 28 | 29 | if (!Units.add(unit, Wire) || !Units.begin()) { 30 | M5_LOGE("Failed to begin"); 31 | lcd.clear(TFT_RED); 32 | while (true) { 33 | m5::utility::delay(10000); 34 | } 35 | } 36 | 37 | M5_LOGI("M5UnitUnified has been begun"); 38 | M5_LOGI("%s", Units.debugInfo().c_str()); 39 | lcd.clear(TFT_DARKGREEN); 40 | } 41 | 42 | void loop() 43 | { 44 | M5.update(); 45 | Units.update(); 46 | if (unit.updated()) { 47 | #if defined(UNIT_BME688_USING_BSEC2) 48 | M5.Log.printf(">IAQ:%.2f\n>Temperature:%.2f\n>Pressure:%.2f\n>Humidity:%.2f\n>GAS:%.2f\n", unit.iaq(), 49 | unit.temperature(), unit.pressure(), unit.humidity(), unit.gas()); 50 | #else 51 | M5.Log.printf(">Temperature:%.2f\n>Pressure:%.2f\n>Humidity:%.2f\n>GAS:%.2f\n", unit.temperature(), 52 | unit.pressure(), unit.humidity(), unit.gas()); 53 | m5::utility::delay(1000); 54 | #endif 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /examples/UnitUnified/UnitTVOC/PlotToSerial/PlotToSerial.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | Example using M5UnitUnified for UnitTVOC 8 | */ 9 | #include "main/PlotToSerial.cpp" 10 | -------------------------------------------------------------------------------- /examples/UnitUnified/UnitTVOC/PlotToSerial/main/PlotToSerial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | Example using M5UnitUnified for UnitTVOC 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace { 15 | auto& lcd = M5.Display; 16 | 17 | m5::unit::UnitUnified Units; 18 | m5::unit::UnitTVOC unit; 19 | } // namespace 20 | 21 | void setup() 22 | { 23 | M5.begin(); 24 | 25 | auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); 26 | auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); 27 | M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); 28 | Wire.end(); 29 | Wire.begin(pin_num_sda, pin_num_scl, 400 * 1000U); 30 | 31 | if (!Units.add(unit, Wire) || !Units.begin()) { 32 | M5_LOGE("Failed to begin"); 33 | lcd.clear(TFT_RED); 34 | while (true) { 35 | m5::utility::delay(10000); 36 | } 37 | } 38 | 39 | M5_LOGI("M5UnitUnified has been begun"); 40 | M5_LOGI("%s", Units.debugInfo().c_str()); 41 | M5_LOGW("SGP30 measurement starts 15 seconds after begin"); 42 | 43 | lcd.clear(TFT_DARKGREEN); 44 | } 45 | 46 | void loop() 47 | { 48 | M5.update(); 49 | Units.update(); 50 | 51 | // SGP30 measurement starts 15 seconds after begin. 52 | if (unit.updated()) { 53 | // Can be checked on serial plotters 54 | M5.Log.printf("\n>CO2eq:%u\n>TVOC:%u", unit.co2eq(), unit.tvoc()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /examples/Unit_BPS1.1_M5Atom/Unit_BPS1.1_M5Atom.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS1.1_M5Atom.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Atom + Unit BPS 1.1 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | QMP6988 qmp; 18 | 19 | void setup() { 20 | Serial.begin(115200); 21 | 22 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 26, 32, 400000U)) { 23 | Serial.println("Couldn't find QMP6988"); 24 | while (1) delay(1); 25 | } 26 | } 27 | 28 | void loop() { 29 | if (qmp.update()) { 30 | Serial.println("-----QMP6988-----"); 31 | Serial.print(F("Temperature: ")); 32 | Serial.print(qmp.cTemp); 33 | Serial.println(" *C"); 34 | Serial.print(F("Pressure: ")); 35 | Serial.print(qmp.pressure); 36 | Serial.println(" Pa"); 37 | Serial.print(F("Approx altitude: ")); 38 | Serial.print(qmp.altitude); 39 | Serial.println(" m"); 40 | Serial.println("-------------\r\n"); 41 | } 42 | delay(1000); 43 | } 44 | -------------------------------------------------------------------------------- /examples/Unit_BPS1.1_M5AtomS3/Unit_BPS1.1_M5AtomS3.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS1.1_M5AtomS3.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5AtomS3 + Unit BPS 1.1 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | QMP6988 qmp; 18 | 19 | void setup() { 20 | Serial.begin(115200); 21 | 22 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 2, 1, 400000U)) { 23 | Serial.println("Couldn't find QMP6988"); 24 | while (1) delay(1); 25 | } 26 | } 27 | 28 | void loop() { 29 | if (qmp.update()) { 30 | Serial.println("-----QMP6988-----"); 31 | Serial.print(F("Temperature: ")); 32 | Serial.print(qmp.cTemp); 33 | Serial.println(" *C"); 34 | Serial.print(F("Pressure: ")); 35 | Serial.print(qmp.pressure); 36 | Serial.println(" Pa"); 37 | Serial.print(F("Approx altitude: ")); 38 | Serial.print(qmp.altitude); 39 | Serial.println(" m"); 40 | Serial.println("-------------\r\n"); 41 | } 42 | delay(1000); 43 | } 44 | -------------------------------------------------------------------------------- /examples/Unit_BPS1.1_M5AtomS3Lite/Unit_BPS1.1_M5AtomS3Lite.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS1.1_M5AtomS3Lite.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5AtomS3Lite + Unit BPS 1.1 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | QMP6988 qmp; 18 | 19 | void setup() { 20 | Serial.begin(115200); 21 | 22 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 2, 1, 400000U)) { 23 | Serial.println("Couldn't find QMP6988"); 24 | while (1) delay(1); 25 | } 26 | } 27 | 28 | void loop() { 29 | if (qmp.update()) { 30 | Serial.println("-----QMP6988-----"); 31 | Serial.print(F("Temperature: ")); 32 | Serial.print(qmp.cTemp); 33 | Serial.println(" *C"); 34 | Serial.print(F("Pressure: ")); 35 | Serial.print(qmp.pressure); 36 | Serial.println(" Pa"); 37 | Serial.print(F("Approx altitude: ")); 38 | Serial.print(qmp.altitude); 39 | Serial.println(" m"); 40 | Serial.println("-------------\r\n"); 41 | } 42 | delay(1000); 43 | } 44 | -------------------------------------------------------------------------------- /examples/Unit_BPS1.1_M5Core/Unit_BPS1.1_M5Core.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS1.1_M5Core.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core + Unit BPS 1.1 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | QMP6988 qmp; 18 | 19 | void setup() { 20 | Serial.begin(115200); 21 | 22 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 21, 22, 400000U)) { 23 | Serial.println("Couldn't find QMP6988"); 24 | while (1) delay(1); 25 | } 26 | } 27 | 28 | void loop() { 29 | if (qmp.update()) { 30 | Serial.println("-----QMP6988-----"); 31 | Serial.print(F("Temperature: ")); 32 | Serial.print(qmp.cTemp); 33 | Serial.println(" *C"); 34 | Serial.print(F("Pressure: ")); 35 | Serial.print(qmp.pressure); 36 | Serial.println(" Pa"); 37 | Serial.print(F("Approx altitude: ")); 38 | Serial.print(qmp.altitude); 39 | Serial.println(" m"); 40 | Serial.println("-------------\r\n"); 41 | } 42 | delay(1000); 43 | } 44 | -------------------------------------------------------------------------------- /examples/Unit_BPS1.1_M5Core2/Unit_BPS1.1_M5Core2.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS1.1_M5Core2.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core2 + Unit BPS 1.1 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | QMP6988 qmp; 20 | 21 | void setup() { 22 | M5.begin(); 23 | 24 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find QMP6988"); 26 | while (1) delay(1); 27 | } 28 | } 29 | 30 | void loop() { 31 | if (qmp.update()) { 32 | Serial.println("-----QMP6988-----"); 33 | Serial.print(F("Temperature: ")); 34 | Serial.print(qmp.cTemp); 35 | Serial.println(" *C"); 36 | Serial.print(F("Pressure: ")); 37 | Serial.print(qmp.pressure); 38 | Serial.println(" Pa"); 39 | Serial.print(F("Approx altitude: ")); 40 | Serial.print(qmp.altitude); 41 | Serial.println(" m"); 42 | Serial.println("-------------\r\n"); 43 | } 44 | delay(1000); 45 | } 46 | -------------------------------------------------------------------------------- /examples/Unit_BPS1.1_M5StickC/Unit_BPS1.1_M5StickC.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS1.1_M5StickC.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5StickC + Unit BPS 1.1 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | QMP6988 qmp; 20 | 21 | void setup() { 22 | M5.begin(); 23 | 24 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find QMP6988"); 26 | while (1) delay(1); 27 | } 28 | } 29 | 30 | void loop() { 31 | if (qmp.update()) { 32 | Serial.println("-----QMP6988-----"); 33 | Serial.print(F("Temperature: ")); 34 | Serial.print(qmp.cTemp); 35 | Serial.println(" *C"); 36 | Serial.print(F("Pressure: ")); 37 | Serial.print(qmp.pressure); 38 | Serial.println(" Pa"); 39 | Serial.print(F("Approx altitude: ")); 40 | Serial.print(qmp.altitude); 41 | Serial.println(" m"); 42 | Serial.println("-------------\r\n"); 43 | } 44 | delay(1000); 45 | } 46 | -------------------------------------------------------------------------------- /examples/Unit_BPS1.1_M5StickCPlus/Unit_BPS1.1_M5StickCPlus.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS1.1_M5StickCPlus.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5StickCPlus + Unit BPS 1.1 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | QMP6988 qmp; 20 | 21 | void setup() { 22 | M5.begin(); 23 | 24 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find QMP6988"); 26 | while (1) delay(1); 27 | } 28 | } 29 | 30 | void loop() { 31 | if (qmp.update()) { 32 | Serial.println("-----QMP6988-----"); 33 | Serial.print(F("Temperature: ")); 34 | Serial.print(qmp.cTemp); 35 | Serial.println(" *C"); 36 | Serial.print(F("Pressure: ")); 37 | Serial.print(qmp.pressure); 38 | Serial.println(" Pa"); 39 | Serial.print(F("Approx altitude: ")); 40 | Serial.print(qmp.altitude); 41 | Serial.println(" m"); 42 | Serial.println("-------------\r\n"); 43 | } 44 | delay(1000); 45 | } 46 | -------------------------------------------------------------------------------- /examples/Unit_BPS_M5Atom/Unit_BPS_M5Atom.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS_M5Atom.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Atom + Unit BPS 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | BMP280 bmp; 18 | 19 | void setup() { 20 | Serial.begin(115200); 21 | 22 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 26, 32, 400000U)) { 23 | Serial.println("Couldn't find BMP280"); 24 | while (1) delay(1); 25 | } 26 | /* Default settings from datasheet. */ 27 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 28 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 29 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 30 | BMP280::FILTER_X16, /* Filtering. */ 31 | BMP280::STANDBY_MS_500); /* Standby time. */ 32 | } 33 | 34 | void loop() { 35 | if (bmp.update()) { 36 | Serial.println("-----BMP280-----"); 37 | Serial.print(F("Temperature: ")); 38 | Serial.print(bmp.cTemp); 39 | Serial.println(" degrees C"); 40 | Serial.print(F("Pressure: ")); 41 | Serial.print(bmp.pressure); 42 | Serial.println(" Pa"); 43 | Serial.print(F("Approx altitude: ")); 44 | Serial.print(bmp.altitude); 45 | Serial.println(" m"); 46 | Serial.println("-------------\r\n"); 47 | } 48 | delay(1000); 49 | } 50 | -------------------------------------------------------------------------------- /examples/Unit_BPS_M5AtomS3/Unit_BPS_M5AtomS3.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS_M5AtomS3.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5AtomS3 + Unit BPS 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | BMP280 bmp; 18 | 19 | void setup() { 20 | Serial.begin(115200); 21 | 22 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 2, 1, 400000U)) { 23 | Serial.println("Couldn't find BMP280"); 24 | while (1) delay(1); 25 | } 26 | /* Default settings from datasheet. */ 27 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 28 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 29 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 30 | BMP280::FILTER_X16, /* Filtering. */ 31 | BMP280::STANDBY_MS_500); /* Standby time. */ 32 | } 33 | 34 | void loop() { 35 | if (bmp.update()) { 36 | Serial.println("-----BMP280-----"); 37 | Serial.print(F("Temperature: ")); 38 | Serial.print(bmp.cTemp); 39 | Serial.println(" degrees C"); 40 | Serial.print(F("Pressure: ")); 41 | Serial.print(bmp.pressure); 42 | Serial.println(" Pa"); 43 | Serial.print(F("Approx altitude: ")); 44 | Serial.print(bmp.altitude); 45 | Serial.println(" m"); 46 | Serial.println("-------------\r\n"); 47 | } 48 | delay(1000); 49 | } 50 | -------------------------------------------------------------------------------- /examples/Unit_BPS_M5AtomS3Lite/Unit_BPS_M5AtomS3Lite.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS_M5AtomS3Lite.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5AtomS3Lite + Unit BPS 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | BMP280 bmp; 18 | 19 | void setup() { 20 | Serial.begin(115200); 21 | 22 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 2, 1, 400000U)) { 23 | Serial.println("Couldn't find BMP280"); 24 | while (1) delay(1); 25 | } 26 | /* Default settings from datasheet. */ 27 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 28 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 29 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 30 | BMP280::FILTER_X16, /* Filtering. */ 31 | BMP280::STANDBY_MS_500); /* Standby time. */ 32 | } 33 | 34 | void loop() { 35 | if (bmp.update()) { 36 | Serial.println("-----BMP280-----"); 37 | Serial.print(F("Temperature: ")); 38 | Serial.print(bmp.cTemp); 39 | Serial.println(" degrees C"); 40 | Serial.print(F("Pressure: ")); 41 | Serial.print(bmp.pressure); 42 | Serial.println(" Pa"); 43 | Serial.print(F("Approx altitude: ")); 44 | Serial.print(bmp.altitude); 45 | Serial.println(" m"); 46 | Serial.println("-------------\r\n"); 47 | } 48 | delay(1000); 49 | } 50 | -------------------------------------------------------------------------------- /examples/Unit_BPS_M5Core/Unit_BPS_M5Core.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS_M5Core.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core + Unit BPS 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | BMP280 bmp; 18 | 19 | void setup() { 20 | Serial.begin(115200); 21 | 22 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 21, 22, 400000U)) { 23 | Serial.println("Couldn't find BMP280"); 24 | while (1) delay(1); 25 | } 26 | /* Default settings from datasheet. */ 27 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 28 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 29 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 30 | BMP280::FILTER_X16, /* Filtering. */ 31 | BMP280::STANDBY_MS_500); /* Standby time. */ 32 | } 33 | 34 | void loop() { 35 | if (bmp.update()) { 36 | Serial.println("-----BMP280-----"); 37 | Serial.print(F("Temperature: ")); 38 | Serial.print(bmp.cTemp); 39 | Serial.println(" degrees C"); 40 | Serial.print(F("Pressure: ")); 41 | Serial.print(bmp.pressure); 42 | Serial.println(" Pa"); 43 | Serial.print(F("Approx altitude: ")); 44 | Serial.print(bmp.altitude); 45 | Serial.println(" m"); 46 | Serial.println("-------------\r\n"); 47 | } 48 | delay(1000); 49 | } 50 | -------------------------------------------------------------------------------- /examples/Unit_BPS_M5Core2/Unit_BPS_M5Core2.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS_M5Core2.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core2 + Unit BPS 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | BMP280 bmp; 20 | 21 | void setup() { 22 | M5.begin(); 23 | 24 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find BMP280"); 26 | while (1) delay(1); 27 | } 28 | /* Default settings from datasheet. */ 29 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 30 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 31 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 32 | BMP280::FILTER_X16, /* Filtering. */ 33 | BMP280::STANDBY_MS_500); /* Standby time. */ 34 | } 35 | 36 | void loop() { 37 | if (bmp.update()) { 38 | Serial.println("-----BMP280-----"); 39 | Serial.print(F("Temperature: ")); 40 | Serial.print(bmp.cTemp); 41 | Serial.println(" degrees C"); 42 | Serial.print(F("Pressure: ")); 43 | Serial.print(bmp.pressure); 44 | Serial.println(" Pa"); 45 | Serial.print(F("Approx altitude: ")); 46 | Serial.print(bmp.altitude); 47 | Serial.println(" m"); 48 | Serial.println("-------------\r\n"); 49 | } 50 | delay(1000); 51 | } 52 | -------------------------------------------------------------------------------- /examples/Unit_BPS_M5StickC/Unit_BPS_M5StickC.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS_M5StickC.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5StickC + Unit BPS 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | BMP280 bmp; 20 | 21 | void setup() { 22 | M5.begin(); 23 | 24 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find BMP280"); 26 | while (1) delay(1); 27 | } 28 | /* Default settings from datasheet. */ 29 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 30 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 31 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 32 | BMP280::FILTER_X16, /* Filtering. */ 33 | BMP280::STANDBY_MS_500); /* Standby time. */ 34 | } 35 | 36 | void loop() { 37 | if (bmp.update()) { 38 | Serial.println("-----BMP280-----"); 39 | Serial.print(F("Temperature: ")); 40 | Serial.print(bmp.cTemp); 41 | Serial.println(" degrees C"); 42 | Serial.print(F("Pressure: ")); 43 | Serial.print(bmp.pressure); 44 | Serial.println(" Pa"); 45 | Serial.print(F("Approx altitude: ")); 46 | Serial.print(bmp.altitude); 47 | Serial.println(" m"); 48 | Serial.println("-------------\r\n"); 49 | } 50 | delay(1000); 51 | } 52 | -------------------------------------------------------------------------------- /examples/Unit_BPS_M5StickCPlus/Unit_BPS_M5StickCPlus.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_BPS_M5StickCPlus.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5StickCPlus + Unit BPS 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | BMP280 bmp; 20 | 21 | void setup() { 22 | M5.begin(); 23 | 24 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find BMP280"); 26 | while (1) delay(1); 27 | } 28 | /* Default settings from datasheet. */ 29 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 30 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 31 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 32 | BMP280::FILTER_X16, /* Filtering. */ 33 | BMP280::STANDBY_MS_500); /* Standby time. */ 34 | } 35 | 36 | void loop() { 37 | if (bmp.update()) { 38 | Serial.println("-----BMP280-----"); 39 | Serial.print(F("Temperature: ")); 40 | Serial.print(bmp.cTemp); 41 | Serial.println(" degrees C"); 42 | Serial.print(F("Pressure: ")); 43 | Serial.print(bmp.pressure); 44 | Serial.println(" Pa"); 45 | Serial.print(F("Approx altitude: ")); 46 | Serial.print(bmp.altitude); 47 | Serial.println(" m"); 48 | Serial.println("-------------\r\n"); 49 | } 50 | delay(1000); 51 | } 52 | -------------------------------------------------------------------------------- /examples/Unit_CO2_M5Atom/Unit_CO2_M5Atom.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "M5UnitENV.h" 3 | 4 | SCD4X scd4x; 5 | 6 | void setup() { 7 | Serial.begin(115200); 8 | 9 | if (!scd4x.begin(&Wire, SCD4X_I2C_ADDR, 26, 32, 400000U)) { 10 | Serial.println("Couldn't find SCD4X"); 11 | while (1) delay(1); 12 | } 13 | 14 | uint16_t error; 15 | // stop potentially previously started measurement 16 | error = scd4x.stopPeriodicMeasurement(); 17 | if (error) { 18 | Serial.print("Error trying to execute stopPeriodicMeasurement(): "); 19 | } 20 | 21 | // Start Measurement 22 | error = scd4x.startPeriodicMeasurement(); 23 | if (error) { 24 | Serial.print("Error trying to execute startPeriodicMeasurement(): "); 25 | } 26 | 27 | Serial.println("Waiting for first measurement... (5 sec)"); 28 | } 29 | 30 | void loop() { 31 | if (scd4x.update()) // readMeasurement will return true when 32 | // fresh data is available 33 | { 34 | Serial.println(); 35 | 36 | Serial.print(F("CO2(ppm):")); 37 | Serial.print(scd4x.getCO2()); 38 | 39 | Serial.print(F("\tTemperature(C):")); 40 | Serial.print(scd4x.getTemperature(), 1); 41 | 42 | Serial.print(F("\tHumidity(%RH):")); 43 | Serial.print(scd4x.getHumidity(), 1); 44 | 45 | Serial.println(); 46 | } else { 47 | Serial.print(F(".")); 48 | } 49 | 50 | delay(1000); 51 | } 52 | -------------------------------------------------------------------------------- /examples/Unit_CO2_M5AtomS3/Unit_CO2_M5AtomS3.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "M5UnitENV.h" 3 | 4 | SCD4X scd4x; 5 | 6 | void setup() { 7 | Serial.begin(115200); 8 | 9 | if (!scd4x.begin(&Wire, SCD4X_I2C_ADDR, 2, 1, 400000U)) { 10 | Serial.println("Couldn't find SCD4X"); 11 | while (1) delay(1); 12 | } 13 | 14 | uint16_t error; 15 | // stop potentially previously started measurement 16 | error = scd4x.stopPeriodicMeasurement(); 17 | if (error) { 18 | Serial.print("Error trying to execute stopPeriodicMeasurement(): "); 19 | } 20 | 21 | // Start Measurement 22 | error = scd4x.startPeriodicMeasurement(); 23 | if (error) { 24 | Serial.print("Error trying to execute startPeriodicMeasurement(): "); 25 | } 26 | 27 | Serial.println("Waiting for first measurement... (5 sec)"); 28 | } 29 | 30 | void loop() { 31 | if (scd4x.update()) // readMeasurement will return true when 32 | // fresh data is available 33 | { 34 | Serial.println(); 35 | 36 | Serial.print(F("CO2(ppm):")); 37 | Serial.print(scd4x.getCO2()); 38 | 39 | Serial.print(F("\tTemperature(C):")); 40 | Serial.print(scd4x.getTemperature(), 1); 41 | 42 | Serial.print(F("\tHumidity(%RH):")); 43 | Serial.print(scd4x.getHumidity(), 1); 44 | 45 | Serial.println(); 46 | } else { 47 | Serial.print(F(".")); 48 | } 49 | 50 | delay(1000); 51 | } 52 | -------------------------------------------------------------------------------- /examples/Unit_CO2_M5AtomS3Lite/Unit_CO2_M5AtomS3Lite.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "M5UnitENV.h" 3 | 4 | SCD4X scd4x; 5 | 6 | void setup() { 7 | Serial.begin(115200); 8 | 9 | if (!scd4x.begin(&Wire, SCD4X_I2C_ADDR, 2, 1, 400000U)) { 10 | Serial.println("Couldn't find SCD4X"); 11 | while (1) delay(1); 12 | } 13 | 14 | uint16_t error; 15 | // stop potentially previously started measurement 16 | error = scd4x.stopPeriodicMeasurement(); 17 | if (error) { 18 | Serial.print("Error trying to execute stopPeriodicMeasurement(): "); 19 | } 20 | 21 | // Start Measurement 22 | error = scd4x.startPeriodicMeasurement(); 23 | if (error) { 24 | Serial.print("Error trying to execute startPeriodicMeasurement(): "); 25 | } 26 | 27 | Serial.println("Waiting for first measurement... (5 sec)"); 28 | } 29 | 30 | void loop() { 31 | if (scd4x.update()) // readMeasurement will return true when 32 | // fresh data is available 33 | { 34 | Serial.println(); 35 | 36 | Serial.print(F("CO2(ppm):")); 37 | Serial.print(scd4x.getCO2()); 38 | 39 | Serial.print(F("\tTemperature(C):")); 40 | Serial.print(scd4x.getTemperature(), 1); 41 | 42 | Serial.print(F("\tHumidity(%RH):")); 43 | Serial.print(scd4x.getHumidity(), 1); 44 | 45 | Serial.println(); 46 | } else { 47 | Serial.print(F(".")); 48 | } 49 | 50 | delay(1000); 51 | } 52 | -------------------------------------------------------------------------------- /examples/Unit_CO2_M5Core/Unit_CO2_M5Core.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "M5UnitENV.h" 3 | 4 | SCD4X scd4x; 5 | 6 | void setup() { 7 | Serial.begin(115200); 8 | 9 | if (!scd4x.begin(&Wire, SCD4X_I2C_ADDR, 21, 22, 400000U)) { 10 | Serial.println("Couldn't find SCD4X"); 11 | while (1) delay(1); 12 | } 13 | 14 | uint16_t error; 15 | // stop potentially previously started measurement 16 | error = scd4x.stopPeriodicMeasurement(); 17 | if (error) { 18 | Serial.print("Error trying to execute stopPeriodicMeasurement(): "); 19 | } 20 | 21 | // Start Measurement 22 | error = scd4x.startPeriodicMeasurement(); 23 | if (error) { 24 | Serial.print("Error trying to execute startPeriodicMeasurement(): "); 25 | } 26 | 27 | Serial.println("Waiting for first measurement... (5 sec)"); 28 | } 29 | 30 | void loop() { 31 | if (scd4x.update()) // readMeasurement will return true when 32 | // fresh data is available 33 | { 34 | Serial.println(); 35 | 36 | Serial.print(F("CO2(ppm):")); 37 | Serial.print(scd4x.getCO2()); 38 | 39 | Serial.print(F("\tTemperature(C):")); 40 | Serial.print(scd4x.getTemperature(), 1); 41 | 42 | Serial.print(F("\tHumidity(%RH):")); 43 | Serial.print(scd4x.getHumidity(), 1); 44 | 45 | Serial.println(); 46 | } else { 47 | Serial.print(F(".")); 48 | } 49 | 50 | delay(1000); 51 | } 52 | -------------------------------------------------------------------------------- /examples/Unit_CO2_M5Core2/Unit_CO2_M5Core2.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_CO2_M5Core2.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core2 + Unit CO2 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | SCD4X scd4x; 20 | 21 | void setup() { 22 | M5.begin(); 23 | 24 | if (!scd4x.begin(&Wire, SCD4X_I2C_ADDR, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find SCD4X"); 26 | while (1) delay(1); 27 | } 28 | 29 | uint16_t error; 30 | // stop potentially previously started measurement 31 | error = scd4x.stopPeriodicMeasurement(); 32 | if (error) { 33 | Serial.print("Error trying to execute stopPeriodicMeasurement(): "); 34 | } 35 | 36 | // Start Measurement 37 | error = scd4x.startPeriodicMeasurement(); 38 | if (error) { 39 | Serial.print("Error trying to execute startPeriodicMeasurement(): "); 40 | } 41 | 42 | Serial.println("Waiting for first measurement... (5 sec)"); 43 | } 44 | 45 | void loop() { 46 | if (scd4x.update()) // readMeasurement will return true when 47 | // fresh data is available 48 | { 49 | Serial.println(); 50 | 51 | Serial.print(F("CO2(ppm):")); 52 | Serial.print(scd4x.getCO2()); 53 | 54 | Serial.print(F("\tTemperature(C):")); 55 | Serial.print(scd4x.getTemperature(), 1); 56 | 57 | Serial.print(F("\tHumidity(%RH):")); 58 | Serial.print(scd4x.getHumidity(), 1); 59 | 60 | Serial.println(); 61 | } else { 62 | Serial.print(F(".")); 63 | } 64 | 65 | delay(1000); 66 | } 67 | -------------------------------------------------------------------------------- /examples/Unit_CO2_M5StickC/Unit_CO2_M5StickC.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_CO2_M5StickC.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5StickC + Unit CO2 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | SCD4X scd4x; 20 | 21 | void setup() { 22 | M5.begin(); 23 | 24 | if (!scd4x.begin(&Wire, SCD4X_I2C_ADDR, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find SCD4X"); 26 | while (1) delay(1); 27 | } 28 | 29 | uint16_t error; 30 | // stop potentially previously started measurement 31 | error = scd4x.stopPeriodicMeasurement(); 32 | if (error) { 33 | Serial.print("Error trying to execute stopPeriodicMeasurement(): "); 34 | } 35 | 36 | // Start Measurement 37 | error = scd4x.startPeriodicMeasurement(); 38 | if (error) { 39 | Serial.print("Error trying to execute startPeriodicMeasurement(): "); 40 | } 41 | 42 | Serial.println("Waiting for first measurement... (5 sec)"); 43 | } 44 | 45 | void loop() { 46 | if (scd4x.update()) // readMeasurement will return true when 47 | // fresh data is available 48 | { 49 | Serial.println(); 50 | 51 | Serial.print(F("CO2(ppm):")); 52 | Serial.print(scd4x.getCO2()); 53 | 54 | Serial.print(F("\tTemperature(C):")); 55 | Serial.print(scd4x.getTemperature(), 1); 56 | 57 | Serial.print(F("\tHumidity(%RH):")); 58 | Serial.print(scd4x.getHumidity(), 1); 59 | 60 | Serial.println(); 61 | } else { 62 | Serial.print(F(".")); 63 | } 64 | 65 | delay(1000); 66 | } 67 | -------------------------------------------------------------------------------- /examples/Unit_CO2_M5StickCPlus/Unit_CO2_M5StickCPlus.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_CO2_M5StickCPlus.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5StickCPlus + Unit CO2 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | SCD4X scd4x; 20 | 21 | void setup() { 22 | M5.begin(); 23 | 24 | if (!scd4x.begin(&Wire, SCD4X_I2C_ADDR, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find SCD4X"); 26 | while (1) delay(1); 27 | } 28 | 29 | uint16_t error; 30 | // stop potentially previously started measurement 31 | error = scd4x.stopPeriodicMeasurement(); 32 | if (error) { 33 | Serial.print("Error trying to execute stopPeriodicMeasurement(): "); 34 | } 35 | 36 | // Start Measurement 37 | error = scd4x.startPeriodicMeasurement(); 38 | if (error) { 39 | Serial.print("Error trying to execute startPeriodicMeasurement(): "); 40 | } 41 | 42 | Serial.println("Waiting for first measurement... (5 sec)"); 43 | } 44 | 45 | void loop() { 46 | if (scd4x.update()) // readMeasurement will return true when 47 | // fresh data is available 48 | { 49 | Serial.println(); 50 | 51 | Serial.print(F("CO2(ppm):")); 52 | Serial.print(scd4x.getCO2()); 53 | 54 | Serial.print(F("\tTemperature(C):")); 55 | Serial.print(scd4x.getTemperature(), 1); 56 | 57 | Serial.print(F("\tHumidity(%RH):")); 58 | Serial.print(scd4x.getHumidity(), 1); 59 | 60 | Serial.println(); 61 | } else { 62 | Serial.print(F(".")); 63 | } 64 | 65 | delay(1000); 66 | } 67 | -------------------------------------------------------------------------------- /examples/Unit_ENVIII_M5Atom/Unit_ENVIII_M5Atom.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV_III.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.2 6 | * @date 2024-07-18 7 | * 8 | * 9 | * @Hardwares: M5Atom + Unit ENV_III 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | SHT3X sht3x; 18 | QMP6988 qmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 26, 32, 400000U)) { 23 | while (1) { 24 | Serial.println("Couldn't find QMP6988"); 25 | delay(500); 26 | } 27 | } 28 | 29 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 26, 32, 400000U)) { 30 | while (1) { 31 | Serial.println("Couldn't find SHT3X"); 32 | delay(500); 33 | } 34 | } 35 | } 36 | 37 | void loop() { 38 | if (sht3x.update()) { 39 | Serial.println("-----SHT3X-----"); 40 | Serial.print("Temperature: "); 41 | Serial.print(sht3x.cTemp); 42 | Serial.println(" degrees C"); 43 | Serial.print("Humidity: "); 44 | Serial.print(sht3x.humidity); 45 | Serial.println("% rH"); 46 | Serial.println("-------------\r\n"); 47 | } 48 | 49 | if (qmp.update()) { 50 | Serial.println("-----QMP6988-----"); 51 | Serial.print(F("Temperature: ")); 52 | Serial.print(qmp.cTemp); 53 | Serial.println(" *C"); 54 | Serial.print(F("Pressure: ")); 55 | Serial.print(qmp.pressure); 56 | Serial.println(" Pa"); 57 | Serial.print(F("Approx altitude: ")); 58 | Serial.print(qmp.altitude); 59 | Serial.println(" m"); 60 | Serial.println("-------------\r\n"); 61 | } 62 | delay(1000); 63 | } 64 | -------------------------------------------------------------------------------- /examples/Unit_ENVIII_M5AtomS3/Unit_ENVIII_M5AtomS3.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV_III.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.2 6 | * @date 2024-07-18 7 | * 8 | * 9 | * @Hardwares: M5AtomS3 + Unit ENV_III 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | SHT3X sht3x; 18 | QMP6988 qmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 2, 1, 400000U)) { 23 | while (1) { 24 | Serial.println("Couldn't find QMP6988"); 25 | delay(500); 26 | } 27 | } 28 | 29 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 2, 1, 400000U)) { 30 | while (1) { 31 | Serial.println("Couldn't find SHT3X"); 32 | delay(500); 33 | } 34 | } 35 | } 36 | 37 | void loop() { 38 | if (sht3x.update()) { 39 | Serial.println("-----SHT3X-----"); 40 | Serial.print("Temperature: "); 41 | Serial.print(sht3x.cTemp); 42 | Serial.println(" degrees C"); 43 | Serial.print("Humidity: "); 44 | Serial.print(sht3x.humidity); 45 | Serial.println("% rH"); 46 | Serial.println("-------------\r\n"); 47 | } 48 | 49 | if (qmp.update()) { 50 | Serial.println("-----QMP6988-----"); 51 | Serial.print(F("Temperature: ")); 52 | Serial.print(qmp.cTemp); 53 | Serial.println(" *C"); 54 | Serial.print(F("Pressure: ")); 55 | Serial.print(qmp.pressure); 56 | Serial.println(" Pa"); 57 | Serial.print(F("Approx altitude: ")); 58 | Serial.print(qmp.altitude); 59 | Serial.println(" m"); 60 | Serial.println("-------------\r\n"); 61 | } 62 | delay(1000); 63 | } 64 | -------------------------------------------------------------------------------- /examples/Unit_ENVIII_M5AtomS3Lite/Unit_ENVIII_M5AtomS3Lite.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV_III.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.2 6 | * @date 2024-07-18 7 | * 8 | * 9 | * @Hardwares: M5AtomS3Lite + Unit ENV_III 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | SHT3X sht3x; 18 | QMP6988 qmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 2, 1, 400000U)) { 23 | while (1) { 24 | Serial.println("Couldn't find QMP6988"); 25 | delay(500); 26 | } 27 | } 28 | 29 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 2, 1, 400000U)) { 30 | while (1) { 31 | Serial.println("Couldn't find SHT3X"); 32 | delay(500); 33 | } 34 | } 35 | } 36 | 37 | void loop() { 38 | if (sht3x.update()) { 39 | Serial.println("-----SHT3X-----"); 40 | Serial.print("Temperature: "); 41 | Serial.print(sht3x.cTemp); 42 | Serial.println(" degrees C"); 43 | Serial.print("Humidity: "); 44 | Serial.print(sht3x.humidity); 45 | Serial.println("% rH"); 46 | Serial.println("-------------\r\n"); 47 | } 48 | 49 | if (qmp.update()) { 50 | Serial.println("-----QMP6988-----"); 51 | Serial.print(F("Temperature: ")); 52 | Serial.print(qmp.cTemp); 53 | Serial.println(" *C"); 54 | Serial.print(F("Pressure: ")); 55 | Serial.print(qmp.pressure); 56 | Serial.println(" Pa"); 57 | Serial.print(F("Approx altitude: ")); 58 | Serial.print(qmp.altitude); 59 | Serial.println(" m"); 60 | Serial.println("-------------\r\n"); 61 | } 62 | delay(1000); 63 | } 64 | -------------------------------------------------------------------------------- /examples/Unit_ENVIII_M5Core/Unit_ENVIII_M5Core.ino: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @file ENV_III.ino 4 | * @author SeanKwok (shaoxiang@m5stack.com) 5 | * @brief 6 | * @version 0.1 7 | * @date 2024-01-30 8 | * 9 | * 10 | * @Hardwares: M5Core + Unit ENV_III 11 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 12 | * @Dependent Library: 13 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 14 | */ 15 | 16 | #include "M5UnitENV.h" 17 | 18 | SHT3X sht3x; 19 | QMP6988 qmp; 20 | 21 | void setup() { 22 | Serial.begin(115200); 23 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 21, 22, 400000U)) { 24 | Serial.println("Couldn't find QMP6988"); 25 | while (1) delay(1); 26 | } 27 | 28 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 21, 22, 400000U)) { 29 | Serial.println("Couldn't find SHT3X"); 30 | while (1) delay(1); 31 | } 32 | } 33 | 34 | void loop() { 35 | if (sht3x.update()) { 36 | Serial.println("-----SHT3X-----"); 37 | Serial.print("Temperature: "); 38 | Serial.print(sht3x.cTemp); 39 | Serial.println(" degrees C"); 40 | Serial.print("Humidity: "); 41 | Serial.print(sht3x.humidity); 42 | Serial.println("% rH"); 43 | Serial.println("-------------\r\n"); 44 | } 45 | 46 | if (qmp.update()) { 47 | Serial.println("-----QMP6988-----"); 48 | Serial.print(F("Temperature: ")); 49 | Serial.print(qmp.cTemp); 50 | Serial.println(" *C"); 51 | Serial.print(F("Pressure: ")); 52 | Serial.print(qmp.pressure); 53 | Serial.println(" Pa"); 54 | Serial.print(F("Approx altitude: ")); 55 | Serial.print(qmp.altitude); 56 | Serial.println(" m"); 57 | Serial.println("-------------\r\n"); 58 | } 59 | delay(1000); 60 | } 61 | -------------------------------------------------------------------------------- /examples/Unit_ENVIII_M5Core2/Unit_ENVIII_M5Core2.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_ENVIII_M5Core2.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core2 + Unit ENVIII 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | SHT3X sht3x; 20 | QMP6988 qmp; 21 | 22 | void setup() { 23 | M5.begin(); 24 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find QMP6988"); 26 | while (1) delay(1); 27 | } 28 | 29 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 32, 33, 400000U)) { 30 | Serial.println("Couldn't find SHT3X"); 31 | while (1) delay(1); 32 | } 33 | } 34 | 35 | void loop() { 36 | if (sht3x.update()) { 37 | Serial.println("-----SHT3X-----"); 38 | Serial.print("Temperature: "); 39 | Serial.print(sht3x.cTemp); 40 | Serial.println(" degrees C"); 41 | Serial.print("Humidity: "); 42 | Serial.print(sht3x.humidity); 43 | Serial.println("% rH"); 44 | Serial.println("-------------\r\n"); 45 | } 46 | 47 | if (qmp.update()) { 48 | Serial.println("-----QMP6988-----"); 49 | Serial.print(F("Temperature: ")); 50 | Serial.print(qmp.cTemp); 51 | Serial.println(" *C"); 52 | Serial.print(F("Pressure: ")); 53 | Serial.print(qmp.pressure); 54 | Serial.println(" Pa"); 55 | Serial.print(F("Approx altitude: ")); 56 | Serial.print(qmp.altitude); 57 | Serial.println(" m"); 58 | Serial.println("-------------\r\n"); 59 | } 60 | delay(1000); 61 | } 62 | -------------------------------------------------------------------------------- /examples/Unit_ENVIII_M5Station/Unit_ENVIII_M5Station.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_ENVIII_M5Station.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Station + Unit ENVIII 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | SHT3X sht3x; 20 | QMP6988 qmp; 21 | 22 | void setup() { 23 | M5.begin(); 24 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find QMP6988"); 26 | while (1) delay(1); 27 | } 28 | 29 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 32, 33, 400000U)) { 30 | Serial.println("Couldn't find SHT3X"); 31 | while (1) delay(1); 32 | } 33 | } 34 | 35 | void loop() { 36 | if (sht3x.update()) { 37 | Serial.println("-----SHT3X-----"); 38 | Serial.print("Temperature: "); 39 | Serial.print(sht3x.cTemp); 40 | Serial.println(" degrees C"); 41 | Serial.print("Humidity: "); 42 | Serial.print(sht3x.humidity); 43 | Serial.println("% rH"); 44 | Serial.println("-------------\r\n"); 45 | } 46 | 47 | if (qmp.update()) { 48 | Serial.println("-----QMP6988-----"); 49 | Serial.print(F("Temperature: ")); 50 | Serial.print(qmp.cTemp); 51 | Serial.println(" *C"); 52 | Serial.print(F("Pressure: ")); 53 | Serial.print(qmp.pressure); 54 | Serial.println(" Pa"); 55 | Serial.print(F("Approx altitude: ")); 56 | Serial.print(qmp.altitude); 57 | Serial.println(" m"); 58 | Serial.println("-------------\r\n"); 59 | } 60 | delay(1000); 61 | } 62 | -------------------------------------------------------------------------------- /examples/Unit_ENVIII_M5StickC/Unit_ENVIII_M5StickC.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_ENVIII_M5StickC.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5StickC + Unit ENVIII 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | 20 | SHT3X sht3x; 21 | QMP6988 qmp; 22 | 23 | void setup() { 24 | M5.begin(); 25 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 32, 33, 400000U)) { 26 | Serial.println("Couldn't find QMP6988"); 27 | while (1) delay(1); 28 | } 29 | 30 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 32, 33, 400000U)) { 31 | Serial.println("Couldn't find SHT3X"); 32 | while (1) delay(1); 33 | } 34 | } 35 | 36 | void loop() { 37 | if (sht3x.update()) { 38 | Serial.println("-----SHT3X-----"); 39 | Serial.print("Temperature: "); 40 | Serial.print(sht3x.cTemp); 41 | Serial.println(" degrees C"); 42 | Serial.print("Humidity: "); 43 | Serial.print(sht3x.humidity); 44 | Serial.println("% rH"); 45 | Serial.println("-------------\r\n"); 46 | } 47 | 48 | if (qmp.update()) { 49 | Serial.println("-----QMP6988-----"); 50 | Serial.print(F("Temperature: ")); 51 | Serial.print(qmp.cTemp); 52 | Serial.println(" *C"); 53 | Serial.print(F("Pressure: ")); 54 | Serial.print(qmp.pressure); 55 | Serial.println(" Pa"); 56 | Serial.print(F("Approx altitude: ")); 57 | Serial.print(qmp.altitude); 58 | Serial.println(" m"); 59 | Serial.println("-------------\r\n"); 60 | } 61 | delay(1000); 62 | } 63 | -------------------------------------------------------------------------------- /examples/Unit_ENVIII_M5StickCPlus/Unit_ENVIII_M5StickCPlus.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_ENVIII_M5StickCPlus.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5StickCPlus + Unit ENVIII 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | SHT3X sht3x; 20 | QMP6988 qmp; 21 | 22 | void setup() { 23 | M5.begin(); 24 | if (!qmp.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find QMP6988"); 26 | while (1) delay(1); 27 | } 28 | 29 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 32, 33, 400000U)) { 30 | Serial.println("Couldn't find SHT3X"); 31 | while (1) delay(1); 32 | } 33 | } 34 | 35 | void loop() { 36 | if (sht3x.update()) { 37 | Serial.println("-----SHT3X-----"); 38 | Serial.print("Temperature: "); 39 | Serial.print(sht3x.cTemp); 40 | Serial.println(" degrees C"); 41 | Serial.print("Humidity: "); 42 | Serial.print(sht3x.humidity); 43 | Serial.println("% rH"); 44 | Serial.println("-------------\r\n"); 45 | } 46 | 47 | if (qmp.update()) { 48 | Serial.println("-----QMP6988-----"); 49 | Serial.print(F("Temperature: ")); 50 | Serial.print(qmp.cTemp); 51 | Serial.println(" *C"); 52 | Serial.print(F("Pressure: ")); 53 | Serial.print(qmp.pressure); 54 | Serial.println(" Pa"); 55 | Serial.print(F("Approx altitude: ")); 56 | Serial.print(qmp.altitude); 57 | Serial.println(" m"); 58 | Serial.println("-------------\r\n"); 59 | } 60 | delay(1000); 61 | } 62 | -------------------------------------------------------------------------------- /examples/Unit_ENVII_M5Atom/Unit_ENVII_M5Atom.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV_II.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core + Unit ENV_II 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | SHT3X sht3x; 18 | BMP280 bmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | 23 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 26, 32, 400000U)) { 24 | Serial.println("Couldn't find SHT3X"); 25 | while (1) delay(1); 26 | } 27 | 28 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 26, 32, 400000U)) { 29 | Serial.println("Couldn't find BMP280"); 30 | while (1) delay(1); 31 | } 32 | /* Default settings from datasheet. */ 33 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 34 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 35 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 36 | BMP280::FILTER_X16, /* Filtering. */ 37 | BMP280::STANDBY_MS_500); /* Standby time. */ 38 | } 39 | 40 | void loop() { 41 | if (sht3x.update()) { 42 | Serial.println("-----SHT3X-----"); 43 | Serial.print("Temperature: "); 44 | Serial.print(sht3x.cTemp); 45 | Serial.println(" degrees C"); 46 | Serial.print("Humidity: "); 47 | Serial.print(sht3x.humidity); 48 | Serial.println("% rH"); 49 | Serial.println("-------------\r\n"); 50 | } 51 | 52 | if (bmp.update()) { 53 | Serial.println("-----BMP280-----"); 54 | Serial.print(F("Temperature: ")); 55 | Serial.print(bmp.cTemp); 56 | Serial.println(" degrees C"); 57 | Serial.print(F("Pressure: ")); 58 | Serial.print(bmp.pressure); 59 | Serial.println(" Pa"); 60 | Serial.print(F("Approx altitude: ")); 61 | Serial.print(bmp.altitude); 62 | Serial.println(" m"); 63 | Serial.println("-------------\r\n"); 64 | } 65 | delay(1000); 66 | } 67 | -------------------------------------------------------------------------------- /examples/Unit_ENVII_M5AtomS3/Unit_ENVII_M5AtomS3.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV_II.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core + Unit ENV_II 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | SHT3X sht3x; 18 | BMP280 bmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | 23 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 2, 1, 400000U)) { 24 | Serial.println("Couldn't find SHT3X"); 25 | while (1) delay(1); 26 | } 27 | 28 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 2, 1, 400000U)) { 29 | Serial.println("Couldn't find BMP280"); 30 | while (1) delay(1); 31 | } 32 | /* Default settings from datasheet. */ 33 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 34 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 35 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 36 | BMP280::FILTER_X16, /* Filtering. */ 37 | BMP280::STANDBY_MS_500); /* Standby time. */ 38 | } 39 | 40 | void loop() { 41 | if (sht3x.update()) { 42 | Serial.println("-----SHT3X-----"); 43 | Serial.print("Temperature: "); 44 | Serial.print(sht3x.cTemp); 45 | Serial.println(" degrees C"); 46 | Serial.print("Humidity: "); 47 | Serial.print(sht3x.humidity); 48 | Serial.println("% rH"); 49 | Serial.println("-------------\r\n"); 50 | } 51 | 52 | if (bmp.update()) { 53 | Serial.println("-----BMP280-----"); 54 | Serial.print(F("Temperature: ")); 55 | Serial.print(bmp.cTemp); 56 | Serial.println(" degrees C"); 57 | Serial.print(F("Pressure: ")); 58 | Serial.print(bmp.pressure); 59 | Serial.println(" Pa"); 60 | Serial.print(F("Approx altitude: ")); 61 | Serial.print(bmp.altitude); 62 | Serial.println(" m"); 63 | Serial.println("-------------\r\n"); 64 | } 65 | delay(1000); 66 | } 67 | -------------------------------------------------------------------------------- /examples/Unit_ENVII_M5AtomS3Lite/Unit_ENVII_M5AtomS3Lite.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV_II.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core + Unit ENV_II 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | SHT3X sht3x; 18 | BMP280 bmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | 23 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 2, 1, 400000U)) { 24 | Serial.println("Couldn't find SHT3X"); 25 | while (1) delay(1); 26 | } 27 | 28 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 2, 1, 400000U)) { 29 | Serial.println("Couldn't find BMP280"); 30 | while (1) delay(1); 31 | } 32 | /* Default settings from datasheet. */ 33 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 34 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 35 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 36 | BMP280::FILTER_X16, /* Filtering. */ 37 | BMP280::STANDBY_MS_500); /* Standby time. */ 38 | } 39 | 40 | void loop() { 41 | if (sht3x.update()) { 42 | Serial.println("-----SHT3X-----"); 43 | Serial.print("Temperature: "); 44 | Serial.print(sht3x.cTemp); 45 | Serial.println(" degrees C"); 46 | Serial.print("Humidity: "); 47 | Serial.print(sht3x.humidity); 48 | Serial.println("% rH"); 49 | Serial.println("-------------\r\n"); 50 | } 51 | 52 | if (bmp.update()) { 53 | Serial.println("-----BMP280-----"); 54 | Serial.print(F("Temperature: ")); 55 | Serial.print(bmp.cTemp); 56 | Serial.println(" degrees C"); 57 | Serial.print(F("Pressure: ")); 58 | Serial.print(bmp.pressure); 59 | Serial.println(" Pa"); 60 | Serial.print(F("Approx altitude: ")); 61 | Serial.print(bmp.altitude); 62 | Serial.println(" m"); 63 | Serial.println("-------------\r\n"); 64 | } 65 | delay(1000); 66 | } 67 | -------------------------------------------------------------------------------- /examples/Unit_ENVII_M5Core/Unit_ENVII_M5Core.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV_II.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core + Unit ENV_II 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | SHT3X sht3x; 18 | BMP280 bmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | 23 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 21, 22, 400000U)) { 24 | Serial.println("Couldn't find SHT3X"); 25 | while (1) delay(1); 26 | } 27 | 28 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 21, 22, 400000U)) { 29 | Serial.println("Couldn't find BMP280"); 30 | while (1) delay(1); 31 | } 32 | /* Default settings from datasheet. */ 33 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 34 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 35 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 36 | BMP280::FILTER_X16, /* Filtering. */ 37 | BMP280::STANDBY_MS_500); /* Standby time. */ 38 | } 39 | 40 | void loop() { 41 | if (sht3x.update()) { 42 | Serial.println("-----SHT3X-----"); 43 | Serial.print("Temperature: "); 44 | Serial.print(sht3x.cTemp); 45 | Serial.println(" degrees C"); 46 | Serial.print("Humidity: "); 47 | Serial.print(sht3x.humidity); 48 | Serial.println("% rH"); 49 | Serial.println("-------------\r\n"); 50 | } 51 | 52 | if (bmp.update()) { 53 | Serial.println("-----BMP280-----"); 54 | Serial.print(F("Temperature: ")); 55 | Serial.print(bmp.cTemp); 56 | Serial.println(" degrees C"); 57 | Serial.print(F("Pressure: ")); 58 | Serial.print(bmp.pressure); 59 | Serial.println(" Pa"); 60 | Serial.print(F("Approx altitude: ")); 61 | Serial.print(bmp.altitude); 62 | Serial.println(" m"); 63 | Serial.println("-------------\r\n"); 64 | } 65 | delay(1000); 66 | } 67 | -------------------------------------------------------------------------------- /examples/Unit_ENVII_M5Core2/Unit_ENVII_M5Core2.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_ENVII_M5Core2.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core2 + Unit ENVII 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | SHT3X sht3x; 20 | BMP280 bmp; 21 | 22 | void setup() { 23 | M5.begin(); 24 | 25 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 32, 33, 400000U)) { 26 | Serial.println("Couldn't find SHT3X"); 27 | while (1) delay(1); 28 | } 29 | 30 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 32, 33, 400000U)) { 31 | Serial.println("Couldn't find BMP280"); 32 | while (1) delay(1); 33 | } 34 | /* Default settings from datasheet. */ 35 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 36 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 37 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 38 | BMP280::FILTER_X16, /* Filtering. */ 39 | BMP280::STANDBY_MS_500); /* Standby time. */ 40 | } 41 | 42 | void loop() { 43 | if (sht3x.update()) { 44 | Serial.println("-----SHT3X-----"); 45 | Serial.print("Temperature: "); 46 | Serial.print(sht3x.cTemp); 47 | Serial.println(" degrees C"); 48 | Serial.print("Humidity: "); 49 | Serial.print(sht3x.humidity); 50 | Serial.println("% rH"); 51 | Serial.println("-------------\r\n"); 52 | } 53 | 54 | if (bmp.update()) { 55 | Serial.println("-----BMP280-----"); 56 | Serial.print(F("Temperature: ")); 57 | Serial.print(bmp.cTemp); 58 | Serial.println(" degrees C"); 59 | Serial.print(F("Pressure: ")); 60 | Serial.print(bmp.pressure); 61 | Serial.println(" Pa"); 62 | Serial.print(F("Approx altitude: ")); 63 | Serial.print(bmp.altitude); 64 | Serial.println(" m"); 65 | Serial.println("-------------\r\n"); 66 | } 67 | delay(1000); 68 | } 69 | -------------------------------------------------------------------------------- /examples/Unit_ENVII_M5StickC/Unit_ENVII_M5StickC.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_ENVII_M5StickC.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5StickC + Unit ENVII 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | SHT3X sht3x; 20 | BMP280 bmp; 21 | 22 | void setup() { 23 | M5.begin(); 24 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find SHT3X"); 26 | while (1) delay(1); 27 | } 28 | 29 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 32, 33, 400000U)) { 30 | Serial.println("Couldn't find BMP280"); 31 | while (1) delay(1); 32 | } 33 | /* Default settings from datasheet. */ 34 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 35 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 36 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 37 | BMP280::FILTER_X16, /* Filtering. */ 38 | BMP280::STANDBY_MS_500); /* Standby time. */ 39 | } 40 | 41 | void loop() { 42 | if (sht3x.update()) { 43 | Serial.println("-----SHT3X-----"); 44 | Serial.print("Temperature: "); 45 | Serial.print(sht3x.cTemp); 46 | Serial.println(" degrees C"); 47 | Serial.print("Humidity: "); 48 | Serial.print(sht3x.humidity); 49 | Serial.println("% rH"); 50 | Serial.println("-------------\r\n"); 51 | } 52 | 53 | if (bmp.update()) { 54 | Serial.println("-----BMP280-----"); 55 | Serial.print(F("Temperature: ")); 56 | Serial.print(bmp.cTemp); 57 | Serial.println(" degrees C"); 58 | Serial.print(F("Pressure: ")); 59 | Serial.print(bmp.pressure); 60 | Serial.println(" Pa"); 61 | Serial.print(F("Approx altitude: ")); 62 | Serial.print(bmp.altitude); 63 | Serial.println(" m"); 64 | Serial.println("-------------\r\n"); 65 | } 66 | delay(1000); 67 | } 68 | -------------------------------------------------------------------------------- /examples/Unit_ENVII_M5StickCPlus/Unit_ENVII_M5StickCPlus.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_ENVII_M5StickCPlus.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5StickCPlus + Unit ENVII 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | SHT3X sht3x; 20 | BMP280 bmp; 21 | 22 | void setup() { 23 | M5.begin(); 24 | 25 | if (!sht3x.begin(&Wire, SHT3X_I2C_ADDR, 32, 33, 400000U)) { 26 | Serial.println("Couldn't find SHT3X"); 27 | while (1) delay(1); 28 | } 29 | 30 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 32, 33, 400000U)) { 31 | Serial.println("Couldn't find BMP280"); 32 | while (1) delay(1); 33 | } 34 | /* Default settings from datasheet. */ 35 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 36 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 37 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 38 | BMP280::FILTER_X16, /* Filtering. */ 39 | BMP280::STANDBY_MS_500); /* Standby time. */ 40 | } 41 | 42 | void loop() { 43 | if (sht3x.update()) { 44 | Serial.println("-----SHT3X-----"); 45 | Serial.print("Temperature: "); 46 | Serial.print(sht3x.cTemp); 47 | Serial.println(" degrees C"); 48 | Serial.print("Humidity: "); 49 | Serial.print(sht3x.humidity); 50 | Serial.println("% rH"); 51 | Serial.println("-------------\r\n"); 52 | } 53 | 54 | if (bmp.update()) { 55 | Serial.println("-----BMP280-----"); 56 | Serial.print(F("Temperature: ")); 57 | Serial.print(bmp.cTemp); 58 | Serial.println(" degrees C"); 59 | Serial.print(F("Pressure: ")); 60 | Serial.print(bmp.pressure); 61 | Serial.println(" Pa"); 62 | Serial.print(F("Approx altitude: ")); 63 | Serial.print(bmp.altitude); 64 | Serial.println(" m"); 65 | Serial.println("-------------\r\n"); 66 | } 67 | delay(1000); 68 | } 69 | -------------------------------------------------------------------------------- /examples/Unit_ENVIV_M5Core/Unit_ENVIV_M5Core.ino: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @file ENV_IV.ino 4 | * @author SeanKwok (shaoxiang@m5stack.com) 5 | * @brief 6 | * @version 0.1 7 | * @date 2024-01-30 8 | * 9 | * 10 | * @Hardwares: M5Core + Unit ENV_IV 11 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 12 | * @Dependent Library: 13 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 14 | */ 15 | 16 | #include "M5UnitENV.h" 17 | 18 | SHT4X sht4; 19 | BMP280 bmp; 20 | 21 | void setup() { 22 | Serial.begin(115200); 23 | 24 | if (!sht4.begin(&Wire, SHT40_I2C_ADDR_44, 21, 22, 400000U)) { 25 | Serial.println("Couldn't find SHT4x"); 26 | while (1) delay(1); 27 | } 28 | 29 | // You can have 3 different precisions, higher precision takes longer 30 | sht4.setPrecision(SHT4X_HIGH_PRECISION); 31 | sht4.setHeater(SHT4X_NO_HEATER); 32 | 33 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 21, 22, 400000U)) { 34 | Serial.println("Couldn't find BMP280"); 35 | while (1) delay(1); 36 | } 37 | /* Default settings from datasheet. */ 38 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 39 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 40 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 41 | BMP280::FILTER_X16, /* Filtering. */ 42 | BMP280::STANDBY_MS_500); /* Standby time. */ 43 | } 44 | 45 | void loop() { 46 | if (sht4.update()) { 47 | Serial.println("-----SHT4X-----"); 48 | Serial.print("Temperature: "); 49 | Serial.print(sht4.cTemp); 50 | Serial.println(" degrees C"); 51 | Serial.print("Humidity: "); 52 | Serial.print(sht4.humidity); 53 | Serial.println("% rH"); 54 | Serial.println("-------------\r\n"); 55 | } 56 | 57 | if (bmp.update()) { 58 | Serial.println("-----BMP280-----"); 59 | Serial.print(F("Temperature: ")); 60 | Serial.print(bmp.cTemp); 61 | Serial.println(" degrees C"); 62 | Serial.print(F("Pressure: ")); 63 | Serial.print(bmp.pressure); 64 | Serial.println(" Pa"); 65 | Serial.print(F("Approx altitude: ")); 66 | Serial.print(bmp.altitude); 67 | Serial.println(" m"); 68 | Serial.println("-------------\r\n"); 69 | } 70 | delay(1000); 71 | } 72 | -------------------------------------------------------------------------------- /examples/Unit_ENVIV_M5Core2/Unit_ENVIV_M5Core2.ino: -------------------------------------------------------------------------------- 1 | /* 2 | ******************************************************************************* 3 | * Copyright (c) 2023 by M5Stack 4 | * Equipped with M5Core2 sample source code 5 | * 配套 M5Core2 示例源代码 6 | * Visit to get information: https://docs.m5stack.com/en/unit/ENV%E2%85%A3%20Unit 7 | * 获取更多资料请访问: https://docs.m5stack.com/zh_CN/unit/ENV%E2%85%A3%20Unit 8 | * 9 | * Product: ENVIV_SHT40_BMP280. 环境传感器 10 | * Date: 2023/8/24 11 | ******************************************************************************* 12 | Please connect to Port,Read temperature, humidity and atmospheric pressure and 13 | display them on the display screen 14 | 请连接端口,读取温度、湿度和大气压强并在显示屏上显示 15 | Libraries: 16 | - [Adafruit_BMP280](https://github.com/adafruit/Adafruit_BMP280_Library) 17 | - [Adafruit_Sensor](https://github.com/adafruit/Adafruit_Sensor) 18 | - [SensirionI2CSht4x](https://github.com/Tinyu-Zhao/arduino-i2c-sht4x) 19 | */ 20 | #include 21 | #include 22 | #include 23 | #include "Adafruit_Sensor.h" 24 | 25 | // 初始化传感器 26 | Adafruit_BMP280 bmp; 27 | 28 | SensirionI2CSht4x sht4x; 29 | float temperature, pressure, 30 | humidity; // Store the vuale of pressure and Temperature. 存储压力和温度 31 | 32 | void setup() 33 | { 34 | // 初始化传感器 35 | M5.begin(); 36 | M5.Lcd.setTextSize(2); 37 | Wire.begin(); // SDA = 16, SCL = 34 38 | Serial.begin(115200); 39 | while (!Serial) 40 | { 41 | delay(100); 42 | } 43 | while (!bmp.begin( 44 | 0x76)) 45 | { // Init this sensor,True if the init was successful, otherwise 46 | // false. 初始化传感器,如果初始化成功返回1 47 | M5.Lcd.println("Could not find a valid BMP280 sensor, check wiring!"); 48 | Serial.println(F("BMP280 fail")); 49 | } 50 | M5.Lcd.clear(); // Clear the screen. 清屏 51 | Serial.println(F("BMP280 test")); 52 | 53 | uint16_t error; 54 | char errorMessage[256]; 55 | 56 | sht4x.begin(Wire); 57 | 58 | uint32_t serialNumber; 59 | error = sht4x.serialNumber(serialNumber); 60 | if (error) 61 | { 62 | Serial.print("Error trying to execute serialNumber(): "); 63 | errorToString(error, errorMessage, 256); 64 | Serial.println(errorMessage); 65 | } 66 | else 67 | { 68 | Serial.print("Serial Number: "); 69 | Serial.println(serialNumber); 70 | } 71 | 72 | // 设置传感器的采样率和滤波器 73 | bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, // 模式:正常 74 | Adafruit_BMP280::SAMPLING_X2, // 温度采样率:2倍 75 | Adafruit_BMP280::SAMPLING_X16, // 压力采样率:16倍 76 | Adafruit_BMP280::FILTER_X16, // 滤波器:16倍 77 | Adafruit_BMP280::STANDBY_MS_500); // 等待时间:500毫秒 78 | } 79 | 80 | void loop() 81 | { 82 | uint16_t error; 83 | char errorMessage[256]; 84 | 85 | delay(1000); 86 | 87 | error = sht4x.measureHighPrecision(temperature, humidity); 88 | if (error) 89 | { 90 | Serial.print("Error trying to execute measureHighPrecision(): "); 91 | errorToString(error, errorMessage, 256); 92 | Serial.println(errorMessage); 93 | } 94 | else 95 | { 96 | Serial.print("Temperature:"); 97 | Serial.print(temperature); 98 | Serial.print("\t"); 99 | Serial.print("Humidity:"); 100 | Serial.println(humidity); 101 | } 102 | pressure = bmp.readPressure(); 103 | M5.Lcd.setCursor(0, 0); // 将光标设置在(0 ,0). Set the cursor to (0,0) 104 | M5.Lcd.printf("Pressure:%2.0fPa\nTemperature:%2.0f^C", pressure, 105 | temperature); 106 | M5.Lcd.setCursor(0, 40); 107 | M5.Lcd.print("humidity:"); 108 | M5.Lcd.print(humidity); 109 | M5.Lcd.print("%"); 110 | delay(100); 111 | } 112 | -------------------------------------------------------------------------------- /examples/Unit_ENV_M5Atom/Unit_ENV_M5Atom.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core + Unit ENV 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | DHT12 dht; 18 | BMP280 bmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | if (!dht.begin(&Wire, DHT12_I2C_ADDR, 26, 32, 400000U)) { 23 | Serial.println("Couldn't find DHT12"); 24 | while (1) delay(1); 25 | } 26 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 26, 32, 400000U)) { 27 | Serial.println("Couldn't find BMP280"); 28 | while (1) delay(1); 29 | } 30 | /* Default settings from datasheet. */ 31 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 32 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 33 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 34 | BMP280::FILTER_X16, /* Filtering. */ 35 | BMP280::STANDBY_MS_500); /* Standby time. */ 36 | } 37 | 38 | void loop() { 39 | if (dht.update()) { 40 | Serial.println("-----DHT12-----"); 41 | Serial.print("Temperature: "); 42 | Serial.print(dht.cTemp); 43 | Serial.println(" degrees C"); 44 | Serial.print("Humidity: "); 45 | Serial.print(dht.humidity); 46 | Serial.println("% rH"); 47 | Serial.println("-------------\r\n"); 48 | } 49 | 50 | if (bmp.update()) { 51 | Serial.println("-----BMP280-----"); 52 | Serial.print(F("Temperature: ")); 53 | Serial.print(bmp.cTemp); 54 | Serial.println(" degrees C"); 55 | Serial.print(F("Pressure: ")); 56 | Serial.print(bmp.pressure); 57 | Serial.println(" Pa"); 58 | Serial.print(F("Approx altitude: ")); 59 | Serial.print(bmp.altitude); 60 | Serial.println(" m"); 61 | Serial.println("-------------\r\n"); 62 | } 63 | delay(1000); 64 | } 65 | -------------------------------------------------------------------------------- /examples/Unit_ENV_M5AtomS3/Unit_ENV_M5AtomS3.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core + Unit ENV 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | DHT12 dht; 18 | BMP280 bmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | if (!dht.begin(&Wire, DHT12_I2C_ADDR, 2, 1, 400000U)) { 23 | Serial.println("Couldn't find DHT12"); 24 | while (1) delay(1); 25 | } 26 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 2, 1, 400000U)) { 27 | Serial.println("Couldn't find BMP280"); 28 | while (1) delay(1); 29 | } 30 | /* Default settings from datasheet. */ 31 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 32 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 33 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 34 | BMP280::FILTER_X16, /* Filtering. */ 35 | BMP280::STANDBY_MS_500); /* Standby time. */ 36 | } 37 | 38 | void loop() { 39 | if (dht.update()) { 40 | Serial.println("-----DHT12-----"); 41 | Serial.print("Temperature: "); 42 | Serial.print(dht.cTemp); 43 | Serial.println(" degrees C"); 44 | Serial.print("Humidity: "); 45 | Serial.print(dht.humidity); 46 | Serial.println("% rH"); 47 | Serial.println("-------------\r\n"); 48 | } 49 | 50 | if (bmp.update()) { 51 | Serial.println("-----BMP280-----"); 52 | Serial.print(F("Temperature: ")); 53 | Serial.print(bmp.cTemp); 54 | Serial.println(" degrees C"); 55 | Serial.print(F("Pressure: ")); 56 | Serial.print(bmp.pressure); 57 | Serial.println(" Pa"); 58 | Serial.print(F("Approx altitude: ")); 59 | Serial.print(bmp.altitude); 60 | Serial.println(" m"); 61 | Serial.println("-------------\r\n"); 62 | } 63 | delay(1000); 64 | } 65 | -------------------------------------------------------------------------------- /examples/Unit_ENV_M5AtomS3Lite/Unit_ENV_M5AtomS3Lite.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core + Unit ENV 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | DHT12 dht; 18 | BMP280 bmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | if (!dht.begin(&Wire, DHT12_I2C_ADDR, 2, 1, 400000U)) { 23 | Serial.println("Couldn't find DHT12"); 24 | while (1) delay(1); 25 | } 26 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 2, 1, 400000U)) { 27 | Serial.println("Couldn't find BMP280"); 28 | while (1) delay(1); 29 | } 30 | /* Default settings from datasheet. */ 31 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 32 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 33 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 34 | BMP280::FILTER_X16, /* Filtering. */ 35 | BMP280::STANDBY_MS_500); /* Standby time. */ 36 | } 37 | 38 | void loop() { 39 | if (dht.update()) { 40 | Serial.println("-----DHT12-----"); 41 | Serial.print("Temperature: "); 42 | Serial.print(dht.cTemp); 43 | Serial.println(" degrees C"); 44 | Serial.print("Humidity: "); 45 | Serial.print(dht.humidity); 46 | Serial.println("% rH"); 47 | Serial.println("-------------\r\n"); 48 | } 49 | 50 | if (bmp.update()) { 51 | Serial.println("-----BMP280-----"); 52 | Serial.print(F("Temperature: ")); 53 | Serial.print(bmp.cTemp); 54 | Serial.println(" degrees C"); 55 | Serial.print(F("Pressure: ")); 56 | Serial.print(bmp.pressure); 57 | Serial.println(" Pa"); 58 | Serial.print(F("Approx altitude: ")); 59 | Serial.print(bmp.altitude); 60 | Serial.println(" m"); 61 | Serial.println("-------------\r\n"); 62 | } 63 | delay(1000); 64 | } 65 | -------------------------------------------------------------------------------- /examples/Unit_ENV_M5Core/Unit_ENV_M5Core.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ENV.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core + Unit ENV 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | */ 14 | 15 | #include "M5UnitENV.h" 16 | 17 | DHT12 dht; 18 | BMP280 bmp; 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | if (!dht.begin(&Wire, DHT12_I2C_ADDR, 21, 22, 400000U)) { 23 | Serial.println("Couldn't find DHT12"); 24 | while (1) delay(1); 25 | } 26 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 21, 22, 400000U)) { 27 | Serial.println("Couldn't find BMP280"); 28 | while (1) delay(1); 29 | } 30 | /* Default settings from datasheet. */ 31 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 32 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 33 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 34 | BMP280::FILTER_X16, /* Filtering. */ 35 | BMP280::STANDBY_MS_500); /* Standby time. */ 36 | } 37 | 38 | void loop() { 39 | if (dht.update()) { 40 | Serial.println("-----DHT12-----"); 41 | Serial.print("Temperature: "); 42 | Serial.print(dht.cTemp); 43 | Serial.println(" degrees C"); 44 | Serial.print("Humidity: "); 45 | Serial.print(dht.humidity); 46 | Serial.println("% rH"); 47 | Serial.println("-------------\r\n"); 48 | } 49 | 50 | if (bmp.update()) { 51 | Serial.println("-----BMP280-----"); 52 | Serial.print(F("Temperature: ")); 53 | Serial.print(bmp.cTemp); 54 | Serial.println(" degrees C"); 55 | Serial.print(F("Pressure: ")); 56 | Serial.print(bmp.pressure); 57 | Serial.println(" Pa"); 58 | Serial.print(F("Approx altitude: ")); 59 | Serial.print(bmp.altitude); 60 | Serial.println(" m"); 61 | Serial.println("-------------\r\n"); 62 | } 63 | delay(1000); 64 | } 65 | -------------------------------------------------------------------------------- /examples/Unit_ENV_M5Core2/Unit_ENV_M5Core2.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_ENV_M5Core2.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5Core2 + Unit ENV 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | DHT12 dht; 20 | BMP280 bmp; 21 | 22 | void setup() { 23 | M5.begin(); 24 | if (!dht.begin(&Wire, DHT12_I2C_ADDR, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find DHT12"); 26 | while (1) delay(1); 27 | } 28 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 32, 33, 400000U)) { 29 | Serial.println("Couldn't find BMP280"); 30 | while (1) delay(1); 31 | } 32 | /* Default settings from datasheet. */ 33 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 34 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 35 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 36 | BMP280::FILTER_X16, /* Filtering. */ 37 | BMP280::STANDBY_MS_500); /* Standby time. */ 38 | } 39 | 40 | void loop() { 41 | if (dht.update()) { 42 | Serial.println("-----DHT12-----"); 43 | Serial.print("Temperature: "); 44 | Serial.print(dht.cTemp); 45 | Serial.println(" degrees C"); 46 | Serial.print("Humidity: "); 47 | Serial.print(dht.humidity); 48 | Serial.println("% rH"); 49 | Serial.println("-------------\r\n"); 50 | } 51 | 52 | if (bmp.update()) { 53 | Serial.println("-----BMP280-----"); 54 | Serial.print(F("Temperature: ")); 55 | Serial.print(bmp.cTemp); 56 | Serial.println(" degrees C"); 57 | Serial.print(F("Pressure: ")); 58 | Serial.print(bmp.pressure); 59 | Serial.println(" Pa"); 60 | Serial.print(F("Approx altitude: ")); 61 | Serial.print(bmp.altitude); 62 | Serial.println(" m"); 63 | Serial.println("-------------\r\n"); 64 | } 65 | delay(1000); 66 | } 67 | -------------------------------------------------------------------------------- /examples/Unit_ENV_M5StickC/Unit_ENV_M5StickC.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_ENV_M5StickC.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5StickC + Unit ENV 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | DHT12 dht; 20 | BMP280 bmp; 21 | 22 | void setup() { 23 | M5.begin(); 24 | if (!dht.begin(&Wire, DHT12_I2C_ADDR, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find DHT12"); 26 | while (1) delay(1); 27 | } 28 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 32, 33, 400000U)) { 29 | Serial.println("Couldn't find BMP280"); 30 | while (1) delay(1); 31 | } 32 | /* Default settings from datasheet. */ 33 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 34 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 35 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 36 | BMP280::FILTER_X16, /* Filtering. */ 37 | BMP280::STANDBY_MS_500); /* Standby time. */ 38 | } 39 | 40 | void loop() { 41 | if (dht.update()) { 42 | Serial.println("-----DHT12-----"); 43 | Serial.print("Temperature: "); 44 | Serial.print(dht.cTemp); 45 | Serial.println(" degrees C"); 46 | Serial.print("Humidity: "); 47 | Serial.print(dht.humidity); 48 | Serial.println("% rH"); 49 | Serial.println("-------------\r\n"); 50 | } 51 | 52 | if (bmp.update()) { 53 | Serial.println("-----BMP280-----"); 54 | Serial.print(F("Temperature: ")); 55 | Serial.print(bmp.cTemp); 56 | Serial.println(" degrees C"); 57 | Serial.print(F("Pressure: ")); 58 | Serial.print(bmp.pressure); 59 | Serial.println(" Pa"); 60 | Serial.print(F("Approx altitude: ")); 61 | Serial.print(bmp.altitude); 62 | Serial.println(" m"); 63 | Serial.println("-------------\r\n"); 64 | } 65 | delay(1000); 66 | } 67 | -------------------------------------------------------------------------------- /examples/Unit_ENV_M5StickCPlus/Unit_ENV_M5StickCPlus.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Unit_ENV_M5StickCPlus.ino 3 | * @author SeanKwok (shaoxiang@m5stack.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2024-01-30 7 | * 8 | * 9 | * @Hardwares: M5StickCPlus + Unit ENV 10 | * @Platform Version: Arduino M5Stack Board Manager v2.1.0 11 | * @Dependent Library: 12 | * M5UnitENV: https://github.com/m5stack/M5Unit-ENV 13 | * M5Unified: https://github.com/m5stack/M5Unified 14 | */ 15 | 16 | #include 17 | #include "M5UnitENV.h" 18 | 19 | DHT12 dht; 20 | BMP280 bmp; 21 | 22 | void setup() { 23 | M5.begin(); 24 | if (!dht.begin(&Wire, DHT12_I2C_ADDR, 32, 33, 400000U)) { 25 | Serial.println("Couldn't find DHT12"); 26 | while (1) delay(1); 27 | } 28 | if (!bmp.begin(&Wire, BMP280_I2C_ADDR, 32, 33, 400000U)) { 29 | Serial.println("Couldn't find BMP280"); 30 | while (1) delay(1); 31 | } 32 | /* Default settings from datasheet. */ 33 | bmp.setSampling(BMP280::MODE_NORMAL, /* Operating Mode. */ 34 | BMP280::SAMPLING_X2, /* Temp. oversampling */ 35 | BMP280::SAMPLING_X16, /* Pressure oversampling */ 36 | BMP280::FILTER_X16, /* Filtering. */ 37 | BMP280::STANDBY_MS_500); /* Standby time. */ 38 | } 39 | 40 | void loop() { 41 | if (dht.update()) { 42 | Serial.println("-----DHT12-----"); 43 | Serial.print("Temperature: "); 44 | Serial.print(dht.cTemp); 45 | Serial.println(" degrees C"); 46 | Serial.print("Humidity: "); 47 | Serial.print(dht.humidity); 48 | Serial.println("% rH"); 49 | Serial.println("-------------\r\n"); 50 | } 51 | 52 | if (bmp.update()) { 53 | Serial.println("-----BMP280-----"); 54 | Serial.print(F("Temperature: ")); 55 | Serial.print(bmp.cTemp); 56 | Serial.println(" degrees C"); 57 | Serial.print(F("Pressure: ")); 58 | Serial.print(bmp.pressure); 59 | Serial.println(" Pa"); 60 | Serial.print(F("Approx altitude: ")); 61 | Serial.print(bmp.altitude); 62 | Serial.println(" m"); 63 | Serial.println("-------------\r\n"); 64 | } 65 | delay(1000); 66 | } 67 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "M5Unit-ENV", 3 | "description": "Library for M5Stack UNIT ENV", 4 | "keywords": "M5Stack UNIT ENV,M5UnitUnified", 5 | "authors": { 6 | "name": "M5Stack", 7 | "url": "http://www.m5stack.com" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/m5stack/M5Unit-ENV.git" 12 | }, 13 | "dependencies": 14 | { 15 | "m5stack/M5UnitUnified": ">=0.1.0", 16 | "boschsensortec/BME68x Sensor library": ">=1.3.40408", 17 | "boschsensortec/bsec2": ">=1.10.2610" 18 | }, 19 | "version": "1.3.0", 20 | "frameworks": [ 21 | "arduino" 22 | ], 23 | "headers": [ 24 | "M5UnitENV.h", 25 | "M5UnitUnifiedENV.h" 26 | ], 27 | "platforms": "espressif32", 28 | "license": "MIT", 29 | "export": { 30 | "exclude": [ 31 | "docs/html" 32 | ] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=M5Unit-ENV 2 | version=1.3.0 3 | author=M5Stack 4 | maintainer=M5Stack 5 | sentence=Library for M5Stack UNIT ENV 6 | paragraph=See more on https://docs.m5stack.com/en/unit/envIII 7 | category=Device Control 8 | url=https://github.com/m5stack/M5Unit-ENV 9 | architectures=esp32 10 | includes=M5UnitENV.h, M5UnitUnifiedENV.h 11 | depends=M5UnitUnified,M5Utility,M5HAL,bsec2,BME68x Sensor library 12 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------------------- 2 | ; M5Unit-ENV 3 | ; For UnitTest and examples (Using M5UnitUnified) 4 | ;----------------------------------------------------------------------- 5 | [platformio] 6 | extra_configs = unit_co2_env.ini, unit_env3_env.ini, unit_env4_env.ini, unit_envpro_env.ini, unit_tvoc_env.ini 7 | 8 | [env] 9 | build_flags =-Wall -Wextra -Wreturn-local-addr -Werror=format -Werror=return-local-addr 10 | lib_ldf_mode = deep 11 | test_framework = googletest 12 | test_build_src = true 13 | lib_deps=m5stack/M5Unified 14 | m5stack/M5UnitUnified 15 | boschsensortec/BME68x Sensor library@>=1.3.40408 16 | 17 | ; -------------------------------- 18 | [bsec2] 19 | lib_deps = boschsensortec/bsec2@>=1.10.2610 20 | 21 | [m5base] 22 | monitor_speed = 115200 23 | monitor_filters = esp32_exception_decoder, time 24 | upload_speed = 1500000 25 | test_speed = 115200 26 | test_ignore= native/* 27 | 28 | [Core] 29 | extends = m5base 30 | board = m5stack-grey 31 | ;m5stack-grey 32 | ;m5stack-core-esp32-16M ;;6.8.0 or later 33 | ;m5stack-core-esp32 34 | lib_deps = ${env.lib_deps} 35 | ${bsec2.lib_deps} 36 | 37 | [Core2] 38 | extends = m5base 39 | board = m5stack-core2 40 | lib_deps = ${env.lib_deps} 41 | ${bsec2.lib_deps} 42 | 43 | [CoreS3] 44 | extends = m5base 45 | board = m5stack-cores3 46 | lib_deps = ${env.lib_deps} 47 | ${bsec2.lib_deps} 48 | 49 | [Fire] 50 | extends = m5base 51 | board = m5stack-fire 52 | lib_deps = ${env.lib_deps} 53 | ${bsec2.lib_deps} 54 | 55 | [StampS3] 56 | ;include M5Capsule,M5DinMeter 57 | extends = m5base 58 | board = m5stack-stamps3 59 | lib_deps = ${env.lib_deps} 60 | ${bsec2.lib_deps} 61 | 62 | [Dial] 63 | extends = m5base 64 | board = m5stack-stamps3 65 | lib_deps = ${env.lib_deps} 66 | ${bsec2.lib_deps} 67 | m5stack/M5Dial 68 | 69 | [AtomMatrix] 70 | extends = m5base 71 | board = m5stack-atom 72 | lib_deps = ${env.lib_deps} 73 | ${bsec2.lib_deps} 74 | 75 | [AtomS3] 76 | extends = m5base 77 | board = m5stack-atoms3 78 | lib_deps = ${env.lib_deps} 79 | ${bsec2.lib_deps} 80 | 81 | ; Using ./boards/m5stack-atoms3r.json 82 | [AtomS3R] 83 | extends = m5base 84 | board = m5stack-atoms3r 85 | lib_deps = ${env.lib_deps} 86 | ${bsec2.lib_deps} 87 | 88 | ; Using ./boards/m5stack-nanoc6.json 89 | [NanoC6] 90 | extends = m5base 91 | board = m5stack-nanoc6 92 | platform = https://github.com/platformio/platform-espressif32.git 93 | platform_packages = 94 | platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.7 95 | platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 96 | board_build.partitions = default.csv 97 | lib_deps = ${env.lib_deps} 98 | 99 | [StickCPlus] 100 | extends = m5base 101 | board = m5stick-c 102 | lib_deps = ${env.lib_deps} 103 | ${bsec2.lib_deps} 104 | 105 | ; Using ./boards/m5stick-cplus2.json 106 | [StickCPlus2] 107 | extends = m5base 108 | board = m5stick-cplus2 109 | lib_deps = ${env.lib_deps} 110 | ${bsec2.lib_deps} 111 | 112 | [Paper] 113 | extends = m5base 114 | board = m5stack-fire 115 | lib_deps = ${env.lib_deps} 116 | ${bsec2.lib_deps} 117 | 118 | [CoreInk] 119 | extends = m5base 120 | board = m5stack-coreink 121 | lib_deps = ${env.lib_deps} 122 | ${bsec2.lib_deps} 123 | 124 | [sdl] 125 | build_flags = -O3 -xc++ -std=c++14 -lSDL2 126 | -arch arm64 ; for arm mac 127 | -I"/usr/local/include/SDL2" ; for intel mac homebrew SDL2 128 | -L"/usr/local/lib" ; for intel mac homebrew SDL2 129 | -I"${sysenv.HOMEBREW_PREFIX}/include/SDL2" ; for arm mac homebrew SDL2 130 | -L"${sysenv.HOMEBREW_PREFIX}/lib" ; for arm mac homebrew SDL2 131 | platform = native 132 | test_filter= native/* 133 | test_ignore= embedded/* 134 | lib_deps = ${env.lib_deps} 135 | 136 | ; -------------------------------- 137 | ;Choose framework 138 | [arduino_latest] 139 | platform = espressif32 @ 6.8.1 140 | framework = arduino 141 | 142 | [arduino_6_6_0] 143 | platform = espressif32 @ 6.6.0 144 | framework = arduino 145 | 146 | [arduino_6_0_1] 147 | platform = espressif32 @ 6.0.1 148 | framework = arduino 149 | 150 | [arduino_5_4_0] 151 | platform = espressif32 @ 5.4.0 152 | framework = arduino 153 | 154 | [arduino_4_4_0] 155 | platform = espressif32 @ 4.4.0 156 | framework = arduino 157 | 158 | ;[arduino_3_5_0] 159 | ;platform = espressif32 @ 3.5.0 160 | ;framework = arduino 161 | 162 | [esp-idf] 163 | platform = espressif32 @ 6.8.1 164 | framework = espidf 165 | 166 | ; -------------------------------- 167 | ;Choose build options 168 | [option_release] 169 | build_type=release 170 | build_flags = ${env.build_flags} 171 | -DCORE_DEBUG_LEVEL=3 172 | -DLOG_LOCAL_LEVEL=3 173 | -DAPP_LOG_LEVEL=3 174 | -DM5_LOG_LEVEL=3 175 | 176 | [option_log] 177 | build_type=release 178 | build_flags = ${env.build_flags} 179 | -DCORE_DEBUG_LEVEL=5 180 | -DLOG_LOCAL_LEVEL=5 181 | -DAPP_LOG_LEVEL=5 182 | 183 | [option_debug] 184 | build_type=debug 185 | build_flags = ${env.build_flags} 186 | -DCORE_DEBUG_LEVEL=5 187 | -DLOG_LOCAL_LEVEL=5 188 | -DAPP_LOG_LEVEL=5 189 | -DDEBUG 190 | 191 | [option_map] 192 | build_type=release 193 | build_flags = ${env.build_flags} 194 | -DCORE_DEBUG_LEVEL=3 195 | -DLOG_LOCAL_LEVEL=3 196 | -DAPP_LOG_LEVEL=3 197 | -DM5_LOG_LEVEL=0 198 | -Wl,-Map,output.map 199 | 200 | ; Require at leaset C++14 after 1.13.0 201 | [test_fw] 202 | lib_deps = google/googletest@1.12.1 203 | 204 | -------------------------------------------------------------------------------- /src/DHT12.cpp: -------------------------------------------------------------------------------- 1 | #include "DHT12.h" 2 | 3 | bool DHT12::begin(TwoWire* wire, uint8_t addr, uint8_t sda, uint8_t scl, 4 | long freq) { 5 | _i2c.begin(wire, sda, scl, freq); 6 | _addr = addr; 7 | return _i2c.exist(_addr); 8 | } 9 | 10 | bool DHT12::update() { 11 | uint8_t datos[5] = {0}; 12 | if (_i2c.readBytes(_addr, 0, datos, 5)) { 13 | if (datos[4] != (datos[0] + datos[1] + datos[2] + datos[3])) { 14 | return false; 15 | } 16 | cTemp = (datos[2] + (float)datos[3] / 10); 17 | fTemp = ((datos[2] + (float)datos[3] / 10) * 1.8 + 32); 18 | kTemp = (datos[2] + (float)datos[3] / 10) + 273.15; 19 | humidity = (datos[0] + (float)datos[1] / 10); 20 | return true; 21 | } 22 | return false; 23 | } 24 | -------------------------------------------------------------------------------- /src/DHT12.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _DHT12_H 3 | #define _DHT12_H 4 | 5 | #include "Arduino.h" 6 | #include "Wire.h" 7 | #include "I2C_Class.h" 8 | 9 | #define DHT12_I2C_ADDR 0x5c 10 | 11 | class DHT12 { 12 | public: 13 | bool begin(TwoWire* wire = &Wire, uint8_t addr = DHT12_I2C_ADDR, 14 | uint8_t sda = 21, uint8_t scl = 22, long freq = 400000U); 15 | bool update(); 16 | float cTemp = 0; 17 | float fTemp = 0; 18 | float kTemp = 0; 19 | float humidity = 0; 20 | 21 | private: 22 | uint8_t _addr; 23 | I2C_Class _i2c; 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/I2C_Class.cpp: -------------------------------------------------------------------------------- 1 | #include "I2C_Class.h" 2 | 3 | void I2C_Class::begin(TwoWire *wire, uint8_t sda, uint8_t scl, long freq) { 4 | _wire = wire; 5 | _sda = sda; 6 | _scl = scl; 7 | _freq = freq; 8 | _wire->end(); 9 | _wire->begin(static_cast(_sda), _scl, freq); 10 | } 11 | 12 | bool I2C_Class::exist(uint8_t addr) { 13 | int error; 14 | _wire->beginTransmission(addr); 15 | error = _wire->endTransmission(); 16 | if (error == 0) { 17 | return true; 18 | } 19 | return false; 20 | } 21 | 22 | bool I2C_Class::writeBytes(uint8_t addr, uint8_t reg, uint8_t *buffer, 23 | uint8_t length) { 24 | _wire->beginTransmission(addr); 25 | _wire->write(reg); 26 | _wire->write(buffer, length); 27 | if (_wire->endTransmission() == 0) return true; 28 | return false; 29 | } 30 | 31 | bool I2C_Class::readBytes(uint8_t addr, uint8_t reg, uint8_t *buffer, 32 | uint8_t length) { 33 | uint8_t index = 0; 34 | _wire->beginTransmission(addr); 35 | _wire->write(reg); 36 | _wire->endTransmission(); 37 | if (_wire->requestFrom(addr, length)) { 38 | for (uint8_t i = 0; i < length; i++) { 39 | buffer[index++] = _wire->read(); 40 | } 41 | return true; 42 | } 43 | return false; 44 | } 45 | 46 | bool I2C_Class::readU16(uint8_t addr, uint8_t reg_addr, uint16_t *value) { 47 | uint8_t read_buf[2] = {0x00, 0x00}; 48 | bool result = readBytes(addr, reg_addr, read_buf, 2); 49 | *value = (read_buf[0] << 8) | read_buf[1]; 50 | return result; 51 | } 52 | 53 | bool I2C_Class::writeU16(uint8_t addr, uint8_t reg_addr, uint16_t value) { 54 | uint8_t write_buf[2]; 55 | write_buf[0] = value >> 8; 56 | write_buf[1] = value & 0xff; 57 | return writeBytes(addr, reg_addr, write_buf, 2); 58 | } 59 | 60 | bool I2C_Class::writeByte(uint8_t addr, uint8_t reg, uint8_t data) { 61 | _wire->beginTransmission(addr); 62 | _wire->write(reg); 63 | _wire->write(data); 64 | if (_wire->endTransmission() == 0) return true; 65 | return false; 66 | } 67 | 68 | uint8_t I2C_Class::readByte(uint8_t addr, uint8_t reg) { 69 | _wire->beginTransmission(addr); 70 | _wire->write(reg); 71 | _wire->endTransmission(); 72 | 73 | if (_wire->requestFrom(addr, 1)) { 74 | return _wire->read(); 75 | } 76 | return 0; 77 | } 78 | 79 | bool I2C_Class::writeBitOn(uint8_t addr, uint8_t reg, uint8_t data) { 80 | uint8_t temp; 81 | uint8_t write_back; 82 | temp = readByte(addr, reg); 83 | write_back = (temp | data); 84 | return (writeByte(addr, reg, write_back)); 85 | } 86 | 87 | bool I2C_Class::writeBitOff(uint8_t addr, uint8_t reg, uint8_t data) { 88 | uint8_t temp; 89 | uint8_t write_back; 90 | temp = readByte(addr, reg); 91 | write_back = (temp & (~data)); 92 | return (writeByte(addr, reg, write_back)); 93 | } 94 | -------------------------------------------------------------------------------- /src/I2C_Class.h: -------------------------------------------------------------------------------- 1 | #ifndef _I2C_DEVICE_BUS_ 2 | #define _I2C_DEVICE_BUS_ 3 | 4 | #include "Arduino.h" 5 | #include "Wire.h" 6 | 7 | class I2C_Class { 8 | private: 9 | TwoWire* _wire; 10 | uint8_t _scl; 11 | uint8_t _sda; 12 | long _freq; 13 | 14 | public: 15 | void begin(TwoWire* wire, uint8_t sda, uint8_t scl, long freq = 100000); 16 | bool exist(uint8_t addr); 17 | 18 | bool writeBytes(uint8_t addr, uint8_t reg, uint8_t* buffer, uint8_t length); 19 | bool readBytes(uint8_t addr, uint8_t reg, uint8_t* buffer, uint8_t length); 20 | 21 | bool readU16(uint8_t addr, uint8_t reg_addr, uint16_t* value); 22 | bool writeU16(uint8_t addr, uint8_t reg_addr, uint16_t value); 23 | 24 | bool writeByte(uint8_t addr, uint8_t reg, uint8_t data); 25 | uint8_t readByte(uint8_t addr, uint8_t reg); 26 | bool writeBitOn(uint8_t addr, uint8_t reg, uint8_t data); 27 | bool writeBitOff(uint8_t addr, uint8_t reg, uint8_t data); 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /src/M5UnitENV.h: -------------------------------------------------------------------------------- 1 | #if defined(M5_UNIT_UNIFIED_ENV_HPP) 2 | #error "DO NOT USE it at the same time as M5UnitUnified libraries" 3 | #endif 4 | 5 | #ifndef _M5_UNIT_ENV_H_ 6 | #define _M5_UNIT_ENV_H_ 7 | 8 | #include "Arduino.h" 9 | #include "DHT12.h" 10 | #include "QMP6988.h" 11 | #include "SHT3X.h" 12 | #include "SHT4X.h" 13 | #include "BMP280.h" 14 | #include "SCD4X.h" 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/M5UnitUnifiedENV.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /*! 7 | @file M5UnitUnifiedENV.h 8 | @brief Main header of M5UnitENV using M5UnitUnfied 9 | */ 10 | #ifndef M5_UNIT_UNIFIED_ENV_H 11 | #define M5_UNIT_UNIFIED_ENV_H 12 | #ifdef __cplusplus 13 | #include "M5UnitUnifiedENV.hpp" 14 | #else 15 | #error M5UnitUnifiedENV requires a C++ compiler, please change file extension to .cc or .cpp 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /src/M5UnitUnifiedENV.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /*! 7 | @file M5UnitUnifiedENV.hpp 8 | @brief Main header of M5UnitENV using M5UnitUnified 9 | 10 | @mainpage M5Unit-ENV 11 | Library for UnitENV using M5UnitUnified. 12 | */ 13 | #if defined(_M5_UNIT_ENV_H_) 14 | #error "DO NOT USE it at the same time as conventional libraries" 15 | #endif 16 | 17 | #ifndef M5_UNIT_UNIFIED_ENV_HPP 18 | #define M5_UNIT_UNIFIED_ENV_HPP 19 | 20 | // CO2 21 | #include "unit/unit_SCD40.hpp" 22 | #include "unit/unit_SCD41.hpp" 23 | // ENVIII 24 | #include "unit/unit_SHT30.hpp" 25 | #include "unit/unit_QMP6988.hpp" 26 | #include "unit/unit_ENV3.hpp" 27 | // ENVPro 28 | #include "unit/unit_BME688.hpp" 29 | // TVOC 30 | #include "unit/unit_SGP30.hpp" 31 | // ENVIV 32 | #include "unit/unit_SHT40.hpp" 33 | #include "unit/unit_BMP280.hpp" 34 | #include "unit/unit_ENV4.hpp" 35 | 36 | /*! 37 | @namespace m5 38 | @brief Top level namespace of M5stack 39 | */ 40 | namespace m5 { 41 | 42 | /*! 43 | @namespace unit 44 | @brief Unit-related namespace 45 | */ 46 | namespace unit { 47 | 48 | using UnitCO2 = m5::unit::UnitSCD40; 49 | using UnitCO2L = m5::unit::UnitSCD41; 50 | using UnitENVPro = m5::unit::UnitBME688; 51 | using UnitTVOC = m5::unit::UnitSGP30; 52 | 53 | } // namespace unit 54 | } // namespace m5 55 | #endif 56 | -------------------------------------------------------------------------------- /src/QMP6988.h: -------------------------------------------------------------------------------- 1 | #ifndef __QMP6988_H 2 | #define __QMP6988_H 3 | 4 | #include "Arduino.h" 5 | #include "Wire.h" 6 | #include "I2C_Class.h" 7 | 8 | #define QMP6988_SLAVE_ADDRESS_L (0x70) 9 | #define QMP6988_SLAVE_ADDRESS_H (0x56) 10 | 11 | #define QMP6988_U16_t unsigned short 12 | #define QMP6988_S16_t short 13 | #define QMP6988_U32_t unsigned int 14 | #define QMP6988_S32_t int 15 | #define QMP6988_U64_t unsigned long long 16 | #define QMP6988_S64_t long long 17 | 18 | #define QMP6988_CHIP_ID 0x5C 19 | 20 | #define QMP6988_CHIP_ID_REG 0xD1 21 | #define QMP6988_RESET_REG 0xE0 /* Device reset register */ 22 | #define QMP6988_DEVICE_STAT_REG 0xF3 /* Device state register */ 23 | #define QMP6988_CTRLMEAS_REG 0xF4 /* Measurement Condition Control Register */ 24 | /* data */ 25 | #define QMP6988_PRESSURE_MSB_REG 0xF7 /* Pressure MSB Register */ 26 | #define QMP6988_TEMPERATURE_MSB_REG 0xFA /* Temperature MSB Reg */ 27 | 28 | /* compensation calculation */ 29 | #define QMP6988_CALIBRATION_DATA_START \ 30 | 0xA0 /* QMP6988 compensation coefficients */ 31 | #define QMP6988_CALIBRATION_DATA_LENGTH 25 32 | 33 | #define SHIFT_RIGHT_4_POSITION 4 34 | #define SHIFT_LEFT_2_POSITION 2 35 | #define SHIFT_LEFT_4_POSITION 4 36 | #define SHIFT_LEFT_5_POSITION 5 37 | #define SHIFT_LEFT_8_POSITION 8 38 | #define SHIFT_LEFT_12_POSITION 12 39 | #define SHIFT_LEFT_16_POSITION 16 40 | 41 | /* power mode */ 42 | #define QMP6988_SLEEP_MODE 0x00 43 | #define QMP6988_FORCED_MODE 0x01 44 | #define QMP6988_NORMAL_MODE 0x03 45 | 46 | #define QMP6988_CTRLMEAS_REG_MODE__POS 0 47 | #define QMP6988_CTRLMEAS_REG_MODE__MSK 0x03 48 | #define QMP6988_CTRLMEAS_REG_MODE__LEN 2 49 | 50 | /* oversampling */ 51 | #define QMP6988_OVERSAMPLING_SKIPPED 0x00 52 | #define QMP6988_OVERSAMPLING_1X 0x01 53 | #define QMP6988_OVERSAMPLING_2X 0x02 54 | #define QMP6988_OVERSAMPLING_4X 0x03 55 | #define QMP6988_OVERSAMPLING_8X 0x04 56 | #define QMP6988_OVERSAMPLING_16X 0x05 57 | #define QMP6988_OVERSAMPLING_32X 0x06 58 | #define QMP6988_OVERSAMPLING_64X 0x07 59 | 60 | #define QMP6988_CTRLMEAS_REG_OSRST__POS 5 61 | #define QMP6988_CTRLMEAS_REG_OSRST__MSK 0xE0 62 | #define QMP6988_CTRLMEAS_REG_OSRST__LEN 3 63 | 64 | #define QMP6988_CTRLMEAS_REG_OSRSP__POS 2 65 | #define QMP6988_CTRLMEAS_REG_OSRSP__MSK 0x1C 66 | #define QMP6988_CTRLMEAS_REG_OSRSP__LEN 3 67 | 68 | /* filter */ 69 | #define QMP6988_FILTERCOEFF_OFF 0x00 70 | #define QMP6988_FILTERCOEFF_2 0x01 71 | #define QMP6988_FILTERCOEFF_4 0x02 72 | #define QMP6988_FILTERCOEFF_8 0x03 73 | #define QMP6988_FILTERCOEFF_16 0x04 74 | #define QMP6988_FILTERCOEFF_32 0x05 75 | 76 | #define QMP6988_CONFIG_REG 0xF1 /*IIR filter co-efficient setting Register*/ 77 | #define QMP6988_CONFIG_REG_FILTER__POS 0 78 | #define QMP6988_CONFIG_REG_FILTER__MSK 0x07 79 | #define QMP6988_CONFIG_REG_FILTER__LEN 3 80 | 81 | #define SUBTRACTOR 8388608 82 | 83 | typedef struct _qmp6988_cali_data { 84 | QMP6988_S32_t COE_a0; 85 | QMP6988_S16_t COE_a1; 86 | QMP6988_S16_t COE_a2; 87 | QMP6988_S32_t COE_b00; 88 | QMP6988_S16_t COE_bt1; 89 | QMP6988_S16_t COE_bt2; 90 | QMP6988_S16_t COE_bp1; 91 | QMP6988_S16_t COE_b11; 92 | QMP6988_S16_t COE_bp2; 93 | QMP6988_S16_t COE_b12; 94 | QMP6988_S16_t COE_b21; 95 | QMP6988_S16_t COE_bp3; 96 | } qmp6988_cali_data_t; 97 | 98 | typedef struct _qmp6988_fk_data { 99 | float a0, b00; 100 | float a1, a2, bt1, bt2, bp1, b11, bp2, b12, b21, bp3; 101 | } qmp6988_fk_data_t; 102 | 103 | typedef struct _qmp6988_ik_data { 104 | QMP6988_S32_t a0, b00; 105 | QMP6988_S32_t a1, a2; 106 | QMP6988_S64_t bt1, bt2, bp1, b11, bp2, b12, b21, bp3; 107 | } qmp6988_ik_data_t; 108 | 109 | typedef struct _qmp6988_data { 110 | uint8_t slave; 111 | uint8_t chip_id; 112 | uint8_t power_mode; 113 | float temperature; 114 | float pressure; 115 | float altitude; 116 | qmp6988_cali_data_t qmp6988_cali; 117 | qmp6988_ik_data_t ik; 118 | } qmp6988_data_t; 119 | 120 | class QMP6988 { 121 | private: 122 | qmp6988_data_t qmp6988; 123 | uint8_t _addr; 124 | I2C_Class _i2c; 125 | 126 | // read calibration data from otp 127 | int getCalibrationData(); 128 | QMP6988_S32_t getPressure02e(qmp6988_ik_data_t* ik, QMP6988_S32_t dp, 129 | QMP6988_S16_t tx); 130 | QMP6988_S16_t convTx02e(qmp6988_ik_data_t* ik, QMP6988_S32_t dt); 131 | 132 | void reset(); 133 | 134 | public: 135 | bool begin(TwoWire* wire = &Wire, uint8_t addr = QMP6988_SLAVE_ADDRESS_H, 136 | uint8_t sda = 21, uint8_t scl = 22, long freq = 400000U); 137 | bool update(); 138 | 139 | float pressure = 0; 140 | float cTemp = 0; 141 | float altitude = 0; 142 | 143 | float calcAltitude(float pressure, float temp); 144 | float calcPressure(); 145 | float calcTemperature(); 146 | 147 | void setpPowermode(int power_mode); 148 | void setFilter(unsigned char filter); 149 | void setOversamplingP(unsigned char oversampling_p); 150 | void setOversamplingT(unsigned char oversampling_t); 151 | }; 152 | 153 | #endif 154 | -------------------------------------------------------------------------------- /src/SHT3X.cpp: -------------------------------------------------------------------------------- 1 | #include "SHT3X.h" 2 | 3 | bool SHT3X::begin(TwoWire* wire, uint8_t addr, uint8_t sda, uint8_t scl, 4 | long freq) { 5 | _i2c.begin(wire, sda, scl, freq); 6 | _addr = addr; 7 | _wire = wire; 8 | return _i2c.exist(_addr); 9 | } 10 | 11 | bool SHT3X::update() { 12 | unsigned int data[6]; 13 | 14 | // Start I2C Transmission 15 | _wire->beginTransmission(_addr); 16 | // Send measurement command 17 | _wire->write(0x2C); 18 | _wire->write(0x06); 19 | // Stop I2C transmission 20 | if (_wire->endTransmission() != 0) return false; 21 | 22 | delay(200); 23 | 24 | // Request 6 bytes of data 25 | _wire->requestFrom(_addr, (uint8_t)6); 26 | 27 | // Read 6 bytes of data 28 | // cTemp msb, cTemp lsb, cTemp crc, humidity msb, humidity lsb, humidity crc 29 | for (int i = 0; i < 6; i++) { 30 | data[i] = _wire->read(); 31 | }; 32 | 33 | delay(50); 34 | 35 | if (_wire->available() != 0) return false; 36 | 37 | // Convert the data 38 | cTemp = ((((data[0] * 256.0) + data[1]) * 175) / 65535.0) - 45; 39 | fTemp = (cTemp * 1.8) + 32; 40 | humidity = ((((data[3] * 256.0) + data[4]) * 100) / 65535.0); 41 | 42 | return true; 43 | } 44 | -------------------------------------------------------------------------------- /src/SHT3X.h: -------------------------------------------------------------------------------- 1 | #ifndef __SHT3X_H_ 2 | #define __SHT3X_H_ 3 | 4 | #include "Arduino.h" 5 | #include "I2C_Class.h" 6 | #include "Wire.h" 7 | 8 | #define SHT3X_I2C_ADDR 0x44 9 | 10 | class SHT3X { 11 | public: 12 | bool begin(TwoWire* wire = &Wire, uint8_t addr = SHT3X_I2C_ADDR, 13 | uint8_t sda = 21, uint8_t scl = 22, long freq = 400000U); 14 | bool update(void); 15 | float cTemp = 0; 16 | float fTemp = 0; 17 | float humidity = 0; 18 | 19 | private: 20 | TwoWire* _wire; 21 | uint8_t _addr; 22 | I2C_Class _i2c; 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/SHT4X.cpp: -------------------------------------------------------------------------------- 1 | #include "SHT4X.h" 2 | 3 | bool SHT4X::begin(TwoWire* wire, uint8_t addr, uint8_t sda, uint8_t scl, 4 | long freq) { 5 | _i2c.begin(wire, sda, scl, freq); 6 | _addr = addr; 7 | _wire = wire; 8 | return _i2c.exist(_addr); 9 | } 10 | 11 | bool SHT4X::update() { 12 | uint8_t readbuffer[6]; 13 | uint8_t cmd = SHT4x_NOHEAT_HIGHPRECISION; 14 | uint16_t duration = 10; 15 | 16 | if (_heater == SHT4X_NO_HEATER) { 17 | if (_precision == SHT4X_HIGH_PRECISION) { 18 | cmd = SHT4x_NOHEAT_HIGHPRECISION; 19 | duration = 10; 20 | } 21 | if (_precision == SHT4X_MED_PRECISION) { 22 | cmd = SHT4x_NOHEAT_MEDPRECISION; 23 | duration = 5; 24 | } 25 | if (_precision == SHT4X_LOW_PRECISION) { 26 | cmd = SHT4x_NOHEAT_LOWPRECISION; 27 | duration = 2; 28 | } 29 | } 30 | 31 | if (_heater == SHT4X_HIGH_HEATER_1S) { 32 | cmd = SHT4x_HIGHHEAT_1S; 33 | duration = 1100; 34 | } 35 | if (_heater == SHT4X_HIGH_HEATER_100MS) { 36 | cmd = SHT4x_HIGHHEAT_100MS; 37 | duration = 110; 38 | } 39 | 40 | if (_heater == SHT4X_MED_HEATER_1S) { 41 | cmd = SHT4x_MEDHEAT_1S; 42 | duration = 1100; 43 | } 44 | if (_heater == SHT4X_MED_HEATER_100MS) { 45 | cmd = SHT4x_MEDHEAT_100MS; 46 | duration = 110; 47 | } 48 | 49 | if (_heater == SHT4X_LOW_HEATER_1S) { 50 | cmd = SHT4x_LOWHEAT_1S; 51 | duration = 1100; 52 | } 53 | if (_heater == SHT4X_LOW_HEATER_100MS) { 54 | cmd = SHT4x_LOWHEAT_100MS; 55 | duration = 110; 56 | } 57 | 58 | _i2c.writeByte(_addr, cmd, 1); 59 | 60 | delay(duration); 61 | 62 | _wire->requestFrom(_addr, (uint8_t)6); 63 | 64 | for (uint16_t i = 0; i < 6; i++) { 65 | readbuffer[i] = _wire->read(); 66 | } 67 | 68 | if (readbuffer[2] != crc8(readbuffer, 2) || 69 | readbuffer[5] != crc8(readbuffer + 3, 2)) { 70 | return false; 71 | } 72 | 73 | float t_ticks = (uint16_t)readbuffer[0] * 256 + (uint16_t)readbuffer[1]; 74 | float rh_ticks = (uint16_t)readbuffer[3] * 256 + (uint16_t)readbuffer[4]; 75 | 76 | cTemp = -45 + 175 * t_ticks / 65535; 77 | humidity = -6 + 125 * rh_ticks / 65535; 78 | humidity = min(max(humidity, (float)0.0), (float)100.0); 79 | return true; 80 | } 81 | 82 | void SHT4X::setPrecision(sht4x_precision_t prec) { 83 | _precision = prec; 84 | } 85 | 86 | sht4x_precision_t SHT4X::getPrecision(void) { 87 | return _precision; 88 | } 89 | 90 | void SHT4X::setHeater(sht4x_heater_t heat) { 91 | _heater = heat; 92 | } 93 | 94 | sht4x_heater_t SHT4X::getHeater(void) { 95 | return _heater; 96 | } 97 | -------------------------------------------------------------------------------- /src/SHT4X.h: -------------------------------------------------------------------------------- 1 | #ifndef __SHT4X_H_ 2 | #define __SHT4X_H_ 3 | 4 | #include "Arduino.h" 5 | #include "I2C_Class.h" 6 | #include "Wire.h" 7 | #include "utility.h" 8 | 9 | #define SHT40_I2C_ADDR_44 0x44 10 | #define SHT40_I2C_ADDR_45 0x45 11 | #define SHT41_I2C_ADDR_44 0x44 12 | #define SHT41_I2C_ADDR_45 0x45 13 | #define SHT45_I2C_ADDR_44 0x44 14 | #define SHT45_I2C_ADDR_45 0x45 15 | 16 | #define SHT4x_DEFAULT_ADDR 0x44 /**< SHT4x I2C Address */ 17 | #define SHT4x_NOHEAT_HIGHPRECISION \ 18 | 0xFD /**< High precision measurement, no heater */ 19 | #define SHT4x_NOHEAT_MEDPRECISION \ 20 | 0xF6 /**< Medium precision measurement, no heater */ 21 | #define SHT4x_NOHEAT_LOWPRECISION \ 22 | 0xE0 /**< Low precision measurement, no heater */ 23 | 24 | #define SHT4x_HIGHHEAT_1S \ 25 | 0x39 /**< High precision measurement, high heat for 1 sec */ 26 | #define SHT4x_HIGHHEAT_100MS \ 27 | 0x32 /**< High precision measurement, high heat for 0.1 sec */ 28 | #define SHT4x_MEDHEAT_1S \ 29 | 0x2F /**< High precision measurement, med heat for 1 sec */ 30 | #define SHT4x_MEDHEAT_100MS \ 31 | 0x24 /**< High precision measurement, med heat for 0.1 sec */ 32 | #define SHT4x_LOWHEAT_1S \ 33 | 0x1E /**< High precision measurement, low heat for 1 sec */ 34 | #define SHT4x_LOWHEAT_100MS \ 35 | 0x15 /**< High precision measurement, low heat for 0.1 sec */ 36 | 37 | #define SHT4x_READSERIAL 0x89 /**< Read Out of Serial Register */ 38 | #define SHT4x_SOFTRESET 0x94 /**< Soft Reset */ 39 | 40 | typedef enum { 41 | SHT4X_HIGH_PRECISION, 42 | SHT4X_MED_PRECISION, 43 | SHT4X_LOW_PRECISION, 44 | } sht4x_precision_t; 45 | 46 | /** Optional pre-heater configuration setting */ 47 | typedef enum { 48 | SHT4X_NO_HEATER, 49 | SHT4X_HIGH_HEATER_1S, 50 | SHT4X_HIGH_HEATER_100MS, 51 | SHT4X_MED_HEATER_1S, 52 | SHT4X_MED_HEATER_100MS, 53 | SHT4X_LOW_HEATER_1S, 54 | SHT4X_LOW_HEATER_100MS, 55 | } sht4x_heater_t; 56 | 57 | class SHT4X { 58 | public: 59 | bool begin(TwoWire* wire = &Wire, uint8_t addr = SHT40_I2C_ADDR_44, 60 | uint8_t sda = 21, uint8_t scl = 22, long freq = 400000U); 61 | bool update(void); 62 | 63 | float cTemp = 0; 64 | float humidity = 0; 65 | 66 | void setPrecision(sht4x_precision_t prec); 67 | sht4x_precision_t getPrecision(void); 68 | void setHeater(sht4x_heater_t heat); 69 | sht4x_heater_t getHeater(void); 70 | 71 | private: 72 | TwoWire* _wire; 73 | uint8_t _addr; 74 | I2C_Class _i2c; 75 | 76 | sht4x_precision_t _precision = SHT4X_HIGH_PRECISION; 77 | sht4x_heater_t _heater = SHT4X_NO_HEATER; 78 | }; 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /src/unit/unit_ENV3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /*! 7 | @file unit_ENV3.cpp 8 | @brief ENV III Unit for M5UnitUnified 9 | */ 10 | #include "unit_ENV3.hpp" 11 | #include 12 | 13 | namespace m5 { 14 | namespace unit { 15 | 16 | using namespace m5::utility::mmh3; 17 | using namespace m5::unit::types; 18 | 19 | const char UnitENV3::name[] = "UnitENV3"; 20 | const types::uid_t UnitENV3::uid{"UnitENV3"_mmh3}; 21 | const types::attr_t UnitENV3::attr{attribute::AccessI2C}; 22 | 23 | UnitENV3::UnitENV3(const uint8_t addr) : Component(addr) 24 | { 25 | // Form a parent-child relationship 26 | auto cfg = component_config(); 27 | cfg.max_children = 2; 28 | component_config(cfg); 29 | _valid = add(sht30, 0) && add(qmp6988, 1); 30 | } 31 | 32 | std::shared_ptr UnitENV3::ensure_adapter(const uint8_t ch) 33 | { 34 | if (ch > 2) { 35 | M5_LIB_LOGE("Invalid channel %u", ch); 36 | return std::make_shared(); // Empty adapter 37 | } 38 | auto unit = child(ch); 39 | if (!unit) { 40 | M5_LIB_LOGE("Not exists unit %u", ch); 41 | return std::make_shared(); // Empty adapter 42 | } 43 | auto ad = asAdapter(Adapter::Type::I2C); 44 | return ad ? std::shared_ptr(ad->duplicate(unit->address())) : std::make_shared(); 45 | } 46 | 47 | } // namespace unit 48 | } // namespace m5 49 | -------------------------------------------------------------------------------- /src/unit/unit_ENV3.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /*! 7 | @file unit_ENV3.hpp 8 | @brief ENV III Unit for M5UnitUnified 9 | */ 10 | #ifndef M5_UNIT_ENV_UNIT_ENV3_HPP 11 | #define M5_UNIT_ENV_UNIT_ENV3_HPP 12 | 13 | #include 14 | #include "unit_SHT30.hpp" 15 | #include "unit_QMP6988.hpp" 16 | 17 | namespace m5 { 18 | namespace unit { 19 | 20 | /*! 21 | @class UnitENV3 22 | @brief ENV III is an environmental sensor that integrates SHT30 and QMP6988 23 | @details This unit itself has no I/O, but holds SHT30 and QMP6988 instance 24 | */ 25 | class UnitENV3 : public Component { 26 | // Must not be 0x00 for ensure and assign adapter to children 27 | M5_UNIT_COMPONENT_HPP_BUILDER(UnitENV3, 0xFF /* Dummy address */); 28 | 29 | public: 30 | UnitSHT30 sht30; //!< @brief SHT30 instance 31 | UnitQMP6988 qmp6988; //!< @brief QMP6988 instance 32 | 33 | explicit UnitENV3(const uint8_t addr = DEFAULT_ADDRESS); 34 | virtual ~UnitENV3() 35 | { 36 | } 37 | 38 | virtual bool begin() override 39 | { 40 | return _valid; 41 | } 42 | 43 | protected: 44 | virtual std::shared_ptr ensure_adapter(const uint8_t ch); 45 | 46 | private: 47 | bool _valid{}; // Did the constructor correctly add the child unit? 48 | Component* _children[2]{&sht30, &qmp6988}; 49 | }; 50 | 51 | } // namespace unit 52 | } // namespace m5 53 | #endif 54 | -------------------------------------------------------------------------------- /src/unit/unit_ENV4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /*! 7 | @file unit_ENV4.cpp 8 | @brief ENV 4 Unit for M5UnitUnified 9 | */ 10 | #include "unit_ENV4.hpp" 11 | #include 12 | 13 | namespace m5 { 14 | namespace unit { 15 | 16 | using namespace m5::utility::mmh3; 17 | using namespace m5::unit::types; 18 | 19 | const char UnitENV4::name[] = "UnitENV4"; 20 | const types::uid_t UnitENV4::uid{"UnitENV4"_mmh3}; 21 | const types::attr_t UnitENV4::attr{attribute::AccessI2C}; 22 | 23 | UnitENV4::UnitENV4(const uint8_t addr) : Component(addr) 24 | { 25 | // Form a parent-child relationship 26 | auto cfg = component_config(); 27 | cfg.max_children = 2; 28 | component_config(cfg); 29 | _valid = add(sht40, 0) && add(bmp280, 1); 30 | } 31 | 32 | std::shared_ptr UnitENV4::ensure_adapter(const uint8_t ch) 33 | { 34 | if (ch > 2) { 35 | M5_LIB_LOGE("Invalid channel %u", ch); 36 | return std::make_shared(); // Empty adapter 37 | } 38 | auto unit = child(ch); 39 | if (!unit) { 40 | M5_LIB_LOGE("Not exists unit %u", ch); 41 | return std::make_shared(); // Empty adapter 42 | } 43 | auto ad = asAdapter(Adapter::Type::I2C); 44 | return ad ? std::shared_ptr(ad->duplicate(unit->address())) : std::make_shared(); 45 | } 46 | 47 | } // namespace unit 48 | } // namespace m5 49 | -------------------------------------------------------------------------------- /src/unit/unit_ENV4.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /*! 7 | @file unit_ENV4.hpp 8 | @brief ENV IV Unit for M5UnitUnified 9 | */ 10 | #ifndef M5_UNIT_ENV_UNIT_ENV4_HPP 11 | #define M5_UNIT_ENV_UNIT_ENV4_HPP 12 | 13 | #include 14 | #include 15 | #include "unit_SHT40.hpp" 16 | #include "unit_BMP280.hpp" 17 | 18 | namespace m5 { 19 | namespace unit { 20 | 21 | /*! 22 | @class UnitENV4 23 | @brief ENV IV is an environmental sensor that integrates SHT40 and BMP280 24 | @details This unit itself has no I/O, but holds SHT40 and BMP280 instance 25 | */ 26 | class UnitENV4 : public Component { 27 | // Must not be 0x00 for ensure and assign adapter to children 28 | M5_UNIT_COMPONENT_HPP_BUILDER(UnitENV4, 0xFF /* Dummy address */); 29 | 30 | public: 31 | UnitSHT40 sht40; //!< @brief SHT40 instance 32 | UnitBMP280 bmp280; //!< @brief BMP280 instance 33 | 34 | explicit UnitENV4(const uint8_t addr = DEFAULT_ADDRESS); 35 | virtual ~UnitENV4() 36 | { 37 | } 38 | 39 | virtual bool begin() override 40 | { 41 | return _valid; 42 | } 43 | 44 | protected: 45 | virtual std::shared_ptr ensure_adapter(const uint8_t ch); 46 | 47 | private: 48 | bool _valid{}; // Did the constructor correctly add the child unit? 49 | Component* _children[2]{&sht40, &bmp280}; 50 | }; 51 | 52 | } // namespace unit 53 | } // namespace m5 54 | #endif 55 | -------------------------------------------------------------------------------- /src/unit/unit_SCD41.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /*! 7 | @file unit_SCD41.cpp 8 | @brief SCD41 Unit for M5UnitUnified 9 | */ 10 | #include "unit_SCD41.hpp" 11 | #include 12 | #include 13 | using namespace m5::utility::mmh3; 14 | using namespace m5::unit::types; 15 | using namespace m5::unit::scd4x; 16 | using namespace m5::unit::scd4x::command; 17 | using namespace m5::unit::scd41; 18 | using namespace m5::unit::scd41::command; 19 | 20 | namespace { 21 | // Max command duration(ms) 22 | constexpr uint16_t MEASURE_SINGLE_SHOT_DURATION{5000}; 23 | constexpr uint16_t MEASURE_SINGLE_SHOT_RHT_ONLY_DURATION{50}; 24 | 25 | const uint8_t VARIANT_VALUE[2]{0x14, 0x40}; // SCD41 26 | 27 | } // namespace 28 | 29 | namespace m5 { 30 | namespace unit { 31 | // class UnitSCD41 32 | const char UnitSCD41::name[] = "UnitSCD41"; 33 | const types::uid_t UnitSCD41::uid{"UnitSCD41"_mmh3}; 34 | const types::attr_t UnitSCD41::attr{attribute::AccessI2C}; 35 | 36 | bool UnitSCD41::is_valid_chip() 37 | { 38 | uint8_t var[2]{}; 39 | if (!read_register(GET_SENSOR_VARIANT, var, 2) || memcmp(var, VARIANT_VALUE, 2) != 0) { 40 | M5_LIB_LOGE("Not SCD41 %02X:%02X", var[0], var[1]); 41 | return false; 42 | } 43 | return true; 44 | } 45 | 46 | bool UnitSCD41::measureSingleshot(Data& d) 47 | { 48 | d = Data{}; 49 | 50 | if (inPeriodic()) { 51 | M5_LIB_LOGD("Periodic measurements are running"); 52 | return false; 53 | } 54 | 55 | if (writeRegister(MEASURE_SINGLE_SHOT)) { 56 | m5::utility::delay(MEASURE_SINGLE_SHOT_DURATION); 57 | return read_measurement(d); 58 | } 59 | return false; 60 | } 61 | 62 | bool UnitSCD41::measureSingleshotRHT(Data& d) 63 | { 64 | d = Data{}; 65 | 66 | if (inPeriodic()) { 67 | M5_LIB_LOGD("Periodic measurements are running"); 68 | return false; 69 | } 70 | 71 | if (writeRegister(MEASURE_SINGLE_SHOT_RHT_ONLY)) { 72 | m5::utility::delay(MEASURE_SINGLE_SHOT_RHT_ONLY_DURATION); 73 | return read_measurement(d, false); 74 | } 75 | return false; 76 | } 77 | 78 | bool UnitSCD41::powerDown(const uint32_t duration) 79 | { 80 | if (inPeriodic()) { 81 | M5_LIB_LOGD("Periodic measurements are running"); 82 | return false; 83 | } 84 | if (writeRegister(POWER_DOWN, nullptr, 0)) { 85 | m5::utility::delay(duration); 86 | return true; 87 | } 88 | return false; 89 | } 90 | 91 | bool UnitSCD41::wakeup() 92 | { 93 | constexpr uint32_t WAKE_UP_DURATION{30 + 5}; 94 | 95 | if (inPeriodic()) { 96 | M5_LIB_LOGD("Periodic measurements are running"); 97 | return false; 98 | } 99 | // Note that the SCD4x does not acknowledge the wake_up command 100 | writeRegister(WAKE_UP, nullptr, 0); 101 | m5::utility::delay(WAKE_UP_DURATION); 102 | 103 | // The sensor’s idle state after wake up can be verified by reading out the serial numbe 104 | auto timeout_at = m5::utility::millis() + 1000; 105 | do { 106 | uint64_t sn{}; 107 | if (readSerialNumber(sn)) { 108 | return true; 109 | } 110 | m5::utility::delay(10); 111 | } while (m5::utility::millis() <= timeout_at); 112 | return false; 113 | } 114 | 115 | bool UnitSCD41::writeAutomaticSelfCalibrationInitialPeriod(const uint16_t hours, const uint32_t duration) 116 | { 117 | if (inPeriodic()) { 118 | M5_LIB_LOGD("Periodic measurements are running"); 119 | return false; 120 | } 121 | if (hours % 4) { 122 | M5_LIB_LOGW("Arguments are modified to multiples of 4"); 123 | } 124 | uint16_t h = (hours >> 2) << 2; 125 | m5::types::big_uint16_t u16{h}; 126 | return write_register(SET_AUTOMATIC_SELF_CALIBRATION_INITIAL_PERIOD, u16.data(), u16.size()) && 127 | delay_true(duration); 128 | } 129 | 130 | bool UnitSCD41::readAutomaticSelfCalibrationInitialPeriod(uint16_t& hours) 131 | { 132 | hours = 0; 133 | if (inPeriodic()) { 134 | M5_LIB_LOGD("Periodic measurements are running"); 135 | return false; 136 | } 137 | m5::types::big_uint16_t u16{}; 138 | if (read_register(GET_AUTOMATIC_SELF_CALIBRATION_INITIAL_PERIOD, u16.data(), u16.size(), 139 | GET_AUTOMATIC_SELF_CALIBRATION_INITIAL_PERIOD_DURATION)) { 140 | hours = u16.get(); 141 | return true; 142 | } 143 | return false; 144 | } 145 | 146 | bool UnitSCD41::writeAutomaticSelfCalibrationStandardPeriod(const uint16_t hours, const uint32_t duration) 147 | { 148 | if (inPeriodic()) { 149 | M5_LIB_LOGD("Periodic measurements are running"); 150 | return false; 151 | } 152 | if (hours % 4) { 153 | M5_LIB_LOGW("Arguments are modified to multiples of 4"); 154 | } 155 | uint16_t h = (hours >> 2) << 2; 156 | m5::types::big_uint16_t u16{h}; 157 | return write_register(SET_AUTOMATIC_SELF_CALIBRATION_STANDARD_PERIOD, u16.data(), u16.size()) && 158 | delay_true(duration); 159 | } 160 | 161 | bool UnitSCD41::readAutomaticSelfCalibrationStandardPeriod(uint16_t& hours) 162 | { 163 | hours = 0; 164 | if (inPeriodic()) { 165 | M5_LIB_LOGD("Periodic measurements are running"); 166 | return false; 167 | } 168 | m5::types::big_uint16_t u16{}; 169 | if (read_register(GET_AUTOMATIC_SELF_CALIBRATION_STANDARD_PERIOD, u16.data(), u16.size(), 170 | GET_AUTOMATIC_SELF_CALIBRATION_STANDARD_PERIOD_DURATION)) { 171 | hours = u16.get(); 172 | return true; 173 | } 174 | return false; 175 | } 176 | 177 | } // namespace unit 178 | } // namespace m5 179 | -------------------------------------------------------------------------------- /src/unit/unit_SCD41.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /*! 7 | @file unit_SCD41.hpp 8 | @brief SCD41 Unit for M5UnitUnified 9 | */ 10 | #ifndef M5_UNIT_ENV_UNIT_SCD41_HPP 11 | #define M5_UNIT_ENV_UNIT_SCD41_HPP 12 | 13 | #include "unit_SCD40.hpp" 14 | 15 | namespace m5 { 16 | namespace unit { 17 | /*! 18 | @namespace scd41 19 | @brief For SCD41 20 | */ 21 | namespace scd41 { 22 | ///@cond 23 | // Max command duration(ms) 24 | // For SCD40/41 25 | constexpr uint32_t POWER_DOWN_DURATION{1}; 26 | constexpr uint32_t GET_AUTOMATIC_SELF_CALIBRATION_INITIAL_PERIOD_DURATION{1}; 27 | constexpr uint32_t SET_AUTOMATIC_SELF_CALIBRATION_INITIAL_PERIOD_DURATION{1}; 28 | constexpr uint32_t GET_AUTOMATIC_SELF_CALIBRATION_STANDARD_PERIOD_DURATION{1}; 29 | constexpr uint32_t SET_AUTOMATIC_SELF_CALIBRATION_STANDARD_PERIOD_DURATION{1}; 30 | 31 | ///@endcond 32 | } // namespace scd41 33 | 34 | /*! 35 | @class m5::unit::UnitSCD41 36 | @brief SCD41 unit component 37 | */ 38 | class UnitSCD41 : public UnitSCD40 { 39 | M5_UNIT_COMPONENT_HPP_BUILDER(UnitSCD41, 0x62); 40 | 41 | public: 42 | explicit UnitSCD41(const uint8_t addr = DEFAULT_ADDRESS) : UnitSCD40(addr) 43 | { 44 | auto ccfg = component_config(); 45 | ccfg.clock = 400 * 1000U; 46 | component_config(ccfg); 47 | } 48 | virtual ~UnitSCD41() 49 | { 50 | } 51 | 52 | ///@name Single Shot Measurement Mode 53 | ///@{ 54 | /*! 55 | @brief Request a single measurement 56 | @param[out] d Measurement data 57 | @return True if successful 58 | @note Blocked until measurement results are acquired (5000 ms) 59 | @warning During periodic detection runs, an error is returned 60 | */ 61 | bool measureSingleshot(scd4x::Data& d); 62 | /*! 63 | @brief Request a single measurement temperature and humidity 64 | @param[out] d Measurement data 65 | @return True if successful 66 | @note Values are updated at 50 ms interval 67 | @note Blocked until measurement results are acquired (50 ms) 68 | @warning Information on CO2 is invalid. 69 | @warning During periodic detection runs, an error is returned 70 | */ 71 | bool measureSingleshotRHT(scd4x::Data& d); 72 | ///@} 73 | 74 | ///@name Power mode 75 | ///@{ 76 | /*! 77 | @brief Power down 78 | @details The sensor into sleep mode 79 | @param duration Max command duration(ms) 80 | @return True if successful 81 | @warning During periodic detection runs, an error is returned 82 | */ 83 | bool powerDown(const uint32_t duration = scd41::POWER_DOWN_DURATION); 84 | /*! 85 | @brief Wake up 86 | @details The sensor from sleep mode into idle mode 87 | @param duration Max command duration(ms) 88 | @return True if successful 89 | @warning During periodic detection runs, an error is returned 90 | */ 91 | bool wakeup(); 92 | ///@} 93 | 94 | ///@name For ASC(Auto Self-Calibration) 95 | ///@{ 96 | /*! 97 | @brief Write the duration of the initial period for ASC correction 98 | @param hours ASC initial period 99 | @param duration Max command duration(ms) 100 | @return True if successful 101 | @warning During periodic detection runs, an error is returned 102 | @warning Allowed values are integer multiples of 4 hours 103 | */ 104 | bool writeAutomaticSelfCalibrationInitialPeriod( 105 | const uint16_t hours, const uint32_t duration = scd41::SET_AUTOMATIC_SELF_CALIBRATION_INITIAL_PERIOD_DURATION); 106 | /*! 107 | @brief Read the duration of the initial period for ASC correction 108 | @param[out] hours ASC initial period 109 | @param duration Max command duration(ms) 110 | @return True if successful 111 | @warning During periodic detection runs, an error is returned 112 | */ 113 | bool readAutomaticSelfCalibrationInitialPeriod(uint16_t& hours); 114 | /*! 115 | @brief Write the standard period for ASC correction 116 | @param hours ASC standard period 117 | @param duration Max command duration(ms) 118 | @return True if successful 119 | @warning During periodic detection runs, an error is returned 120 | @warning Allowed values are integer multiples of 4 hours 121 | */ 122 | bool writeAutomaticSelfCalibrationStandardPeriod( 123 | const uint16_t hours, const uint32_t duration = scd41::SET_AUTOMATIC_SELF_CALIBRATION_STANDARD_PERIOD_DURATION); 124 | /*! 125 | @brief Red the standard period for ASC correction 126 | @param[iut] hours ASC standard period 127 | @return True if successful 128 | @warning During periodic detection runs, an error is returned 129 | @warning Allowed values are integer multiples of 4 hours 130 | */ 131 | bool readAutomaticSelfCalibrationStandardPeriod(uint16_t& hours); 132 | ///@} 133 | 134 | protected: 135 | virtual bool is_valid_chip() override; 136 | }; 137 | 138 | namespace scd41 { 139 | ///@cond 140 | namespace command { 141 | // Low power single shot - SCD41 only 142 | constexpr uint16_t MEASURE_SINGLE_SHOT{0x219d}; 143 | constexpr uint16_t MEASURE_SINGLE_SHOT_RHT_ONLY{0x2196}; 144 | constexpr uint16_t POWER_DOWN{0x36e0}; 145 | constexpr uint16_t WAKE_UP{0x36f6}; 146 | constexpr uint16_t SET_AUTOMATIC_SELF_CALIBRATION_INITIAL_PERIOD{0x2445}; 147 | constexpr uint16_t GET_AUTOMATIC_SELF_CALIBRATION_INITIAL_PERIOD{0x2340}; 148 | constexpr uint16_t SET_AUTOMATIC_SELF_CALIBRATION_STANDARD_PERIOD{0x244e}; 149 | constexpr uint16_t GET_AUTOMATIC_SELF_CALIBRATION_STANDARD_PERIOD{0x234b}; 150 | 151 | } // namespace command 152 | ///@endcond 153 | } // namespace scd41 154 | 155 | } // namespace unit 156 | } // namespace m5 157 | #endif 158 | -------------------------------------------------------------------------------- /src/utility.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "utility.h" 3 | 4 | uint8_t crc8(const uint8_t *data, int len) { 5 | /* 6 | * 7 | * CRC-8 formula from page 14 of SHT spec pdf 8 | * 9 | * Test data 0xBE, 0xEF should yield 0x92 10 | * 11 | * Initialization data 0xFF 12 | * Polynomial 0x31 (x8 + x5 +x4 +1) 13 | * Final XOR 0x00 14 | */ 15 | 16 | const uint8_t POLYNOMIAL(0x31); 17 | uint8_t crc(0xFF); 18 | 19 | for (int j = len; j; --j) { 20 | crc ^= *data++; 21 | 22 | for (int i = 8; i; --i) { 23 | crc = (crc & 0x80) ? (crc << 1) ^ POLYNOMIAL : (crc << 1); 24 | } 25 | } 26 | return crc; 27 | } 28 | -------------------------------------------------------------------------------- /src/utility.h: -------------------------------------------------------------------------------- 1 | #ifndef __M5_UNIT_ENV_UTILITY_H_ 2 | #define __M5_UNIT_ENV_UTILITY_H_ 3 | 4 | #include "Arduino.h" 5 | 6 | uint8_t crc8(const uint8_t *data, int len); 7 | 8 | #endif -------------------------------------------------------------------------------- /test/common_main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | main for UnitTest on native 8 | */ 9 | #include 10 | 11 | // C++ version 12 | #if __cplusplus >= 202002L 13 | #pragma message "C++20 or later" 14 | #elif __cplusplus >= 201703L 15 | #pragma message "C++17 or later" 16 | #elif __cplusplus >= 201402L 17 | #pragma message "C++14 or later" 18 | #elif __cplusplus >= 201103L 19 | #pragma message "C++11 or later" 20 | #else 21 | #error "Need C++11 or later" 22 | #endif 23 | // Compiler 24 | #if defined(__clang__) 25 | #pragma message "Clang" 26 | #elif defined(_MSC_VER) 27 | #pragma message "MSVC" 28 | #elif defined(__BORLANDC__) 29 | #pragma message "BORLANDC" 30 | #elif defined(__MINGW32__) || defined(__MINGW64__) 31 | #pragma message "MINGW" 32 | #elif defined(__INTEL_COMPILER) 33 | #pragma message "ICC" 34 | #elif defined(__GNUG__) 35 | #pragma message "GCC" 36 | #else 37 | #pragma message "Unknown compiler" 38 | #endif 39 | 40 | /* 41 | For native test, this main() is used. 42 | If the Arduino framework is used, the framework library main is used. 43 | */ 44 | #if !defined(ARDUINO) 45 | int main(int argc, char **argv) 46 | { 47 | testing::InitGoogleTest(&argc, argv); 48 | 49 | #ifdef GTEST_FILTER 50 | ::testing::GTEST_FLAG(filter) = GTEST_FILTER; 51 | #endif 52 | 53 | #pragma GCC diagnostic push 54 | #pragma GCC diagnostic ignored "-Wunused-result" 55 | RUN_ALL_TESTS(); 56 | #pragma GCC diagnostic pop 57 | // Always return zero-code and allow PlatformIO to parse results 58 | return 0; 59 | } 60 | #endif 61 | -------------------------------------------------------------------------------- /test/embedded/embedded_main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | main for UnitTest on embedded 8 | */ 9 | #include 10 | #include 11 | #include 12 | 13 | #pragma message "Embedded setup/loop" 14 | 15 | #if __has_include() 16 | #include 17 | #else // esp_idf_version.h has been introduced in Arduino 1.0.5 (ESP-IDF3.3) 18 | #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) 19 | #define ESP_IDF_VERSION ESP_IDF_VERSION_VAL(3, 2, 0) 20 | #endif 21 | 22 | namespace { 23 | auto& lcd = M5.Display; 24 | } // namespace 25 | 26 | void test() 27 | { 28 | lcd.fillRect(0, 0, lcd.width() >> 1, lcd.height(), RUN_ALL_TESTS() ? TFT_RED : TFT_GREEN); 29 | } 30 | 31 | void setup() 32 | { 33 | delay(1500); 34 | 35 | M5.begin(); 36 | 37 | M5_LOGI("CPP %ld", __cplusplus); 38 | M5_LOGI("ESP-IDF Version %d.%d.%d", (ESP_IDF_VERSION >> 16) & 0xFF, (ESP_IDF_VERSION >> 8) & 0xFF, 39 | ESP_IDF_VERSION & 0xFF); 40 | M5_LOGI("BOARD:%X", M5.getBoard()); 41 | M5_LOGI("Heap: %u", esp_get_free_heap_size()); 42 | 43 | lcd.clear(TFT_DARKGRAY); 44 | ::testing::InitGoogleTest(); 45 | 46 | #ifdef GTEST_FILTER 47 | ::testing::GTEST_FLAG(filter) = GTEST_FILTER; 48 | #endif 49 | } 50 | 51 | void loop() 52 | { 53 | test(); 54 | #if 0 55 | delay(1000); 56 | esp_restart(); 57 | #endif 58 | while (true) { 59 | delay(10000); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /test/embedded/test_scd40/scd40_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | UnitTest for UnitSCD40 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | using namespace m5::unit::googletest; 20 | using namespace m5::unit; 21 | using namespace m5::unit::scd4x; 22 | using m5::unit::types::elapsed_time_t; 23 | 24 | const ::testing::Environment* global_fixture = ::testing::AddGlobalTestEnvironment(new GlobalFixture<400000U>()); 25 | 26 | constexpr uint32_t STORED_SIZE{4}; 27 | 28 | class TestSCD4x : public ComponentTestBase { 29 | protected: 30 | virtual UnitSCD40* get_instance() override 31 | { 32 | auto ptr = new m5::unit::UnitSCD40(); 33 | auto ccfg = ptr->component_config(); 34 | ccfg.stored_size = STORED_SIZE; 35 | ptr->component_config(ccfg); 36 | auto cfg = ptr->config(); 37 | cfg.start_periodic = false; 38 | ptr->config(cfg); 39 | return ptr; 40 | } 41 | virtual bool is_using_hal() const override 42 | { 43 | return GetParam(); 44 | }; 45 | }; 46 | 47 | // INSTANTIATE_TEST_SUITE_P(ParamValues, TestSCD4x, ::testing::Values(false, true)); 48 | // INSTANTIATE_TEST_SUITE_P(ParamValues, TestSCD4x, ::testing::Values(true)); 49 | INSTANTIATE_TEST_SUITE_P(ParamValues, TestSCD4x, ::testing::Values(false)); 50 | 51 | namespace { 52 | } // namespace 53 | 54 | #include "../scd4x_test.inl" 55 | -------------------------------------------------------------------------------- /test/embedded/test_scd41/scd41_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | /* 7 | UnitTest for UnitSCD41 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace m5::unit::googletest; 19 | using namespace m5::unit; 20 | using namespace m5::unit::scd4x; 21 | using m5::unit::types::elapsed_time_t; 22 | 23 | const ::testing::Environment* global_fixture = ::testing::AddGlobalTestEnvironment(new GlobalFixture<400000U>()); 24 | 25 | constexpr uint32_t STORED_SIZE{4}; 26 | 27 | class TestSCD4x : public ComponentTestBase { 28 | protected: 29 | virtual UnitSCD41* get_instance() override 30 | { 31 | auto ptr = new m5::unit::UnitSCD41(); 32 | auto ccfg = ptr->component_config(); 33 | ccfg.stored_size = STORED_SIZE; 34 | ptr->component_config(ccfg); 35 | auto cfg = ptr->config(); 36 | cfg.start_periodic = false; 37 | ptr->config(cfg); 38 | return ptr; 39 | } 40 | virtual bool is_using_hal() const override 41 | { 42 | return GetParam(); 43 | }; 44 | }; 45 | 46 | // INSTANTIATE_TEST_SUITE_P(ParamValues, TestSCD4x, ::testing::Values(false, true)); 47 | // INSTANTIATE_TEST_SUITE_P(ParamValues, TestSCD4x, ::testing::Values(true)); 48 | INSTANTIATE_TEST_SUITE_P(ParamValues, TestSCD4x, ::testing::Values(false)); 49 | 50 | namespace { 51 | } // namespace 52 | 53 | #include "../scd4x_test.inl" 54 | 55 | TEST_P(TestSCD4x, Singleshot) 56 | { 57 | SCOPED_TRACE(ustr); 58 | { 59 | Data d{}; 60 | EXPECT_FALSE(unit->inPeriodic()); 61 | EXPECT_TRUE(unit->measureSingleshot(d)); 62 | EXPECT_NE(d.co2(), 0); 63 | EXPECT_TRUE(std::isfinite(d.temperature())); 64 | EXPECT_TRUE(std::isfinite(d.humidity())); 65 | 66 | EXPECT_TRUE(unit->startPeriodicMeasurement()); 67 | 68 | EXPECT_TRUE(unit->inPeriodic()); 69 | EXPECT_FALSE(unit->measureSingleshot(d)); 70 | EXPECT_EQ(d.co2(), 0); 71 | EXPECT_FLOAT_EQ(d.temperature(), -45.f); 72 | EXPECT_FLOAT_EQ(d.humidity(), 0.0f); 73 | 74 | EXPECT_TRUE(unit->stopPeriodicMeasurement()); 75 | } 76 | { 77 | Data d{}; 78 | EXPECT_FALSE(unit->inPeriodic()); 79 | EXPECT_TRUE(unit->measureSingleshotRHT(d)); 80 | EXPECT_EQ(d.co2(), 0); 81 | EXPECT_TRUE(std::isfinite(d.temperature())); 82 | EXPECT_TRUE(std::isfinite(d.humidity())); 83 | 84 | EXPECT_TRUE(unit->startPeriodicMeasurement()); 85 | 86 | EXPECT_TRUE(unit->inPeriodic()); 87 | EXPECT_FALSE(unit->measureSingleshotRHT(d)); 88 | EXPECT_EQ(d.co2(), 0); 89 | EXPECT_FLOAT_EQ(d.temperature(), -45.f); 90 | EXPECT_FLOAT_EQ(d.humidity(), 0.0f); 91 | 92 | EXPECT_TRUE(unit->stopPeriodicMeasurement()); 93 | } 94 | } 95 | 96 | TEST_P(TestSCD4x, PowerMode) 97 | { 98 | SCOPED_TRACE(ustr); 99 | 100 | EXPECT_FALSE(unit->inPeriodic()); 101 | 102 | uint32_t count{8}; 103 | while (count--) { 104 | EXPECT_TRUE(unit->powerDown()) << count; 105 | EXPECT_TRUE(unit->wakeup()) << count; 106 | } 107 | 108 | EXPECT_TRUE(unit->startPeriodicMeasurement()); 109 | EXPECT_TRUE(unit->inPeriodic()); 110 | 111 | EXPECT_FALSE(unit->powerDown()); 112 | EXPECT_FALSE(unit->wakeup()); 113 | 114 | EXPECT_TRUE(unit->stopPeriodicMeasurement()); 115 | EXPECT_TRUE(unit->reInit()); 116 | } 117 | 118 | TEST_P(TestSCD4x, ASC) 119 | { 120 | SCOPED_TRACE(ustr); 121 | 122 | constexpr uint16_t hours_table[] = {0, 32768, 65535}; 123 | for (auto&& h : hours_table) { 124 | EXPECT_TRUE(unit->writeAutomaticSelfCalibrationInitialPeriod(h)); 125 | EXPECT_TRUE(unit->writeAutomaticSelfCalibrationStandardPeriod(h)); 126 | 127 | uint16_t ih{}, sh{}; 128 | 129 | EXPECT_TRUE(unit->readAutomaticSelfCalibrationInitialPeriod(ih)); 130 | EXPECT_TRUE(unit->readAutomaticSelfCalibrationStandardPeriod(sh)); 131 | 132 | EXPECT_EQ(ih, (h >> 2) << 2); 133 | EXPECT_EQ(sh, (h >> 2) << 2); 134 | } 135 | 136 | EXPECT_TRUE(unit->startPeriodicMeasurement()); 137 | EXPECT_TRUE(unit->inPeriodic()); 138 | for (auto&& h : hours_table) { 139 | EXPECT_FALSE(unit->writeAutomaticSelfCalibrationInitialPeriod(h)); 140 | EXPECT_FALSE(unit->writeAutomaticSelfCalibrationStandardPeriod(h)); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /test/native/test_dummy/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m5stack/M5Unit-ENV/84dba239ba1c7c6fa4badd2d0dfc514624c6a689/test/native/test_dummy/.keep --------------------------------------------------------------------------------