mirror of
https://github.com/m5stack/M5Unit-HEART.git
synced 2026-05-20 11:28:19 -07:00
Merge branch 'develop'
This commit is contained in:
@@ -1,118 +0,0 @@
|
||||
name: ArduinoBuild(platform-version 2.x)
|
||||
|
||||
env:
|
||||
SKETCH_NAMES_FIND_START: ./examples/UnitUnified
|
||||
REQUIRED_LIBRARIES: M5Unified
|
||||
# M5UNITUNIFIED_BRANCH: main
|
||||
M5UNITUNIFIED_BRANCH: develop
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**.ino'
|
||||
- '**.cpp'
|
||||
- '**.hpp'
|
||||
- '**.h'
|
||||
- '**.c'
|
||||
- '**ArduinoBuild_2.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.ino'
|
||||
- '**.cpp'
|
||||
- '**.hpp'
|
||||
- '**.h'
|
||||
- '**.c'
|
||||
- '**ArduinoBuild_2.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.sketch }}:${{matrix.board}}@${{matrix.platform-version}}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
#max-parallel: 1
|
||||
matrix:
|
||||
platform-url:
|
||||
- https://espressif.github.io/arduino-esp32/package_esp32_index.json
|
||||
|
||||
sketch:
|
||||
- PlotToSerial
|
||||
|
||||
board:
|
||||
- m5stack-core-esp32
|
||||
- m5stack-core2
|
||||
- m5stack-atoms3
|
||||
- m5stack-cores3
|
||||
|
||||
platform-version:
|
||||
#- 2.0.15
|
||||
#- 2.0.16
|
||||
- 2.0.17
|
||||
|
||||
platform:
|
||||
- esp32
|
||||
|
||||
archi:
|
||||
- esp32
|
||||
|
||||
steps:
|
||||
|
||||
- name: Running on GitHub Actions
|
||||
if: env.ACT != 'true'
|
||||
run: echo "This is running on GitHub Actions."
|
||||
|
||||
- name: Running locally with act
|
||||
if: env.ACT == 'true'
|
||||
run: echo "This is running locally with act."
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
# Checkout library from specific URL and branch
|
||||
# Note that dependent libraries are not automatically installed.
|
||||
|
||||
# - name: Configure git for authentication (Until each repository is published)
|
||||
# run: |
|
||||
# git config --global url."https://${{ secrets.TOKEN_M5UNITUNIFIED }}@github.com/".insteadOf "https://github.com/"
|
||||
|
||||
- name: Checkout M5Utility
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: m5stack/M5Utility
|
||||
ref: ${{ env.M5UNITUNIFIED_BRANCH }}
|
||||
path: CustomLibrary_M5Utility # must contain string "Custom"
|
||||
token: ${{ secrets.TOKEN_M5UNITUNIFIED }} # Only required during development in private repo
|
||||
|
||||
- name: Checkout M5HAL
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: m5stack/M5HAL
|
||||
ref: ${{ env.M5UNITUNIFIED_BRANCH }}
|
||||
path: CustomLibrary_M5HAL # must contain string "Custom"
|
||||
token: ${{ secrets.TOKEN_M5UNITUNIFIED }} # Only required during development in private repo
|
||||
|
||||
- name: Checkout M5UnitUnified
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: m5stack/M5UnitUnified
|
||||
ref: ${{ env.M5UNITUNIFIED_BRANCH }}
|
||||
path: CustomLibrary_M5UnitUnified
|
||||
token: ${{ secrets.TOKEN_M5UNITUNIFIED }} # Only required during development in private repo
|
||||
|
||||
# Build
|
||||
- name: Compile examples
|
||||
uses: ArminJo/arduino-test-compile@master
|
||||
with:
|
||||
arduino-board-fqbn: ${{ matrix.platform }}:${{ matrix.archi }}:${{ matrix.board }}
|
||||
arduino-platform: ${{ matrix.platform }}:${{ matrix.archi }}@${{ matrix.platform-version }}
|
||||
platform-url: ${{ matrix.platform-url }}
|
||||
required-libraries: ${{ env.REQUIRED_LIBRARIES }}
|
||||
extra-arduino-cli-args: ${{ matrix.cli-args }}
|
||||
#build-properties: ${{ toJson(matrix.build-properties) }}
|
||||
sketch-names: ${{ matrix.sketch }}.ino
|
||||
sketch-names-find-start: ${{ env.SKETCH_NAMES_FIND_START }}
|
||||
#sketches-exclude: ${{ matrix.sketches-exclude }}
|
||||
@@ -1,124 +0,0 @@
|
||||
name: ArduinoBuild(platform-version 3.x)
|
||||
|
||||
env:
|
||||
SKETCH_NAMES_FIND_START: ./examples/UnitUnified
|
||||
REQUIRED_LIBRARIES: M5Unified
|
||||
# M5UNITUNIFIED_BRANCH: main
|
||||
M5UNITUNIFIED_BRANCH: develop
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**.ino'
|
||||
- '**.cpp'
|
||||
- '**.hpp'
|
||||
- '**.h'
|
||||
- '**.c'
|
||||
- '**ArduinoBuild_3.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.ino'
|
||||
- '**.cpp'
|
||||
- '**.hpp'
|
||||
- '**.h'
|
||||
- '**.c'
|
||||
- '**ArduinoBuild_3.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.sketch }}:${{matrix.board}}@${{matrix.platform-version}}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
#max-parallel: 1
|
||||
matrix:
|
||||
platform-url:
|
||||
- https://espressif.github.io/arduino-esp32/package_esp32_index.json
|
||||
|
||||
sketch:
|
||||
- PlotToSerial
|
||||
|
||||
board:
|
||||
- m5stack_core
|
||||
- m5stack_core2
|
||||
- m5stack_atoms3
|
||||
- m5stack_cores3
|
||||
- m5stack_dial
|
||||
- m5stack_nanoc6
|
||||
- m5stack_paper
|
||||
- m5stack_stickc_plus
|
||||
|
||||
platform-version:
|
||||
#- 3.0.0
|
||||
#- 3.0.1
|
||||
#- 3.0.2
|
||||
#- 3.0.3
|
||||
- 3.0.4
|
||||
|
||||
platform:
|
||||
- esp32
|
||||
|
||||
archi:
|
||||
- esp32
|
||||
|
||||
steps:
|
||||
|
||||
- name: Running on GitHub Actions
|
||||
if: env.ACT != 'true'
|
||||
run: echo "This is running on GitHub Actions."
|
||||
|
||||
- name: Running locally with act
|
||||
if: env.ACT == 'true'
|
||||
run: echo "This is running locally with act."
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
# Checkout library from specific URL and branch
|
||||
# Note that dependent libraries are not automatically installed.
|
||||
|
||||
# - name: Configure git for authentication (Until each repository is published)
|
||||
# run: |
|
||||
# git config --global url."https://${{ secrets.TOKEN_M5UNITUNIFIED }}@github.com/".insteadOf "https://github.com/"
|
||||
|
||||
- name: Checkout M5Utility
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: m5stack/M5Utility
|
||||
ref: ${{ env.M5UNITUNIFIED_BRANCH }}
|
||||
path: CustomLibrary_M5Utility # must contain string "Custom"
|
||||
token: ${{ secrets.TOKEN_M5UNITUNIFIED }} # Only required during development in private repo
|
||||
|
||||
- name: Checkout M5HAL
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: m5stack/M5HAL
|
||||
ref: ${{ env.M5UNITUNIFIED_BRANCH }}
|
||||
path: CustomLibrary_M5HAL # must contain string "Custom"
|
||||
token: ${{ secrets.TOKEN_M5UNITUNIFIED }} # Only required during development in private repo
|
||||
|
||||
- name: Checkout M5UnitUnified
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: m5stack/M5UnitUnified
|
||||
ref: ${{ env.M5UNITUNIFIED_BRANCH }}
|
||||
path: CustomLibrary_M5UnitUnified
|
||||
token: ${{ secrets.TOKEN_M5UNITUNIFIED }} # Only required during development in private repo
|
||||
|
||||
# Build
|
||||
- name: Compile examples
|
||||
uses: ArminJo/arduino-test-compile@master
|
||||
with:
|
||||
arduino-board-fqbn: ${{ matrix.platform }}:${{ matrix.archi }}:${{ matrix.board }}
|
||||
arduino-platform: ${{ matrix.platform }}:${{ matrix.archi }}@${{ matrix.platform-version }}
|
||||
platform-url: ${{ matrix.platform-url }}
|
||||
required-libraries: ${{ env.REQUIRED_LIBRARIES }}
|
||||
extra-arduino-cli-args: ${{ matrix.cli-args }}
|
||||
#build-properties: ${{ toJson(matrix.build-properties) }}
|
||||
sketch-names: ${{ matrix.sketch }}.ino
|
||||
sketch-names-find-start: ${{ env.SKETCH_NAMES_FIND_START }}
|
||||
#sketches-exclude: ${{ matrix.sketches-exclude }}
|
||||
@@ -1,108 +0,0 @@
|
||||
name: PlatformIOBuild
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**.ino'
|
||||
- '**.cpp'
|
||||
- '**.hpp'
|
||||
- '**.h'
|
||||
- '**.c'
|
||||
- '**PlatformioBuild.yml'
|
||||
- '**platformio.ini'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.ino'
|
||||
- '**.cpp'
|
||||
- '**.hpp'
|
||||
- '**.h'
|
||||
- '**.c'
|
||||
- '**PlatformioBuild.yml'
|
||||
- '**platformio.ini'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.example }}@${{ matrix.board }}:${{ matrix.framework }}:${{ matrix.espressif32 }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
#max-parallel: 1
|
||||
|
||||
matrix:
|
||||
example:
|
||||
- PlotToSerial
|
||||
|
||||
board:
|
||||
- Core
|
||||
- Core2
|
||||
- CoreS3
|
||||
- StampS3
|
||||
- AtomS3
|
||||
- Dial
|
||||
- NanoC6
|
||||
- StickCPlus
|
||||
- Paper
|
||||
- Fire
|
||||
|
||||
framework:
|
||||
- Arduino
|
||||
|
||||
espressif32:
|
||||
- latest
|
||||
- '5_4_0'
|
||||
- '4_4_0'
|
||||
|
||||
exclude:
|
||||
- board: CoreS3
|
||||
espressif32: '5_4_0'
|
||||
- board: CoreS3
|
||||
espressif32: '4_4_0'
|
||||
- board: StampS3
|
||||
espressif32: '5_4_0'
|
||||
- board: StampS3
|
||||
espressif32: '4_4_0'
|
||||
- board: AtomS3
|
||||
espressif32: '5_4_0'
|
||||
- board: AtomS3
|
||||
espressif32: '4_4_0'
|
||||
- board: Dial
|
||||
espressif32: '5_4_0'
|
||||
- board: Dial
|
||||
espressif32: '4_4_0'
|
||||
- board: NanoC6
|
||||
espressif32: '5_4_0'
|
||||
- board: NanoC6
|
||||
espressif32: '4_4_0'
|
||||
- board: StickCPlus
|
||||
espressif32: '5_4_0'
|
||||
- board: StickCPlus
|
||||
espressif32: '4_4_0'
|
||||
- board: Paper
|
||||
espressif32: '5_4_0'
|
||||
- board: Paper
|
||||
espressif32: '4_4_0'
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Configure git for authentication (Until each repository is published)
|
||||
run: |
|
||||
git config --global url."https://${{ secrets.TOKEN_M5UNITUNIFIED }}@github.com/".insteadOf "https://github.com/"
|
||||
|
||||
- name: Build examples
|
||||
uses: karniv00l/platformio-run-action@v1
|
||||
with:
|
||||
environments: ${{ matrix.example }}_${{ matrix.board }}_${{ matrix.framework }}_${{ matrix.espressif32 }}
|
||||
#targets:
|
||||
project-dir: "./"
|
||||
project-conf: "./platformio.ini"
|
||||
#jobs: 6
|
||||
#silent: false
|
||||
#verbose: truee
|
||||
#disable-auto-clean: false
|
||||
@@ -0,0 +1,101 @@
|
||||
name: Build(arduino-esp32:2.x)
|
||||
|
||||
env:
|
||||
SKETCH_NAMES_FIND_START: ./examples/UnitUnified
|
||||
REQUIRED_LIBRARIES: M5Unified,M5UnitUnified
|
||||
|
||||
on:
|
||||
push:
|
||||
tags-ignore:
|
||||
- '*.*.*'
|
||||
- 'v*.*.*'
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- 'src/unit/**.cpp'
|
||||
- 'src/unit/**.hpp'
|
||||
- 'src/unit/**.h'
|
||||
- 'src/unit/**.c'
|
||||
- 'test/**.cpp'
|
||||
- 'test/**.hpp'
|
||||
- 'test/**.h'
|
||||
- 'test/**.c'
|
||||
- 'examples/UnitUnified/**.ino'
|
||||
- 'examples/UnitUnified/**.cpp'
|
||||
- 'examples/UnitUnified/**.hpp'
|
||||
- 'examples/UnitUnified/**.h'
|
||||
- 'examples/UnitUnified/**.c'
|
||||
- '**arduino-esp-v2-build-check.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/unit/**.cpp'
|
||||
- 'src/unit/**.hpp'
|
||||
- 'src/unit/**.h'
|
||||
- 'src/unit/**.c'
|
||||
- 'test/**.cpp'
|
||||
- 'test/**.hpp'
|
||||
- 'test/**.h'
|
||||
- 'test/**.c'
|
||||
- 'examples/UnitUnified/**.ino'
|
||||
- 'examples/UnitUnified/**.cpp'
|
||||
- 'examples/UnitUnified/**.hpp'
|
||||
- 'examples/UnitUnified/**.h'
|
||||
- 'examples/UnitUnified/**.c'
|
||||
- '**arduino-esp-v2-build-check.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.unit }}:${{ matrix.sketch }}:${{matrix.board}}@${{matrix.platform-version}}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
#max-parallel: 1
|
||||
matrix:
|
||||
platform-url:
|
||||
- https://espressif.github.io/arduino-esp32/package_esp32_index.json
|
||||
|
||||
sketch:
|
||||
- PlotToSerial
|
||||
|
||||
unit:
|
||||
- ''
|
||||
|
||||
board:
|
||||
- m5stack-atom
|
||||
- m5stack-atoms3
|
||||
- m5stack-core-esp32
|
||||
- m5stack-core2
|
||||
- m5stack-coreink
|
||||
- m5stack-cores3
|
||||
- m5stack-fire
|
||||
|
||||
platform-version:
|
||||
- 2.0.17
|
||||
|
||||
platform:
|
||||
- esp32
|
||||
|
||||
archi:
|
||||
- esp32
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
# Build
|
||||
- name: Compile examples
|
||||
uses: ArminJo/arduino-test-compile@master
|
||||
with:
|
||||
arduino-board-fqbn: ${{ matrix.platform }}:${{ matrix.archi }}:${{ matrix.board }}
|
||||
arduino-platform: ${{ matrix.platform }}:${{ matrix.archi }}@${{ matrix.platform-version }}
|
||||
platform-url: ${{ matrix.platform-url }}
|
||||
required-libraries: ${{ env.REQUIRED_LIBRARIES }}
|
||||
extra-arduino-cli-args: ${{ matrix.cli-args }}
|
||||
#build-properties: ${{ toJson(matrix.build-properties) }}
|
||||
sketch-names: ${{ matrix.sketch }}.ino
|
||||
sketch-names-find-start: ${{ env.SKETCH_NAMES_FIND_START }}/${{ matrix.unit }}
|
||||
#sketches-exclude: ${{ matrix.sketches-exclude }}
|
||||
@@ -0,0 +1,118 @@
|
||||
name: Build(arduino-esp32:3.x)
|
||||
|
||||
env:
|
||||
SKETCH_NAMES_FIND_START: ./examples/UnitUnified
|
||||
REQUIRED_LIBRARIES: M5Unified,M5UnitUnified
|
||||
|
||||
on:
|
||||
push:
|
||||
tags-ignore:
|
||||
- '*.*.*'
|
||||
- 'v*.*.*'
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- 'src/unit/**.cpp'
|
||||
- 'src/unit/**.hpp'
|
||||
- 'src/unit/**.h'
|
||||
- 'src/unit/**.c'
|
||||
- 'test/**.cpp'
|
||||
- 'test/**.hpp'
|
||||
- 'test/**.h'
|
||||
- 'test/**.c'
|
||||
- 'examples/UnitUnified/**.ino'
|
||||
- 'examples/UnitUnified/**.cpp'
|
||||
- 'examples/UnitUnified/**.hpp'
|
||||
- 'examples/UnitUnified/**.h'
|
||||
- 'examples/UnitUnified/**.c'
|
||||
- '**arduino-esp-v3-build-check.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/unit/**.cpp'
|
||||
- 'src/unit/**.hpp'
|
||||
- 'src/unit/**.h'
|
||||
- 'src/unit/**.c'
|
||||
- 'test/**.cpp'
|
||||
- 'test/**.hpp'
|
||||
- 'test/**.h'
|
||||
- 'test/**.c'
|
||||
- 'examples/UnitUnified/**.ino'
|
||||
- 'examples/UnitUnified/**.cpp'
|
||||
- 'examples/UnitUnified/**.hpp'
|
||||
- 'examples/UnitUnified/**.h'
|
||||
- 'examples/UnitUnified/**.c'
|
||||
- '**arduino-esp-v3-build-check.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.unit }}:${{ matrix.sketch }}:${{matrix.board}}@${{matrix.platform-version}}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
#max-parallel: 1
|
||||
matrix:
|
||||
platform-url:
|
||||
- https://espressif.github.io/arduino-esp32/package_esp32_index.json
|
||||
|
||||
sketch:
|
||||
- PlotToSerial
|
||||
|
||||
unit:
|
||||
- ''
|
||||
|
||||
board:
|
||||
- m5stack_atom
|
||||
- m5stack_atoms3
|
||||
- m5stack_capsule
|
||||
# - m5stack_cardputer
|
||||
- m5stack_core
|
||||
- m5stack_core2
|
||||
- m5stack_coreink
|
||||
- m5stack_cores3
|
||||
- m5stack_dial
|
||||
- m5stack_fire
|
||||
- m5stack_nanoc6
|
||||
- m5stack_paper
|
||||
# - m5stack_poe_cam
|
||||
# - m5stack_stamp_c3
|
||||
# - m5stack_stamp_pico
|
||||
- m5stack_stamp_s3
|
||||
# - m5stack_station
|
||||
# - m5stack_stickc
|
||||
- m5stack_stickc_plus
|
||||
- m5stack_stickc_plus2
|
||||
# - m5stack_timer_cam
|
||||
# - m5stack_tough
|
||||
# - m5stack_unit_cam
|
||||
# - m5stack_unit_cams3
|
||||
|
||||
platform-version:
|
||||
- 3.0.4
|
||||
|
||||
platform:
|
||||
- esp32
|
||||
|
||||
archi:
|
||||
- esp32
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
# Build
|
||||
- name: Compile examples
|
||||
uses: ArminJo/arduino-test-compile@master
|
||||
with:
|
||||
arduino-board-fqbn: ${{ matrix.platform }}:${{ matrix.archi }}:${{ matrix.board }}
|
||||
arduino-platform: ${{ matrix.platform }}:${{ matrix.archi }}@${{ matrix.platform-version }}
|
||||
platform-url: ${{ matrix.platform-url }}
|
||||
required-libraries: ${{ env.REQUIRED_LIBRARIES }}
|
||||
extra-arduino-cli-args: ${{ matrix.cli-args }}
|
||||
#build-properties: ${{ toJson(matrix.build-properties) }}
|
||||
sketch-names: ${{ matrix.sketch }}.ino
|
||||
sketch-names-find-start: ${{ env.SKETCH_NAMES_FIND_START }}/${{ matrix.unit }}
|
||||
#sketches-exclude: ${{ matrix.sketches-exclude }}
|
||||
@@ -0,0 +1,120 @@
|
||||
name: Build(arduino-m5stack)
|
||||
|
||||
env:
|
||||
SKETCH_NAMES_FIND_START: ./examples/UnitUnified
|
||||
REQUIRED_LIBRARIES: M5Unified,M5UnitUnified
|
||||
|
||||
on:
|
||||
push:
|
||||
tags-ignore:
|
||||
- '*.*.*'
|
||||
- 'v*.*.*'
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- 'src/unit/**.cpp'
|
||||
- 'src/unit/**.hpp'
|
||||
- 'src/unit/**.h'
|
||||
- 'src/unit/**.c'
|
||||
- 'test/**.cpp'
|
||||
- 'test/**.hpp'
|
||||
- 'test/**.h'
|
||||
- 'test/**.c'
|
||||
- 'examples/UnitUnified/**.ino'
|
||||
- 'examples/UnitUnified/**.cpp'
|
||||
- 'examples/UnitUnified/**.hpp'
|
||||
- 'examples/UnitUnified/**.h'
|
||||
- 'examples/UnitUnified/**.c'
|
||||
- '**arduino-m5-build-check.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/unit/**.cpp'
|
||||
- 'src/unit/**.hpp'
|
||||
- 'src/unit/**.h'
|
||||
- 'src/unit/**.c'
|
||||
- 'test/**.cpp'
|
||||
- 'test/**.hpp'
|
||||
- 'test/**.h'
|
||||
- 'test/**.c'
|
||||
- 'examples/UnitUnified/**.ino'
|
||||
- 'examples/UnitUnified/**.cpp'
|
||||
- 'examples/UnitUnified/**.hpp'
|
||||
- 'examples/UnitUnified/**.h'
|
||||
- 'examples/UnitUnified/**.c'
|
||||
- '**arduino-m5-build-check.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.unit }}:${{ matrix.sketch }}:${{matrix.board}}@${{matrix.platform-version}}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
# max-parallel: 1
|
||||
matrix:
|
||||
platform-url:
|
||||
- https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json
|
||||
|
||||
sketch:
|
||||
- PlotToSerial
|
||||
|
||||
unit:
|
||||
- ''
|
||||
|
||||
board:
|
||||
- m5stack_atom
|
||||
- m5stack_atoms3
|
||||
- m5stack_atoms3r
|
||||
- m5stack_capsule
|
||||
# - m5stack_cardputer
|
||||
- m5stack_core
|
||||
- m5stack_core2
|
||||
- m5stack_coreink
|
||||
- m5stack_cores3
|
||||
- m5stack_dial
|
||||
- m5stack_dinmeter
|
||||
- m5stack_fire
|
||||
- m5stack_paper
|
||||
# - m5stack_poe_cam
|
||||
# - m5stack_stamp_c3
|
||||
# - m5stack_stamp_pico
|
||||
- m5stack_stamp_s3
|
||||
# - m5stack_station
|
||||
# - m5stack_stickc
|
||||
- m5stack_stickc_plus
|
||||
- m5stack_stickc_plus2
|
||||
# - m5stack_timer_cam
|
||||
# - m5stack_tough
|
||||
# - m5stack_unit_cam
|
||||
# - m5stack_unit_cams3
|
||||
|
||||
platform-version:
|
||||
- 2.1.2
|
||||
|
||||
platform:
|
||||
- m5stack
|
||||
|
||||
archi:
|
||||
- esp32
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
# Build
|
||||
- name: Compile examples
|
||||
uses: ArminJo/arduino-test-compile@master
|
||||
with:
|
||||
arduino-board-fqbn: ${{ matrix.platform }}:${{ matrix.archi }}:${{ matrix.board }}
|
||||
arduino-platform: ${{ matrix.platform }}:${{ matrix.archi }}@${{ matrix.platform-version }}
|
||||
platform-url: ${{ matrix.platform-url }}
|
||||
required-libraries: ${{ env.REQUIRED_LIBRARIES }}
|
||||
extra-arduino-cli-args: ${{ matrix.cli-args }}
|
||||
#build-properties: ${{ toJson(matrix.build-properties) }}
|
||||
sketch-names: ${{ matrix.sketch }}.ino
|
||||
sketch-names-find-start: ${{ env.SKETCH_NAMES_FIND_START }}/${{ matrix.unit }}
|
||||
#sketches-exclude: ${{ matrix.sketches-exclude }}
|
||||
|
||||
@@ -5,6 +5,11 @@ env:
|
||||
|
||||
on:
|
||||
push:
|
||||
tags-ignore:
|
||||
- '*.*.*'
|
||||
- 'v*.*.*'
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.ino'
|
||||
- '**.cpp'
|
||||
@@ -13,7 +18,9 @@ on:
|
||||
- '**.c'
|
||||
- '**.inl'
|
||||
- '**clang-format-check.yml'
|
||||
pull_request:
|
||||
- '**.clang-format'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.ino'
|
||||
- '**.cpp'
|
||||
- '**.hpp'
|
||||
@@ -21,6 +28,8 @@ on:
|
||||
- '**.c'
|
||||
- '**.inl'
|
||||
- '**clang-format-check.yml'
|
||||
- '**.clang-format'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
formatting-check:
|
||||
@@ -36,7 +45,7 @@ jobs:
|
||||
- check: 'examples'
|
||||
exclude: ''
|
||||
steps:
|
||||
- name: Checkout # When pull_request is used, include it in the checkout https://zenn.dev/hkusu/articles/c731862051438b
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
name: Build(platformio)
|
||||
|
||||
on:
|
||||
push:
|
||||
tags-ignore:
|
||||
- '*.*.*'
|
||||
- 'v*.*.*'
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- 'src/unit/**.cpp'
|
||||
- 'src/unit/**.hpp'
|
||||
- 'src/unit/**.h'
|
||||
- 'src/unit/**.c'
|
||||
- 'test/**.cpp'
|
||||
- 'test/**.hpp'
|
||||
- 'test/**.h'
|
||||
- 'test/**.c'
|
||||
- 'examples/UnitUnified/**.ino'
|
||||
- 'examples/UnitUnified/**.cpp'
|
||||
- 'examples/UnitUnified/**.hpp'
|
||||
- 'examples/UnitUnified/**.h'
|
||||
- 'examples/UnitUnified/**.c'
|
||||
- '/platformio-build-check.yml'
|
||||
- '**platformio.ini'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/unit/**.cpp'
|
||||
- 'src/unit/**.hpp'
|
||||
- 'src/unit/**.h'
|
||||
- 'src/unit/**.c'
|
||||
- 'test/**.cpp'
|
||||
- 'test/**.hpp'
|
||||
- 'test/**.h'
|
||||
- 'test/**.c'
|
||||
- 'examples/UnitUnified/**.ino'
|
||||
- 'examples/UnitUnified/**.cpp'
|
||||
- 'examples/UnitUnified/**.hpp'
|
||||
- 'examples/UnitUnified/**.h'
|
||||
- 'examples/UnitUnified/**.c'
|
||||
- '**/platformio-build-check.yml'
|
||||
- '**platformio.ini'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.unit }}:${{ matrix.example }}@${{ matrix.board }}:${{ matrix.framework }}:${{ matrix.espressif32 }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
#max-parallel: 1
|
||||
|
||||
matrix:
|
||||
example:
|
||||
- PlotToSerial
|
||||
|
||||
unit:
|
||||
- ''
|
||||
|
||||
board:
|
||||
- Core
|
||||
- Core2
|
||||
- CoreS3
|
||||
- Fire
|
||||
- StampS3
|
||||
- Dial
|
||||
- AtomMatrix
|
||||
- AtomS3
|
||||
- AtomS3R
|
||||
- NanoC6
|
||||
- StickCPlus
|
||||
- StickCPlus2
|
||||
- Paper
|
||||
- CoreInk
|
||||
|
||||
framework:
|
||||
- Arduino
|
||||
|
||||
espressif32:
|
||||
- latest
|
||||
# - '5_4_0'
|
||||
# - '4_4_0'
|
||||
|
||||
# exclude:
|
||||
# - board: CoreS3
|
||||
# espressif32: '5_4_0'
|
||||
# - board: CoreS3
|
||||
# espressif32: '4_4_0'
|
||||
# - board: StampS3
|
||||
# espressif32: '5_4_0'
|
||||
# - board: StampS3
|
||||
# espressif32: '4_4_0'
|
||||
# - board: AtomS3
|
||||
# espressif32: '5_4_0'
|
||||
# - board: AtomS3
|
||||
# espressif32: '4_4_0'
|
||||
# - board: Dial
|
||||
# espressif32: '5_4_0'
|
||||
# - board: Dial
|
||||
# espressif32: '4_4_0'
|
||||
# - board: NanoC6
|
||||
# espressif32: '5_4_0'
|
||||
# - board: NanoC6
|
||||
# espressif32: '4_4_0'
|
||||
# - board: StickCPlus
|
||||
# espressif32: '5_4_0'
|
||||
# - board: StickCPlus
|
||||
# espressif32: '4_4_0'
|
||||
# - board: Paper
|
||||
# espressif32: '5_4_0'
|
||||
# - board: Paper
|
||||
# espressif32: '4_4_0'
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Build examples
|
||||
uses: karniv00l/platformio-run-action@v1
|
||||
with:
|
||||
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) }}
|
||||
# targets:
|
||||
project-dir: "./"
|
||||
project-conf: "./platformio.ini"
|
||||
# jobs: 6
|
||||
# silent: false
|
||||
# verbose: true
|
||||
# disable-auto-clean: false
|
||||
@@ -34,6 +34,8 @@ See also examples using conventional methods here.
|
||||
See also [examples/UnitUnified](examples/UnitUnified)
|
||||
|
||||
## Doxygen document
|
||||
[GitHub Pages](https://m5stack.github.io/M5Unit-HEART/)
|
||||
|
||||
If you want to generate documents on your local machine, execute the following command
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"memory_type": "qio_opi",
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_8MB.csv"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DARDUINO_M5STACK_ATOMS3R",
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DARDUINO_USB_MODE=1",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32s3",
|
||||
"variant": "m5stack_atoms3"
|
||||
},
|
||||
"connectivity": [
|
||||
"bluetooth",
|
||||
"wifi"
|
||||
],
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "M5Stack AtomS3R",
|
||||
"upload": {
|
||||
"flash_size": "8MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://docs.m5stack.com/en/core/AtomS3R",
|
||||
"vendor": "M5Stack"
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"build": {
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DARDUINO_M5Stack_NanoC6"
|
||||
"-DARDUINO_M5STACK_NANOC6"
|
||||
],
|
||||
"f_cpu": "160000000L",
|
||||
"f_flash": "80000000L",
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino":{
|
||||
"ldscript": "esp32_out.ld",
|
||||
"partitions": "default_8MB.csv"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DM5STACK_M5STICK_CPLUS2",
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-mfix-esp32-psram-cache-issue",
|
||||
"-mfix-esp32-psram-cache-strategy=memw",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "m5stick_c"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth"
|
||||
],
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "M5Stick-CPlus2",
|
||||
"upload": {
|
||||
"flash_size": "8MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"speed": 1500000
|
||||
},
|
||||
"url": "https://docs.m5stack.com/en/core/M5StickC%20PLUS2",
|
||||
"vendor": "M5Stack"
|
||||
}
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <M5Unified.h>
|
||||
#include <M5UnitUnified.h>
|
||||
#include <M5UnitUnifiedHEART.h>
|
||||
#include <utility/heart_rate.hpp>
|
||||
#if !defined(USING_M5HAL)
|
||||
#include <Wire.h>
|
||||
#endif
|
||||
@@ -19,27 +18,25 @@
|
||||
namespace {
|
||||
auto& lcd = M5.Display;
|
||||
m5::unit::UnitUnified Units;
|
||||
m5::unit::UnitHEART unitHeart;
|
||||
m5::max30100::HeartRate heartRate(100 /*sample rate*/);
|
||||
m5::unit::UnitHEART unit;
|
||||
m5::heart::PulseMonitor monitor(100.f);
|
||||
|
||||
} // namespace
|
||||
|
||||
void setup()
|
||||
{
|
||||
m5::utility::delay(1500);
|
||||
|
||||
M5.begin();
|
||||
|
||||
// Another settings
|
||||
if (0) {
|
||||
auto cfg = unitHeart.config();
|
||||
cfg.sample_rate = m5::unit::max30100::Sample::Rate400;
|
||||
cfg.pulse_width = m5::unit::max30100::LedPulseWidth::PW400;
|
||||
cfg.ir_current = m5::unit::max30100::CurrentControl::mA7_6;
|
||||
cfg.red_current = m5::unit::max30100::CurrentControl::mA7_6;
|
||||
heartRate.setSampleRate(m5::max30100::HeartRate::getSampleRate(cfg.sample_rate));
|
||||
// heartRate.setThreshold(25.0f); // depends on ir/redCurrent
|
||||
// cfg.mode = m5::unit::max30100::Mode::HROnly;
|
||||
unitHeart.config(cfg);
|
||||
auto cfg = unit.config();
|
||||
cfg.sampling_rate = m5::unit::max30100::Sampling::Rate200;
|
||||
cfg.pulse_width = m5::unit::max30100::LedPulseWidth::PW200;
|
||||
cfg.ir_current = m5::unit::max30100::CurrentControl::mA7_6;
|
||||
cfg.red_current = m5::unit::max30100::CurrentControl::mA7_6;
|
||||
auto sr = m5::unit::max30100::getSamplingRate(cfg.sampling_rate);
|
||||
monitor.setSamplingRate(sr);
|
||||
unit.config(cfg);
|
||||
}
|
||||
|
||||
auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda);
|
||||
@@ -54,7 +51,7 @@ void setup()
|
||||
i2c_cfg.pin_scl = m5::hal::gpio::getPin(pin_num_scl);
|
||||
auto i2c_bus = m5::hal::bus::i2c::getBus(i2c_cfg);
|
||||
M5_LOGI("Bus:%d", i2c_bus.has_value());
|
||||
if (!Units.add(unitHeart, i2c_bus ? i2c_bus.value() : nullptr) || !Units.begin()) {
|
||||
if (!Units.add(unit, i2c_bus ? i2c_bus.value() : nullptr) || !Units.begin()) {
|
||||
M5_LOGE("Failed to begin");
|
||||
lcd.clear(TFT_RED);
|
||||
while (true) {
|
||||
@@ -65,7 +62,7 @@ void setup()
|
||||
#pragma message "Using Wire"
|
||||
// Using TwoWire
|
||||
Wire.begin(pin_num_sda, pin_num_scl, 400000U);
|
||||
if (!Units.add(unitHeart, Wire) || !Units.begin()) {
|
||||
if (!Units.add(unit, Wire) || !Units.begin()) {
|
||||
M5_LOGE("Failed to begin");
|
||||
lcd.clear(TFT_RED);
|
||||
while (true) {
|
||||
@@ -84,25 +81,29 @@ void loop()
|
||||
{
|
||||
M5.update();
|
||||
Units.update();
|
||||
if (unitHeart.updated()) {
|
||||
while (unitHeart.available()) {
|
||||
M5_LOGI("\n>IR:%u\n>RED:%u", unitHeart.ir(), unitHeart.red());
|
||||
bool beat = heartRate.push_back((float)unitHeart.ir(), (float)unitHeart.red());
|
||||
if (beat) {
|
||||
M5_LOGI("Beat!");
|
||||
}
|
||||
|
||||
unitHeart.discard();
|
||||
if (unit.updated()) {
|
||||
// WARNING
|
||||
// If overflow is occurring, the sampling rate should be reduced because the processing is not up to par
|
||||
if (unit.overflow()) {
|
||||
M5_LOGW("\n>OVERFLOW:%u", unit.overflow());
|
||||
}
|
||||
auto bpm = heartRate.calculate();
|
||||
M5_LOGW("\n>HRR:%f\n>SpO2:%f", bpm, heartRate.SpO2());
|
||||
|
||||
bool beat{};
|
||||
// MAX30100 is equipped with a FIFO, so multiple data may be stored
|
||||
while (unit.available()) {
|
||||
monitor.push_back(unit.ir(), unit.red()); // Push back the oldest data
|
||||
// M5_LOGI("\n>MIR:%f\n>MRED:%f", monitor.latestIR(), monitor.latestRED());
|
||||
monitor.update();
|
||||
beat = monitor.isBeat();
|
||||
unit.discard(); // Discard the oldest data
|
||||
}
|
||||
M5_LOGI("\n>BPM:%f\n>SpO2:%f\n>BEAT:%u", monitor.bpm(), monitor.SpO2(), beat);
|
||||
}
|
||||
|
||||
// buffer clear and measure tempeature
|
||||
// Measure tempeature
|
||||
if (M5.BtnA.wasClicked()) {
|
||||
heartRate.clear();
|
||||
m5::unit::max30100::TemperatureData td{};
|
||||
if (unitHeart.measureTemperatureSingleshot(td)) {
|
||||
if (unit.measureTemperatureSingleshot(td)) {
|
||||
M5_LOGI("\n>Temp:%f", td.celsius());
|
||||
}
|
||||
}
|
||||
|
||||
+4
-7
@@ -11,11 +11,9 @@
|
||||
"url": "https://github.com/m5stack/M5Unit-HEART.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"M5UnitUnified": "https://github.com/m5stack/M5UnitUnified.git",
|
||||
"M5Utility": "https://github.com/m5stack/M5Utility.git",
|
||||
"M5HAL": "https://github.com/m5stack/M5HAL.git"
|
||||
"M5UnitUnified": "https://github.com/m5stack/M5UnitUnified.git"
|
||||
},
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
@@ -25,9 +23,8 @@
|
||||
"headers": "M5UnitUnifiedHEART.h",
|
||||
"license": "MIT",
|
||||
"export": {
|
||||
"exclude":
|
||||
[
|
||||
"exclude": [
|
||||
"docs/html"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
name=M5Unit-HEART
|
||||
version=0.0.1
|
||||
version=0.0.2
|
||||
author=M5Stack
|
||||
maintainer=M5Stack
|
||||
sentence=Library for M5Stack UNIT HEART using M5UnitUnified
|
||||
|
||||
+64
-5
@@ -3,8 +3,6 @@
|
||||
; For UnitTest and examples (Using M5UnitUnified)
|
||||
;-----------------------------------------------------------------------
|
||||
[platformio]
|
||||
;default_envs = test_UnitHEART_Core, test_UnitHEART_Core2, test_UnitHEART_CoreS3, test_UnitHEART_Fire, test_UnitHEART_StampS3, test_UnitHEART_Dial, test_UnitHEART_AtomS3, test_UnitHEART_NanoC6, test_UnitHEART_StickCPlus, test_UnitHEART_Paper
|
||||
;default_envs = PlotToSerial_Core_Arduino_latest, PlotToSerial_Core_Arduino_5_4_0, PlotToSerial_Core_Arduino_4_4_0, PlotToSerial_Core2_Arduino_latest, PlotToSerial_Core2_Arduino_5_4_0, PlotToSerial_Core2_Arduino_4_4_0, PlotToSerial_CoreS3_Arduino_latest, PlotToSerial_StampS3_Arduino_latest, PlotToSerial_AtomS3_Arduino_latest, PlotToSerial_Dial_Arduino_latest, PlotToSerial_NanoC6_Arduino_latest, PlotToSerial_StickCPlus_Arduino_latest, PlotToSerial_Paper_Arduino_latest, PlotToSerial_Fire_Arduino_latest, PlotToSerial_Fire_Arduino_5_4_0, PlotToSerial_Fire_Arduino_4_4_0
|
||||
|
||||
[env]
|
||||
build_flags =-Wall -Wextra -Wreturn-local-addr -Werror=format -Werror=return-local-addr
|
||||
@@ -45,7 +43,7 @@ board = m5stack-fire
|
||||
lib_deps = ${env.lib_deps}
|
||||
|
||||
[StampS3]
|
||||
;include M5Capsule
|
||||
;include M5Capsule, DinMeter
|
||||
extends = m5base
|
||||
board = m5stack-stamps3
|
||||
lib_deps = ${env.lib_deps}
|
||||
@@ -56,11 +54,22 @@ board = m5stack-stamps3
|
||||
lib_deps = ${env.lib_deps}
|
||||
m5stack/M5Dial
|
||||
|
||||
[AtomMatrix]
|
||||
extends = m5base
|
||||
board = m5stack-atom
|
||||
lib_deps = ${env.lib_deps}
|
||||
|
||||
[AtomS3]
|
||||
extends = m5base
|
||||
board = m5stack-atoms3
|
||||
lib_deps = ${env.lib_deps}
|
||||
|
||||
; Using ./boards/m5stack-atoms3r.json
|
||||
[AtomS3R]
|
||||
extends = m5base
|
||||
board = m5stack-atoms3r
|
||||
lib_deps = ${env.lib_deps}
|
||||
|
||||
; Using ./boards/m5stack-nanoc6.json
|
||||
[NanoC6]
|
||||
extends = m5base
|
||||
@@ -77,10 +86,20 @@ extends = m5base
|
||||
board = m5stick-c
|
||||
lib_deps = ${env.lib_deps}
|
||||
|
||||
; Using ./boards/m5stick-cplus2.json
|
||||
[StickCPlus2]
|
||||
extends = m5base
|
||||
board = m5stick-cplus2
|
||||
lib_deps = ${env.lib_deps}
|
||||
|
||||
[Paper]
|
||||
extends = m5base
|
||||
board = m5stack-fire
|
||||
; Using M5Fire instead of the M5Paper(Noting...)
|
||||
lib_deps = ${env.lib_deps}
|
||||
|
||||
[CoreInk]
|
||||
extends = m5base
|
||||
board = m5stack-coreink
|
||||
lib_deps = ${env.lib_deps}
|
||||
|
||||
[sdl]
|
||||
@@ -202,12 +221,24 @@ lib_deps = ${Dial.lib_deps}
|
||||
${test_fw.lib_deps}
|
||||
test_filter= embedded/test_max30100
|
||||
|
||||
[env:test_UnitHEART_AtomMatrix]
|
||||
extends=AtomMatrix, option_release, arduino_latest
|
||||
lib_deps = ${AtomMatrix.lib_deps}
|
||||
${test_fw.lib_deps}
|
||||
test_filter= embedded/test_max30100
|
||||
|
||||
[env:test_UnitHEART_AtomS3]
|
||||
extends=AtomS3, option_release, arduino_latest
|
||||
lib_deps = ${AtomS3.lib_deps}
|
||||
${test_fw.lib_deps}
|
||||
test_filter= embedded/test_max30100
|
||||
|
||||
[env:test_UnitHEART_AtomS3R]
|
||||
extends=AtomS3R, option_release, arduino_latest
|
||||
lib_deps = ${AtomS3R.lib_deps}
|
||||
${test_fw.lib_deps}
|
||||
test_filter= embedded/test_max30100
|
||||
|
||||
[env:test_UnitHEART_NanoC6]
|
||||
extends=NanoC6, option_release, arduino_latest
|
||||
lib_deps = ${NanoC6.lib_deps}
|
||||
@@ -220,12 +251,24 @@ lib_deps = ${StickCPlus.lib_deps}
|
||||
${test_fw.lib_deps}
|
||||
test_filter= embedded/test_max30100
|
||||
|
||||
[env:test_UnitHEART_StickCPlus2]
|
||||
extends=StickCPlus2, option_release, arduino_latest
|
||||
lib_deps = ${StickCPlus2.lib_deps}
|
||||
${test_fw.lib_deps}
|
||||
test_filter= embedded/test_max30100
|
||||
|
||||
[env:test_UnitHEART_Paper]
|
||||
extends=Paper, option_release, arduino_latest
|
||||
lib_deps = ${Paper.lib_deps}
|
||||
${test_fw.lib_deps}
|
||||
test_filter= embedded/test_max30100
|
||||
|
||||
[env:test_UnitHEART_CoreInk]
|
||||
extends=CoreInk, option_release, arduino_latest
|
||||
lib_deps = ${CoreInk.lib_deps}
|
||||
${test_fw.lib_deps}
|
||||
test_filter= embedded/test_max30100
|
||||
|
||||
; --------------------------------
|
||||
;Examples by M5UnitUnified
|
||||
; --------------------------------
|
||||
@@ -239,7 +282,7 @@ extends=Core, option_release, arduino_5_4_0
|
||||
build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial>
|
||||
|
||||
[env:PlotToSerial_Core_Arduino_4_4_0]
|
||||
extends=Core, option_release, arduino_5_4_0
|
||||
extends=Core, option_release, arduino_4_4_0
|
||||
build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial>
|
||||
|
||||
[env:PlotToSerial_Core2_Arduino_latest]
|
||||
@@ -262,10 +305,18 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial
|
||||
extends=StampS3, option_release, arduino_latest
|
||||
build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial>
|
||||
|
||||
[env:PlotToSerial_AtomMatrix_Arduino_latest]
|
||||
extends=AtomMatrix, option_release, arduino_latest
|
||||
build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial>
|
||||
|
||||
[env:PlotToSerial_AtomS3_Arduino_latest]
|
||||
extends=AtomS3, option_release, arduino_latest
|
||||
build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial>
|
||||
|
||||
[env:PlotToSerial_AtomS3R_Arduino_latest]
|
||||
extends=AtomS3R, option_release, arduino_latest
|
||||
build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial>
|
||||
|
||||
[env:PlotToSerial_Dial_Arduino_latest]
|
||||
extends=Dial, option_release, arduino_latest
|
||||
build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial>
|
||||
@@ -278,10 +329,18 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial
|
||||
extends=StickCPlus, option_release, arduino_latest
|
||||
build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial>
|
||||
|
||||
[env:PlotToSerial_StickCPlus2_Arduino_latest]
|
||||
extends=StickCPlus2, option_release, arduino_latest
|
||||
build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial>
|
||||
|
||||
[env:PlotToSerial_Paper_Arduino_latest]
|
||||
extends=Paper, option_release, arduino_latest
|
||||
build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial>
|
||||
|
||||
[env:PlotToSerial_CoreInk_Arduino_latest]
|
||||
extends=CoreInk, option_release, arduino_latest
|
||||
build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial>
|
||||
|
||||
[env:PlotToSerial_Fire_Arduino_latest]
|
||||
extends=Fire, option_release, arduino_latest
|
||||
build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/PlotToSerial>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#define M5_UNIT_HEART_HPP
|
||||
|
||||
#include "unit/unit_MAX30100.hpp"
|
||||
#include "utility/heart_rate.hpp"
|
||||
#include "utility/pulse_monitor.hpp"
|
||||
|
||||
/*!
|
||||
@namespace m5
|
||||
|
||||
@@ -24,6 +24,8 @@ constexpr elapsed_time_t interval_table[] = {
|
||||
1000 / 50, 1000 / 100, 1000 / 167, 1000 / 200, 1000 / 400, 1000 / 600, 1000 / 800, 1000 / 1000,
|
||||
};
|
||||
|
||||
constexpr uint32_t sr_table[] = {50, 100, 167, 200, 400, 600, 800, 1000};
|
||||
|
||||
constexpr uint32_t MEASURE_TEMPERATURE_DURATION{29}; // 29ms
|
||||
|
||||
constexpr uint8_t allowed_spo2_table[] = {
|
||||
@@ -34,7 +36,7 @@ constexpr uint8_t allowed_hr_table[] = {
|
||||
// LSB:200 MSB:1600
|
||||
0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03,
|
||||
};
|
||||
bool is_allowed_settings(const Mode mode, const Sample rate, const LedPulseWidth pw)
|
||||
bool is_allowed_settings(const Mode mode, const Sampling rate, const LedPulseWidth pw)
|
||||
{
|
||||
return (mode != Mode::None)
|
||||
? (mode == Mode::SPO2 ? allowed_spo2_table : allowed_hr_table)[m5::stl::to_underlying(rate)] &
|
||||
@@ -48,6 +50,11 @@ namespace m5 {
|
||||
namespace unit {
|
||||
|
||||
namespace max30100 {
|
||||
uint32_t getSamplingRate(Sampling rate)
|
||||
{
|
||||
return sr_table[m5::stl::to_underlying(rate)];
|
||||
}
|
||||
|
||||
uint16_t Data::ir() const
|
||||
{
|
||||
return m5::types::big_uint16_t(raw[0], raw[1]).get();
|
||||
@@ -100,7 +107,7 @@ bool UnitMAX30100::begin()
|
||||
return false;
|
||||
}
|
||||
|
||||
return _cfg.start_periodic ? startPeriodicMeasurement(_cfg.mode, _cfg.sample_rate, _cfg.pulse_width,
|
||||
return _cfg.start_periodic ? startPeriodicMeasurement(_cfg.mode, _cfg.sampling_rate, _cfg.pulse_width,
|
||||
_cfg.ir_current, _cfg.high_resolution, _cfg.red_current)
|
||||
: true;
|
||||
}
|
||||
@@ -111,7 +118,11 @@ void UnitMAX30100::update(const bool force)
|
||||
if (inPeriodic()) {
|
||||
auto at = m5::utility::millis();
|
||||
if (force || !_latest || at >= _latest + _interval) {
|
||||
// Reduce interval if overflow
|
||||
_updated = read_FIFO();
|
||||
if (_interval && overflow()) {
|
||||
--_interval;
|
||||
}
|
||||
if (_updated) {
|
||||
_latest = at;
|
||||
}
|
||||
@@ -141,7 +152,7 @@ bool UnitMAX30100::start_periodic_measurement()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UnitMAX30100::start_periodic_measurement(const max30100::Mode mode, const max30100::Sample sample_rate,
|
||||
bool UnitMAX30100::start_periodic_measurement(const max30100::Mode mode, const max30100::Sampling sampling_rate,
|
||||
const max30100::LedPulseWidth pulse_width,
|
||||
const max30100::CurrentControl ir_current, const bool high_resolution,
|
||||
const max30100::CurrentControl red_current)
|
||||
@@ -151,7 +162,7 @@ bool UnitMAX30100::start_periodic_measurement(const max30100::Mode mode, const m
|
||||
}
|
||||
|
||||
SpO2Configuration sc{};
|
||||
sc.sampleRate(sample_rate);
|
||||
sc.samplingRate(sampling_rate);
|
||||
sc.ledPulseWidth(pulse_width);
|
||||
sc.highResolution(high_resolution);
|
||||
|
||||
@@ -220,11 +231,11 @@ bool UnitMAX30100::writeSpO2Configuration(const max30100::SpO2Configuration sc)
|
||||
return write_spo2_configration(sc.value);
|
||||
}
|
||||
|
||||
bool UnitMAX30100::writeSampleRate(const max30100::Sample rate)
|
||||
bool UnitMAX30100::writeSamplingRate(const max30100::Sampling rate)
|
||||
{
|
||||
max30100::SpO2Configuration sc{};
|
||||
if (read_spo2_configration(sc.value)) {
|
||||
sc.sampleRate(rate);
|
||||
sc.samplingRate(rate);
|
||||
return write_spo2_configration(sc.value);
|
||||
}
|
||||
return false;
|
||||
@@ -363,13 +374,13 @@ bool UnitMAX30100::write_spo2_configration(const uint8_t c)
|
||||
max30100::SpO2Configuration sc;
|
||||
sc.value = c;
|
||||
|
||||
if (!is_allowed_settings(_mode, sc.sampleRate(), sc.ledPulseWidth())) {
|
||||
M5_LIB_LOGW("Invalid combination %u:%u:%u", _mode, sc.sampleRate(), sc.ledPulseWidth());
|
||||
if (!is_allowed_settings(_mode, sc.samplingRate(), sc.ledPulseWidth())) {
|
||||
M5_LIB_LOGW("Invalid combination %u:%u:%u", _mode, sc.samplingRate(), sc.ledPulseWidth());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (writeRegister8(SPO2_CONFIGURATION, c) && read_spo2_configration(chk) && (chk == c)) {
|
||||
_interval = interval_table[m5::stl::to_underlying(sc.sampleRate())];
|
||||
_interval = interval_table[m5::stl::to_underlying(sc.samplingRate())];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
+24
-17
@@ -81,11 +81,11 @@ struct ModeConfiguration {
|
||||
};
|
||||
|
||||
/*!
|
||||
@enum Sample
|
||||
@brief Sample rate for pulse
|
||||
@enum Sampling
|
||||
@brief Sampling rate for pulse
|
||||
@details Unit is the number of sample per second
|
||||
*/
|
||||
enum class Sample : uint8_t {
|
||||
enum class Sampling : uint8_t {
|
||||
Rate50, //!< 50 sps
|
||||
Rate100, //!< 100 sps
|
||||
Rate167, //!< 167 sps
|
||||
@@ -96,6 +96,13 @@ enum class Sample : uint8_t {
|
||||
Rate1000, //!< 1000 sps
|
||||
};
|
||||
|
||||
/*!
|
||||
@brief Enum to sampling rate value
|
||||
@param rate Enum value
|
||||
@return sampling rate
|
||||
*/
|
||||
uint32_t getSamplingRate(const Sampling rate);
|
||||
|
||||
/*!
|
||||
@enum LedPulseWidth
|
||||
@brief LED pulse width (the IR and RED have the same pulse width)
|
||||
@@ -114,7 +121,7 @@ enum class LedPulseWidth {
|
||||
on the mode
|
||||
|
||||
- Mode:SPO2
|
||||
|Sample\PulseWidth|200 |400 |800 |1600|
|
||||
|Sampling\PulseWidth|200 |400 |800 |1600|
|
||||
|---|---|---|---|---|
|
||||
| 50|o|o|o|o|
|
||||
| 100|o|o|o|o|
|
||||
@@ -125,7 +132,7 @@ enum class LedPulseWidth {
|
||||
| 800|o|x|x|x|
|
||||
|1000|o|x|x|x|
|
||||
- Mode:HROnly
|
||||
|Sample\PulseWidth|200 |400 |800 |1600|
|
||||
|Sampling\PulseWidth|200 |400 |800 |1600|
|
||||
|---|---|---|---|---|
|
||||
| 50|o|o|o|o|
|
||||
| 100|o|o|o|o|
|
||||
@@ -143,9 +150,9 @@ struct SpO2Configuration {
|
||||
{ // for SpO2
|
||||
return value & (1U << 6);
|
||||
}
|
||||
Sample sampleRate() const
|
||||
Sampling samplingRate() const
|
||||
{
|
||||
return static_cast<Sample>((value >> 2) & 0x07);
|
||||
return static_cast<Sampling>((value >> 2) & 0x07);
|
||||
}
|
||||
LedPulseWidth ledPulseWidth() const
|
||||
{
|
||||
@@ -159,7 +166,7 @@ struct SpO2Configuration {
|
||||
{ // for SpO2
|
||||
value = (value & ~(1U << 6)) | ((b ? 1 : 0) << 6);
|
||||
}
|
||||
void sampleRate(const Sample rate)
|
||||
void samplingRate(const Sampling rate)
|
||||
{
|
||||
value = (value & ~(0x07 << 2)) | ((m5::stl::to_underlying(rate) & 0x07) << 2);
|
||||
}
|
||||
@@ -268,15 +275,15 @@ public:
|
||||
/*!
|
||||
@struct config_t
|
||||
@brief Settings for begin
|
||||
@warning Note that some combinations of sample_rate and pulse_width are invalid. See also datasheet
|
||||
@warning Note that some combinations of sampling_rate and pulse_width are invalid. See also datasheet
|
||||
*/
|
||||
struct config_t {
|
||||
//! Start periodic measurement on begin?
|
||||
bool start_periodic{true};
|
||||
//! Operating mode if start on begin
|
||||
max30100::Mode mode{max30100::Mode::SPO2};
|
||||
//! Sample rate if start on begin
|
||||
max30100::Sample sample_rate{m5::unit::max30100::Sample::Rate100};
|
||||
//! Sampling rate if start on begin
|
||||
max30100::Sampling sampling_rate{m5::unit::max30100::Sampling::Rate100};
|
||||
//! Led pulse width if start on begin
|
||||
max30100::LedPulseWidth pulse_width{m5::unit::max30100::LedPulseWidth::PW1600};
|
||||
//! Led current for IR if start on begin
|
||||
@@ -361,7 +368,7 @@ public:
|
||||
/*!
|
||||
@brief Start periodic measurement
|
||||
@param mode Operation mode
|
||||
@param sample_rate Sample rate
|
||||
@param sample_rate Sampling rate
|
||||
@param pulse_width Pulse width
|
||||
@param ir_current IR Led control
|
||||
@param high_resolution (only SpO2)
|
||||
@@ -369,7 +376,7 @@ public:
|
||||
@return True if successful
|
||||
@warning Note that some combinations of sample_rate and pulse_width are invalid. See also datasheet
|
||||
*/
|
||||
inline bool startPeriodicMeasurement(const max30100::Mode mode, const max30100::Sample sample_rate,
|
||||
inline bool startPeriodicMeasurement(const max30100::Mode mode, const max30100::Sampling sample_rate,
|
||||
const max30100::LedPulseWidth pulse_width,
|
||||
const max30100::CurrentControl ir_current, const bool high_resolution = false,
|
||||
const max30100::CurrentControl red_current = max30100::CurrentControl::mA0_0)
|
||||
@@ -387,7 +394,7 @@ public:
|
||||
}
|
||||
|
||||
///@warning Note that there are different combinations that can be set
|
||||
/// depending on the mode See also SpO2Configuration
|
||||
/// depending on the mode See also m5::unit::max30100::SpO2Configuration
|
||||
///@name Mode Configuration
|
||||
///@{
|
||||
/*!
|
||||
@@ -417,7 +424,7 @@ public:
|
||||
///@}
|
||||
|
||||
///@warning Note that there are different combinations that can be set depending on the mode See also
|
||||
/// SpO2Configuration
|
||||
/// m5::unit::max30100::SpO2Configuration
|
||||
///@name SpO2 Configuration
|
||||
///@{
|
||||
/*!
|
||||
@@ -433,7 +440,7 @@ public:
|
||||
*/
|
||||
bool writeSpO2Configuration(const max30100::SpO2Configuration sc);
|
||||
//! @brief Write sample rate
|
||||
bool writeSampleRate(const max30100::Sample rate);
|
||||
bool writeSamplingRate(const max30100::Sampling rate);
|
||||
//! @brief Write LED pulse width
|
||||
bool writeLedPulseWidth(const max30100::LedPulseWidth width);
|
||||
//! @brief Writee SpO2 high resolution mode to enable
|
||||
@@ -496,7 +503,7 @@ public:
|
||||
|
||||
protected:
|
||||
bool start_periodic_measurement();
|
||||
bool start_periodic_measurement(const max30100::Mode mode, const max30100::Sample sample_rate,
|
||||
bool start_periodic_measurement(const max30100::Mode mode, const max30100::Sampling sample_rate,
|
||||
const max30100::LedPulseWidth pulse_width,
|
||||
const max30100::CurrentControl ir_current, const bool high_resolution,
|
||||
const max30100::CurrentControl red_current);
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
/*!
|
||||
@file heart_rate.cpp
|
||||
@brief Calculate heart rate and SpO2
|
||||
*/
|
||||
#include "heart_rate.hpp"
|
||||
#include <M5Unified.hpp>
|
||||
#include <M5Utility.hpp>
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
|
||||
using namespace m5::max30100;
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr float ALPHA{0.95f}; // for removeDC
|
||||
|
||||
void calculateButterworthCoefficients(float Fs, float Fc, float& a0, float& a1, float& b1)
|
||||
{
|
||||
float tanWc = std::tan(M_PI * Fc / Fs);
|
||||
float sqrt2 = std::sqrt(2.0f);
|
||||
|
||||
a0 = tanWc / (tanWc + sqrt2);
|
||||
a1 = a0;
|
||||
b1 = (tanWc - sqrt2) / (tanWc + sqrt2);
|
||||
}
|
||||
|
||||
inline dcFilter_t removeDC(const float x, const float prev_w, const float alpha)
|
||||
{
|
||||
dcFilter_t filtered;
|
||||
filtered.w = x + alpha * prev_w;
|
||||
filtered.result = filtered.w - prev_w;
|
||||
return filtered;
|
||||
}
|
||||
|
||||
float meanDiff(const float M, meanDiffFilter_t& filterValues)
|
||||
{
|
||||
float avg{};
|
||||
|
||||
filterValues.sum -= filterValues.values[filterValues.index];
|
||||
filterValues.values[filterValues.index] = M;
|
||||
filterValues.sum += filterValues.values[filterValues.index];
|
||||
|
||||
filterValues.index++;
|
||||
filterValues.index = filterValues.index % meanDiffFilter_t::MEAN_FILTER_SIZE;
|
||||
|
||||
if (filterValues.count < meanDiffFilter_t::MEAN_FILTER_SIZE) {
|
||||
filterValues.count++;
|
||||
}
|
||||
|
||||
avg = filterValues.sum / filterValues.count;
|
||||
return avg - M;
|
||||
}
|
||||
|
||||
void lowPassButterworthFilter(const float x, butterworthFilter_t& fr)
|
||||
{
|
||||
fr.v[0] = fr.v[1];
|
||||
fr.v[1] = (fr.a0 * x) + (fr.a1 * fr.v[0]) - (fr.b1 * fr.v[1]);
|
||||
fr.result = fr.v[0] + fr.v[1];
|
||||
}
|
||||
|
||||
#if 0
|
||||
std::pair<float /*AC*/, float /*DC*/> calculateACDC(
|
||||
const std::deque<float>& data) {
|
||||
float maxVal = *std::max_element(data.begin(), data.end());
|
||||
float minVal = *std::min_element(data.begin(), data.end());
|
||||
return {maxVal - minVal,
|
||||
std::accumulate(data.begin(), data.end(), 0.0f) / data.size()};
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace m5 {
|
||||
namespace max30100 {
|
||||
|
||||
HeartRate::HeartRate(const uint32_t srate, const float threshold, const size_t max_data_size)
|
||||
: _sampleRate{(float)srate}, _threshold(threshold), _maxDataSize{max_data_size}
|
||||
{
|
||||
assert(srate && "SampleRate must not be zero");
|
||||
if (!max_data_size) {
|
||||
_maxDataSize = (size_t)srate * 30U;
|
||||
}
|
||||
calculateButterworthCoefficients(_sampleRate, 10.0f, _bwfIR.a0, _bwfIR.a1, _bwfIR.b1);
|
||||
}
|
||||
|
||||
void HeartRate::setSampleRate(const uint32_t sr)
|
||||
{
|
||||
_sampleRate = sr;
|
||||
calculateButterworthCoefficients(_sampleRate, 10.0f, _bwfIR.a0, _bwfIR.a1, _bwfIR.b1);
|
||||
clear();
|
||||
}
|
||||
|
||||
void HeartRate::clear()
|
||||
{
|
||||
_dataIR.clear();
|
||||
_peakDowns.clear();
|
||||
_incrasing = false;
|
||||
_dcIR = dcFilter_t{};
|
||||
_mdIR = meanDiffFilter_t{};
|
||||
_bwfIR = butterworthFilter_t{};
|
||||
calculateButterworthCoefficients(_sampleRate, 10.0f, _bwfIR.a0, _bwfIR.a1, _bwfIR.b1);
|
||||
}
|
||||
|
||||
bool HeartRate::push_back(const float ir, const float red)
|
||||
{
|
||||
// Filtering (IR)
|
||||
_dcIR = removeDC(ir, _dcIR.w, ALPHA);
|
||||
// M5_LIB_LOGI("\n>ACIR:%f", _dcIR.result);
|
||||
auto md = meanDiff(_dcIR.result, _mdIR);
|
||||
// M5_LIB_LOGI("\n>MD:%f", md);
|
||||
lowPassButterworthFilter(md, _bwfIR);
|
||||
// M5_LIB_LOGI("\n>LP:%f", _bwfIR.result);
|
||||
|
||||
// Filtering (RED)
|
||||
_dcRED = removeDC(red, _dcRED.w, ALPHA);
|
||||
// M5_LIB_LOGI("\n>ACRED:%f", _dcRED.result);
|
||||
|
||||
// Store
|
||||
_dataIR.push_back(_bwfIR.result);
|
||||
if (_dataIR.size() > _maxDataSize) {
|
||||
_dataIR.pop_front();
|
||||
}
|
||||
|
||||
// Heart beat
|
||||
_beat = detect_beat();
|
||||
|
||||
// SpO2
|
||||
_acSqIR += _dcIR.result * _dcIR.result;
|
||||
//_acSqRED += _dcRED.result * _dcRED.result;
|
||||
_acSqRED = _dcRED.result * _dcRED.result;
|
||||
++_count;
|
||||
if (_beat) {
|
||||
float rr = std::log(std::sqrt(_acSqRED / _count)) / std::log(std::sqrt(_acSqIR / _count));
|
||||
auto s = 110.0f - _coeffSpO2 * rr;
|
||||
_SpO2 = std::fmin(std::fmax(s, 80.f), 100.f);
|
||||
_acSqIR = _acSqRED = 0.0f;
|
||||
_count = 0;
|
||||
}
|
||||
return _beat;
|
||||
}
|
||||
|
||||
float HeartRate::calculate() const
|
||||
{
|
||||
if (_peakDowns.size() < 2) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float total{};
|
||||
for (size_t i = 1; i < _peakDowns.size(); ++i) {
|
||||
total += _peakDowns[i] - _peakDowns[i - 1];
|
||||
}
|
||||
float avg = total / (_peakDowns.size() - 1);
|
||||
return 1.0f / avg * 60000.0f;
|
||||
}
|
||||
|
||||
bool HeartRate::detect_beat()
|
||||
{
|
||||
auto now = m5::utility::millis();
|
||||
bool beat{};
|
||||
|
||||
if (_dataIR.size() >= 4) {
|
||||
auto d3 = _dataIR.back();
|
||||
auto d2 = _dataIR[_dataIR.size() - 2];
|
||||
auto d1 = _dataIR[_dataIR.size() - 3];
|
||||
auto d0 = _dataIR[_dataIR.size() - 4];
|
||||
if (!_incrasing && (d0 > _threshold) && (d1 > d0) && (d2 > d1) && (d3 > d2)) {
|
||||
_incrasing = true;
|
||||
} else if (_incrasing && (d1 < d0) && (d2 < d1) && (d3 < d2)) {
|
||||
_incrasing = false;
|
||||
beat = true;
|
||||
_peakDowns.push_back(now);
|
||||
}
|
||||
}
|
||||
// Remove old peaks from the window
|
||||
while (!_peakDowns.empty() && now - _peakDowns.front() > 1000 * 10) {
|
||||
_peakDowns.pop_front();
|
||||
}
|
||||
return beat;
|
||||
}
|
||||
|
||||
} // namespace max30100
|
||||
} // namespace m5
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user