initial commit
This commit is contained in:
parent
59637f4fa8
commit
f690d03c57
7522
Raumtempregler v10.step
Normal file
7522
Raumtempregler v10.step
Normal file
File diff suppressed because it is too large
Load Diff
5
Raumtermostat/.gitignore
vendored
Normal file
5
Raumtermostat/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
10
Raumtermostat/.vscode/extensions.json
vendored
Normal file
10
Raumtermostat/.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
||||
37
Raumtermostat/include/README
Normal file
37
Raumtermostat/include/README
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the convention is to give header files names that end with `.h'.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||
46
Raumtermostat/lib/README
Normal file
46
Raumtermostat/lib/README
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into the executable file.
|
||||
|
||||
The source code of each library should be placed in a separate directory
|
||||
("lib/your_library_name/[Code]").
|
||||
|
||||
For example, see the structure of the following example libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
Example contents of `src/main.c` using Foo and Bar:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries by scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
3
Raumtermostat/lib/SensorLib-master/.gitattributes
vendored
Normal file
3
Raumtermostat/lib/SensorLib-master/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*.hpp linguist-language=C++
|
||||
|
||||
|
||||
127
Raumtermostat/lib/SensorLib-master/.github/workflows/arduino_ci.yml
vendored
Normal file
127
Raumtermostat/lib/SensorLib-master/.github/workflows/arduino_ci.yml
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
name: Build with Arduino
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
paths:
|
||||
- "src/**"
|
||||
- "examples/**"
|
||||
- ".github/workflows/arduino_ci.yml"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
ArduinoLint:
|
||||
name: ${{ matrix.board.fqbn }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board:
|
||||
- fqbn: esp32:esp32:esp32s3
|
||||
platform: esp32:esp32
|
||||
url: https://espressif.github.io/arduino-esp32/package_esp32_index.json
|
||||
- fqbn: rp2040:rp2040:rpipico
|
||||
platform: rp2040:rp2040
|
||||
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
|
||||
- fqbn: adafruit:nrf52:pca10056
|
||||
platform: adafruit:nrf52
|
||||
url: https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
|
||||
- fqbn: STMicroelectronics:stm32:GenF4
|
||||
platform: stmicroelectronics:stm32
|
||||
url: https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json
|
||||
- fqbn: arduino:mbed_rp2040:pico
|
||||
platform: arduino:mbed_rp2040
|
||||
include:
|
||||
- example_file: examples.txt
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Arduino CLI
|
||||
run: |
|
||||
echo "Installing Arduino CLI..."
|
||||
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to install Arduino CLI."
|
||||
exit 1
|
||||
fi
|
||||
echo "./bin" >> $GITHUB_PATH
|
||||
echo "Arduino CLI installed successfully."
|
||||
|
||||
- name: Install board
|
||||
run: |
|
||||
echo "Initializing Arduino CLI configuration..."
|
||||
arduino-cli config init
|
||||
arduino-cli config set library.enable_unsafe_install true
|
||||
if [ -n "${{ matrix.board.url }}" ]; then
|
||||
echo "Adding additional board manager URL: ${{ matrix.board.url }}"
|
||||
arduino-cli config add board_manager.additional_urls ${{ matrix.board.url }}
|
||||
fi
|
||||
echo "Updating board index..."
|
||||
arduino-cli core update-index
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to update board index."
|
||||
exit 1
|
||||
fi
|
||||
echo "Installing board platform: ${{ matrix.board.platform }}"
|
||||
arduino-cli core install ${{ matrix.board.platform }}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to install board platform."
|
||||
exit 1
|
||||
fi
|
||||
echo "Board platform installed successfully."
|
||||
|
||||
- name: Install libraries
|
||||
run: |
|
||||
echo "Installing required libraries..."
|
||||
arduino-cli lib install --git-url https://github.com/ThingPulse/esp8266-oled-ssd1306.git
|
||||
arduino-cli lib install --git-url https://github.com/arduino-libraries/MadgwickAHRS.git
|
||||
arduino-cli lib install --git-url https://github.com/CreativeRobotics/Commander.git
|
||||
arduino-cli lib install --git-url https://github.com/adafruit/SdFat.git
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to install libraries."
|
||||
exit 1
|
||||
fi
|
||||
echo "Libraries installed successfully."
|
||||
|
||||
- name: Install adafruit-nrfutil
|
||||
if: matrix.board.platform == 'adafruit:nrf52'
|
||||
run: |
|
||||
pip install adafruit-nrfutil
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to install adafruit-nrfutil."
|
||||
exit 1
|
||||
fi
|
||||
echo "adafruit-nrfutil installed successfully."
|
||||
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Find .ino files in examples directory
|
||||
id: find-examples
|
||||
run: |
|
||||
echo "Current working directory: $(pwd)"
|
||||
if [ -d "./examples" ]; then
|
||||
examples=$(find ./examples -name "*.ino" -print0 | tr '\0' ' ')
|
||||
echo "Found examples: $examples"
|
||||
echo "examples=$examples" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "The './examples' directory does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Run test
|
||||
run: |
|
||||
for example in ${{ steps.find-examples.outputs.examples }}; do
|
||||
echo "Compiling example: $example"
|
||||
arduino-cli compile --library . -b ${{ matrix.board.fqbn }} $example
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Compilation failed for example: $example"
|
||||
exit 1
|
||||
fi
|
||||
echo "Compilation succeeded for example: $example"
|
||||
done
|
||||
38
Raumtermostat/lib/SensorLib-master/.github/workflows/esp-idf.yml
vendored
Normal file
38
Raumtermostat/lib/SensorLib-master/.github/workflows/esp-idf.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
name: Build with ESP-IDF
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
paths:
|
||||
- "src/**"
|
||||
- "examples/ESP_IDF_TouchDrvExample/**"
|
||||
- "examples/ESP_IDF_SensorExamples/**"
|
||||
- ".github/workflows/esp-idf.yml"
|
||||
|
||||
jobs:
|
||||
esp-idf-build:
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest"]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: "recursive"
|
||||
- name: Build ESP_IDF_TouchDrvExample
|
||||
shell: bash
|
||||
run: |
|
||||
pwd
|
||||
. ${IDF_PATH}/export.sh
|
||||
cd examples/ESP_IDF_TouchDrvExample
|
||||
idf.py build
|
||||
- name: Build ESP_IDF_SensorExamples
|
||||
shell: bash
|
||||
run: |
|
||||
pwd
|
||||
. ${IDF_PATH}/export.sh
|
||||
cd examples/ESP_IDF_SensorExamples
|
||||
idf.py build
|
||||
80
Raumtermostat/lib/SensorLib-master/.github/workflows/platformio.yml
vendored
Normal file
80
Raumtermostat/lib/SensorLib-master/.github/workflows/platformio.yml
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
name: Build with PlatformIO
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
paths:
|
||||
- "src/**"
|
||||
- "examples/**"
|
||||
- ".github/workflows/platformio.yml"
|
||||
- "platformio.ini"
|
||||
|
||||
jobs:
|
||||
platformio-build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
example: ${{ fromJSON(needs.find-examples.outputs.examples) }}
|
||||
needs: [find-examples]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cache/pip
|
||||
~/.platformio/.cache
|
||||
key: ${{ runner.os }}-pio
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.9"
|
||||
- name: Install PlatformIO Core
|
||||
run: pip install --upgrade platformio
|
||||
|
||||
- name: Install MadgwickAHRS library
|
||||
run: pio pkg install --library "arduino-libraries/Madgwick@^1.2.0" -g
|
||||
|
||||
- name: Install esp8266-oled-ssd1306 library
|
||||
run: pio pkg install --library "thingpulse/ESP8266 and ESP32 OLED driver for SSD1306 displays @ ^4.4.0" -g
|
||||
|
||||
- name: Install Commander library
|
||||
run: pio pkg install --library "creativerobotics/Commander @ ^4.3.0" -g
|
||||
|
||||
- name: Install SdFat
|
||||
run: pio pkg install --library "adafruit/SdFat - Adafruit Fork @ ^2.2.3" -g
|
||||
|
||||
- name: Run PlatformIO
|
||||
run: pio ci --lib="." --board=esp32-s3-devkitm-1 --board=nrf52840_dk_adafruit
|
||||
env:
|
||||
PLATFORMIO_CI_SRC: ${{ matrix.example }}
|
||||
|
||||
find-examples:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
examples: ${{ steps.find.outputs.examples }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Create Python script
|
||||
run: |
|
||||
cat << 'EOF' > find_examples.py
|
||||
import os
|
||||
import json
|
||||
|
||||
examples_dir = 'examples'
|
||||
ino_folders = []
|
||||
|
||||
for root, dirs, files in os.walk(examples_dir):
|
||||
for file in files:
|
||||
if file.endswith('.ino'):
|
||||
ino_folders.append(root)
|
||||
break
|
||||
|
||||
unique_folders = sorted(set(ino_folders))
|
||||
print(json.dumps(unique_folders))
|
||||
EOF
|
||||
- name: Run Python script
|
||||
id: find
|
||||
run: |
|
||||
result=$(python find_examples.py)
|
||||
echo "::set-output name=examples::$result"
|
||||
11
Raumtermostat/lib/SensorLib-master/.gitignore
vendored
Normal file
11
Raumtermostat/lib/SensorLib-master/.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
.pio
|
||||
.vscode
|
||||
test
|
||||
.travis.yml
|
||||
test
|
||||
assets
|
||||
*.bk
|
||||
*.test
|
||||
build
|
||||
*.old
|
||||
sdkconfig
|
||||
19
Raumtermostat/lib/SensorLib-master/CMakeLists.txt
Normal file
19
Raumtermostat/lib/SensorLib-master/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
set(src_dirs ./src
|
||||
./src/touch
|
||||
./src/platform
|
||||
./src/bosch
|
||||
./src/bosch/BMM150
|
||||
./src/bosch/common
|
||||
)
|
||||
set(include_dirs ./src
|
||||
./src/REG
|
||||
./src/touch
|
||||
./src/platform
|
||||
./src/bosch
|
||||
./src/bosch/firmware
|
||||
./src/bosch/BMM150
|
||||
./src/bosch/common)
|
||||
|
||||
idf_component_register(SRC_DIRS ${src_dirs}
|
||||
INCLUDE_DIRS ${include_dirs}
|
||||
REQUIRES esp_timer esp_driver_gpio driver)
|
||||
16
Raumtermostat/lib/SensorLib-master/Kconfig
Normal file
16
Raumtermostat/lib/SensorLib-master/Kconfig
Normal file
@ -0,0 +1,16 @@
|
||||
menu "SensorLib Configuration"
|
||||
|
||||
choice SensorLib_ESP_IDF_API
|
||||
prompt "SensorLib library esp-idf api version"
|
||||
default SENSORLIB_ESP_IDF_NEW_API
|
||||
help
|
||||
Define API version
|
||||
|
||||
config SENSORLIB_ESP_IDF_NEW_API
|
||||
bool "Use esp-idf higher version (>= 5.0) API"
|
||||
config SENSORLIB_ESP_IDF_OLD_API
|
||||
bool "Use esp-idf lower version ( < 5.0) API , Compatible with lower versions of esp-idf"
|
||||
endchoice
|
||||
|
||||
|
||||
endmenu
|
||||
21
Raumtermostat/lib/SensorLib-master/LICENSE
Normal file
21
Raumtermostat/lib/SensorLib-master/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
44
Raumtermostat/lib/SensorLib-master/README.md
Normal file
44
Raumtermostat/lib/SensorLib-master/README.md
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
<center><img src="extras/images/SensroLib.jpg" width="80%" height="30%"></center>
|
||||
|
||||
|
||||
[](https://github.com/lewisxhe/SensorLib/actions/workflows/esp-idf.yml)
|
||||
[](https://github.com/lewisxhe/SensorLib/actions/workflows/arduino_ci.yml)
|
||||
[](https://github.com/lewisxhe/SensorLib/actions/workflows/platformio.yml)
|
||||
[](https://www.ardu-badge.com/SensorLib)
|
||||
[](https://registry.platformio.org/libraries/lewisxhe/SensorLib)
|
||||
|
||||
[](https://github.com/lewisxhe/SensorLib/blob/master/LICENSE)
|
||||
[](https://github.com/lewisxhe/SensorsLib/issues)
|
||||
[](https://github.com/lewisxhe/SensorsLib/graphs/contributors)
|
||||
[](https://github.com/lewisxhe/SensorsLib/stargazers)
|
||||
[](https://github.com/lewisxhe/SensorLib/releases)
|
||||
|
||||
Support list:
|
||||
|
||||
| Sensor | Description | I2C | SPI |
|
||||
| --------------- | ------------------------ | --- | --- |
|
||||
| PCF8563/HYM8563 | Real-time clock | ✔️ | ❌ |
|
||||
| PCF85063 | Real-time clock | ✔️ | ❌ |
|
||||
| QMI8658 | IMU | ✔️ | ✔️ |
|
||||
| BHI260AP | IMU | ✔️ | ✔️ |
|
||||
| QMC6310 | Magnetic Sensor | ✔️ | ❌ |
|
||||
| BMM150 | Magnetic Sensor | ✔️ | ❌ |
|
||||
| XL9555 | I/O expander | ✔️ | ❌ |
|
||||
| BMA423 | Accelerometer | ✔️ | ❌ |
|
||||
| DRV2605 | Haptic Driver | ✔️ | ❌ |
|
||||
| CM32181 | Ambient Light Sensor | ✔️ | ❌ |
|
||||
| LTR553 | Light & Proximity Sensor | ✔️ | ❌ |
|
||||
| FT3267 | Capacitive touch | ✔️ | ❌ |
|
||||
| FT5206 | Capacitive touch | ✔️ | ❌ |
|
||||
| FT6206 | Capacitive touch | ✔️ | ❌ |
|
||||
| FT6236 | Capacitive touch | ✔️ | ❌ |
|
||||
| CST820 | Capacitive touch | ✔️ | ❌ |
|
||||
| CST816S/T/D | Capacitive touch | ✔️ | ❌ |
|
||||
| CST226SE | Capacitive touch | ✔️ | ❌ |
|
||||
| CHSC5816 | Capacitive touch | ✔️ | ❌ |
|
||||
| GT911 | Capacitive touch | ✔️ | ❌ |
|
||||
| CST9217 | Capacitive touch | ✔️ | ❌ |
|
||||
| CST9220 | Capacitive touch | ✔️ | ❌ |
|
||||
| GT9895 | Capacitive touch | ✔️ | ❌ |
|
||||
| AW9364 | Led Driver (GPIO) | ❌ | ❌ |
|
||||
BIN
Raumtermostat/lib/SensorLib-master/datasheet/BMA423.PDF
Normal file
BIN
Raumtermostat/lib/SensorLib-master/datasheet/BMA423.PDF
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Raumtermostat/lib/SensorLib-master/datasheet/CM32181A3OP.pdf
Normal file
BIN
Raumtermostat/lib/SensorLib-master/datasheet/CM32181A3OP.pdf
Normal file
Binary file not shown.
BIN
Raumtermostat/lib/SensorLib-master/datasheet/DRV2605.pdf
Normal file
BIN
Raumtermostat/lib/SensorLib-master/datasheet/DRV2605.pdf
Normal file
Binary file not shown.
BIN
Raumtermostat/lib/SensorLib-master/datasheet/GT911 Rev.10.pdf
Normal file
BIN
Raumtermostat/lib/SensorLib-master/datasheet/GT911 Rev.10.pdf
Normal file
Binary file not shown.
BIN
Raumtermostat/lib/SensorLib-master/datasheet/HYM8563.pdf
Normal file
BIN
Raumtermostat/lib/SensorLib-master/datasheet/HYM8563.pdf
Normal file
Binary file not shown.
BIN
Raumtermostat/lib/SensorLib-master/datasheet/LTR-553ALS-01.pdf
Normal file
BIN
Raumtermostat/lib/SensorLib-master/datasheet/LTR-553ALS-01.pdf
Normal file
Binary file not shown.
BIN
Raumtermostat/lib/SensorLib-master/datasheet/PCF85063A.pdf
Normal file
BIN
Raumtermostat/lib/SensorLib-master/datasheet/PCF85063A.pdf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Raumtermostat/lib/SensorLib-master/datasheet/环境光与接近传感器应用与选型.pdf
Normal file
BIN
Raumtermostat/lib/SensorLib-master/datasheet/环境光与接近传感器应用与选型.pdf
Normal file
Binary file not shown.
@ -0,0 +1,70 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2024 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file AW9364_LedDriver.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2024-11-22
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#include "AW9364LedDriver.hpp"
|
||||
|
||||
#ifdef ENABLE_TFT
|
||||
#include "TFT_eSPI.h"
|
||||
TFT_eSPI tft;
|
||||
#endif
|
||||
|
||||
// Drive LED pin
|
||||
#define BACKLIGHT_PIN 2
|
||||
|
||||
AW9364LedDriver ledDriver;
|
||||
|
||||
uint8_t level = 0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
#ifdef ENABLE_TFT
|
||||
tft.begin();
|
||||
tft.setRotation(1);
|
||||
tft.fillScreen(TFT_GREEN);
|
||||
#endif
|
||||
|
||||
// Initialize LED driver
|
||||
ledDriver.begin(BACKLIGHT_PIN);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// 16 dimming levels
|
||||
Serial.print("level:");
|
||||
Serial.println(level);
|
||||
ledDriver.setBrightness(level);
|
||||
level++;
|
||||
level %= MAX_BRIGHTNESS_STEPS;
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,293 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2023 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_6DoF.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-09-06
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <SensorBHI260AP.hpp>
|
||||
#include <bosch/BoschSensorDataHelper.hpp>
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
|
||||
/*
|
||||
* Define the USING_DATA_HELPER use of data assistants.
|
||||
* No callback function will be used. Data can be obtained directly through
|
||||
* the data assistant. Note that this method is not a thread-safe function.
|
||||
* Please pay attention to protecting data access security.
|
||||
* */
|
||||
#define USING_DATA_HELPER
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
SensorXYZ accel(SensorBHI260AP::ACCEL_PASSTHROUGH, bhy);
|
||||
SensorXYZ gyro(SensorBHI260AP::GYRO_PASSTHROUGH, bhy);
|
||||
#endif
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
#define BOSCH_APP30_SHUTTLE_BHI260_FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO
|
||||
// #define BOSCH_BHI260_AUX_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO
|
||||
// #define BOSCH_BHI260_GPIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_GPIO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
#ifndef USING_DATA_HELPER
|
||||
void xyz_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
struct bhy2_data_xyz data;
|
||||
float scaling_factor = bhy.getScaling(sensor_id);
|
||||
bhy2_parse_xyz(data_ptr, &data);
|
||||
Serial.print(bhy.getSensorName(sensor_id));
|
||||
Serial.print(" ");
|
||||
Serial.print("x: ");
|
||||
Serial.print(data.x * scaling_factor);
|
||||
Serial.print(", y: ");
|
||||
Serial.print(data.y * scaling_factor);
|
||||
Serial.print(", z: ");
|
||||
Serial.print(data.z * scaling_factor);
|
||||
Serial.println(";");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
float sample_rate = 100.0; /* Read out data measured at 100Hz */
|
||||
uint32_t report_latency_ms = 0; /* Report immediately */
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
// Enable acceleration
|
||||
accel.enable(sample_rate, report_latency_ms);
|
||||
// Enable gyroscope
|
||||
gyro.enable(sample_rate, report_latency_ms);
|
||||
#else
|
||||
// Enable acceleration
|
||||
bhy.configure(SensorBHI260AP::ACCEL_PASSTHROUGH, sample_rate, report_latency_ms);
|
||||
// Enable gyroscope
|
||||
bhy.configure(SensorBHI260AP::GYRO_PASSTHROUGH, sample_rate, report_latency_ms);
|
||||
// Set the acceleration sensor result callback function
|
||||
bhy.onResultEvent(SensorBHI260AP::ACCEL_PASSTHROUGH, xyz_process_callback);
|
||||
// Set the gyroscope sensor result callback function
|
||||
bhy.onResultEvent(SensorBHI260AP::GYRO_PASSTHROUGH, xyz_process_callback);
|
||||
#endif
|
||||
// Set the specified pin (BHI260_IRQ) as an input pin.
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
// Attach an interrupt service routine (ISR) 'dataReadyISR' to the specified pin (BHI260_IRQ).
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
#ifdef USING_DATA_HELPER
|
||||
if (accel.hasUpdated() && gyro.hasUpdated()) {
|
||||
uint32_t s;
|
||||
uint32_t ns;
|
||||
accel.getLastTime(s, ns);
|
||||
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
Serial.printf("[T: %" PRIu32 ".%09" PRIu32 "] AX:%+7.2f AY:%+7.2f AZ:%+7.2f GX:%+7.2f GY:%+7.2f GZ:%+7.2f \n",
|
||||
s, ns, accel.getX(), accel.getY(), accel.getZ(),
|
||||
gyro.getX(), gyro.getY(), gyro.getZ());
|
||||
|
||||
#else
|
||||
Serial.print("[T: ");
|
||||
Serial.print(s);
|
||||
Serial.print(".");
|
||||
Serial.print(ns);
|
||||
Serial.print("] AX:");
|
||||
Serial.print(accel.getX(), 2);
|
||||
Serial.print(" AY:");
|
||||
Serial.print(accel.getY(), 2);
|
||||
Serial.print(" AZ:");
|
||||
Serial.print(accel.getZ(), 2);
|
||||
Serial.print(" GX:");
|
||||
Serial.print(gyro.getX(), 2);
|
||||
Serial.print(" GY:");
|
||||
Serial.print(gyro.getY(), 2);
|
||||
Serial.print(" GZ:");
|
||||
Serial.print(gyro.getZ(), 2);
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif /*USING_DATA_HELPER*/
|
||||
delay(50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,278 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_Activity .ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-02-04
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <SensorBHI260AP.hpp>
|
||||
#include <bosch/BoschSensorDataHelper.hpp>
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
SensorActivity activity(bhy);
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
#define BOSCH_APP30_SHUTTLE_BHI260_FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO
|
||||
// #define BOSCH_BHI260_AUX_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO
|
||||
// #define BOSCH_BHI260_GPIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_GPIO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
float sample_rate = 1.0;
|
||||
uint32_t report_latency_ms = 0;
|
||||
/**
|
||||
* Configure the activity recognition sensor of the BHI260AP sensor.
|
||||
*
|
||||
* This function sets the sampling rate and report latency for the activity recognition sensor.
|
||||
* The sampling rate determines how often the sensor takes measurements, and the report latency
|
||||
* determines the delay between when a measurement is taken and when it is reported.
|
||||
* The activity recognition sensor will only be triggered when there is a change.
|
||||
* @param samplingRate The sampling rate of the sensor. A value greater than 1 enables the sensor,
|
||||
* while a value of 0 disables it.
|
||||
* @param latencyMs The report latency in milliseconds.
|
||||
*/
|
||||
activity.enable(sample_rate, report_latency_ms);
|
||||
|
||||
// Set the specified pin (BHI260_IRQ) as an input pin.
|
||||
// This prepares the pin to receive external signals.
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
|
||||
// Attach an interrupt service routine (ISR) to the specified pin (BHI260_IRQ).
|
||||
// The ISR 'dataReadyISR' will be called whenever a rising edge is detected on the pin.
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (activity.hasUpdated()) {
|
||||
|
||||
if (activity.isActivitySet(SensorActivity::STILL_ACTIVITY_ENDED)) {
|
||||
Serial.println("Still activity ended is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::WALKING_ACTIVITY_ENDED)) {
|
||||
Serial.println("Walking activity ended is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::RUNNING_ACTIVITY_ENDED)) {
|
||||
Serial.println("Running activity ended is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::ON_BICYCLE_ACTIVITY_ENDED)) {
|
||||
Serial.println("On Bicycle activity ended is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::IN_VEHICLE_ACTIVITY_ENDED)) {
|
||||
Serial.println("In Vehicle activity ended is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::TILTING_ACTIVITY_ENDED)) {
|
||||
Serial.println("Tilting activity ended is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::IN_VEHICLE_STILL_ENDED)) {
|
||||
Serial.println("In Vehicle still ended is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::STILL_ACTIVITY_STARTED)) {
|
||||
Serial.println("Still activity started is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::WALKING_ACTIVITY_STARTED)) {
|
||||
Serial.println("Walking activity started is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::RUNNING_ACTIVITY_STARTED)) {
|
||||
Serial.println("Running activity started is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::ON_BICYCLE_ACTIVITY_STARTED)) {
|
||||
Serial.println("On Bicycle activity started is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::IN_VEHICLE_ACTIVITY_STARTED)) {
|
||||
Serial.println("In Vehicle activity started is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::TILTING_ACTIVITY_STARTED)) {
|
||||
Serial.println("Tilting activity started is set.");
|
||||
}
|
||||
if (activity.isActivitySet(SensorActivity::IN_VEHICLE_STILL_STARTED)) {
|
||||
Serial.println("In Vehicle still started is set.");
|
||||
}
|
||||
}
|
||||
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
delay(50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,326 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_Euler.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-02-04
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <SensorBHI260AP.hpp>
|
||||
#include <bosch/BoschSensorDataHelper.hpp>
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
|
||||
/*
|
||||
* Define the USING_DATA_HELPER use of data assistants.
|
||||
* No callback function will be used. Data can be obtained directly through
|
||||
* the data assistant. Note that this method is not a thread-safe function.
|
||||
* Please pay attention to protecting data access security.
|
||||
* */
|
||||
#define USING_DATA_HELPER
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
SensorQuaternion quaternion(bhy);
|
||||
#endif
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
#define BOSCH_APP30_SHUTTLE_BHI260_FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO
|
||||
// #define BOSCH_BHI260_AUX_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO
|
||||
// #define BOSCH_BHI260_GPIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_GPIO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse the quaternion data from the sensor and convert it to Euler angles.
|
||||
*
|
||||
* This function serves as a callback to handle the sensor data related to the game rotation vector.
|
||||
* It takes the raw quaternion data received from the sensor, converts it into Euler angles (roll, pitch, and yaw),
|
||||
*
|
||||
* @param sensor_id The ID of the sensor that generated the data. It helps in identifying which specific sensor
|
||||
* the data is coming from, especially in systems with multiple sensors.
|
||||
* @param data_ptr A pointer to the buffer containing the raw quaternion data. The data in this buffer
|
||||
* represents the orientation of the sensor in quaternion format.
|
||||
* @param len The length of the data buffer, indicating the size of the quaternion data in bytes.
|
||||
* @param timestamp A pointer to a 64 - bit unsigned integer representing the timestamp when the sensor data was captured.
|
||||
* This can be used to correlate the data with a specific point in time.
|
||||
* @param user_data A generic pointer to user - defined data.
|
||||
*/
|
||||
#ifndef USING_DATA_HELPER
|
||||
void parse_quaternion(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
// Declare variables to store the Euler angles (roll, pitch, and yaw).
|
||||
float roll, pitch, yaw;
|
||||
// Call the bhy2_quaternion_to_euler function to convert the raw quaternion data
|
||||
// pointed to by data_ptr into Euler angles (roll, pitch, and yaw).
|
||||
bhy2_quaternion_to_euler(data_ptr, &roll, &pitch, &yaw);
|
||||
// Print the roll angle to the serial monitor.
|
||||
Serial.print(roll);
|
||||
// Print a comma as a separator between the roll and pitch angles.
|
||||
Serial.print(",");
|
||||
// Print the pitch angle to the serial monitor.
|
||||
Serial.print(pitch);
|
||||
// Print a comma as a separator between the pitch and yaw angles.
|
||||
Serial.print(",");
|
||||
// Print the yaw angle to the serial monitor and start a new line.
|
||||
Serial.println(yaw);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set the axis remapping for the sensor based on the specified orientation.
|
||||
*
|
||||
* This function allows you to configure the sensor's axis remapping according to a specific
|
||||
* physical orientation of the chip. By passing one of the values from the SensorRemap enum,
|
||||
* you can ensure that the sensor data is correctly interpreted based on how the chip is placed.
|
||||
* [bst-bhi260ab-ds000.pdf](https://www.mouser.com/datasheet/2/783/bst-bhi260ab-ds000-1816249.pdf)
|
||||
* 20.3 Sensing axes and axes remapping
|
||||
* @param remap An enumeration value from SensorRemap that specifies the desired axis remapping.
|
||||
* @return Returns true if the axis remapping is successfully set; false otherwise.
|
||||
*/
|
||||
|
||||
// Set the sensor's axis remapping based on the chip's orientation.
|
||||
// These commented-out lines show different ways to configure the sensor according to the chip's corners.
|
||||
// When the chip is viewed from the top, set the orientation to the top-left corner.
|
||||
// bhy.setRemapAxes(SensorBHI260AP::TOP_LAYER_LEFT_CORNER);
|
||||
// When the chip is viewed from the top, set the orientation to the top-right corner.
|
||||
// bhy.setRemapAxes(SensorBHI260AP::TOP_LAYER_RIGHT_CORNER);
|
||||
// When the chip is viewed from the top, set the orientation to the bottom-right corner of the top layer.
|
||||
// bhy.setRemapAxes(SensorBHI260AP::TOP_LAYER_BOTTOM_RIGHT_CORNER);
|
||||
// When the chip is viewed from the top, set the orientation to the bottom-left corner of the top layer.
|
||||
// bhy.setRemapAxes(SensorBHI260AP::TOP_LAYER_BOTTOM_LEFT_CORNER);
|
||||
// When the chip is viewed from the bottom, set the orientation to the top-left corner of the bottom layer.
|
||||
// bhy.setRemapAxes(SensorBHI260AP::BOTTOM_LAYER_TOP_LEFT_CORNER);
|
||||
// When the chip is viewed from the bottom, set the orientation to the top-right corner of the bottom layer.
|
||||
// bhy.setRemapAxes(SensorBHI260AP::BOTTOM_LAYER_TOP_RIGHT_CORNER);
|
||||
// When the chip is viewed from the bottom, set the orientation to the bottom-right corner of the bottom layer.
|
||||
// bhy.setRemapAxes(SensorBHI260AP::BOTTOM_LAYER_BOTTOM_RIGHT_CORNER);
|
||||
// When the chip is viewed from the bottom, set the orientation to the bottom-left corner of the bottom layer.
|
||||
// bhy.setRemapAxes(SensorBHI260AP::BOTTOM_LAYER_BOTTOM_LEFT_CORNER);
|
||||
|
||||
// Define the sample rate for data reading.
|
||||
// The sensor will read out data measured at a frequency of 100Hz.
|
||||
float sample_rate = 100.0;
|
||||
// Define the report latency in milliseconds.
|
||||
// A value of 0 means the sensor will report the measured data immediately.
|
||||
uint32_t report_latency_ms = 0;
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
quaternion.enable(sample_rate, report_latency_ms);
|
||||
#else
|
||||
// GAME_ROTATION_VECTOR virtual sensor does not rely on external magnetometers, such as BMM150, BMM350
|
||||
// Configure the sensor to measure the game rotation vector.
|
||||
// Set the sample rate and report latency for this measurement.
|
||||
bhy.configure(SensorBHI260AP::GAME_ROTATION_VECTOR, sample_rate, report_latency_ms);
|
||||
// Register a callback function 'parse_quaternion' to handle the result events of the game rotation vector measurement.
|
||||
// When the sensor has new data for the game rotation vector, the 'parse_quaternion' function will be called.
|
||||
bhy.onResultEvent(SensorBHI260AP::GAME_ROTATION_VECTOR, parse_quaternion);
|
||||
#endif
|
||||
|
||||
// Set the specified pin (BHI260_IRQ) as an input pin.
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
// Attach an interrupt service routine (ISR) 'dataReadyISR' to the specified pin (BHI260_IRQ).
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
if (quaternion.hasUpdated()) {
|
||||
// Convert rotation vector to Euler angles
|
||||
quaternion.toEuler();
|
||||
// Print the roll angle to the serial monitor.
|
||||
Serial.print(quaternion.getRoll());
|
||||
// Print a comma as a separator between the roll and pitch angles.
|
||||
Serial.print(",");
|
||||
// Print the pitch angle to the serial monitor.
|
||||
Serial.print(quaternion.getPitch());
|
||||
// Print a comma as a separator between the pitch and yaw angles.
|
||||
Serial.print(",");
|
||||
// Print the yaw angle to the serial monitor and start a new line.
|
||||
Serial.println(quaternion.getHeading());
|
||||
}
|
||||
#endif
|
||||
|
||||
delay(50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,319 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_Expand_GPIO.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-04
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorBHI260AP.hpp"
|
||||
|
||||
#include <Commander.h> //Deplib https://github.com/CreativeRobotics/Commander
|
||||
Commander cmd;
|
||||
void initialiseCommander();
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO
|
||||
// #define BOSCH_BHI260_AUX_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO
|
||||
#define BOSCH_BHI260_GPIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_GPIO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
initialiseCommander();
|
||||
|
||||
Serial.println("Hello: Type 'help' to get help");
|
||||
|
||||
cmd.printCommandPrompt();
|
||||
|
||||
// Register interrupt function
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
uint32_t check_millis = 0;
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Call the update functions using the activeCommander pointer
|
||||
cmd.update();
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//All commands for 'master'
|
||||
//COMMAND ARRAY ------------------------------------------------------------------------------
|
||||
const commandList_t masterCommands[] = {
|
||||
{"help", helpHandler, "help"},
|
||||
{"set gpio", setGpioLevel, "set gpio level"},
|
||||
{"get gpio", getGpioLevel, "get gpio level"},
|
||||
{"dis gpio", disGpioMode, "disable gpio"},
|
||||
};
|
||||
|
||||
void initialiseCommander()
|
||||
{
|
||||
cmd.begin(&Serial, masterCommands, sizeof(masterCommands));
|
||||
cmd.commandPrompt(ON); //enable the command prompt
|
||||
cmd.echo(true); //Echo incoming characters to theoutput port
|
||||
cmd.errorMessages(ON); //error messages are enabled - it will tell us if we issue any unrecognised commands
|
||||
//Error messaged do NOT work for quick set and get commands
|
||||
}
|
||||
|
||||
bool helpHandler(Commander &Cmdr)
|
||||
{
|
||||
Serial.println("Help:");
|
||||
Serial.println("\tCustom firmware valid gpio : 1, 4, 5, 6, 14, 15, 16, 17, 18, 19, 20");
|
||||
Serial.println("\tset gpio [gpio num] [level]");
|
||||
Serial.println("\tget gpio [gpio num] [pullup]");
|
||||
Serial.println("\tdis gpio [gpio num]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* GPIO Comparison Table
|
||||
* M1SCX = N.A ! INVALID PIN
|
||||
* M1SDX = N.A ! INVALID PIN
|
||||
* M1SDI = N.A ! INVALID PIN
|
||||
* M2SCX = 14 ! OK
|
||||
* M2SDX = 15 ! OK
|
||||
* M2SDI = 16 ! OK
|
||||
* MCSB1 = 1 ! OK
|
||||
* MCSB2 = 4 ! OK
|
||||
* M3SCL = 17 ! OK
|
||||
* M3SDA = 18 ! OK
|
||||
* MCSB3 = 5 ! OK
|
||||
* MCSB4 = 6 ! OK
|
||||
* JTAG_CLK = 19 ! OK
|
||||
* JTAG_DIO = 20 ! OK
|
||||
* RESV1 = 2 ! INVALID PIN
|
||||
* RESV2 = 3 ! INVALID PIN
|
||||
* RESV3 = N.A ! INVALID PIN
|
||||
* */
|
||||
bool setGpioLevel(Commander &Cmdr)
|
||||
{
|
||||
int values[2] = {0, 0};
|
||||
int items = Cmdr.countItems();
|
||||
if (items < 2) {
|
||||
return false;
|
||||
}
|
||||
for (int n = 0; n < 2; n++) {
|
||||
Cmdr.getInt(values[n]);
|
||||
}
|
||||
uint8_t pin = values[0];
|
||||
uint8_t level = values[1];
|
||||
bhy.digitalWrite(pin, level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool getGpioLevel(Commander &Cmdr)
|
||||
{
|
||||
int values[2] = {0, 0};
|
||||
int items = Cmdr.countItems();
|
||||
if (items < 1) {
|
||||
return 0;
|
||||
}
|
||||
if (items > 2 )items = 2;
|
||||
for (int n = 0; n < items; n++) {
|
||||
Cmdr.getInt(values[n]);
|
||||
}
|
||||
bool pullup = false;
|
||||
uint8_t pin = values[0];
|
||||
if (items == 2 ) {
|
||||
pullup = values[1];
|
||||
}
|
||||
uint8_t level = bhy.digitalRead(pin, pullup);
|
||||
Serial.print("Get GPIO : "); Serial.print(pin);
|
||||
Serial.print(" level is "); Serial.println(level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool disGpioMode(Commander &Cmdr)
|
||||
{
|
||||
int values[1] = {0};
|
||||
int items = Cmdr.countItems();
|
||||
if (items < 1) {
|
||||
return 0;
|
||||
}
|
||||
Cmdr.getInt(values[0]);
|
||||
uint8_t pin = values[0];
|
||||
bhy.disableGpio(pin);
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,276 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_Klio_Recognition.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-02-02
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorBHI260AP.hpp"
|
||||
#include "SensorBHI260AP_Klio.hpp"
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
SensorBHI260AP_Klio klio(bhy);
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
#define BOSCH_BHI260_KLIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_BHI260_KLIO_FLASH
|
||||
// #define BOSCH_BHI260_KLIO_TURBO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
/* Action 1 mode, BHI260 should point upwards, for action instructions,
|
||||
see action1.gif in the example directory */
|
||||
uint8_t action1_pattern_id = 1;
|
||||
uint8_t action1_pattern[] = {
|
||||
0x52, 0x42, 0x31, 0x06, 0x03, 0xfd, 0xad, 0x80,
|
||||
0x40, 0x0a, 0xd7, 0x23, 0x3c, 0x78, 0xe2, 0x44,
|
||||
0xbf, 0x63, 0xe1, 0x0d, 0xc0, 0x19, 0x39, 0x97,
|
||||
0xbf, 0xdb, 0x93, 0x04, 0x3f, 0xce, 0x07, 0xb7,
|
||||
0x3e, 0x5e, 0xda, 0xf0, 0x3d, 0xe3, 0x6f, 0x8f,
|
||||
0x3e, 0x65, 0x7c, 0x4f, 0x40, 0x46, 0x3f, 0xb4,
|
||||
0x3f, 0xdf, 0xd1, 0x3d, 0xbf, 0xfa, 0x5a, 0x82,
|
||||
0xbf, 0x35, 0xf6, 0x16, 0x3e, 0xbe, 0x70, 0x82,
|
||||
0x40, 0xaa, 0x21, 0x70, 0x41, 0xcb, 0x27, 0xf0,
|
||||
0x40, 0x19, 0x06, 0xd9, 0xbf, 0x3a, 0x10, 0xa7,
|
||||
0xbf, 0x27, 0x07, 0x31, 0x3f, 0x27, 0x23, 0xc9,
|
||||
0xbd, 0x44, 0x29, 0x2f, 0x40, 0xa6, 0x61, 0x97,
|
||||
0xc0, 0x29, 0x5d, 0x21, 0xbe, 0x82, 0xd4, 0x0d,
|
||||
0x3e, 0xc0, 0xf0, 0x15, 0x3d, 0x00, 0xbc, 0xda,
|
||||
0x3d, 0x14, 0x0c, 0xc5, 0xbd, 0x46, 0xa0, 0x03,
|
||||
0x3e, 0xca, 0x5c, 0x95, 0x3d, 0x24, 0xe5, 0x13,
|
||||
0x3c, 0x70, 0x0a, 0x81, 0x3c, 0x69, 0x22, 0xd6,
|
||||
0x3c, 0x51, 0xa4, 0xdf, 0x3e, 0x4c, 0xa8, 0x55,
|
||||
0xbf, 0xe1, 0xe8, 0xc7, 0xbd, 0xe8, 0x7c, 0xbe,
|
||||
0x3d, 0xf7, 0x5b, 0x21, 0x3c
|
||||
};
|
||||
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
// Attempt to initialize the KLIO sensor.
|
||||
if (!klio.begin()) {
|
||||
while (1) {
|
||||
Serial.println("Failed to initialize Klio sensor. Are you currently using a firmware that includes Klio sensor functionality?");
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// Call the getMaxPatterns() method of the klio object to get the maximum number of patterns allowed by the KLIO sensor.
|
||||
// This method returns a value of type uint8_t representing the maximum number of patterns and stores it in the variable max_patterns.
|
||||
uint8_t max_patterns = klio.getMaxPatterns();
|
||||
Serial.print("Klio sensor max patterns:");
|
||||
Serial.println(max_patterns);
|
||||
|
||||
// Set the callback function for the recognition event of the KLIO sensor.
|
||||
// The callback function takes a pattern ID, a count value, and a pointer to user data as parameters.
|
||||
// When a recognition event occurs, the callback function will be called, and it will print
|
||||
// information about the recognized pattern (pattern ID and count) to the serial monitor.
|
||||
// The user data pointer setting can be set to nullptr, or custom data can be passed in.
|
||||
// If the recognition action is successful, the pointer is passed to the callback function
|
||||
klio.setRecognitionCallback([](uint8_t pattern_id, float count, void *user_data) {
|
||||
Serial.print("<-Recognition[Id:");
|
||||
Serial.print(pattern_id);
|
||||
Serial.print(" Count:");
|
||||
Serial.print(count);
|
||||
Serial.print("]");
|
||||
}, nullptr);
|
||||
|
||||
// Try to write a pattern to the KLIO sensor.
|
||||
// The pattern ID is specified by action1_pattern_id,
|
||||
// and the pattern data is stored in the action1_pattern array.
|
||||
// The size of the pattern data is determined by sizeof(action1_pattern).
|
||||
if (!klio.writePattern(action1_pattern_id,
|
||||
action1_pattern,
|
||||
sizeof(action1_pattern))) {
|
||||
Serial.println("Klio write pattern failed!");
|
||||
}
|
||||
|
||||
// Start the recognition process for a specific pattern.
|
||||
// Pass the address of action1_pattern_id (indicating the pattern to be recognized)
|
||||
// and the number of patterns (1 in this case) to the recognition function.
|
||||
klio.recognition(&action1_pattern_id, 1);
|
||||
|
||||
// Define the sample rate at which data will be read from the KLIO sensor.
|
||||
// Here, the sample rate is set to 25Hz, meaning data will be read 25 times per second.
|
||||
float sample_rate = 25.0;
|
||||
|
||||
// Define the report latency in milliseconds.
|
||||
// A value of 0 means that the sensor will report data immediately as it is measured.
|
||||
uint32_t report_latency_ms = 0;
|
||||
|
||||
// Enable the KLIO sensor with he specified sample rate and report latency.
|
||||
// Once enabled, the sensor will start collecting and reporting data according to these settings.
|
||||
klio.enable(sample_rate, report_latency_ms);
|
||||
|
||||
// Set the specified pin (BHI260_IRQ) as an input pin.
|
||||
// This prepares the pin to receive external signals.
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
|
||||
// Attach an interrupt service routine (ISR) to the specified pin (BHI260_IRQ).
|
||||
// The ISR 'dataReadyISR' will be called whenever a rising edge is detected on the pin.
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
delay(50);
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
@ -0,0 +1,346 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_Klio_RecognizeMultiple.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-02-02
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorBHI260AP.hpp"
|
||||
#include "SensorBHI260AP_Klio.hpp"
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
SensorBHI260AP_Klio klio(bhy);
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
#define BOSCH_BHI260_KLIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_BHI260_KLIO_FLASH
|
||||
// #define BOSCH_BHI260_KLIO_TURBO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
/* Action 1 mode, BHI260 should point upwards, for action instructions,
|
||||
see action1.gif in the example directory */
|
||||
uint8_t action1_pattern_id = 1;
|
||||
uint8_t action1_pattern[] = {
|
||||
0x52, 0x42, 0x31, 0x06, 0x03, 0xfd, 0xad, 0x80,
|
||||
0x40, 0x0a, 0xd7, 0x23, 0x3c, 0x78, 0xe2, 0x44,
|
||||
0xbf, 0x63, 0xe1, 0x0d, 0xc0, 0x19, 0x39, 0x97,
|
||||
0xbf, 0xdb, 0x93, 0x04, 0x3f, 0xce, 0x07, 0xb7,
|
||||
0x3e, 0x5e, 0xda, 0xf0, 0x3d, 0xe3, 0x6f, 0x8f,
|
||||
0x3e, 0x65, 0x7c, 0x4f, 0x40, 0x46, 0x3f, 0xb4,
|
||||
0x3f, 0xdf, 0xd1, 0x3d, 0xbf, 0xfa, 0x5a, 0x82,
|
||||
0xbf, 0x35, 0xf6, 0x16, 0x3e, 0xbe, 0x70, 0x82,
|
||||
0x40, 0xaa, 0x21, 0x70, 0x41, 0xcb, 0x27, 0xf0,
|
||||
0x40, 0x19, 0x06, 0xd9, 0xbf, 0x3a, 0x10, 0xa7,
|
||||
0xbf, 0x27, 0x07, 0x31, 0x3f, 0x27, 0x23, 0xc9,
|
||||
0xbd, 0x44, 0x29, 0x2f, 0x40, 0xa6, 0x61, 0x97,
|
||||
0xc0, 0x29, 0x5d, 0x21, 0xbe, 0x82, 0xd4, 0x0d,
|
||||
0x3e, 0xc0, 0xf0, 0x15, 0x3d, 0x00, 0xbc, 0xda,
|
||||
0x3d, 0x14, 0x0c, 0xc5, 0xbd, 0x46, 0xa0, 0x03,
|
||||
0x3e, 0xca, 0x5c, 0x95, 0x3d, 0x24, 0xe5, 0x13,
|
||||
0x3c, 0x70, 0x0a, 0x81, 0x3c, 0x69, 0x22, 0xd6,
|
||||
0x3c, 0x51, 0xa4, 0xdf, 0x3e, 0x4c, 0xa8, 0x55,
|
||||
0xbf, 0xe1, 0xe8, 0xc7, 0xbd, 0xe8, 0x7c, 0xbe,
|
||||
0x3d, 0xf7, 0x5b, 0x21, 0x3c
|
||||
};
|
||||
|
||||
/* Action 2 mode, BHI260 should point to the right,
|
||||
for action instructions, see action2.gif in the example directory*/
|
||||
uint8_t action2_pattern_id = 2;
|
||||
const uint8_t action2_pattern[] = {
|
||||
0x52, 0x42, 0x31, 0x06, 0x03, 0xfd, 0xad, 0x80,
|
||||
0x40, 0x0a, 0xd7, 0x23, 0x3c, 0x38, 0xf3, 0x08,
|
||||
0x40, 0x1a, 0x9e, 0x06, 0xbf, 0xde, 0xcd, 0xca,
|
||||
0x3d, 0x88, 0xb3, 0x9b, 0x3e, 0x01, 0x26, 0xb9,
|
||||
0x3d, 0x8f, 0xe9, 0x88, 0x3d, 0x6e, 0xc3, 0x13,
|
||||
0xc1, 0x4f, 0x1e, 0x09, 0x40, 0x75, 0x7a, 0x2d,
|
||||
0xc0, 0x80, 0x31, 0xdb, 0xbd, 0x2f, 0x1e, 0x83,
|
||||
0x3f, 0xc0, 0x6f, 0x10, 0x3d, 0xf7, 0xc1, 0x26,
|
||||
0xbf, 0x5a, 0x36, 0x00, 0x3f, 0x8b, 0x31, 0x77,
|
||||
0xbe, 0x51, 0x09, 0x3b, 0xbf, 0x16, 0xa9, 0xa0,
|
||||
0xbf, 0x6d, 0x90, 0x89, 0x3d, 0x39, 0x79, 0xb3,
|
||||
0x3d, 0x39, 0x0e, 0x9f, 0xbd, 0xfc, 0x77, 0x55,
|
||||
0xbd, 0x69, 0x44, 0x13, 0xbf, 0x02, 0x31, 0x14,
|
||||
0x3e, 0x60, 0xe6, 0x75, 0x3b, 0xd2, 0x69, 0x19,
|
||||
0xbc, 0xa8, 0x41, 0x46, 0x3d, 0x87, 0x45, 0x88,
|
||||
0x3e, 0x70, 0xf7, 0x87, 0x3d, 0x81, 0x8a, 0xe2,
|
||||
0x3d, 0xea, 0x15, 0x8d, 0x3b, 0xf5, 0x2e, 0xc1,
|
||||
0x3c, 0x1e, 0xcc, 0x05, 0x3e, 0x00, 0x70, 0x16,
|
||||
0x3c, 0x41, 0x8b, 0x07, 0xbe, 0x4e, 0xd8, 0xb0,
|
||||
0x3d, 0x94, 0xd9, 0x40, 0x3b
|
||||
};
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback function for KLIO sensor recognition events.
|
||||
*
|
||||
* This function serves as a callback that gets triggered when the KLIO sensor
|
||||
* successfully recognizes a pattern. It's designed to handle the recognition
|
||||
* event and provide information about the recognized pattern.
|
||||
*
|
||||
* @param pattern_id The unique identifier of the recognized pattern.
|
||||
* Each pattern in the KLIO sensor's recognition library
|
||||
* is assigned a distinct ID, and this parameter indicates
|
||||
* which specific pattern has been recognized.
|
||||
* @param count A floating point value representing the number of actions with
|
||||
* the recognized pattern
|
||||
* @param user_data A generic pointer to user - defined data. This can be used
|
||||
* to pass additional context or information from the calling
|
||||
* code to the callback function.
|
||||
*/
|
||||
void recognition_event_callback(uint8_t pattern_id, float count, void *user_data)
|
||||
{
|
||||
Serial.print("<-Recognition[Id:");
|
||||
Serial.print(pattern_id);
|
||||
Serial.print(" Count:");
|
||||
Serial.print(count);
|
||||
Serial.print("]");
|
||||
|
||||
// When the recognition counter is greater than 10 times, reset the recognition counter
|
||||
if (count > 10) {
|
||||
|
||||
Serial.println("Reset recognition counter!");
|
||||
|
||||
// Disable Klio
|
||||
klio.disable();
|
||||
|
||||
// Restart Recognition
|
||||
beginRecognition();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void beginRecognition()
|
||||
{
|
||||
// Define an array to hold the IDs of the patterns to be written to the KLIO sensor.
|
||||
// 'action1_pattern_id' and 'action2_pattern_id' are predefined pattern IDs.
|
||||
uint8_t patterns_ids[] = {action1_pattern_id, action2_pattern_id};
|
||||
|
||||
// Define an array of pointers to the actual pattern data.
|
||||
// 'action1_pattern' and 'action2_pattern' are arrays containing the pattern data.
|
||||
const uint8_t *patterns[] = {action1_pattern, action2_pattern};
|
||||
|
||||
// Define an array to hold the sizes of each pattern.
|
||||
// Use the sizeof operator to determine the size of each pattern array.
|
||||
uint16_t patterns_sizes[] = {sizeof(action1_pattern), sizeof(action2_pattern)};
|
||||
|
||||
// Calculate the number of patterns in the 'patterns_ids' array.
|
||||
// This is done by dividing the total size of the array by the size of a single element.
|
||||
uint8_t patterns_count = sizeof(patterns_ids) / sizeof(patterns_ids[0]);
|
||||
|
||||
// Try to write multiple patterns to the KLIO sensor.
|
||||
// Call the writeMultiplePatterns() method with the arrays of pattern IDs, pattern data pointers,
|
||||
// pattern sizes, and the number of patterns. If the write operation fails, print an error message.
|
||||
if (!klio.writeMultiplePatterns(patterns_ids, patterns, patterns_sizes, patterns_count)) {
|
||||
Serial.println("Klio write multiple patterns failed!");
|
||||
}
|
||||
|
||||
// Start the recognition process for the specified patterns.
|
||||
// Call the recognition() method with the array of pattern IDs and the number of patterns.
|
||||
klio.recognition(patterns_ids, patterns_count);
|
||||
|
||||
// Define the sample rate for data reading.
|
||||
// The sample rate is set to 25.0 Hz, meaning data will be read 25 times per second.
|
||||
float sample_rate = 25.0; /* Read out data measured at 25Hz */
|
||||
|
||||
// Define the report latency in milliseconds.
|
||||
// A value of 0 means that the sensor will report data immediately as it is measured.
|
||||
uint32_t report_latency_ms = 0; /* Report immediately */
|
||||
|
||||
// Enable the KLIO sensor with the specified sample rate and report latency.
|
||||
// Call the enable() method to activate the sensor and configure it according to the settings.
|
||||
klio.enable(sample_rate, report_latency_ms);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
// Try to initialize the KLIO sensor.
|
||||
if (!klio.begin()) {
|
||||
while (1) {
|
||||
Serial.println("Failed to initialize Klio sensor. Are you currently using a firmware that includes Klio sensor functionality?");
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the callback function for recognition events.
|
||||
// Similar to the learning callback, the setRecognitionCallback() method registers a function
|
||||
// that will be invoked when a recognition - related event happens in the KLIO sensor.
|
||||
// 'recognition_event_callback' is the callback function, and 'nullptr' is used as the user data pointer.
|
||||
klio.setRecognitionCallback(recognition_event_callback, nullptr);
|
||||
|
||||
// Start Recognition
|
||||
beginRecognition();
|
||||
|
||||
// Set the specified pin (BHI260_IRQ) as an input pin.
|
||||
// This prepares the pin to receive external signals.
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
|
||||
// Attach an interrupt service routine (ISR) to the specified pin (BHI260_IRQ).
|
||||
// The ISR 'dataReadyISR' will be called whenever a rising edge is detected on the pin.
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
|
||||
Serial.println("Please check the gif(atcion1.gif,action2.gif) image in the example directory to see the action instructions."
|
||||
"If the action meets the record value, the action record counter will be triggered.");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
delay(50);
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 244 KiB |
@ -0,0 +1,348 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_Klio_Selflearning.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-02-02
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorBHI260AP.hpp"
|
||||
#include "SensorBHI260AP_Klio.hpp"
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
SensorBHI260AP_Klio klio(bhy);
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
#define BOSCH_BHI260_KLIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_BHI260_KLIO_FLASH
|
||||
// #define BOSCH_BHI260_KLIO_TURBO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback function for handling KLIO sensor recognition events.
|
||||
*
|
||||
* This function is invoked when the KLIO sensor successfully recognizes a specific pattern.
|
||||
* Its main purpose is to print information about the recognized pattern, including the pattern ID
|
||||
* and the recognition count, to the serial monitor. This allows developers to monitor the recognition
|
||||
* process effectively.
|
||||
*
|
||||
* @param pattern_id The unique identifier of the recognized pattern. Each predefined or learned
|
||||
* pattern in the system has a distinct ID, and this parameter indicates which
|
||||
* specific pattern has been recognized.
|
||||
* @param count A floating-point value representing the recognition count. This could be the number
|
||||
* of times the pattern has been recognized, a confidence level associated with the
|
||||
* recognition, or some other metric depending on the implementation of the recognition
|
||||
* algorithm.
|
||||
* @param user_data A pointer to user-defined data. It can be used to pass additional context or
|
||||
* information from the calling code to this callback function. In this implementation,
|
||||
* it is not used, but it is included to maintain compatibility with the callback function signature.
|
||||
*/
|
||||
void recognition_event_callback(uint8_t pattern_id, float count, void *user_data)
|
||||
{
|
||||
Serial.print("<-Recognition[Id:");
|
||||
Serial.print(pattern_id);
|
||||
Serial.print(" Count:");
|
||||
Serial.print(count);
|
||||
Serial.print("]");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback function for KLIO sensor learning events.
|
||||
*
|
||||
* This function is invoked whenever there is a change in the learning process of the KLIO sensor.
|
||||
* It handles different learning - related events, logs information about the learning progress,
|
||||
* and takes actions based on the learning results.
|
||||
*
|
||||
* @param reason The reason for the learning change. It is an enumeration value from the
|
||||
* SensorBHI260AP_Klio::LeaningChangeReason type, indicating why the learning state has changed.
|
||||
* @param progress The current progress of the learning process, represented as an unsigned 32 - bit integer.
|
||||
* This value typically ranges from 0 to 100, indicating the percentage of the learning completion.
|
||||
* @param learn_index The index of the learned pattern. If the learning is invalid, it will be set to
|
||||
* SensorBHI260AP_Klio::INVALID_LEARNING_INDEX. Otherwise, it represents the index of the successfully learned pattern.
|
||||
* @param user_data A pointer to user - defined data. It can be used to pass additional context information
|
||||
* from the calling code to this callback function. In this implementation, it may not be used actively.
|
||||
*/
|
||||
void learning_event_callback(SensorBHI260AP_Klio::LeaningChangeReason reason, uint32_t progress, int learn_index, void *user_data)
|
||||
{
|
||||
// Print the learning event details to the serial monitor, including the progress, reason, and learned pattern index.
|
||||
Serial.print("->Learning [Progress:");
|
||||
Serial.print(progress);
|
||||
Serial.print(" Reason:");
|
||||
Serial.print(static_cast<uint8_t>(reason));
|
||||
Serial.print(" ID:");
|
||||
Serial.print(learn_index);
|
||||
Serial.println("]");
|
||||
|
||||
// Check if the learning index is valid (not equal to INVALID_LEARNING_INDEX).
|
||||
if (learn_index != SensorBHI260AP_Klio::INVALID_LEARNING_INDEX) {
|
||||
// Create a buffer to store the learned pattern data. The buffer size is 252 bytes.
|
||||
uint8_t tmp_buf[252];
|
||||
// Store the size of the buffer. This variable will be updated with the actual size of the learned pattern.
|
||||
uint16_t bufsize = sizeof(tmp_buf);
|
||||
|
||||
// Try to retrieve the learned pattern from the sensor using the getLearnPattern function.
|
||||
// The result indicates whether the retrieval is successful.
|
||||
bool learn_success = klio.getLearnPattern(tmp_buf, &bufsize);
|
||||
if (!learn_success) {
|
||||
// If the retrieval fails, print an error message and the specific error reason.
|
||||
Serial.print("Read learnt failed. Reason:");
|
||||
Serial.println(klio.errorToString());
|
||||
} else {
|
||||
// If the retrieval is successful, print a success message and the details of the learned pattern.
|
||||
Serial.println("Learning the action successfully");
|
||||
Serial.println("PATTERN LEARNT: ");
|
||||
Serial.print("const uint8_t * learn_pattern = { ");
|
||||
// Iterate through the buffer and print the pattern data in hexadecimal format.
|
||||
for (uint16_t i = 0; i < bufsize; i++) {
|
||||
if (i > 0 && i % 8 == 0) {
|
||||
// Print a new line every 8 bytes for better readability.
|
||||
Serial.println();
|
||||
}
|
||||
Serial.print("0x"); Serial.print(tmp_buf[i], HEX);
|
||||
if (i < bufsize - 1) {
|
||||
// Add a comma and a space after each byte except the last one.
|
||||
Serial.print(", ");
|
||||
}
|
||||
}
|
||||
Serial.println(" \n};\n");
|
||||
}
|
||||
// Print a message indicating that the learned pattern will be written.
|
||||
Serial.println("Write the learning pattern.");
|
||||
// Define an example pattern ID.
|
||||
uint8_t examples_id = 1;
|
||||
// Try to write the learned pattern to the sensor using the writePattern function.
|
||||
if (!klio.writePattern(examples_id, tmp_buf, bufsize)) {
|
||||
// If the write operation fails, print an error message.
|
||||
Serial.println("Klio write pattern failed!");
|
||||
}
|
||||
// Print messages indicating that the action recognition will start.
|
||||
Serial.println("Start recognizing actions");
|
||||
Serial.println("Please perform the learned action instructions and the sensor will start to recognize the number of actions.");
|
||||
// Start the recognition process for the specified pattern ID.
|
||||
klio.recognition(&examples_id, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
// Try to initialize the KLIO sensor.
|
||||
// The begin() method is called on the 'klio' object to set up the sensor.
|
||||
if (!klio.begin()) {
|
||||
while (1) {
|
||||
Serial.println("Failed to initialize Klio sensor. Are you currently using a firmware that includes Klio sensor functionality?");
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// Call the getMaxPatterns() method of the klio object to get the maximum number of patterns allowed by the KLIO sensor.
|
||||
// This method returns a value of type uint8_t representing the maximum number of patterns and stores it in the variable max_patterns.
|
||||
uint8_t max_patterns = klio.getMaxPatterns();
|
||||
Serial.print("Klio sensor max patterns:");
|
||||
Serial.println(max_patterns);
|
||||
|
||||
// Set the callback function for learning events.
|
||||
// The setLearningCallback() method is used to register a function that will be called
|
||||
// whenever a learning - related event occurs in the KLIO sensor.
|
||||
// 'learning_event_callback' is the name of the callback function,
|
||||
// and 'nullptr' is passed as the user data pointer, meaning no additional user - specific data is provided.
|
||||
klio.setLearningCallback(learning_event_callback, nullptr);
|
||||
|
||||
// Set the callback function for recognition events.
|
||||
// Similar to the learning callback, the setRecognitionCallback() method registers a function
|
||||
// that will be invoked when a recognition - related event happens in the KLIO sensor.
|
||||
// 'recognition_event_callback' is the callback function, and 'nullptr' is used as the user data pointer.
|
||||
klio.setRecognitionCallback(recognition_event_callback, nullptr);
|
||||
|
||||
// Start the learning process of the KLIO sensor.
|
||||
// The learning() method initiates the sensor's functionality to start learning patterns or behaviors.
|
||||
klio.learning();
|
||||
|
||||
// Define the sample rate for data reading.
|
||||
// The variable'sample_rate' is set to 25.0, which means the sensor will read out data
|
||||
// at a frequency of 25 Hertz (25 times per second).
|
||||
float sample_rate = 25.0;
|
||||
|
||||
// Define the report latency in milliseconds.
|
||||
// The variable'report_latency_ms' is set to 0, indicating that the sensor should report
|
||||
// the measured data immediately without any delay.
|
||||
uint32_t report_latency_ms = 0;
|
||||
|
||||
// Enable the KLIO sensor with he specified sample rate and report latency.
|
||||
// The enable() method activates the sensor and configures it to operate at the given sample rate
|
||||
// and report latency. This allows the sensor to start collecting and reporting data according to the settings.
|
||||
klio.enable(sample_rate, report_latency_ms);
|
||||
|
||||
// Set the specified pin (BHI260_IRQ) as an input pin.
|
||||
// This prepares the pin to receive external signals.
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
|
||||
// Attach an interrupt service routine (ISR) to the specified pin (BHI260_IRQ).
|
||||
// The ISR 'dataReadyISR' will be called whenever a rising edge is detected on the pin.
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
|
||||
Serial.println("Please repeat the movements you want to learn and the sensor will start recording.");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
delay(50);
|
||||
}
|
||||
@ -0,0 +1,303 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2023 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_Orientation.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-10-07
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <SensorBHI260AP.hpp>
|
||||
#include <bosch/BoschSensorDataHelper.hpp>
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
|
||||
/*
|
||||
* Define the USING_DATA_HELPER use of data assistants.
|
||||
* No callback function will be used. Data can be obtained directly through
|
||||
* the data assistant. Note that this method is not a thread-safe function.
|
||||
* Please pay attention to protecting data access security.
|
||||
* */
|
||||
#define USING_DATA_HELPER
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
SensorOrientation orientation(bhy);
|
||||
#endif
|
||||
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
#define BOSCH_APP30_SHUTTLE_BHI260_FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO
|
||||
// #define BOSCH_BHI260_AUX_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO
|
||||
// #define BOSCH_BHI260_GPIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_GPIO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
void print_orientation(uint8_t direction)
|
||||
{
|
||||
char report[256];
|
||||
switch (direction) {
|
||||
case SensorBHI260AP::DIRECTION_BOTTOM_LEFT:
|
||||
sprintf( report, "\r\n ________________ " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | * | " \
|
||||
"\r\n |________________| \r\n" );
|
||||
|
||||
break;
|
||||
case SensorBHI260AP::DIRECTION_TOP_RIGHT:
|
||||
sprintf( report, "\r\n ________________ " \
|
||||
"\r\n | | " \
|
||||
"\r\n | * | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n |________________| \r\n" );
|
||||
break;
|
||||
case SensorBHI260AP::DIRECTION_TOP_LEFT:
|
||||
sprintf( report, "\r\n ________________ " \
|
||||
"\r\n | | " \
|
||||
"\r\n | * | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n |________________| \r\n" );
|
||||
break;
|
||||
case SensorBHI260AP::DIRECTION_BOTTOM_RIGHT:
|
||||
sprintf( report, "\r\n ________________ " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | * | " \
|
||||
"\r\n |________________| \r\n" );
|
||||
break;
|
||||
default:
|
||||
sprintf( report, "None of the 3D orientation axes is set in BHI260 - accelerometer.\r\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.println(direction);
|
||||
Serial.println(report);
|
||||
}
|
||||
|
||||
#ifndef USING_DATA_HELPER
|
||||
void orientation_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
uint8_t direction = *data_ptr;
|
||||
Serial.print(bhy.getSensorName(sensor_id));
|
||||
Serial.print(":");
|
||||
print_orientation(direction);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Init BHI260AP Sensor success!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
// The orientation sensor will only report when it changes, so the value is 0 ~ 1
|
||||
float sample_rate = 1;
|
||||
uint32_t report_latency_ms = 0; /* Report immediately */
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
orientation.enable(sample_rate, report_latency_ms);
|
||||
#else
|
||||
// Enable direction detection
|
||||
bhy.configure(SensorBHI260AP::DEVICE_ORIENTATION, sample_rate, report_latency_ms);
|
||||
// Set the direction detection result output processing function
|
||||
bhy.onResultEvent(SensorBHI260AP::DEVICE_ORIENTATION, orientation_process_callback);
|
||||
#endif
|
||||
// Set the specified pin (BHI260_IRQ) as an input pin.
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
// Attach an interrupt service routine (ISR) 'dataReadyISR' to the specified pin (BHI260_IRQ).
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
if (orientation.hasUpdated()) {
|
||||
print_orientation(orientation.getOrientation());
|
||||
}
|
||||
#endif
|
||||
delay(50);
|
||||
}
|
||||
|
||||
@ -0,0 +1,290 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2023 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_StepCounter.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-10-08
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <SensorBHI260AP.hpp>
|
||||
#include <bosch/BoschSensorDataHelper.hpp>
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
|
||||
/*
|
||||
* Define the USING_DATA_HELPER use of data assistants.
|
||||
* No callback function will be used. Data can be obtained directly through
|
||||
* the data assistant. Note that this method is not a thread-safe function.
|
||||
* Please pay attention to protecting data access security.
|
||||
* */
|
||||
#define USING_DATA_HELPER
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
SensorStepCounter stepCounter(bhy);
|
||||
SensorStepDetector stepDetector(bhy);
|
||||
#endif
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
#define BOSCH_APP30_SHUTTLE_BHI260_FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO
|
||||
// #define BOSCH_BHI260_AUX_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO
|
||||
// #define BOSCH_BHI260_GPIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_GPIO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
#ifndef USING_DATA_HELPER
|
||||
void step_detector_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
Serial.print(bhy.getSensorName(sensor_id));
|
||||
Serial.println(" detected.");
|
||||
}
|
||||
|
||||
void step_counter_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
Serial.print(bhy.getSensorName(sensor_id));
|
||||
Serial.print(":");
|
||||
Serial.println(bhy2_parse_step_counter(data_ptr));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
// The stepcount sensor will only report when it changes, so the value is 0 ~ 1
|
||||
float sample_rate = 1.0;
|
||||
uint32_t report_latency_ms = 0; /* Report immediately */
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
stepDetector.enable(sample_rate, report_latency_ms);
|
||||
stepCounter.enable(sample_rate, report_latency_ms);
|
||||
#else
|
||||
// Enable Step detector
|
||||
bhy.configure(SensorBHI260AP::STEP_DETECTOR, sample_rate, report_latency_ms);
|
||||
// Enable Step counter
|
||||
bhy.configure(SensorBHI260AP::STEP_COUNTER, sample_rate, report_latency_ms);
|
||||
// Set the number of steps to detect the callback function
|
||||
bhy.onResultEvent(SensorBHI260AP::STEP_DETECTOR, step_detector_process_callback);
|
||||
bhy.onResultEvent(SensorBHI260AP::STEP_COUNTER, step_counter_process_callback);
|
||||
#endif
|
||||
|
||||
// Set the specified pin (BHI260_IRQ) as an input pin.
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
// Attach an interrupt service routine (ISR) 'dataReadyISR' to the specified pin (BHI260_IRQ).
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint32_t s;
|
||||
uint32_t ns;
|
||||
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
if (stepCounter.hasUpdated()) {
|
||||
stepCounter.getLastTime(s, ns);
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
Serial.printf("[T: %" PRIu32 ".%09" PRIu32 "]: Step Count:", s, ns);
|
||||
#else
|
||||
Serial.print("[T: ");
|
||||
Serial.print(s);
|
||||
Serial.print(".");
|
||||
Serial.print(ns);
|
||||
Serial.print("]: Step Count:");
|
||||
#endif
|
||||
Serial.println(stepCounter.getStepCount());
|
||||
}
|
||||
if (stepDetector.hasUpdated()) {
|
||||
if (stepDetector.isDetected()) {
|
||||
stepDetector.getLastTime(s, ns);
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
Serial.printf("[T: %" PRIu32 ".%09" PRIu32 "]:", s, ns);
|
||||
#else
|
||||
Serial.print("[T: ");
|
||||
Serial.print(s);
|
||||
Serial.print(".");
|
||||
Serial.print(ns);
|
||||
Serial.print("]:");
|
||||
#endif
|
||||
Serial.println("Step detector detects steps");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
delay(50);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,292 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2024 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_UpdateFirmware.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2024-10-23
|
||||
* @note Demonstrates loading firmware from a file into BHI260, only testing the NRF52840 platform
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#if defined(ARDUINO_ARCH_NRF52)
|
||||
|
||||
#include <SdFat.h> //Deplib https://github.com/adafruit/SdFat.git
|
||||
#include <SensorBHI260AP.hpp>
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_SPI_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
|
||||
|
||||
#define CS_PIN 5
|
||||
|
||||
/***************************************
|
||||
* SD CARD
|
||||
***************************************/
|
||||
SdFat32 sd;
|
||||
|
||||
// Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.
|
||||
#define SPI_CLOCK SD_SCK_MHZ(8)
|
||||
//------------------------------------------------------------------------------
|
||||
// Store error strings in flash to save RAM.
|
||||
#define error(s) sd.errorHalt(&Serial, F(s))
|
||||
#define SD_CONFIG SdSpiConfig(CS_PIN, DEDICATED_SPI, SPI_CLOCK)
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
void parse_bme280_sensor_data(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
float humidity = 0;
|
||||
float temperature = 0;
|
||||
float pressure = 0;
|
||||
switch (sensor_id) {
|
||||
case SensorBHI260AP::HUMIDITY:
|
||||
bhy2_parse_humidity(data_ptr, &humidity);
|
||||
Serial.print("humidity:"); Serial.print(humidity); Serial.println("%");
|
||||
break;
|
||||
case SensorBHI260AP::TEMPERATURE:
|
||||
bhy2_parse_temperature_celsius(data_ptr, &temperature);
|
||||
Serial.print("temperature:"); Serial.print(temperature); Serial.println("*C");
|
||||
break;
|
||||
case SensorBHI260AP::BAROMETER:
|
||||
bhy2_parse_pressure(data_ptr, &pressure);
|
||||
Serial.print("pressure:"); Serial.print(pressure); Serial.println("hPa");
|
||||
break;
|
||||
default:
|
||||
Serial.println("Unkown.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void printResult(uint8_t sensor_id, float sample_rate, bool rlst)
|
||||
{
|
||||
const char *sensorName = bhy.getSensorName(sensor_id);
|
||||
Serial.print("Configure ");
|
||||
Serial.print(sensorName);
|
||||
Serial.print(" sensor ");
|
||||
Serial.print(sample_rate, 2);
|
||||
Serial.print(" HZ ");
|
||||
if (rlst) {
|
||||
Serial.print("successfully");
|
||||
} else {
|
||||
Serial.print("failed");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// In this example, BHI260 and SD Card are on the same SPI bus
|
||||
SPI.setPins(SPI_MISO, SPI_SCK, SPI_MOSI);
|
||||
|
||||
SPI.begin();
|
||||
|
||||
/***************************************
|
||||
* SD CARD
|
||||
***************************************/
|
||||
// If multiple SPI peripherals are mounted on a single bus, first set the CS of other peripherals to HIGH
|
||||
const uint8_t other_spi_dev_cs_pin[] = {5, 28, 40};
|
||||
for (size_t i = 0; i < sizeof(other_spi_dev_cs_pin); ++i) {
|
||||
pinMode(other_spi_dev_cs_pin[i], OUTPUT);
|
||||
digitalWrite(other_spi_dev_cs_pin[i], HIGH);
|
||||
}
|
||||
|
||||
// Initialize the SD card.
|
||||
Serial.println("Initializing SD Card ...");
|
||||
if (!sd.begin(SD_CONFIG)) {
|
||||
sd.initErrorHalt(&Serial);
|
||||
while (1);
|
||||
} else {
|
||||
Serial.println(" success");
|
||||
}
|
||||
|
||||
File firmware_file = sd.open("/BHI260AP_aux_BMM150_BME280_GPIO-flash.fw", FILE_READ);
|
||||
if (!firmware_file) {
|
||||
Serial.println("Open firmware file failed!");
|
||||
while (1);
|
||||
}
|
||||
|
||||
size_t fw_size = firmware_file.size();
|
||||
Serial.println("Read firmware file successfully .");
|
||||
|
||||
uint8_t *firmware = (uint8_t *)malloc(fw_size);
|
||||
if (!firmware) {
|
||||
Serial.println("malloc memory failed!");
|
||||
while (1);
|
||||
}
|
||||
|
||||
firmware_file.readBytes(firmware, fw_size);
|
||||
|
||||
firmware_file.close();
|
||||
|
||||
|
||||
/***************************************
|
||||
* BHI260 Initializing
|
||||
***************************************/
|
||||
Serial.println("Initializing Sensors...");
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
// Force update of the current firmware, regardless of whether it exists.
|
||||
// After uploading the firmware once, you can change it to false to speed up the startup time.
|
||||
bool force_update = true;
|
||||
// true : Write firmware to flash , false : Write to ram
|
||||
bool write_to_flash = true;
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(firmware, fw_size, write_to_flash, force_update);
|
||||
// Set to load firmware from flash or ram
|
||||
bhy.setBootFromFlash(write_to_flash);
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Release the requested memory space
|
||||
free(firmware);
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enable monitoring.
|
||||
* sample_rate can only control the rate of the pressure sensor.
|
||||
* Temperature and humidity will only be updated when there is a change.
|
||||
* * */
|
||||
float sample_rate = 1.0; /* Set to 1Hz update frequency */
|
||||
uint32_t report_latency_ms = 0; /* Report immediately */
|
||||
bool rlst = false;
|
||||
|
||||
rlst = bhy.configure(SensorBHI260AP::TEMPERATURE, sample_rate, report_latency_ms);
|
||||
printResult(SensorBHI260AP::TEMPERATURE, sample_rate, rlst);
|
||||
rlst = bhy.configure(SensorBHI260AP::BAROMETER, sample_rate, report_latency_ms);
|
||||
printResult(SensorBHI260AP::BAROMETER, sample_rate, rlst);
|
||||
rlst = bhy.configure(SensorBHI260AP::HUMIDITY, sample_rate, report_latency_ms);
|
||||
printResult(SensorBHI260AP::HUMIDITY, sample_rate, rlst);
|
||||
|
||||
// Register BME280 data parse callback function
|
||||
Serial.println("Register sensor result callback function");
|
||||
bhy.onResultEvent(SensorBHI260AP::TEMPERATURE, parse_bme280_sensor_data);
|
||||
bhy.onResultEvent(SensorBHI260AP::HUMIDITY, parse_bme280_sensor_data);
|
||||
bhy.onResultEvent(SensorBHI260AP::BAROMETER, parse_bme280_sensor_data);
|
||||
|
||||
// Register interrupt function
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
delay(50);
|
||||
}
|
||||
#else
|
||||
void setup() {}
|
||||
void loop() {}
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,295 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2024 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_aux_BMM150.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2024-07-22
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <SensorBHI260AP.hpp>
|
||||
#include <bosch/BoschSensorDataHelper.hpp>
|
||||
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
|
||||
/*
|
||||
* Define the USING_DATA_HELPER use of data assistants.
|
||||
* No callback function will be used. Data can be obtained directly through
|
||||
* the data assistant. Note that this method is not a thread-safe function.
|
||||
* Please pay attention to protecting data access security.
|
||||
* */
|
||||
#define USING_DATA_HELPER
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
SensorXYZ accel(SensorBHI260AP::ACCEL_PASSTHROUGH, bhy);
|
||||
SensorXYZ gyro(SensorBHI260AP::GYRO_PASSTHROUGH, bhy);
|
||||
SensorXYZ mag(SensorBHI260AP::MAGNETOMETER_PASSTHROUGH, bhy);
|
||||
#endif
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FW
|
||||
#define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO
|
||||
// #define BOSCH_BHI260_AUX_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO
|
||||
// #define BOSCH_BHI260_GPIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_GPIO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
#ifndef USING_DATA_HELPER
|
||||
void xyz_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
struct bhy2_data_xyz data;
|
||||
float scaling_factor = bhy.getScaling(sensor_id);
|
||||
bhy2_parse_xyz(data_ptr, &data);
|
||||
Serial.print(bhy.getSensorName(sensor_id));
|
||||
Serial.print(" ");
|
||||
Serial.print("x: ");
|
||||
Serial.print(data.x * scaling_factor);
|
||||
Serial.print(", y: ");
|
||||
Serial.print(data.y * scaling_factor);
|
||||
Serial.print(", z: ");
|
||||
Serial.print(data.z * scaling_factor);
|
||||
Serial.println(";");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
float sample_rate = 10.0; /* Read out data measured at 10Hz */
|
||||
uint32_t report_latency_ms = 0; /* 0 = report immediately */
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
// Enable acceleration
|
||||
accel.enable(sample_rate, report_latency_ms);
|
||||
// Enable gyroscope
|
||||
gyro.enable(sample_rate, report_latency_ms);
|
||||
// Enable magnetometer
|
||||
mag.enable(sample_rate, report_latency_ms);
|
||||
#else
|
||||
// Enable acceleration
|
||||
bhy.configure(SensorBHI260AP::ACCEL_PASSTHROUGH, sample_rate, report_latency_ms);
|
||||
// Enable gyroscope
|
||||
bhy.configure(SensorBHI260AP::GYRO_PASSTHROUGH, sample_rate, report_latency_ms);
|
||||
// Enable magnetometer
|
||||
bhy.configure(SensorBHI260AP::MAGNETOMETER_PASSTHROUGH, sample_rate, report_latency_ms);
|
||||
// Set the acceleration sensor result callback function
|
||||
bhy.onResultEvent(SensorBHI260AP::ACCEL_PASSTHROUGH, xyz_process_callback);
|
||||
// Set the gyroscope sensor result callback function
|
||||
bhy.onResultEvent(SensorBHI260AP::GYRO_PASSTHROUGH, xyz_process_callback);
|
||||
// Set the magnetometer sensor result callback function
|
||||
bhy.onResultEvent(SensorBHI260AP::MAGNETOMETER_PASSTHROUGH, xyz_process_callback);
|
||||
#endif
|
||||
// Set the specified pin (BHI260_IRQ) as an input pin.
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
// Attach an interrupt service routine (ISR) 'dataReadyISR' to the specified pin (BHI260_IRQ).
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
if (accel.hasUpdated() && gyro.hasUpdated() && mag.hasUpdated()) {
|
||||
uint32_t s;
|
||||
uint32_t ns;
|
||||
accel.getLastTime(s, ns);
|
||||
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
Serial.printf("[T: %" PRIu32 ".%09" PRIu32 "] AX:%+7.2f AY:%+7.2f AZ:%+7.2f GX:%+7.2f GY:%+7.2f GZ:%+7.2f MX:%+7.2f MY:%+7.2f MZ:%+7.2f\n",
|
||||
s, ns, accel.getX(), accel.getY(), accel.getZ(),
|
||||
gyro.getX(), gyro.getY(), gyro.getZ(),
|
||||
mag.getX(), mag.getY(), mag.getZ());
|
||||
#else
|
||||
Serial.print("[T: "); Serial.print(s);
|
||||
Serial.print("."); Serial.print(ns); Serial.print("] ");
|
||||
Serial.print("AX:"); Serial.print(accel.getX(), 2);
|
||||
Serial.print(" AY:"); Serial.print(accel.getY(), 2);
|
||||
Serial.print(" AZ:"); Serial.print(accel.getZ(), 2);
|
||||
Serial.print(" GX:"); Serial.print(gyro.getX(), 2);
|
||||
Serial.print(" GY:"); Serial.print(gyro.getY(), 2);
|
||||
Serial.print(" GZ:"); Serial.print(gyro.getZ(), 2);
|
||||
Serial.print(" MX:"); Serial.print(mag.getX(), 2);
|
||||
Serial.print(" MY:"); Serial.print(mag.getY(), 2);
|
||||
Serial.print(" MZ:"); Serial.print(mag.getZ(), 2);
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
delay(50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,356 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2024 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_aux_BMM150_BME280.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2024-07-24
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <SensorBHI260AP.hpp>
|
||||
#include <bosch/BoschSensorDataHelper.hpp>
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
|
||||
/*
|
||||
* Define the USING_DATA_HELPER use of data assistants.
|
||||
* No callback function will be used. Data can be obtained directly through
|
||||
* the data assistant. Note that this method is not a thread-safe function.
|
||||
* Please pay attention to protecting data access security.
|
||||
* */
|
||||
#define USING_DATA_HELPER
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
SensorTemperature temperature(bhy);
|
||||
SensorHumidity humidity(bhy);
|
||||
SensorPressure pressure(bhy);
|
||||
#endif
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO
|
||||
// #define BOSCH_BHI260_AUX_BEM280
|
||||
#define BOSCH_BHI260_AUX_BMM150_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO
|
||||
// #define BOSCH_BHI260_GPIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_GPIO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
#ifndef USING_DATA_HELPER
|
||||
void parse_bme280_sensor_data(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
float humidity = 0;
|
||||
float temperature = 0;
|
||||
float pressure = 0;
|
||||
switch (sensor_id) {
|
||||
case SensorBHI260AP::HUMIDITY:
|
||||
bhy2_parse_humidity(data_ptr, &humidity);
|
||||
Serial.print("humidity:"); Serial.print(humidity); Serial.println("%");
|
||||
break;
|
||||
case SensorBHI260AP::TEMPERATURE:
|
||||
bhy2_parse_temperature_celsius(data_ptr, &temperature);
|
||||
Serial.print("temperature:"); Serial.print(temperature); Serial.println("*C");
|
||||
break;
|
||||
case SensorBHI260AP::BAROMETER:
|
||||
bhy2_parse_pressure(data_ptr, &pressure);
|
||||
Serial.print("pressure:"); Serial.print(pressure); Serial.println("Pa");
|
||||
break;
|
||||
default:
|
||||
Serial.println("Unkown.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
void printResult(uint8_t sensor_id, float sample_rate, bool rlst)
|
||||
{
|
||||
const char *sensorName = bhy.getSensorName(sensor_id);
|
||||
Serial.print("Configure ");
|
||||
Serial.print(sensorName);
|
||||
Serial.print(" sensor ");
|
||||
Serial.print(sample_rate, 2);
|
||||
Serial.print(" HZ ");
|
||||
if (rlst) {
|
||||
Serial.print("successfully");
|
||||
} else {
|
||||
Serial.print("failed");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enable monitoring.
|
||||
* sample_rate can only control the rate of the pressure sensor.
|
||||
* Temperature and humidity will only be updated when there is a change.
|
||||
* * */
|
||||
float sample_rate = 2.0; /* Set pressure sensor to 2Hz update frequency */
|
||||
uint32_t report_latency_ms = 0; /* Report immediately */
|
||||
|
||||
/*
|
||||
* Enable BME280 function
|
||||
* Function depends on BME280.
|
||||
* If the hardware is not connected to BME280, the function cannot be used.
|
||||
* * */
|
||||
#ifdef USING_DATA_HELPER
|
||||
temperature.enable();
|
||||
humidity.enable();
|
||||
pressure.enable(sample_rate, report_latency_ms);
|
||||
#else
|
||||
bool rlst = false;
|
||||
rlst = bhy.configure(SensorBHI260AP::TEMPERATURE, sample_rate, report_latency_ms);
|
||||
printResult(SensorBHI260AP::TEMPERATURE, sample_rate, rlst);
|
||||
rlst = bhy.configure(SensorBHI260AP::BAROMETER, sample_rate, report_latency_ms);
|
||||
printResult(SensorBHI260AP::BAROMETER, sample_rate, rlst);
|
||||
rlst = bhy.configure(SensorBHI260AP::HUMIDITY, sample_rate, report_latency_ms);
|
||||
printResult(SensorBHI260AP::HUMIDITY, sample_rate, rlst);
|
||||
// Register BME280 data parse callback function
|
||||
Serial.println("Register sensor result callback function");
|
||||
bhy.onResultEvent(SensorBHI260AP::TEMPERATURE, parse_bme280_sensor_data);
|
||||
bhy.onResultEvent(SensorBHI260AP::HUMIDITY, parse_bme280_sensor_data);
|
||||
bhy.onResultEvent(SensorBHI260AP::BAROMETER, parse_bme280_sensor_data);
|
||||
#endif
|
||||
// Set the specified pin (BHI260_IRQ) as an input pin.
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
// Attach an interrupt service routine (ISR) 'dataReadyISR' to the specified pin (BHI260_IRQ).
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint32_t s;
|
||||
uint32_t ns;
|
||||
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
#ifdef USING_DATA_HELPER
|
||||
if (temperature.hasUpdated()) {
|
||||
temperature.getLastTime(s, ns);
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
Serial.printf("[T: %" PRIu32 ".%09" PRIu32 "] ", s, ns);
|
||||
Serial.printf("Temperature: %.2f *C %.2f *F %.2f K\n",
|
||||
temperature.getCelsius(), temperature.getFahrenheit(), temperature.getKelvin());
|
||||
#else
|
||||
Serial.print("[T: ");
|
||||
Serial.print(s);
|
||||
Serial.print(".");
|
||||
Serial.print(ns);
|
||||
Serial.print("]:");
|
||||
Serial.print("Temperature: ");
|
||||
Serial.print(temperature.getCelsius()); Serial.print(" *C");
|
||||
Serial.print(temperature.getFahrenheit()); Serial.print(" *F");
|
||||
Serial.print(temperature.getKelvin()); Serial.print(" *F");
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (humidity.hasUpdated()) {
|
||||
humidity.getLastTime(s, ns);
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
Serial.printf("[T: %" PRIu32 ".%09" PRIu32 "] ", s, ns);
|
||||
Serial.printf("Humidity: %.2f %%\n", humidity.getHumidity());
|
||||
#else
|
||||
Serial.print("[T: ");
|
||||
Serial.print(s);
|
||||
Serial.print(".");
|
||||
Serial.print(ns);
|
||||
Serial.print("]:");
|
||||
Serial.print("Humidity: ");
|
||||
Serial.print(humidity.getHumidity()); Serial.print(" %");
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (pressure.hasUpdated()) {
|
||||
pressure.getLastTime(s, ns);
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
Serial.printf("[T: %" PRIu32 ".%09" PRIu32 "] ", s, ns);
|
||||
Serial.printf("Pressure: %.2f Pascal\n", pressure.getPressure());
|
||||
#else
|
||||
Serial.print("[T: ");
|
||||
Serial.print(s);
|
||||
Serial.print(".");
|
||||
Serial.print(ns);
|
||||
Serial.print("]:");
|
||||
Serial.print("Humidity: ");
|
||||
Serial.print(pressure.getPressure()); Serial.print(" Pascal");
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
delay(50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,414 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2024 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_aux_BMM150_BME280_Expand_GPIO.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2024-10-10
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorBHI260AP.hpp"
|
||||
|
||||
#include <Commander.h> //Deplib https://github.com/CreativeRobotics/Commander
|
||||
Commander cmd;
|
||||
void initialiseCommander();
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO
|
||||
// #define BOSCH_BHI260_AUX_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280
|
||||
#define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO
|
||||
// #define BOSCH_BHI260_GPIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_GPIO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
void parse_bme280_sensor_data(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
float humidity = 0;
|
||||
float temperature = 0;
|
||||
float pressure = 0;
|
||||
switch (sensor_id) {
|
||||
case SensorBHI260AP::HUMIDITY:
|
||||
bhy2_parse_humidity(data_ptr, &humidity);
|
||||
Serial.print("humidity:"); Serial.print(humidity); Serial.println("%");
|
||||
break;
|
||||
case SensorBHI260AP::TEMPERATURE:
|
||||
bhy2_parse_temperature_celsius(data_ptr, &temperature);
|
||||
Serial.print("temperature:"); Serial.print(temperature); Serial.println("*C");
|
||||
break;
|
||||
case SensorBHI260AP::BAROMETER:
|
||||
bhy2_parse_pressure(data_ptr, &pressure);
|
||||
Serial.print("pressure:"); Serial.print(pressure); Serial.println("hPa");
|
||||
break;
|
||||
default:
|
||||
Serial.println("Unkown.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void sensor_event_callback(uint8_t event, uint8_t sensor_id, uint8_t data)
|
||||
{
|
||||
Serial.print("Sensor Event:");
|
||||
const char *sensorName = bhy.getSensorName(sensor_id);
|
||||
switch (event) {
|
||||
case BHY2_META_EVENT_SAMPLE_RATE_CHANGED:
|
||||
Serial.print("Sample rate changed for ");
|
||||
Serial.print(sensorName);
|
||||
Serial.println(" sensor");
|
||||
break;
|
||||
case BHY2_META_EVENT_POWER_MODE_CHANGED:
|
||||
Serial.print("Power mode changed for ");
|
||||
Serial.print(sensorName);
|
||||
Serial.println(" sensor");
|
||||
break;
|
||||
default:
|
||||
Serial.print("Other event : ");
|
||||
Serial.println(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Register sensor change event callback
|
||||
bhy.onEvent(sensor_event_callback);
|
||||
|
||||
// Register BME280 data parse callback function
|
||||
bhy.onResultEvent(SensorBHI260AP::TEMPERATURE, parse_bme280_sensor_data);
|
||||
bhy.onResultEvent(SensorBHI260AP::HUMIDITY, parse_bme280_sensor_data);
|
||||
bhy.onResultEvent(SensorBHI260AP::BAROMETER, parse_bme280_sensor_data);
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
initialiseCommander();
|
||||
|
||||
Serial.println("Hello: Type 'help' to get help");
|
||||
|
||||
cmd.printCommandPrompt();
|
||||
|
||||
// Register interrupt function
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Call the update functions using the activeCommander pointer
|
||||
cmd.update();
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//All commands for 'master'
|
||||
//COMMAND ARRAY ------------------------------------------------------------------------------
|
||||
const commandList_t masterCommands[] = {
|
||||
{"help", helpHandler, "help"},
|
||||
{"set gpio", setGpioLevel, "set gpio level"},
|
||||
{"get gpio", getGpioLevel, "get gpio level"},
|
||||
{"dis gpio", disGpioMode, "disable gpio"},
|
||||
{"temperature", setTemperature, "Temperature"},
|
||||
{"humidity", setHumidity, "Humidity"},
|
||||
{"pressure", setPressure, "Pressure"},
|
||||
};
|
||||
|
||||
void initialiseCommander()
|
||||
{
|
||||
cmd.begin(&Serial, masterCommands, sizeof(masterCommands));
|
||||
cmd.commandPrompt(ON); //enable the command prompt
|
||||
cmd.echo(true); //Echo incoming characters to theoutput port
|
||||
cmd.errorMessages(ON); //error messages are enabled - it will tell us if we issue any unrecognised commands
|
||||
//Error messaged do NOT work for quick set and get commands
|
||||
}
|
||||
|
||||
bool helpHandler(Commander &Cmdr)
|
||||
{
|
||||
Serial.println("Help:");
|
||||
Serial.println("\tCustom firmware valid gpio : 1, 5, 6, 14, 15, 16, 19, 20");
|
||||
Serial.println("\tset gpio [gpio num] [level]");
|
||||
Serial.println("\tget gpio [gpio num] [pullup]");
|
||||
Serial.println("\tdis gpio [gpio num]");
|
||||
Serial.println("\ttemperature [on/off] : range 0 ~ 1");
|
||||
Serial.println("\thumidity [on/off] : range 0 ~ 1");
|
||||
Serial.println("\tpressure [sample_rate/HZ] : range 0~1000");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool setTemperature(Commander &Cmdr)
|
||||
{
|
||||
float sample_rate;
|
||||
int items = Cmdr.countItems();
|
||||
if (items < 1) {
|
||||
return 0;
|
||||
}
|
||||
Cmdr.getFloat(sample_rate);
|
||||
bhy.configure(SensorBHI260AP::TEMPERATURE, sample_rate, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool setHumidity(Commander &Cmdr)
|
||||
{
|
||||
float sample_rate;
|
||||
int items = Cmdr.countItems();
|
||||
if (items < 1) {
|
||||
return 0;
|
||||
}
|
||||
Cmdr.getFloat(sample_rate);
|
||||
bhy.configure(SensorBHI260AP::HUMIDITY, sample_rate, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool setPressure(Commander &Cmdr)
|
||||
{
|
||||
float sample_rate;
|
||||
int items = Cmdr.countItems();
|
||||
if (items < 1) {
|
||||
return 0;
|
||||
}
|
||||
Cmdr.getFloat(sample_rate);
|
||||
bhy.configure(SensorBHI260AP::BAROMETER, sample_rate, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GPIO Comparison Table
|
||||
* M1SCX = N.A ! INVALID PIN
|
||||
* M1SDX = N.A ! INVALID PIN
|
||||
* M1SDI = N.A ! INVALID PIN
|
||||
* M2SCX = 14 ! OK
|
||||
* M2SDX = 15 ! OK
|
||||
* M2SDI = 16 ! OK
|
||||
* MCSB1 = 1 ! OK
|
||||
* MCSB2 = 4 ! aux BMM150
|
||||
* M3SCL = 17 ! aux BMM150
|
||||
* M3SDA = 18 ! aux BMM150
|
||||
* MCSB3 = 5 ! OK
|
||||
* MCSB4 = 6 ! OK
|
||||
* JTAG_CLK = 19 ! OK
|
||||
* JTAG_DIO = 20 ! OK
|
||||
* RESV1 = 2 ! INVALID PIN
|
||||
* RESV2 = 3 ! INVALID PIN
|
||||
* RESV3 = N.A ! INVALID PIN
|
||||
* */
|
||||
bool setGpioLevel(Commander &Cmdr)
|
||||
{
|
||||
int values[2] = {0, 0};
|
||||
int items = Cmdr.countItems();
|
||||
if (items < 2) {
|
||||
return false;
|
||||
}
|
||||
for (int n = 0; n < 2; n++) {
|
||||
Cmdr.getInt(values[n]);
|
||||
}
|
||||
uint8_t pin = values[0];
|
||||
uint8_t level = values[1];
|
||||
bhy.digitalWrite(pin, level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool getGpioLevel(Commander &Cmdr)
|
||||
{
|
||||
int values[2] = {0, 0};
|
||||
int items = Cmdr.countItems();
|
||||
if (items < 1) {
|
||||
return 0;
|
||||
}
|
||||
if (items > 2 )items = 2;
|
||||
for (int n = 0; n < items; n++) {
|
||||
Cmdr.getInt(values[n]);
|
||||
}
|
||||
bool pullup = false;
|
||||
uint8_t pin = values[0];
|
||||
if (items == 2 ) {
|
||||
pullup = values[1];
|
||||
}
|
||||
uint8_t level = bhy.digitalRead(pin, pullup);
|
||||
Serial.print("Get GPIO : "); Serial.print(pin);
|
||||
Serial.print(" level is "); Serial.println(level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool disGpioMode(Commander &Cmdr)
|
||||
{
|
||||
int values[1] = {0};
|
||||
int items = Cmdr.countItems();
|
||||
if (items < 1) {
|
||||
return 0;
|
||||
}
|
||||
Cmdr.getInt(values[0]);
|
||||
uint8_t pin = values[0];
|
||||
bhy.disableGpio(pin);
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,282 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2024 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_aux_BMM150_euler.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2024-07-23
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <SensorBHI260AP.hpp>
|
||||
#include <bosch/BoschSensorDataHelper.hpp>
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
|
||||
/*
|
||||
* Define the USING_DATA_HELPER use of data assistants.
|
||||
* No callback function will be used. Data can be obtained directly through
|
||||
* the data assistant. Note that this method is not a thread-safe function.
|
||||
* Please pay attention to protecting data access security.
|
||||
* */
|
||||
#define USING_DATA_HELPER
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
SensorEuler euler(bhy);
|
||||
#endif
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FW
|
||||
#define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO
|
||||
// #define BOSCH_BHI260_AUX_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO
|
||||
// #define BOSCH_BHI260_GPIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_GPIO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
#ifndef USING_DATA_HELPER
|
||||
void parse_euler(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
struct bhy2_data_orientation data;
|
||||
uint32_t s, ns;
|
||||
uint64_t tns;
|
||||
// Function to parse FIFO frame data into orientation
|
||||
bhy2_parse_orientation(data_ptr, &data);
|
||||
uint64_t _timestamp = *timestamp;
|
||||
time_to_s_ns(_timestamp, &s, &ns, &tns);
|
||||
uint8_t accuracy = bhy.getAccuracy();
|
||||
if (accuracy) {
|
||||
Serial.print("SID:"); Serial.print(sensor_id);
|
||||
Serial.print(" T:"); Serial.print(s);
|
||||
Serial.print("."); Serial.print(ns);
|
||||
Serial.print(" x:"); Serial.print(data.heading * 360.0f / 32768.0f);
|
||||
Serial.print(" y:"); Serial.print(data.pitch * 360.0f / 32768.0f);
|
||||
Serial.print(" x:"); Serial.print(data.roll * 360.0f / 32768.0f);
|
||||
Serial.print(" acc:"); Serial.println(accuracy);
|
||||
} else {
|
||||
Serial.print("SID:"); Serial.print(sensor_id);
|
||||
Serial.print(" T:"); Serial.print(s);
|
||||
Serial.print("."); Serial.print(ns);
|
||||
Serial.print(" x:"); Serial.print(data.heading * 360.0f / 32768.0f);
|
||||
Serial.print(" y:"); Serial.print(data.pitch * 360.0f / 32768.0f);
|
||||
Serial.print(" x:"); Serial.println(data.roll * 360.0f / 32768.0f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
float sample_rate = 100.0; /* Read out data measured at 100Hz */
|
||||
uint32_t report_latency_ms = 0; /* Report immediately */
|
||||
|
||||
/*
|
||||
* Enable Euler function
|
||||
* The Euler function depends on BMM150.
|
||||
* If the hardware is not connected to BMM150, the Euler function cannot be used.
|
||||
* * */
|
||||
#ifdef USING_DATA_HELPER
|
||||
euler.enable(sample_rate, report_latency_ms);
|
||||
#else
|
||||
bhy.configure(SensorBHI260AP::ORIENTATION_WAKE_UP, sample_rate, report_latency_ms);
|
||||
// Register event callback function
|
||||
bhy.onResultEvent(SensorBHI260AP::ORIENTATION_WAKE_UP, parse_euler);
|
||||
#endif
|
||||
// Set the specified pin (BHI260_IRQ) as an input pin.
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
// Attach an interrupt service routine (ISR) 'dataReadyISR' to the specified pin (BHI260_IRQ).
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
if (euler.hasUpdated()) {
|
||||
// Print the roll angle to the serial monitor.
|
||||
Serial.print(euler.getRoll());
|
||||
// Print a comma as a separator between the roll and pitch angles.
|
||||
Serial.print(",");
|
||||
// Print the pitch angle to the serial monitor.
|
||||
Serial.print(euler.getPitch());
|
||||
// Print a comma as a separator between the pitch and yaw angles.
|
||||
Serial.print(",");
|
||||
// Print the yaw angle to the serial monitor and start a new line.
|
||||
Serial.println(euler.getHeading());
|
||||
}
|
||||
#endif
|
||||
delay(50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,284 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2024 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BHI260AP_aux_BMM150_quaternion.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2024-07-23
|
||||
* @note Changed from Boschsensortec API https://github.com/boschsensortec/BHY2_SensorAPI
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <SensorBHI260AP.hpp>
|
||||
#include <bosch/BoschSensorDataHelper.hpp>
|
||||
|
||||
// #define USE_I2C_INTERFACE true
|
||||
// #define USE_SPI_INTERFACE true
|
||||
|
||||
#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
|
||||
#define USE_I2C_INTERFACE
|
||||
#warning "No interface type is selected, use I2C interface"
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPI_INTERFACE)
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI 33
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO 34
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK 35
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 37
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_CS
|
||||
#define BHI260_CS 36
|
||||
#endif
|
||||
|
||||
#else //* I2C */
|
||||
|
||||
#ifndef BHI260_SDA
|
||||
#define BHI260_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_SCL
|
||||
#define BHI260_SCL 3
|
||||
#endif
|
||||
|
||||
#ifndef BHI260_IRQ
|
||||
#define BHI260_IRQ 8
|
||||
#endif
|
||||
#endif /*USE_SPI_INTERFACE*/
|
||||
|
||||
#ifndef BHI260_RST
|
||||
#define BHI260_RST -1
|
||||
#endif
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
|
||||
/*
|
||||
* Define the USING_DATA_HELPER use of data assistants.
|
||||
* No callback function will be used. Data can be obtained directly through
|
||||
* the data assistant. Note that this method is not a thread-safe function.
|
||||
* Please pay attention to protecting data access security.
|
||||
* */
|
||||
#define USING_DATA_HELPER
|
||||
|
||||
#ifdef USING_DATA_HELPER
|
||||
SensorQuaternion quaternion(bhy);
|
||||
#endif
|
||||
|
||||
// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FW
|
||||
#define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150FW
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO
|
||||
// #define BOSCH_BHI260_AUX_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO
|
||||
// #define BOSCH_BHI260_GPIO
|
||||
|
||||
// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_AUX_BMM150_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BME68X_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_BMP390_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_FLASH
|
||||
// #define BOSCH_APP30_SHUTTLE_BHI260_TURBO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_BEM280_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_AUX_BMM150_GPIO_FLASH
|
||||
// #define BOSCH_BHI260_GPIO_FLASH
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
|
||||
// Force update of current firmware, whether it exists or not.
|
||||
// Only works when external SPI Flash is connected to BHI260.
|
||||
// After uploading firmware once, you can change this to false to speed up boot time.
|
||||
bool force_update_flash_firmware = true;
|
||||
|
||||
bool isReadyFlag = false;
|
||||
|
||||
void dataReadyISR()
|
||||
{
|
||||
isReadyFlag = true;
|
||||
}
|
||||
|
||||
#ifndef USING_DATA_HELPER
|
||||
void parse_quaternion(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
struct bhy2_data_quaternion data;
|
||||
uint32_t s, ns;
|
||||
uint64_t tns;
|
||||
// Function to parse FIFO frame data into orientation
|
||||
bhy2_parse_quaternion(data_ptr, &data);
|
||||
uint64_t _timestamp = *timestamp;
|
||||
time_to_s_ns(_timestamp, &s, &ns, &tns);
|
||||
Serial.print("SID:"); Serial.print(sensor_id);
|
||||
Serial.print(" T:"); Serial.print(s);
|
||||
Serial.print("."); Serial.print(ns);
|
||||
Serial.print(" x:"); Serial.print(data.x / 16384.0f);
|
||||
Serial.print(" y:"); Serial.print(data.y / 16384.0f);
|
||||
Serial.print(" x:"); Serial.print(data.z / 16384.0f);
|
||||
Serial.print(" w:"); Serial.print(data.w / 16384.0f);
|
||||
Serial.print(" acc:"); Serial.println(((data.accuracy * 180.0f) / 16384.0f) / 3.141592653589793f);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Firmware update progress callback
|
||||
void progress_callback(void *user_data, uint32_t total, uint32_t transferred)
|
||||
{
|
||||
float progress = (float)transferred / total * 100;
|
||||
Serial.print("Upload progress: ");
|
||||
Serial.print(progress);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(BHI260_RST);
|
||||
|
||||
Serial.println("Initializing Sensors...");
|
||||
|
||||
// Set the firmware array address and firmware size
|
||||
bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
|
||||
|
||||
// Set the firmware update processing progress callback function
|
||||
// bhy.setUpdateProcessCallback(progress_callback, NULL);
|
||||
|
||||
// Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
|
||||
// bhy.setMaxiTransferSize(256);
|
||||
|
||||
// Set the processing fifo data buffer size,The default size is 512 bytes.
|
||||
// bhy.setProcessBufferSize(1024);
|
||||
|
||||
// Set to load firmware from flash
|
||||
bhy.setBootFromFlash(bosch_firmware_type);
|
||||
|
||||
#ifdef USE_I2C_INTERFACE
|
||||
// Using I2C interface
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_INTERFACE
|
||||
// Using SPI interface
|
||||
if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
|
||||
Serial.print("Failed to initialize sensor - error code:");
|
||||
Serial.println(bhy.getError());
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Serial.println("Initializing the sensor successfully!");
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
info.printInfo(Serial);
|
||||
#else
|
||||
info.printInfo();
|
||||
#endif
|
||||
|
||||
float sample_rate = 100.0; /* Read out data measured at 100Hz */
|
||||
uint32_t report_latency_ms = 0; /* Report immediately */
|
||||
|
||||
/*
|
||||
* Enable Quaternion function
|
||||
* The Quaternion function depends on BMM150.
|
||||
* If the hardware is not connected to BMM150, the Quaternion function cannot be used.
|
||||
* * */
|
||||
#ifdef USING_DATA_HELPER
|
||||
quaternion.enable(sample_rate, report_latency_ms);
|
||||
#else
|
||||
bhy.configure(SensorBHI260AP::ROTATION_VECTOR, sample_rate, report_latency_ms);
|
||||
// Register event callback function
|
||||
bhy.onResultEvent(SensorBHI260AP::ROTATION_VECTOR, parse_quaternion);
|
||||
#endif
|
||||
// Set the specified pin (BHI260_IRQ) as an input pin.
|
||||
pinMode(BHI260_IRQ, INPUT);
|
||||
// Attach an interrupt service routine (ISR) 'dataReadyISR' to the specified pin (BHI260_IRQ).
|
||||
attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Update sensor fifo
|
||||
if (isReadyFlag) {
|
||||
isReadyFlag = false;
|
||||
bhy.update();
|
||||
}
|
||||
#ifdef USING_DATA_HELPER
|
||||
if (quaternion.hasUpdated()) {
|
||||
uint32_t s;
|
||||
uint32_t ns;
|
||||
quaternion.getLastTime(s, ns);
|
||||
#ifdef PLATFORM_HAS_PRINTF
|
||||
Serial.printf("[T: %" PRIu32 ".%09" PRIu32 "] QX:%+7.2f QY:%+7.2f QZ:%+7.2f QW:%+7.2f\n",
|
||||
s, ns, quaternion.getX(), quaternion.getY(), quaternion.getZ(), quaternion.getW());
|
||||
#else
|
||||
Serial.print("[T: ");
|
||||
Serial.print(s);
|
||||
Serial.print(".");
|
||||
Serial.print(ns);
|
||||
Serial.print("] ");
|
||||
Serial.print("QX:");
|
||||
Serial.print(quaternion.getX(), 2);
|
||||
Serial.print(" QY:");
|
||||
Serial.print(quaternion.getY(), 2);
|
||||
Serial.print(" QZ:");
|
||||
Serial.print(quaternion.getZ(), 2);
|
||||
Serial.print(" QW:");
|
||||
Serial.print(quaternion.getW(), 2);
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
delay(50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BMA423_Accelerometer.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-04-01
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorBMA423.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 39
|
||||
#endif
|
||||
|
||||
SensorBMA423 accel;
|
||||
uint32_t intervalue;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
pinMode(SENSOR_IRQ, INPUT);
|
||||
|
||||
/*
|
||||
* BMA423_I2C_ADDR_PRIMARY = 0x18
|
||||
* BMA423_I2C_ADDR_SECONDARY = 0x19
|
||||
* * */
|
||||
if (!accel.begin(Wire, BMA423_I2C_ADDR_SECONDARY, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find BMA423 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
Serial.println("Init BAM423 Sensor success!");
|
||||
|
||||
//Default 4G ,200HZ
|
||||
accel.configAccelerometer();
|
||||
|
||||
accel.enableAccelerometer();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
int16_t x = 0, y = 0, z = 0;
|
||||
accel.getAccelerometer(x, y, z);
|
||||
Serial.print("X:");
|
||||
Serial.print(x); Serial.print(" ");
|
||||
Serial.print("Y:");
|
||||
Serial.print(y); Serial.print(" ");
|
||||
Serial.print("Z:");
|
||||
Serial.print(z);
|
||||
Serial.println();
|
||||
|
||||
delay(50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,145 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BMA423_Feature.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-04-03
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorBMA423.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 39
|
||||
#endif
|
||||
|
||||
SensorBMA423 accel;
|
||||
uint32_t intervalue;
|
||||
bool sensorIRQ = false;
|
||||
|
||||
|
||||
void setFlag()
|
||||
{
|
||||
sensorIRQ = true;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
pinMode(SENSOR_IRQ, INPUT);
|
||||
attachInterrupt(SENSOR_IRQ, setFlag, RISING);
|
||||
|
||||
/*
|
||||
* BMA423_I2C_ADDR_PRIMARY = 0x18
|
||||
* BMA423_I2C_ADDR_SECONDARY = 0x19
|
||||
* * */
|
||||
if (!accel.begin(Wire, BMA423_I2C_ADDR_SECONDARY, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find BMA423 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("Init BAM423 Sensor success!");
|
||||
|
||||
//Default 4G ,200HZ
|
||||
accel.configAccelerometer();
|
||||
|
||||
// Enable acceleration sensor
|
||||
accel.enableAccelerometer();
|
||||
|
||||
// Enable pedometer steps
|
||||
accel.enablePedometer();
|
||||
|
||||
// Emptying the pedometer steps
|
||||
accel.resetPedometer();
|
||||
|
||||
// Enable sensor features
|
||||
accel.enableFeature(SensorBMA423::FEATURE_STEP_CNTR |
|
||||
SensorBMA423::FEATURE_ANY_MOTION |
|
||||
SensorBMA423::FEATURE_ACTIVITY |
|
||||
SensorBMA423::FEATURE_TILT |
|
||||
SensorBMA423::FEATURE_WAKEUP,
|
||||
true);
|
||||
|
||||
// Pedometer interrupt enable
|
||||
accel.enablePedometerIRQ();
|
||||
// Tilt interrupt enable
|
||||
accel.enableTiltIRQ();
|
||||
// DoubleTap interrupt enable
|
||||
accel.enableWakeupIRQ();
|
||||
// Any motion / no motion interrupt enable
|
||||
accel.enableAnyNoMotionIRQ();
|
||||
// Activity interruption enable
|
||||
accel.enableActivityIRQ();
|
||||
// Chip interrupt function enable
|
||||
accel.configInterrupt();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (sensorIRQ) {
|
||||
sensorIRQ = false;
|
||||
// The interrupt status must be read after an interrupt is detected
|
||||
uint16_t status = accel.readIrqStatus();
|
||||
Serial.print("Accelerometer interrupt mask : 0x");
|
||||
Serial.println(status, HEX);
|
||||
|
||||
if (accel.isPedometer()) {
|
||||
uint32_t stepCounter = accel.getPedometerCounter();
|
||||
Serial.print("Step count interrupt,step Counter:");
|
||||
Serial.println(stepCounter);
|
||||
}
|
||||
if (accel.isActivity()) {
|
||||
Serial.println("Activity interrupt");
|
||||
}
|
||||
if (accel.isTilt()) {
|
||||
Serial.println("Tilt interrupt");
|
||||
}
|
||||
if (accel.isDoubleTap()) {
|
||||
Serial.println("DoubleTap interrupt");
|
||||
}
|
||||
if (accel.isAnyNoMotion()) {
|
||||
Serial.println("Any motion / no motion interrupt");
|
||||
}
|
||||
}
|
||||
delay(50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,147 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BMA423_Orientation.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-04-03
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorBMA423.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 39
|
||||
#endif
|
||||
|
||||
SensorBMA423 accel;
|
||||
char report[256];
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
pinMode(SENSOR_IRQ, INPUT);
|
||||
|
||||
/*
|
||||
* BMA423_I2C_ADDR_PRIMARY = 0x18
|
||||
* BMA423_I2C_ADDR_SECONDARY = 0x19
|
||||
* * */
|
||||
if (!accel.begin(Wire, BMA423_I2C_ADDR_SECONDARY, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find BMA423 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
Serial.println("Init BAM423 Sensor success!");
|
||||
|
||||
//Default 4G ,200HZ
|
||||
accel.configAccelerometer();
|
||||
|
||||
accel.enableAccelerometer();
|
||||
|
||||
|
||||
Serial.println("Output ...");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint8_t direction = accel.direction();
|
||||
switch (direction) {
|
||||
case SensorBMA423::DIRECTION_BOTTOM_LEFT:
|
||||
|
||||
sprintf( report, "\r\n ________________ " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | * | " \
|
||||
"\r\n |________________| \r\n" );
|
||||
|
||||
break;
|
||||
case SensorBMA423::DIRECTION_TOP_RIGHT:
|
||||
sprintf( report, "\r\n ________________ " \
|
||||
"\r\n | | " \
|
||||
"\r\n | * | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n |________________| \r\n" );
|
||||
break;
|
||||
case SensorBMA423::DIRECTION_TOP_LEFT:
|
||||
sprintf( report, "\r\n ________________ " \
|
||||
"\r\n | | " \
|
||||
"\r\n | * | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n |________________| \r\n" );
|
||||
break;
|
||||
case SensorBMA423::DIRECTION_BOTTOM_RIGHT:
|
||||
sprintf( report, "\r\n ________________ " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | | " \
|
||||
"\r\n | * | " \
|
||||
"\r\n |________________| \r\n" );
|
||||
break;
|
||||
case SensorBMA423::DIRECTION_BOTTOM:
|
||||
sprintf( report, "\r\n ________________ " \
|
||||
"\r\n |________________| " \
|
||||
"\r\n * \r\n" );
|
||||
break;
|
||||
case SensorBMA423::DIRECTION_TOP:
|
||||
sprintf( report, "\r\n __*_____________ " \
|
||||
"\r\n |________________| \r\n" );
|
||||
break;
|
||||
default:
|
||||
sprintf( report, "None of the 3D orientation axes is set in BMA423 - accelerometer.\r\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.println(direction);
|
||||
Serial.println(report);
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,84 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BMA423_Temperature.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-04-01
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorBMA423.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 39
|
||||
#endif
|
||||
|
||||
SensorBMA423 accel;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
pinMode(SENSOR_IRQ, INPUT);
|
||||
|
||||
Serial.println("BMA423 Sensor Temperature");
|
||||
|
||||
/*
|
||||
* BMA423_I2C_ADDR_PRIMARY = 0x18
|
||||
* BMA423_I2C_ADDR_SECONDARY = 0x19
|
||||
* * */
|
||||
if (!accel.begin(Wire, BMA423_I2C_ADDR_SECONDARY, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find BMA423 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
Serial.println("Init BAM423 Sensor success!");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print("getTemperature:");
|
||||
Serial.print(accel.getTemperature(SensorBMA423::TEMP_DEG));
|
||||
Serial.print("*C ");
|
||||
Serial.print(accel.getTemperature(SensorBMA423::TEMP_FAHRENHEIT));
|
||||
Serial.print("*F");
|
||||
Serial.println();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,102 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2023 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BMM150_GetDataExample.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-10-10
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorBMM150.hpp"
|
||||
#include "SensorWireHelper.h"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 33
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 35
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ -1
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_RST
|
||||
#define SENSOR_RST -1
|
||||
#endif
|
||||
|
||||
|
||||
SensorBMM150 bmm;
|
||||
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
// Using I2C interface
|
||||
if (!bmm.begin(Wire, BMM150_I2C_ADDRESS_CSB_HIGH_SDO_LOW, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.print("Failed to init BMM150 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("Init BMM150 Sensor success!");
|
||||
|
||||
/* Set magnetometer run mode */
|
||||
/**
|
||||
* * POWERMODE_NORMAL,
|
||||
* * POWERMODE_FORCED,
|
||||
* * POWERMODE_SLEEP,
|
||||
* * POWERMODE_SUSPEND,
|
||||
*/
|
||||
bmm.setMode(SensorBMM150::POWERMODE_NORMAL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
int16_t x, y, z;
|
||||
/* Read mag data */
|
||||
/* Unit for magnetometer data is micro tesla(uT) */
|
||||
if (bmm.getMag(x, y, z)) {
|
||||
Serial.print("X:");
|
||||
Serial.print(x);
|
||||
Serial.print("uT,");
|
||||
Serial.print("Y:");
|
||||
Serial.print(y);
|
||||
Serial.print("uT,");
|
||||
Serial.print("Z:");
|
||||
Serial.print(z);
|
||||
Serial.println("uT");
|
||||
}
|
||||
delay(50);
|
||||
}
|
||||
|
||||
@ -0,0 +1,260 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file BQ27220_GaugeExample.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-02-13
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <GaugeBQ27220.hpp>
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 2
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 3
|
||||
#endif
|
||||
|
||||
GaugeBQ27220 gauge;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
if (!gauge.begin(Wire, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to BQ27220 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
Serial.println("Init BQ27220 Sensor success!");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the new design capacity and full charge capacity of the battery.
|
||||
*
|
||||
* This function is responsible for updating the design capacity and full charge capacity of the battery.
|
||||
* It first checks the device's access settings, enters the configuration update mode, writes the new capacity values
|
||||
* and checksums, and finally exits the configuration update mode. If the device was previously in a sealed state,
|
||||
* it will be restored to the sealed mode after the operation is completed.
|
||||
* For new devices, use the default key for access. If it is an encrypted device, use setAccessKey(uint32_t key) to set the key.
|
||||
* @param newDesignCapacity The new design capacity to be set, of type uint16_t.
|
||||
* @param newFullChargeCapacity The new full charge capacity to be set, of type uint16_t.
|
||||
* @return bool Returns true if the setting is successful, false otherwise.
|
||||
*/
|
||||
|
||||
// uint32_t key = 0x12345678;
|
||||
// gauge.setAccessKey(key)
|
||||
|
||||
uint16_t newDesignCapacity = 3500;
|
||||
uint16_t newFullChargeCapacity = 3500;
|
||||
gauge.setNewCapacity(newDesignCapacity, newFullChargeCapacity);
|
||||
|
||||
OperationConfig config = gauge.getOperationConfig();
|
||||
|
||||
//* OperationConfig A *//
|
||||
Serial.print("OperationConfigA Values:0x");
|
||||
Serial.println(config.getConfigA(), HEX);
|
||||
|
||||
Serial.print("External Thermistor Selected: ");
|
||||
Serial.println(config.isTempsSet() ? "YES" : "NO");
|
||||
|
||||
Serial.print("BATT_GD Pin Polarity High: ");
|
||||
Serial.println(config.isBatgPolHigh() ? "YES" : "NO");
|
||||
|
||||
Serial.print("BATT_GD Function Enabled: ");
|
||||
Serial.println(config.isBatgEnEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.print("Can Enter SLEEP State: ");
|
||||
Serial.println(config.canEnterSleep() ? "YES" : "NO");
|
||||
|
||||
Serial.print("slpwakechg Function Enabled: ");
|
||||
Serial.println(config.isSlpwakechgEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.print("Write Temperature Function Enabled: ");
|
||||
Serial.println(config.isWrtempEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.print("Battery Insertion Detection Enabled: ");
|
||||
Serial.println(config.isBienableEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.print("Battery Insertion Pin Pull - Up Enabled: ");
|
||||
Serial.println(config.isBlPupEnEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.print("Pin Function Code (PFC) Mode: ");
|
||||
Serial.println(config.getPfcCfg());
|
||||
|
||||
Serial.print("Wake - Up Function Enabled: ");
|
||||
Serial.println(config.isWakeEnEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.print("Wake - Up Threshold 1: ");
|
||||
Serial.println(config.getWkTh1());
|
||||
|
||||
Serial.print("Wake - Up Threshold 0: ");
|
||||
Serial.println(config.getWkTh0());
|
||||
|
||||
//* OperationConfig B *//
|
||||
Serial.print("\nOperationConfigB Values:0x");
|
||||
Serial.println(config.getConfigB(), HEX);
|
||||
|
||||
Serial.print("Default Seal Option Enabled: ");
|
||||
Serial.println(config.isDefaultSealEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.print("Non - Removable Option Set: ");
|
||||
Serial.println(config.isNonRemovableSet() ? "YES" : "NO");
|
||||
|
||||
Serial.print("INT_BREM Function Enabled: ");
|
||||
Serial.println(config.isIntBremEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.print("INT_BATL Function Enabled: ");
|
||||
Serial.println(config.isIntBatLEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.print("INT_STATE Function Enabled: ");
|
||||
Serial.println(config.isIntStateEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.print("INT_OCV Function Enabled: ");
|
||||
Serial.println(config.isIntOcvEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.print("INT_OT Function Enabled: ");
|
||||
Serial.println(config.isIntOtEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.print("INT_POL Function Enabled (High - Level Polarity): ");
|
||||
Serial.println(config.isIntPolHigh() ? "YES" : "NO");
|
||||
|
||||
Serial.print("INT_FOCV Function Enabled: ");
|
||||
Serial.println(config.isIntFocvEnabled() ? "YES" : "NO");
|
||||
|
||||
delay(10000);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint32_t startMeasTime = millis();
|
||||
|
||||
if (gauge.refresh()) {
|
||||
|
||||
uint32_t endMesTime = millis();
|
||||
|
||||
Serial.print("Polling time: "); Serial.print(endMesTime - startMeasTime); Serial.println(" ms");
|
||||
|
||||
Serial.println("\nStandard query:");
|
||||
Serial.print("\t- AtRate:"); Serial.print(gauge.getAtRate()); Serial.println(" mA");
|
||||
Serial.print("\t- AtRateTimeToEmpty:"); Serial.print(gauge.getAtRateTimeToEmpty()); Serial.println(" minutes");
|
||||
Serial.print("\t- Temperature:"); Serial.print(gauge.getTemperature() ); Serial.println(" ℃");
|
||||
Serial.print("\t- BatteryVoltage:"); Serial.print(gauge.getVoltage()); Serial.println(" mV");
|
||||
Serial.print("\t- InstantaneousCurrent:"); Serial.print(gauge.getCurrent()); Serial.println(" mAh");
|
||||
Serial.print("\t- RemainingCapacity:"); Serial.print(gauge.getRemainingCapacity()); Serial.println(" mAh");
|
||||
Serial.print("\t- FullChargeCapacity:"); Serial.print(gauge.getFullChargeCapacity()); Serial.println(" mAh");
|
||||
Serial.print("\t- DesignCapacity:"); Serial.print(gauge.getDesignCapacity()); Serial.println(" mAh");
|
||||
Serial.print("\t- TimeToEmpty:"); Serial.print(gauge.getTimeToEmpty()); Serial.println(" minutes");
|
||||
Serial.print("\t- TimeToFull:"); Serial.print(gauge.getTimeToFull()); Serial.println(" minutes");
|
||||
Serial.print("\t- StandbyCurrent:"); Serial.print(gauge.getStandbyCurrent()); Serial.println(" mA");
|
||||
Serial.print("\t- StandbyTimeToEmpty:"); Serial.print(gauge.getStandbyTimeToEmpty()); Serial.println(" minutes");
|
||||
Serial.print("\t- MaxLoadCurrent:"); Serial.print(gauge.getMaxLoadCurrent()); Serial.println(" mA");
|
||||
Serial.print("\t- MaxLoadTimeToEmpty:"); Serial.print(gauge.getMaxLoadTimeToEmpty()); Serial.println(" minute");
|
||||
Serial.print("\t- RawCoulombCount:"); Serial.print(gauge.getRawCoulombCount()); Serial.println(" mAh");
|
||||
Serial.print("\t- AveragePower:"); Serial.print(gauge.getAveragePower()); Serial.println(" mW");
|
||||
Serial.print("\t- InternalTemperature:"); Serial.print(gauge.getInternalTemperature()); Serial.println(" ℃");
|
||||
Serial.print("\t- CycleCount:"); Serial.println(gauge.getCycleCount());
|
||||
Serial.print("\t- StateOfCharge:"); Serial.print(gauge.getStateOfCharge()); Serial.println(" %");
|
||||
Serial.print("\t- StateOfHealth:"); Serial.print(gauge.getStateOfHealth()); Serial.println(" %");
|
||||
Serial.print("\t- RequestChargingVoltage:"); Serial.print(gauge.getRequestChargingVoltage()); Serial.println(" mV");
|
||||
Serial.print("\t- RequestChargingCurrent:"); Serial.print(gauge.getRequestChargingCurrent()); Serial.println(" mA");
|
||||
Serial.print("\t- BTPDischargeSet:"); Serial.print(gauge.getBTPDischargeSet()); Serial.println(" mAh");
|
||||
Serial.print("\t- BTPChargeSet:"); Serial.print(gauge.getBTPChargeSet()); Serial.println(" mAh");
|
||||
FuelGaugeOperationStatus status = gauge.getOperationStatus();
|
||||
BatteryStatus batteryStatus = gauge.getBatteryStatus();
|
||||
|
||||
Serial.println("\nOperation Status:");
|
||||
Serial.print("\t- getIsConfigUpdateMode:"); Serial.println(status.getIsConfigUpdateMode() ? "YES" : "NO");
|
||||
Serial.print("\t- getIsBtpThresholdExceeded:"); Serial.println(status.getIsBtpThresholdExceeded() ? "YES" : "NO");
|
||||
Serial.print("\t- getIsCapacityAccumulationThrottled:"); Serial.println(status.getIsCapacityAccumulationThrottled() ? "YES" : "NO");
|
||||
Serial.print("\t- getIsInitializationComplete:"); Serial.println(status.getIsInitializationComplete() ? "YES" : "NO");
|
||||
Serial.print("\t- getIsDischargeCycleCompliant:"); Serial.println(status.getIsDischargeCycleCompliant() ? "YES" : "NO");
|
||||
Serial.print("\t- getIsBatteryVoltageBelowEdv2:"); Serial.println(status.getIsBatteryVoltageBelowEdv2() ? "YES" : "NO");
|
||||
Serial.print("\t- getSecurityAccessLevel:"); Serial.println(status.getSecurityAccessLevel());
|
||||
Serial.print("\t- getIsCalibrationModeEnabled:"); Serial.println(status.getIsCalibrationModeEnabled() ? "YES" : "NO");
|
||||
|
||||
Serial.println("\nBattery Status:");
|
||||
if (batteryStatus.isFullDischargeDetected()) {
|
||||
Serial.println("\t- Full discharge detected.");
|
||||
}
|
||||
if (batteryStatus.isOcvMeasurementUpdateComplete()) {
|
||||
Serial.println("\t- OCV measurement update is complete.");
|
||||
}
|
||||
if (batteryStatus.isOcvReadFailedDueToCurrent()) {
|
||||
Serial.println("\t- Status bit indicating that an OCV read failed due to current.");
|
||||
Serial.println("\tThis bit can only be set if a battery is present after receiving an OCV_CMD().");
|
||||
}
|
||||
if (batteryStatus.isInSleepMode()) {
|
||||
Serial.println("\t- The device operates in SLEEP mode");
|
||||
}
|
||||
if (batteryStatus.isOverTemperatureDuringCharging()) {
|
||||
Serial.println("\t- Over-temperature is detected during charging.");
|
||||
}
|
||||
if (batteryStatus.isOverTemperatureDuringDischarge()) {
|
||||
Serial.println("\t- Over-temperature detected during discharge condition.");
|
||||
}
|
||||
if (batteryStatus.isFullChargeDetected()) {
|
||||
Serial.println("\t- Full charge detected.");
|
||||
}
|
||||
if (batteryStatus.isChargeInhibited()) {
|
||||
Serial.println("\t- Charge Inhibit: If set, indicates that charging should not begin because the Temperature() is outside the range");
|
||||
Serial.println("\t[Charge Inhibit Temp Low, Charge Inhibit Temp High]. ");
|
||||
}
|
||||
if (batteryStatus.isChargingTerminationAlarm()) {
|
||||
Serial.println("\t- Termination of charging alarm. This flag is set and cleared based on the selected SOC Flag Config A option.");
|
||||
}
|
||||
if (batteryStatus.isGoodOcvMeasurement()) {
|
||||
Serial.println("\t- A good OCV measurement was made.");
|
||||
}
|
||||
if (batteryStatus.isBatteryInserted()) {
|
||||
Serial.println("\t- Detects inserted battery.");
|
||||
}
|
||||
if (batteryStatus.isBatteryPresent()) {
|
||||
Serial.println("\t- Battery presence detected.");
|
||||
}
|
||||
if (batteryStatus.isDischargeTerminationAlarm()) {
|
||||
Serial.println("\t- Termination discharge alarm. This flag is set and cleared according to the selected SOC Flag Config A option.");
|
||||
}
|
||||
if (batteryStatus.isSystemShutdownRequired()) {
|
||||
Serial.println("\t- System shutdown bit indicating that the system should be shut down. True when set. If set, the SOC_INT pin toggles once.");
|
||||
}
|
||||
if (batteryStatus.isInDischargeMode()) {
|
||||
Serial.println("\t- When set, the device is in DISCHARGE mode; when cleared, the device is in CHARGING or RELAXATION mode.");
|
||||
}
|
||||
Serial.println("===============================================");
|
||||
|
||||
}
|
||||
delay(3000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,98 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file CM32181_LightSensor.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-04-14
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorCM32181.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 39
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 40
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 1
|
||||
#endif
|
||||
|
||||
SensorCM32181 light;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
pinMode(SENSOR_IRQ, INPUT_PULLUP);
|
||||
|
||||
if (!light.begin(Wire, CM32181_ADDR_PRIMARY, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find CM32181 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("Init CM32181 Sensor success!");
|
||||
|
||||
int id = light.getChipID();
|
||||
Serial.print("CM32181 ID = "); Serial.println(id);
|
||||
|
||||
/*
|
||||
Sensitivity mode selection
|
||||
SAMPLING_X1
|
||||
SAMPLING_X2
|
||||
SAMPLING_X1_8
|
||||
SAMPLING_X1_4
|
||||
*/
|
||||
light.setSampling(SensorCM32181::SAMPLING_X2);
|
||||
|
||||
//Power On sensor
|
||||
light.powerOn();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Get raw data
|
||||
uint16_t raw = light.getRaw();
|
||||
|
||||
// Get conversion data , The manual does not provide information on how to obtain the
|
||||
// calibration value, now use the calibration value 0.28 provided by the manual
|
||||
float lux = light.getLux();
|
||||
Serial.print(" RAW:"); Serial.print(raw);
|
||||
Serial.print(" Lux:"); Serial.println(lux);
|
||||
delay(500);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,158 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2023 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file CM32181_LightSensorInterrupt.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-09-13
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorCM32181.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 39
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 40
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 1
|
||||
#endif
|
||||
|
||||
SensorCM32181 light;
|
||||
|
||||
#ifdef ARDUINO_T_AMOLED_147
|
||||
#include <XPowersAXP2101.tpp> //PMU Library https://github.com/lewisxhe/XPowersLib.git
|
||||
XPowersAXP2101 power;
|
||||
#endif
|
||||
|
||||
void beginPower()
|
||||
{
|
||||
// T_AMOLED_147 The PMU voltage needs to be turned on to use the sensor
|
||||
#if defined(ARDUINO_T_AMOLED_147)
|
||||
bool ret = power.begin(Wire, AXP2101_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL);
|
||||
if (!ret) {
|
||||
Serial.println("PMU NOT FOUND!\n");
|
||||
}
|
||||
power.setALDO1Voltage(1800); power.enableALDO1();
|
||||
power.setALDO3Voltage(3300); power.enableALDO3();
|
||||
power.setBLDO1Voltage(1800); power.enableBLDO1();
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "SensorWireHelper.h"
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
beginPower();
|
||||
|
||||
SensorWireHelper::dumpDevices(Wire);
|
||||
|
||||
pinMode(SENSOR_IRQ, INPUT_PULLUP);
|
||||
|
||||
if (!light.begin(Wire, CM32181_ADDR_PRIMARY, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find CM32181 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("Init CM32181 Sensor success!");
|
||||
|
||||
int id = light.getChipID();
|
||||
Serial.print("CM32181 ID = "); Serial.println(id);
|
||||
|
||||
/*
|
||||
Sensitivity mode selection
|
||||
SAMPLING_X1
|
||||
SAMPLING_X2
|
||||
SAMPLING_X1_8
|
||||
SAMPLING_X1_4
|
||||
*/
|
||||
light.setSampling(SensorCM32181::SAMPLING_X2,
|
||||
SensorCM32181::INTEGRATION_TIME_400MS
|
||||
);
|
||||
|
||||
// Set high and low thresholds. If the threshold is higher or lower than the set threshold, an interrupt will be triggered.
|
||||
uint16_t lowThresholdRaw = 100;
|
||||
uint16_t highThresholdRaw = 250;
|
||||
light.setIntThreshold(lowThresholdRaw, highThresholdRaw);
|
||||
|
||||
//Power On sensor
|
||||
light.powerOn();
|
||||
|
||||
// Turn on interrupt
|
||||
light.enableINT();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
int pinVal = digitalRead(SENSOR_IRQ) ;
|
||||
if (pinVal == LOW) {
|
||||
|
||||
// After triggering the interrupt, the interrupt status must be read
|
||||
SensorCM32181::InterruptEvent event = light.getIrqStatus();
|
||||
|
||||
// Turn off interrupts
|
||||
light.disableINT();
|
||||
|
||||
// Get Status
|
||||
switch (event) {
|
||||
case SensorCM32181::ALS_EVENT_LOW_TRIGGER:
|
||||
Serial.println("Low interrupt event");
|
||||
break;
|
||||
case SensorCM32181::ALS_EVENT_HIGH_TRIGGER:
|
||||
Serial.println("High interrupt event");
|
||||
break;
|
||||
default:
|
||||
Serial.println("This is an impossible place to reach");
|
||||
break;
|
||||
}
|
||||
|
||||
// Get raw data
|
||||
uint16_t raw = light.getRaw();
|
||||
|
||||
// Get conversion data , The manual does not provide information on how to obtain the
|
||||
// calibration value, now use the calibration value 0.28 provided by the manual
|
||||
float lux = light.getLux();
|
||||
Serial.print(" IRQ:"); Serial.print(pinVal);
|
||||
Serial.print(" RAW:"); Serial.print(raw);
|
||||
Serial.print(" Lux:"); Serial.println(lux);
|
||||
// Turn on interrupts
|
||||
light.enableINT();
|
||||
}
|
||||
|
||||
delay(800);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,297 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file CustomCallbackTouchDrvInterface.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-21
|
||||
* @note CustomCallbackTouchDrvInterface use LilyGo T-RGB,T-RGB has three types of screens, each of which uses different touch driver chips.
|
||||
* The example demonstrates using the touch interface class and one sketch is suitable for three types of touch chips.
|
||||
* The example demonstrates using custom callbacks to read touch or sensors. This method is also applicable to other platforms.
|
||||
* The prerequisite compilation platform must support C++11.
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "TouchDrvFT6X36.hpp"
|
||||
#include "TouchDrvCSTXXX.hpp"
|
||||
#include "TouchDrvGT911.hpp"
|
||||
#include "ExtensionIOXL9555.hpp"
|
||||
#include "SensorWireHelper.h"
|
||||
|
||||
#ifndef TOUCH_SDA
|
||||
#define TOUCH_SDA 8
|
||||
#endif
|
||||
|
||||
#ifndef TOUCH_SCL
|
||||
#define TOUCH_SCL 48
|
||||
#endif
|
||||
|
||||
#ifndef TOUCH_IRQ
|
||||
#define TOUCH_IRQ 1
|
||||
#endif
|
||||
|
||||
#ifndef TOUCH_RST
|
||||
#define TOUCH_RST 1
|
||||
#endif
|
||||
|
||||
// Use the TouchDrvInterface base class for automatic discovery and use of multi-touch devices
|
||||
TouchDrvInterface *touchDrv;
|
||||
// T-RGB uses XL9555 as the reset control of the touch screen
|
||||
ExtensionIOXL9555 extension;
|
||||
|
||||
int16_t x[5], y[5];
|
||||
|
||||
ExtensionIOXL9555::ExtensionGPIO tp_reset = ExtensionIOXL9555::IO1;
|
||||
|
||||
/**
|
||||
* @brief i2c_wr_function
|
||||
* @note I2C communication using custom callbacks
|
||||
* @param addr: 7-Bit Device Address
|
||||
* @param reg: Register address, only needs to be written when writeReg is true
|
||||
* @param *buf: When isWrite is true, it represents the written buf, otherwise it is the read data buffer
|
||||
* @param len: When isWrite is true, it indicates the length of data written , otherwise it is the data read length
|
||||
* @param writeReg: writeReg is the register address that needs to be written, otherwise the register address is not written
|
||||
* @param isWrite: Data write and read direction, true means write, false means read
|
||||
* @retval True means the device is executed successfully, false means it fails
|
||||
*/
|
||||
bool i2c_wr_function(uint8_t addr, uint8_t reg, uint8_t *buf, size_t len, bool writeReg, bool isWrite)
|
||||
{
|
||||
if (isWrite) {
|
||||
Wire.beginTransmission(addr);
|
||||
if (writeReg) {
|
||||
Wire.write(reg);
|
||||
}
|
||||
if (buf && len > 0) {
|
||||
Wire.write(buf, len);
|
||||
}
|
||||
return (Wire.endTransmission() == 0);
|
||||
} else {
|
||||
if (writeReg) {
|
||||
Wire.beginTransmission(addr);
|
||||
Wire.write(reg);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
Wire.requestFrom(addr, static_cast<uint8_t>(len));
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
if (Wire.available()) {
|
||||
buf[i] = Wire.read();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t hal_callback(SensorCommCustomHal::Operation op, void *param1, void *param2)
|
||||
{
|
||||
switch (op) {
|
||||
// Set GPIO mode
|
||||
case SensorCommCustomHal::OP_PINMODE: {
|
||||
uint8_t pin = reinterpret_cast<uintptr_t>(param1);
|
||||
uint8_t mode = reinterpret_cast<uintptr_t>(param2);
|
||||
pinMode(pin, mode);
|
||||
}
|
||||
break;
|
||||
// Set GPIO level
|
||||
case SensorCommCustomHal::OP_DIGITALWRITE: {
|
||||
uint8_t pin = reinterpret_cast<uintptr_t>(param1);
|
||||
uint8_t level = reinterpret_cast<uintptr_t>(param2);
|
||||
digitalWrite(pin, level);
|
||||
}
|
||||
break;
|
||||
// Read GPIO level
|
||||
case SensorCommCustomHal::OP_DIGITALREAD: {
|
||||
uint8_t pin = reinterpret_cast<uintptr_t>(param1);
|
||||
return digitalRead(pin);
|
||||
}
|
||||
break;
|
||||
// Get the current running milliseconds
|
||||
case SensorCommCustomHal::OP_MILLIS:
|
||||
return millis();
|
||||
|
||||
// Delay in milliseconds
|
||||
case SensorCommCustomHal::OP_DELAY: {
|
||||
if (param1) {
|
||||
uint32_t ms = reinterpret_cast<uintptr_t>(param1);
|
||||
delay(ms);
|
||||
}
|
||||
}
|
||||
break;
|
||||
// Delay in microseconds
|
||||
case SensorCommCustomHal::OP_DELAYMICROSECONDS: {
|
||||
uint32_t us = reinterpret_cast<uintptr_t>(param1);
|
||||
delayMicroseconds(us);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TouchDrvDigitalWrite(uint8_t gpio, uint8_t level)
|
||||
{
|
||||
if (gpio & 0x80) {
|
||||
extension.digitalWrite(gpio & 0x7F, level);
|
||||
} else {
|
||||
digitalWrite(gpio, level);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t TouchDrvDigitalRead(uint8_t gpio)
|
||||
{
|
||||
if (gpio & 0x80) {
|
||||
return extension.digitalRead(gpio & 0x7F);
|
||||
} else {
|
||||
return digitalRead(gpio);
|
||||
}
|
||||
}
|
||||
|
||||
void TouchDrvPinMode(uint8_t gpio, uint8_t mode)
|
||||
{
|
||||
if (gpio & 0x80) {
|
||||
extension.pinMode(gpio & 0x7F, mode);
|
||||
} else {
|
||||
pinMode(gpio, mode);
|
||||
}
|
||||
}
|
||||
|
||||
bool setupTouchDrv()
|
||||
{
|
||||
// Add the highest bit to indicate that the GPIO extension is used, not the ESP's GPIO
|
||||
const uint8_t touch_reset_pin = tp_reset | 0x80;
|
||||
const uint8_t touch_irq_pin = TOUCH_IRQ;
|
||||
bool result = false;
|
||||
|
||||
touchDrv = new TouchDrvCSTXXX();
|
||||
touchDrv->setGpioCallback(TouchDrvPinMode, TouchDrvDigitalWrite, TouchDrvDigitalRead);
|
||||
touchDrv->setPins(touch_reset_pin, touch_irq_pin);
|
||||
result = touchDrv->begin(i2c_wr_function, hal_callback, CST816_SLAVE_ADDRESS);
|
||||
if (result) {
|
||||
const char *model = touchDrv->getModelName();
|
||||
Serial.print("Successfully initialized "); Serial.print(model);
|
||||
Serial.print(",using "); Serial.print(model); Serial.println(" Driver!");
|
||||
return true;
|
||||
}
|
||||
delete touchDrv;
|
||||
|
||||
touchDrv = new TouchDrvGT911();
|
||||
touchDrv->setGpioCallback(TouchDrvPinMode, TouchDrvDigitalWrite, TouchDrvDigitalRead);
|
||||
touchDrv->setPins(touch_reset_pin, touch_irq_pin);
|
||||
result = touchDrv->begin(i2c_wr_function, hal_callback, GT911_SLAVE_ADDRESS_L);
|
||||
if (result) {
|
||||
const char *model = touchDrv->getModelName();
|
||||
Serial.print("Successfully initialized "); Serial.print(model);
|
||||
Serial.print(",using "); Serial.print(model); Serial.println(" Driver!");
|
||||
return true;
|
||||
}
|
||||
delete touchDrv;
|
||||
|
||||
touchDrv = new TouchDrvFT6X36();
|
||||
touchDrv->setGpioCallback(TouchDrvPinMode, TouchDrvDigitalWrite, TouchDrvDigitalRead);
|
||||
touchDrv->setPins(touch_reset_pin, touch_irq_pin);
|
||||
result = touchDrv->begin(i2c_wr_function, hal_callback, FT3267_SLAVE_ADDRESS);
|
||||
if (result) {
|
||||
TouchDrvFT6X36 *tmp = static_cast<TouchDrvFT6X36 *>(touchDrv);
|
||||
tmp->interruptTrigger();
|
||||
const char *model = touchDrv->getModelName();
|
||||
Serial.print("Successfully initialized "); Serial.print(model);
|
||||
Serial.print(",using "); Serial.print(model); Serial.println(" Driver!");
|
||||
return true;
|
||||
}
|
||||
delete touchDrv;
|
||||
|
||||
Serial.println("Unable to find touch device.");
|
||||
|
||||
touchDrv = NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
Serial.println("Start!");
|
||||
|
||||
#if (defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_STM32)) && !defined(ARDUINO_ARCH_MBED)
|
||||
Wire.setSCL(TOUCH_SCL);
|
||||
Wire.setSDA(TOUCH_SDA);
|
||||
Wire.begin();
|
||||
#elif defined(ARDUINO_ARCH_NRF52)
|
||||
Wire.setPins(TOUCH_SDA, TOUCH_SCL);
|
||||
Wire.begin();
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
Wire.begin(TOUCH_SDA, TOUCH_SCL);
|
||||
#else
|
||||
Wire.begin();
|
||||
#endif
|
||||
|
||||
SensorWireHelper::dumpDevices(Wire);
|
||||
|
||||
// Use unspecified address to test the address discovery function.
|
||||
// T-RGB XL9555 uses 0X20 device address
|
||||
if (!extension.begin(i2c_wr_function, XL9555_UNKOWN_ADDRESS)) {
|
||||
Serial.println("Failed to find XL9555 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
if (!setupTouchDrv()) {
|
||||
while (1) {
|
||||
delay(3000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (touchDrv->isPressed()) {
|
||||
uint8_t touched = touchDrv->getPoint(x, y, touchDrv->getSupportTouchPoint());
|
||||
if (touched) {
|
||||
for (int i = 0; i < touched; ++i) {
|
||||
Serial.print("X[");
|
||||
Serial.print(i);
|
||||
Serial.print("]:");
|
||||
Serial.print(x[i]);
|
||||
Serial.print(" ");
|
||||
Serial.print(" Y[");
|
||||
Serial.print(i);
|
||||
Serial.print("]:");
|
||||
Serial.print(y[i]);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
delay(5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,219 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file CustomCallbackUsageExamples.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-20
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorPCF8563.hpp"
|
||||
#include "SensorBMA423.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 22
|
||||
#endif
|
||||
|
||||
SensorPCF8563 rtc;
|
||||
SensorBMA423 accel;
|
||||
|
||||
uint32_t intervalue;
|
||||
char buf[64];
|
||||
|
||||
bool i2c_wr_function(uint8_t addr, uint8_t reg, uint8_t *buf, size_t len, bool writeReg, bool isWrite)
|
||||
{
|
||||
if (isWrite) {
|
||||
Wire.beginTransmission(addr);
|
||||
if (writeReg) {
|
||||
Wire.write(reg);
|
||||
}
|
||||
if (buf && len > 0) {
|
||||
Wire.write(buf, len);
|
||||
}
|
||||
return (Wire.endTransmission() == 0);
|
||||
|
||||
} else {
|
||||
if (writeReg) {
|
||||
Wire.beginTransmission(addr);
|
||||
Wire.write(reg);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
Wire.requestFrom(addr, static_cast<uint8_t>(len));
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
if (Wire.available()) {
|
||||
buf[i] = Wire.read();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t hal_callback(SensorCommCustomHal::Operation op, void *param1, void *param2)
|
||||
{
|
||||
switch (op) {
|
||||
case SensorCommCustomHal::OP_PINMODE: {
|
||||
uint8_t pin = reinterpret_cast<uintptr_t>(param1);
|
||||
uint8_t mode = reinterpret_cast<uintptr_t>(param2);
|
||||
pinMode(pin, mode);
|
||||
}
|
||||
break;
|
||||
case SensorCommCustomHal::OP_DIGITALWRITE: {
|
||||
uint8_t pin = reinterpret_cast<uintptr_t>(param1);
|
||||
uint8_t level = reinterpret_cast<uintptr_t>(param2);
|
||||
digitalWrite(pin, level);
|
||||
}
|
||||
break;
|
||||
case SensorCommCustomHal::OP_DIGITALREAD: {
|
||||
uint8_t pin = reinterpret_cast<uintptr_t>(param1);
|
||||
return digitalRead(pin);
|
||||
}
|
||||
break;
|
||||
case SensorCommCustomHal::OP_MILLIS:
|
||||
return millis();
|
||||
break;
|
||||
case SensorCommCustomHal::OP_DELAY: {
|
||||
if (param1) {
|
||||
uint32_t ms = reinterpret_cast<uintptr_t>(param1);
|
||||
delay(ms);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SensorCommCustomHal::OP_DELAYMICROSECONDS: {
|
||||
uint32_t us = reinterpret_cast<uintptr_t>(param1);
|
||||
delayMicroseconds(us);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
#if (defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_STM32)) && !defined(ARDUINO_ARCH_MBED)
|
||||
Wire.setSCL(SENSOR_SCL);
|
||||
Wire.setSDA(SENSOR_SDA);
|
||||
Wire.begin();
|
||||
#elif defined(ARDUINO_ARCH_NRF52)
|
||||
Wire.setPins(SENSOR_SDA, SENSOR_SCL);
|
||||
Wire.begin();
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
Wire.begin(SENSOR_SDA, SENSOR_SCL);
|
||||
#else
|
||||
Wire.begin();
|
||||
#endif
|
||||
|
||||
// Using SensorLib with callback functions
|
||||
// Other sensor classes also support the same methods and can be applied to different platforms
|
||||
if (!rtc.begin(i2c_wr_function)) {
|
||||
Serial.println("Failed to find PCF8563 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// The simplest way to set up
|
||||
rtc.setDateTime(2024, 1, 17, 4, 21, 30);
|
||||
|
||||
// Unix tm structure sets the time
|
||||
struct tm timeinfo;
|
||||
timeinfo.tm_yday = 2025 - 1900; //Counting starts from 1900, so subtract 1900 here
|
||||
timeinfo.tm_mon = 1 - 1; //Months start at 0, so you need to subtract 1.
|
||||
timeinfo.tm_mday = 17;
|
||||
timeinfo.tm_hour = 4;
|
||||
timeinfo.tm_min = 30;
|
||||
timeinfo.tm_sec = 30;
|
||||
rtc.setDateTime(timeinfo);
|
||||
|
||||
if (!accel.begin(i2c_wr_function, hal_callback)) {
|
||||
Serial.println("Failed to find BMA423 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
//Default 4G ,200HZ
|
||||
accel.configAccelerometer();
|
||||
|
||||
accel.enableAccelerometer();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (millis() - intervalue > 1000) {
|
||||
|
||||
intervalue = millis();
|
||||
|
||||
struct tm timeinfo;
|
||||
// Get the time C library structure
|
||||
rtc.getDateTime(&timeinfo);
|
||||
|
||||
// Format the output using the strftime function
|
||||
// For more formats, please refer to :
|
||||
// https://man7.org/linux/man-pages/man3/strftime.3.html
|
||||
|
||||
size_t written = strftime(buf, 64, "%A, %B %d %Y %H:%M:%S", &timeinfo);
|
||||
|
||||
if (written != 0) {
|
||||
Serial.println(buf);
|
||||
}
|
||||
|
||||
written = strftime(buf, 64, "%b %d %Y %H:%M:%S", &timeinfo);
|
||||
if (written != 0) {
|
||||
Serial.println(buf);
|
||||
}
|
||||
|
||||
|
||||
written = strftime(buf, 64, "%A, %d. %B %Y %I:%M%p", &timeinfo);
|
||||
if (written != 0) {
|
||||
Serial.println(buf);
|
||||
}
|
||||
|
||||
Serial.print("Temperature:");
|
||||
Serial.print(accel.getTemperature(SensorBMA423::TEMP_DEG));
|
||||
Serial.print("*C ");
|
||||
Serial.print(accel.getTemperature(SensorBMA423::TEMP_FAHRENHEIT));
|
||||
Serial.print("*F");
|
||||
Serial.print("Dir:");
|
||||
Serial.print(accel.direction());
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,464 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file DRV2605_Basic.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-04-03
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorDRV2605.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 22
|
||||
#endif
|
||||
|
||||
|
||||
SensorDRV2605 drv;
|
||||
|
||||
uint8_t effect = 1;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
|
||||
if (!drv.begin(Wire, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find DRV2605 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
Serial.println("Init DRV2605 Sensor success!");
|
||||
|
||||
|
||||
drv.selectLibrary(1);
|
||||
|
||||
// I2C trigger by sending 'run' command
|
||||
// default, internal trigger when sending RUN command
|
||||
drv.setMode(SensorDRV2605::MODE_INTTRIG);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print("Effect #"); Serial.println(effect);
|
||||
|
||||
if (effect == 1) {
|
||||
Serial.println("11.2 Waveform Library Effects List");
|
||||
}
|
||||
|
||||
if (effect == 1) {
|
||||
Serial.println(F("1 - Strong Click - 100%"));
|
||||
}
|
||||
if (effect == 2) {
|
||||
Serial.println(F("2 - Strong Click - 60%"));
|
||||
}
|
||||
if (effect == 3) {
|
||||
Serial.println(F("3 - Strong Click - 30%"));
|
||||
}
|
||||
if (effect == 4) {
|
||||
Serial.println(F("4 - Sharp Click - 100%"));
|
||||
}
|
||||
if (effect == 5) {
|
||||
Serial.println(F("5 - Sharp Click - 60%"));
|
||||
}
|
||||
if (effect == 6) {
|
||||
Serial.println(F("6 - Sharp Click - 30%"));
|
||||
}
|
||||
if (effect == 7) {
|
||||
Serial.println(F("7 - Soft Bump - 100%"));
|
||||
}
|
||||
if (effect == 8) {
|
||||
Serial.println(F("8 - Soft Bump - 60%"));
|
||||
}
|
||||
if (effect == 9) {
|
||||
Serial.println(F("9 - Soft Bump - 30%"));
|
||||
}
|
||||
if (effect == 10) {
|
||||
Serial.println(F("10 - Double Click - 100%"));
|
||||
}
|
||||
if (effect == 11) {
|
||||
Serial.println(F("11 - Double Click - 60%"));
|
||||
}
|
||||
if (effect == 12) {
|
||||
Serial.println(F("12 - Triple Click - 100%"));
|
||||
}
|
||||
if (effect == 13) {
|
||||
Serial.println(F("13 - Soft Fuzz - 60%"));
|
||||
}
|
||||
if (effect == 14) {
|
||||
Serial.println(F("14 - Strong Buzz - 100%"));
|
||||
}
|
||||
if (effect == 15) {
|
||||
Serial.println(F("15 - 750 ms Alert 100%"));
|
||||
}
|
||||
if (effect == 16) {
|
||||
Serial.println(F("16 - 1000 ms Alert 100%"));
|
||||
}
|
||||
if (effect == 17) {
|
||||
Serial.println(F("17 - Strong Click 1 - 100%"));
|
||||
}
|
||||
if (effect == 18) {
|
||||
Serial.println(F("18 - Strong Click 2 - 80%"));
|
||||
}
|
||||
if (effect == 19) {
|
||||
Serial.println(F("19 - Strong Click 3 - 60%"));
|
||||
}
|
||||
if (effect == 20) {
|
||||
Serial.println(F("20 - Strong Click 4 - 30%"));
|
||||
}
|
||||
if (effect == 21) {
|
||||
Serial.println(F("21 - Medium Click 1 - 100%"));
|
||||
}
|
||||
if (effect == 22) {
|
||||
Serial.println(F("22 - Medium Click 2 - 80%"));
|
||||
}
|
||||
if (effect == 23) {
|
||||
Serial.println(F("23 - Medium Click 3 - 60%"));
|
||||
}
|
||||
if (effect == 24) {
|
||||
Serial.println(F("24 - Sharp Tick 1 - 100%"));
|
||||
}
|
||||
if (effect == 25) {
|
||||
Serial.println(F("25 - Sharp Tick 2 - 80%"));
|
||||
}
|
||||
if (effect == 26) {
|
||||
Serial.println(F("26 - Sharp Tick 3 - 60%"));
|
||||
}
|
||||
if (effect == 27) {
|
||||
Serial.println(F("27 - Short Double Click Strong 1 - 100%"));
|
||||
}
|
||||
if (effect == 28) {
|
||||
Serial.println(F("28 - Short Double Click Strong 2 - 80%"));
|
||||
}
|
||||
if (effect == 29) {
|
||||
Serial.println(F("29 - Short Double Click Strong 3 - 60%"));
|
||||
}
|
||||
if (effect == 30) {
|
||||
Serial.println(F("30 - Short Double Click Strong 4 - 30%"));
|
||||
}
|
||||
if (effect == 31) {
|
||||
Serial.println(F("31 - Short Double Click Medium 1 - 100%"));
|
||||
}
|
||||
if (effect == 32) {
|
||||
Serial.println(F("32 - Short Double Click Medium 2 - 80%"));
|
||||
}
|
||||
if (effect == 33) {
|
||||
Serial.println(F("33 - Short Double Click Medium 3 - 60%"));
|
||||
}
|
||||
if (effect == 34) {
|
||||
Serial.println(F("34 - Short Double Sharp Tick 1 - 100%"));
|
||||
}
|
||||
if (effect == 35) {
|
||||
Serial.println(F("35 - Short Double Sharp Tick 2 - 80%"));
|
||||
}
|
||||
if (effect == 36) {
|
||||
Serial.println(F("36 - Short Double Sharp Tick 3 - 60%"));
|
||||
}
|
||||
if (effect == 37) {
|
||||
Serial.println(F("37 - Long Double Sharp Click Strong 1 - 100%"));
|
||||
}
|
||||
if (effect == 38) {
|
||||
Serial.println(F("38 - Long Double Sharp Click Strong 2 - 80%"));
|
||||
}
|
||||
if (effect == 39) {
|
||||
Serial.println(F("39 - Long Double Sharp Click Strong 3 - 60%"));
|
||||
}
|
||||
if (effect == 40) {
|
||||
Serial.println(F("40 - Long Double Sharp Click Strong 4 - 30%"));
|
||||
}
|
||||
if (effect == 41) {
|
||||
Serial.println(F("41 - Long Double Sharp Click Medium 1 - 100%"));
|
||||
}
|
||||
if (effect == 42) {
|
||||
Serial.println(F("42 - Long Double Sharp Click Medium 2 - 80%"));
|
||||
}
|
||||
if (effect == 43) {
|
||||
Serial.println(F("43 - Long Double Sharp Click Medium 3 - 60%"));
|
||||
}
|
||||
if (effect == 44) {
|
||||
Serial.println(F("44 - Long Double Sharp Tick 1 - 100%"));
|
||||
}
|
||||
if (effect == 45) {
|
||||
Serial.println(F("45 - Long Double Sharp Tick 2 - 80%"));
|
||||
}
|
||||
if (effect == 46) {
|
||||
Serial.println(F("46 - Long Double Sharp Tick 3 - 60%"));
|
||||
}
|
||||
if (effect == 47) {
|
||||
Serial.println(F("47 - Buzz 1 - 100%"));
|
||||
}
|
||||
if (effect == 48) {
|
||||
Serial.println(F("48 - Buzz 2 - 80%"));
|
||||
}
|
||||
if (effect == 49) {
|
||||
Serial.println(F("49 - Buzz 3 - 60%"));
|
||||
}
|
||||
if (effect == 50) {
|
||||
Serial.println(F("50 - Buzz 4 - 40%"));
|
||||
}
|
||||
if (effect == 51) {
|
||||
Serial.println(F("51 - Buzz 5 - 20%"));
|
||||
}
|
||||
if (effect == 52) {
|
||||
Serial.println(F("52 - Pulsing Strong 1 - 100%"));
|
||||
}
|
||||
if (effect == 53) {
|
||||
Serial.println(F("53 - Pulsing Strong 2 - 60%"));
|
||||
}
|
||||
if (effect == 54) {
|
||||
Serial.println(F("54 - Pulsing Medium 1 - 100%"));
|
||||
}
|
||||
if (effect == 55) {
|
||||
Serial.println(F("55 - Pulsing Medium 2 - 60%"));
|
||||
}
|
||||
if (effect == 56) {
|
||||
Serial.println(F("56 - Pulsing Sharp 1 - 100%"));
|
||||
}
|
||||
if (effect == 57) {
|
||||
Serial.println(F("57 - Pulsing Sharp 2 - 60%"));
|
||||
}
|
||||
if (effect == 58) {
|
||||
Serial.println(F("58 - Transition Click 1 - 100%"));
|
||||
}
|
||||
if (effect == 59) {
|
||||
Serial.println(F("59 - Transition Click 2 - 80%"));
|
||||
}
|
||||
if (effect == 60) {
|
||||
Serial.println(F("60 - Transition Click 3 - 60%"));
|
||||
}
|
||||
if (effect == 61) {
|
||||
Serial.println(F("61 - Transition Click 4 - 40%"));
|
||||
}
|
||||
if (effect == 62) {
|
||||
Serial.println(F("62 - Transition Click 5 - 20%"));
|
||||
}
|
||||
if (effect == 63) {
|
||||
Serial.println(F("63 - Transition Click 6 - 10%"));
|
||||
}
|
||||
if (effect == 64) {
|
||||
Serial.println(F("64 - Transition Hum 1 - 100%"));
|
||||
}
|
||||
if (effect == 65) {
|
||||
Serial.println(F("65 - Transition Hum 2 - 80%"));
|
||||
}
|
||||
if (effect == 66) {
|
||||
Serial.println(F("66 - Transition Hum 3 - 60%"));
|
||||
}
|
||||
if (effect == 67) {
|
||||
Serial.println(F("67 - Transition Hum 4 - 40%"));
|
||||
}
|
||||
if (effect == 68) {
|
||||
Serial.println(F("68 - Transition Hum 5 - 20%"));
|
||||
}
|
||||
if (effect == 69) {
|
||||
Serial.println(F("69 - Transition Hum 6 - 10%"));
|
||||
}
|
||||
if (effect == 70) {
|
||||
Serial.println(F("70 - Transition Ramp Down Long Smooth 1 - 100 to 0%"));
|
||||
}
|
||||
if (effect == 71) {
|
||||
Serial.println(F("71 - Transition Ramp Down Long Smooth 2 - 100 to 0%"));
|
||||
}
|
||||
if (effect == 72) {
|
||||
Serial.println(F("72 - Transition Ramp Down Medium Smooth 1 - 100 to 0%"));
|
||||
}
|
||||
if (effect == 73) {
|
||||
Serial.println(F("73 - Transition Ramp Down Medium Smooth 2 - 100 to 0%"));
|
||||
}
|
||||
if (effect == 74) {
|
||||
Serial.println(F("74 - Transition Ramp Down Short Smooth 1 - 100 to 0%"));
|
||||
}
|
||||
if (effect == 75) {
|
||||
Serial.println(F("75 - Transition Ramp Down Short Smooth 2 - 100 to 0%"));
|
||||
}
|
||||
if (effect == 76) {
|
||||
Serial.println(F("76 - Transition Ramp Down Long Sharp 1 - 100 to 0%"));
|
||||
}
|
||||
if (effect == 77) {
|
||||
Serial.println(F("77 - Transition Ramp Down Long Sharp 2 - 100 to 0%"));
|
||||
}
|
||||
if (effect == 78) {
|
||||
Serial.println(F("78 - Transition Ramp Down Medium Sharp 1 - 100 to 0%"));
|
||||
}
|
||||
if (effect == 79) {
|
||||
Serial.println(F("79 - Transition Ramp Down Medium Sharp 2 - 100 to 0%"));
|
||||
}
|
||||
if (effect == 80) {
|
||||
Serial.println(F("80 - Transition Ramp Down Short Sharp 1 - 100 to 0%"));
|
||||
}
|
||||
if (effect == 81) {
|
||||
Serial.println(F("81 - Transition Ramp Down Short Sharp 2 - 100 to 0%"));
|
||||
}
|
||||
if (effect == 82) {
|
||||
Serial.println(F("82 - Transition Ramp Up Long Smooth 1 - 0 to 100%"));
|
||||
}
|
||||
if (effect == 83) {
|
||||
Serial.println(F("83 - Transition Ramp Up Long Smooth 2 - 0 to 100%"));
|
||||
}
|
||||
if (effect == 84) {
|
||||
Serial.println(F("84 - Transition Ramp Up Medium Smooth 1 - 0 to 100%"));
|
||||
}
|
||||
if (effect == 85) {
|
||||
Serial.println(F("85 - Transition Ramp Up Medium Smooth 2 - 0 to 100%"));
|
||||
}
|
||||
if (effect == 86) {
|
||||
Serial.println(F("86 - Transition Ramp Up Short Smooth 1 - 0 to 100%"));
|
||||
}
|
||||
if (effect == 87) {
|
||||
Serial.println(F("87 - Transition Ramp Up Short Smooth 2 - 0 to 100%"));
|
||||
}
|
||||
if (effect == 88) {
|
||||
Serial.println(F("88 - Transition Ramp Up Long Sharp 1 - 0 to 100%"));
|
||||
}
|
||||
if (effect == 89) {
|
||||
Serial.println(F("89 - Transition Ramp Up Long Sharp 2 - 0 to 100%"));
|
||||
}
|
||||
if (effect == 90) {
|
||||
Serial.println(F("90 - Transition Ramp Up Medium Sharp 1 - 0 to 100%"));
|
||||
}
|
||||
if (effect == 91) {
|
||||
Serial.println(F("91 - Transition Ramp Up Medium Sharp 2 - 0 to 100%"));
|
||||
}
|
||||
if (effect == 92) {
|
||||
Serial.println(F("92 - Transition Ramp Up Short Sharp 1 - 0 to 100%"));
|
||||
}
|
||||
if (effect == 93) {
|
||||
Serial.println(F("93 - Transition Ramp Up Short Sharp 2 - 0 to 100%"));
|
||||
}
|
||||
if (effect == 94) {
|
||||
Serial.println(F("94 - Transition Ramp Down Long Smooth 1 - 50 to 0%"));
|
||||
}
|
||||
if (effect == 95) {
|
||||
Serial.println(F("95 - Transition Ramp Down Long Smooth 2 - 50 to 0%"));
|
||||
}
|
||||
if (effect == 96) {
|
||||
Serial.println(F("96 - Transition Ramp Down Medium Smooth 1 - 50 to 0%"));
|
||||
}
|
||||
if (effect == 97) {
|
||||
Serial.println(F("97 - Transition Ramp Down Medium Smooth 2 - 50 to 0%"));
|
||||
}
|
||||
if (effect == 98) {
|
||||
Serial.println(F("98 - Transition Ramp Down Short Smooth 1 - 50 to 0%"));
|
||||
}
|
||||
if (effect == 99) {
|
||||
Serial.println(F("99 - Transition Ramp Down Short Smooth 2 - 50 to 0%"));
|
||||
}
|
||||
if (effect == 100) {
|
||||
Serial.println(F("100 - Transition Ramp Down Long Sharp 1 - 50 to 0%"));
|
||||
}
|
||||
if (effect == 101) {
|
||||
Serial.println(F("101 - Transition Ramp Down Long Sharp 2 - 50 to 0%"));
|
||||
}
|
||||
if (effect == 102) {
|
||||
Serial.println(F("102 - Transition Ramp Down Medium Sharp 1 - 50 to 0%"));
|
||||
}
|
||||
if (effect == 103) {
|
||||
Serial.println(F("103 - Transition Ramp Down Medium Sharp 2 - 50 to 0%"));
|
||||
}
|
||||
if (effect == 104) {
|
||||
Serial.println(F("104 - Transition Ramp Down Short Sharp 1 - 50 to 0%"));
|
||||
}
|
||||
if (effect == 105) {
|
||||
Serial.println(F("105 - Transition Ramp Down Short Sharp 2 - 50 to 0%"));
|
||||
}
|
||||
if (effect == 106) {
|
||||
Serial.println(F("106 - Transition Ramp Up Long Smooth 1 - 0 to 50%"));
|
||||
}
|
||||
if (effect == 107) {
|
||||
Serial.println(F("107 - Transition Ramp Up Long Smooth 2 - 0 to 50%"));
|
||||
}
|
||||
if (effect == 108) {
|
||||
Serial.println(F("108 - Transition Ramp Up Medium Smooth 1 - 0 to 50%"));
|
||||
}
|
||||
if (effect == 109) {
|
||||
Serial.println(F("109 - Transition Ramp Up Medium Smooth 2 - 0 to 50%"));
|
||||
}
|
||||
if (effect == 110) {
|
||||
Serial.println(F("110 - Transition Ramp Up Short Smooth 1 - 0 to 50%"));
|
||||
}
|
||||
if (effect == 111) {
|
||||
Serial.println(F("111 - Transition Ramp Up Short Smooth 2 - 0 to 50%"));
|
||||
}
|
||||
if (effect == 112) {
|
||||
Serial.println(F("112 - Transition Ramp Up Long Sharp 1 - 0 to 50%"));
|
||||
}
|
||||
if (effect == 113) {
|
||||
Serial.println(F("113 - Transition Ramp Up Long Sharp 2 - 0 to 50%"));
|
||||
}
|
||||
if (effect == 114) {
|
||||
Serial.println(F("114 - Transition Ramp Up Medium Sharp 1 - 0 to 50%"));
|
||||
}
|
||||
if (effect == 115) {
|
||||
Serial.println(F("115 - Transition Ramp Up Medium Sharp 2 - 0 to 50%"));
|
||||
}
|
||||
if (effect == 116) {
|
||||
Serial.println(F("116 - Transition Ramp Up Short Sharp 1 - 0 to 50%"));
|
||||
}
|
||||
if (effect == 117) {
|
||||
Serial.println(F("117 - Transition Ramp Up Short Sharp 2 - 0 to 50%"));
|
||||
}
|
||||
if (effect == 118) {
|
||||
Serial.println(F("118 - Long buzz for programmatic stopping - 100%"));
|
||||
}
|
||||
if (effect == 119) {
|
||||
Serial.println(F("119 - Smooth Hum 1 (No kick or brake pulse) - 50%"));
|
||||
}
|
||||
if (effect == 120) {
|
||||
Serial.println(F("120 - Smooth Hum 2 (No kick or brake pulse) - 40%"));
|
||||
}
|
||||
if (effect == 121) {
|
||||
Serial.println(F("121 - Smooth Hum 3 (No kick or brake pulse) - 30%"));
|
||||
}
|
||||
if (effect == 122) {
|
||||
Serial.println(F("122 - Smooth Hum 4 (No kick or brake pulse) - 20%"));
|
||||
}
|
||||
if (effect == 123) {
|
||||
Serial.println(F("123 - Smooth Hum 5 (No kick or brake pulse) - 10%"));
|
||||
}
|
||||
|
||||
// set the effect to play
|
||||
drv.setWaveform(0, effect); // play effect
|
||||
drv.setWaveform(1, 0); // end waveform
|
||||
|
||||
// play the effect!
|
||||
drv.run();
|
||||
|
||||
// wait a bit
|
||||
delay(500);
|
||||
|
||||
effect++;
|
||||
if (effect > 117) effect = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
# The following five lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS ../../../SensorLib)
|
||||
|
||||
project(ESP_IDF_SensorExamples)
|
||||
@ -0,0 +1,10 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := ESP_IDF_SensorPCF8563
|
||||
|
||||
EXTRA_COMPONENT_DIRS = ../../../SensorLib
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
@ -0,0 +1,840 @@
|
||||
# ESP-IDF Sensor hub examples
|
||||
|
||||
## Configure the Project
|
||||
|
||||
Open the project configuration menu (`idf.py menuconfig`).
|
||||
|
||||
In the `SensorLib Example Configuration` menu:
|
||||
|
||||
* Select Sensor Type , Different sensors have different transmission methods, I2C, SPI
|
||||
- BHI260 Sensor (I2C & SPI)
|
||||
- PCF8563 (I2C Only)
|
||||
- BMA423 (I2C Only)
|
||||
- FT636X (I2C Only)
|
||||
- XL9555 (I2C Only)
|
||||
- The other models are the same
|
||||
* If you choose a sensor with I2C communication, there will be three methods to choose from:
|
||||
* Configuring the sensor pins
|
||||
|
||||
## How to Use Example
|
||||
|
||||
Before project configuration and build, be sure to set the correct chip target using `idf.py set-target <chip_name>`. default use **esp32**
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
The output information is to configure the output voltage and enable status of the Sensor
|
||||
|
||||
### LL Driver
|
||||
|
||||
```bash
|
||||
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
configsip: 0, SPIWP:0xee
|
||||
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
mode:DIO, clock div:2
|
||||
load:0x3fff0030,len:7176
|
||||
load:0x40078000,len:15564
|
||||
ho 0 tail 12 room 4
|
||||
load:0x40080400,len:4
|
||||
0x40080400: _init at ??:?
|
||||
|
||||
load:0x40080404,len:3904
|
||||
entry 0x40080640
|
||||
I (30) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader
|
||||
I (30) boot: compile time Jan 22 2025 17:30:49
|
||||
I (33) boot: Multicore bootloader
|
||||
I (37) boot: chip revision: v1.0
|
||||
I (41) boot.esp32: SPI Speed : 40MHz
|
||||
I (45) boot.esp32: SPI Mode : DIO
|
||||
I (50) boot.esp32: SPI Flash Size : 2MB
|
||||
I (54) boot: Enabling RNG early entropy source...
|
||||
I (60) boot: Partition Table:
|
||||
I (63) boot: ## Label Usage Type ST Offset Length
|
||||
I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000
|
||||
I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000
|
||||
I (85) boot: 2 factory factory app 00 00 00010000 00100000
|
||||
I (93) boot: End of partition table
|
||||
I (97) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0d54ch ( 54604) map
|
||||
I (124) esp_image: segment 1: paddr=0001d574 vaddr=3ffb0000 size=022b8h ( 8888) load
|
||||
I (128) esp_image: segment 2: paddr=0001f834 vaddr=40080000 size=007e4h ( 2020) load
|
||||
I (131) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=1c450h (115792) map
|
||||
I (178) esp_image: segment 4: paddr=0003c478 vaddr=400807e4 size=0bf98h ( 49048) load
|
||||
I (204) boot: Loaded app from partition at offset 0x10000
|
||||
I (204) boot: Disabling RNG early entropy source...
|
||||
I (216) cpu_start: Multicore app
|
||||
I (224) cpu_start: Pro cpu start user code
|
||||
I (224) cpu_start: cpu freq: 240000000 Hz
|
||||
I (224) app_init: Application information:
|
||||
I (227) app_init: Project name: ESP_IDF_TouchDrv_Example
|
||||
I (234) app_init: App version: v0.2.5-8-gde9a1d2-dirty
|
||||
I (240) app_init: Compile time: Jan 22 2025 17:32:37
|
||||
I (246) app_init: ELF file SHA256: ef2e805bc...
|
||||
I (251) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt
|
||||
I (258) efuse_init: Min chip rev: v0.0
|
||||
I (263) efuse_init: Max chip rev: v3.99
|
||||
I (268) efuse_init: Chip rev: v1.0
|
||||
I (273) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (280) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
|
||||
I (286) heap_init: At 3FFB2BD0 len 0002D430 (181 KiB): DRAM
|
||||
I (292) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
|
||||
I (299) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
|
||||
I (305) heap_init: At 4008C77C len 00013884 (78 KiB): IRAM
|
||||
I (313) spi_flash: detected chip: winbond
|
||||
I (316) spi_flash: flash io: dio
|
||||
W (320) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
I (334) main_task: Started on CPU0
|
||||
I (344) main_task: Calling app_main()
|
||||
I (344) I2C: Implemented using read and write callback methods (Use higher version >= 5.0 API)
|
||||
W (344) i2c.master: Please check pull-up resistances whether be connected properly. Otherwise unexpected behavior would happen. For more detailed information, please read docs
|
||||
I (364) gpio: GPIO[21]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (374) gpio: GPIO[22]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (384) main: I2C initialized successfully
|
||||
Scan I2C Devices:
|
||||
0 1 2 3 4 5 6 7 8 9 a b c d e f
|
||||
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
10: -- -- -- -- -- -- -- -- -- 19 -- -- -- -- -- --
|
||||
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
30: -- -- -- -- -- 35 -- -- -- -- -- -- -- -- -- --
|
||||
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
|
||||
|
||||
|
||||
I (434) RTC: ----DRIVER PCF8563 ----
|
||||
I (434) RTC: Implemented using built-in read and write methods (Use higher version >= 5.0 API)
|
||||
Using ESP-IDF Driver interface.Added Device Address : 0x51 New Dev Address: 0x3ffb4f9c Speed :400000 I (444) RTC: Initializing PCF8563 real-time clock successfully!
|
||||
I (464) BMA: ----DRIVER BMA423----
|
||||
I (464) BMA: Implemented using built-in read and write methods (Use higher version >= 5.0 API)
|
||||
Using ESP-IDF Driver interface.Added Device Address : 0x19 New Dev Address: 0x3ffb4ffc Speed :400000 No need configure!I (474) BMA: Initialization of BMA423 accelerometer is successful!
|
||||
I (494) main: Run...
|
||||
I (494) main_task: Returned from app_main()
|
||||
I (494) RTC: Friday, January 17 2025 04:30:30
|
||||
I (504) RTC: Jan 17 2025 04:30:30
|
||||
I (504) RTC: Friday, 17. January 2025 04:30AM
|
||||
I (514) BMA423: Temperature:38.00*C
|
||||
I (514) BMA423: Temperature:100.40*F
|
||||
I (524) BMA423: Direction:5
|
||||
I (1524) RTC: Friday, January 17 2025 04:30:31
|
||||
I (1524) RTC: Jan 17 2025 04:30:31
|
||||
I (1524) RTC: Friday, 17. January 2025 04:30AM
|
||||
I (1524) BMA423: Temperature:38.00*C
|
||||
I (1524) BMA423: Temperature:100.40*F
|
||||
I (1534) BMA423: Direction:5
|
||||
I (2534) RTC: Friday, January 17 2025 04:30:32
|
||||
I (2534) RTC: Jan 17 2025 04:30:32
|
||||
I (2534) RTC: Friday, 17. January 2025 04:30AM
|
||||
I (2534) BMA423: Temperature:38.00*C
|
||||
I (2534) BMA423: Temperature:100.40*F
|
||||
I (2544) BMA423: Direction:5
|
||||
I (3544) RTC: Friday, January 17 2025 04:30:33
|
||||
I (3544) RTC: Jan 17 2025 04:30:33
|
||||
I (3544) RTC: Friday, 17. January 2025 04:30AM
|
||||
I (3544) BMA423: Temperature:38.00*C
|
||||
I (3544) BMA423: Temperature:100.40*F
|
||||
```
|
||||
|
||||
### Legacy Driver
|
||||
|
||||
```bash
|
||||
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
configsip: 0, SPIWP:0xee
|
||||
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
mode:DIO, clock div:2
|
||||
load:0x3fff0030,len:7176
|
||||
load:0x40078000,len:15564
|
||||
ho 0 tail 12 room 4
|
||||
load:0x40080400,len:4
|
||||
0x40080400: _init at ??:?
|
||||
|
||||
load:0x40080404,len:3904
|
||||
entry 0x40080640
|
||||
I (30) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader
|
||||
I (31) boot: compile time Jan 22 2025 17:30:49
|
||||
I (33) boot: Multicore bootloader
|
||||
I (37) boot: chip revision: v1.0
|
||||
I (41) boot.esp32: SPI Speed : 40MHz
|
||||
I (45) boot.esp32: SPI Mode : DIO
|
||||
I (50) boot.esp32: SPI Flash Size : 2MB
|
||||
I (54) boot: Enabling RNG early entropy source...
|
||||
I (60) boot: Partition Table:
|
||||
I (63) boot: ## Label Usage Type ST Offset Length
|
||||
I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000
|
||||
I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000
|
||||
I (86) boot: 2 factory factory app 00 00 00010000 00100000
|
||||
I (93) boot: End of partition table
|
||||
I (97) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0d200h ( 53760) map
|
||||
I (124) esp_image: segment 1: paddr=0001d228 vaddr=3ffb0000 size=022e8h ( 8936) load
|
||||
I (128) esp_image: segment 2: paddr=0001f518 vaddr=40080000 size=00b00h ( 2816) load
|
||||
I (131) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=1b71ch (112412) map
|
||||
I (177) esp_image: segment 4: paddr=0003b744 vaddr=40080b00 size=0ccd8h ( 52440) load
|
||||
I (204) boot: Loaded app from partition at offset 0x10000
|
||||
I (205) boot: Disabling RNG early entropy source...
|
||||
I (216) cpu_start: Multicore app
|
||||
I (225) cpu_start: Pro cpu start user code
|
||||
I (225) cpu_start: cpu freq: 240000000 Hz
|
||||
I (225) app_init: Application information:
|
||||
I (228) app_init: Project name: ESP_IDF_SensorPCF8563
|
||||
I (234) app_init: App version: v0.2.5-8-gde9a1d2-dirty
|
||||
I (240) app_init: Compile time: Jan 22 2025 17:47:23
|
||||
I (246) app_init: ELF file SHA256: 0fcff42da...
|
||||
I (251) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt
|
||||
I (258) efuse_init: Min chip rev: v0.0
|
||||
I (263) efuse_init: Max chip rev: v3.99
|
||||
I (268) efuse_init: Chip rev: v1.0
|
||||
I (273) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (280) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
|
||||
I (286) heap_init: At 3FFB2BF0 len 0002D410 (181 KiB): DRAM
|
||||
I (292) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
|
||||
I (299) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
|
||||
I (305) heap_init: At 4008D7D8 len 00012828 (74 KiB): IRAM
|
||||
I (313) spi_flash: detected chip: winbond
|
||||
I (316) spi_flash: flash io: dio
|
||||
W (320) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
W (333) i2c: This driver is an old driver, please migrate your application code to adapt `driver/i2c_master.h`
|
||||
I (344) main_task: Started on CPU0
|
||||
I (354) main_task: Calling app_main()
|
||||
I (354) I2C: Implemented using read and write callback methods (Use lower version < 5.0 API)
|
||||
I (354) main: I2C initialized successfully
|
||||
0 1 2 3 4 5 6 7 8 9 a b c d e f
|
||||
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
10: -- -- -- -- -- -- -- -- -- 19 -- -- -- -- -- --
|
||||
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
30: -- -- -- -- -- 35 -- -- -- -- -- -- -- -- -- --
|
||||
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
I (404) RTC: ----DRIVER PCF8563 ----
|
||||
I (404) RTC: Implemented using built-in read and write methods (Use lower version < 5.0 API)
|
||||
I (414) RTC: Initializing PCF8563 real-time clock successfully!
|
||||
I (424) BMA: ----DRIVER BMA423----
|
||||
I (424) BMA: Implemented using built-in read and write methods (Use lower version < 5.0 API)
|
||||
I (444) BMA: Initialization of BMA423 accelerometer is successful!
|
||||
I (444) main: Run...
|
||||
I (444) main_task: Returned from app_main()
|
||||
I (454) RTC: Friday, January 17 2025 04:30:30
|
||||
I (454) RTC: Jan 17 2025 04:30:30
|
||||
I (464) RTC: Friday, 17. January 2025 04:30AM
|
||||
I (464) BMA423: Temperature:37.00*C
|
||||
I (474) BMA423: Temperature:98.60*F
|
||||
I (474) BMA423: Direction:5
|
||||
I (1474) RTC: Friday, January 17 2025 04:30:31
|
||||
I (1474) RTC: Jan 17 2025 04:30:31
|
||||
I (1474) RTC: Friday, 17. January 2025 04:30AM
|
||||
I (1474) BMA423: Temperature:37.00*C
|
||||
I (1474) BMA423: Temperature:98.60*F
|
||||
I (1484) BMA423: Direction:5
|
||||
```
|
||||
|
||||
### Use Read/Write/Hal Callback
|
||||
|
||||
```bash
|
||||
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
configsip: 0, SPIWP:0xee
|
||||
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
mode:DIO, clock div:2
|
||||
load:0x3fff0030,len:7176
|
||||
load:0x40078000,len:15564
|
||||
ho 0 tail 12 room 4
|
||||
load:0x40080400,len:4
|
||||
0x40080400: _init at ??:?
|
||||
|
||||
load:0x40080404,len:3904
|
||||
entry 0x40080640
|
||||
I (30) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader
|
||||
I (31) boot: compile time Jan 22 2025 17:30:49
|
||||
I (33) boot: Multicore bootloader
|
||||
I (37) boot: chip revision: v1.0
|
||||
I (41) boot.esp32: SPI Speed : 40MHz
|
||||
I (45) boot.esp32: SPI Mode : DIO
|
||||
I (50) boot.esp32: SPI Flash Size : 2MB
|
||||
I (54) boot: Enabling RNG early entropy source...
|
||||
I (60) boot: Partition Table:
|
||||
I (63) boot: ## Label Usage Type ST Offset Length
|
||||
I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000
|
||||
I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000
|
||||
I (86) boot: 2 factory factory app 00 00 00010000 00100000
|
||||
I (93) boot: End of partition table
|
||||
I (97) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0d2b0h ( 53936) map
|
||||
I (124) esp_image: segment 1: paddr=0001d2d8 vaddr=3ffb0000 size=022e8h ( 8936) load
|
||||
I (128) esp_image: segment 2: paddr=0001f5c8 vaddr=40080000 size=00a50h ( 2640) load
|
||||
I (131) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=1b97ch (113020) map
|
||||
I (177) esp_image: segment 4: paddr=0003b9a4 vaddr=40080a50 size=0cd88h ( 52616) load
|
||||
I (205) boot: Loaded app from partition at offset 0x10000
|
||||
I (205) boot: Disabling RNG early entropy source...
|
||||
I (216) cpu_start: Multicore app
|
||||
I (225) cpu_start: Pro cpu start user code
|
||||
I (225) cpu_start: cpu freq: 240000000 Hz
|
||||
I (225) app_init: Application information:
|
||||
I (228) app_init: Project name: ESP_IDF_SensorPCF8563
|
||||
I (234) app_init: App version: v0.2.5-8-gde9a1d2-dirty
|
||||
I (240) app_init: Compile time: Jan 22 2025 18:19:56
|
||||
I (246) app_init: ELF file SHA256: 952e2e97b...
|
||||
I (252) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt
|
||||
I (259) efuse_init: Min chip rev: v0.0
|
||||
I (263) efuse_init: Max chip rev: v3.99
|
||||
I (268) efuse_init: Chip rev: v1.0
|
||||
I (273) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (281) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
|
||||
I (286) heap_init: At 3FFB2BF0 len 0002D410 (181 KiB): DRAM
|
||||
I (293) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
|
||||
I (299) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
|
||||
I (306) heap_init: At 4008D7D8 len 00012828 (74 KiB): IRAM
|
||||
I (313) spi_flash: detected chip: winbond
|
||||
I (316) spi_flash: flash io: dio
|
||||
W (320) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
W (333) i2c: This driver is an old driver, please migrate your application code to adapt `driver/i2c_master.h`
|
||||
I (345) main_task: Started on CPU0
|
||||
I (355) main_task: Calling app_main()
|
||||
I (355) I2C: Implemented using read and write callback methods (Use lower version < 5.0 API)
|
||||
I (355) main: I2C initialized successfully
|
||||
0 1 2 3 4 5 6 7 8 9 a b c d e f
|
||||
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
10: -- -- -- -- -- -- -- -- -- 19 -- -- -- -- -- --
|
||||
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
30: -- -- -- -- -- 35 -- -- -- -- -- -- -- -- -- --
|
||||
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
I (405) RTC: ----DRIVER PCF8563 ----
|
||||
I (405) RTC: Implemented using read and write callback methods
|
||||
I (415) RTC: Initializing PCF8563 real-time clock successfully!
|
||||
I (425) BMA: ----DRIVER BMA423----
|
||||
I (425) BMA: Implemented using read and write callback methods
|
||||
I (435) BMA: Initialization of BMA423 accelerometer is successful!
|
||||
I (445) main: Run...
|
||||
I (445) main_task: Returned from app_main()
|
||||
I (445) RTC: Friday, January 17 2025 04:30:30
|
||||
I (455) RTC: Jan 17 2025 04:30:30
|
||||
I (455) RTC: Friday, 17. January 2025 04:30AM
|
||||
I (465) BMA423: Temperature:35.00*C
|
||||
I (465) BMA423: Temperature:95.00*F
|
||||
I (475) BMA423: Direction:5
|
||||
I (1475) RTC: Friday, January 17 2025 04:30:31
|
||||
I (1475) RTC: Jan 17 2025 04:30:31
|
||||
I (1475) RTC: Friday, 17. January 2025 04:30AM
|
||||
I (1475) BMA423: Temperature:35.00*C
|
||||
I (1475) BMA423: Temperature:95.00*F
|
||||
I (1485) BMA423: Direction:5
|
||||
I (2485) RTC: Friday, January 17 2025 04:30:32
|
||||
I (2485) RTC: Jan 17 2025 04:30:32
|
||||
I (2485) RTC: Friday, 17. January 2025 04:30AM
|
||||
```
|
||||
|
||||
### BHI260AP SPI Interface
|
||||
|
||||
```bash
|
||||
SPIWP:0xee
|
||||
mode:DIO, clock div:1
|
||||
load:0x3fce2810,len:0x178c
|
||||
load:0x403c8700,len:0x4
|
||||
load:0x403c8704,len:0xc10
|
||||
load:0x403cb700,len:0x2dac
|
||||
entry 0x403c8904
|
||||
I (26) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader
|
||||
I (27) boot: compile time Jan 23 2025 11:42:56
|
||||
I (27) boot: Multicore bootloader
|
||||
I (27) boot: chip revision: v0.1
|
||||
I (27) boot.esp32s3: Boot SPI Speed : 80MHz
|
||||
I (27) boot.esp32s3: SPI Mode : DIO
|
||||
I (28) boot.esp32s3: SPI Flash Size : 2MB
|
||||
I (28) boot: Enabling RNG early entropy source...
|
||||
I (28) boot: Partition Table:
|
||||
I (28) boot: ## Label Usage Type ST Offset Length
|
||||
I (29) boot: 0 nvs WiFi data 01 02 00009000 00006000
|
||||
I (29) boot: 1 phy_init RF data 01 01 0000f000 00001000
|
||||
I (29) boot: 2 factory factory app 00 00 00010000 00100000
|
||||
I (30) boot: End of partition table
|
||||
I (30) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=29698h (169624) map
|
||||
I (61) esp_image: segment 1: paddr=000396c0 vaddr=3fc94a00 size=02b0ch ( 11020) load
|
||||
I (64) esp_image: segment 2: paddr=0003c1d4 vaddr=40374000 size=03e44h ( 15940) load
|
||||
I (68) esp_image: segment 3: paddr=00040020 vaddr=42000020 size=28a70h (166512) map
|
||||
I (98) esp_image: segment 4: paddr=00068a98 vaddr=40377e44 size=0cb2ch ( 52012) load
|
||||
I (116) boot: Loaded app from partition at offset 0x10000
|
||||
I (117) boot: Disabling RNG early entropy source...
|
||||
I (117) cpu_start: Multicore app
|
||||
I (127) cpu_start: Pro cpu start user code
|
||||
I (127) cpu_start: cpu freq: 240000000 Hz
|
||||
I (127) app_init: Application information:
|
||||
I (127) app_init: Project name: ESP_IDF_SensorExamples
|
||||
I (127) app_init: App version: v0.2.5-8-gde9a1d2-dirty
|
||||
I (128) app_init: Compile time: Jan 23 2025 11:44:54
|
||||
I (128) app_init: ELF file SHA256: 3512ddfc8...
|
||||
I (128) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt
|
||||
I (128) efuse_init: Min chip rev: v0.0
|
||||
I (128) efuse_init: Max chip rev: v0.99
|
||||
I (128) efuse_init: Chip rev: v0.1
|
||||
I (129) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (129) heap_init: At 3FC97EC0 len 00051850 (326 KiB): RAM
|
||||
I (129) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
|
||||
I (129) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
|
||||
I (130) heap_init: At 600FE100 len 00001EE8 (7 KiB): RTCRAM
|
||||
I (131) spi_flash: detected chip: generic
|
||||
I (131) spi_flash: flash io: dio
|
||||
W (131) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
I (132) sleep: Configure to isolate all GPIO pins in sleep state
|
||||
I (132) sleep: Enable automatic switching of GPIO sleep configuration
|
||||
I (133) main_task: Started on CPU0
|
||||
I (143) main_task: Calling app_main()
|
||||
I (143) BHI: ----DRIVER BHI260AP----
|
||||
I (143) gpio: GPIO[36]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (153) SensorLib: BHI260/BHA260 found. Product ID read 0x89
|
||||
I (583) SensorLib: Boot successful. Kernel version 5991.
|
||||
I (583) SensorLib: [META EVENT WAKE UP] Firmware initialized. Firmware version 5991
|
||||
I (583) SensorLib: [META EVENT] Firmware initialized. Firmware version 5991
|
||||
I (943) BHI: Initialization of BHI260AP is successful!
|
||||
Product ID : 89
|
||||
Kernel version : 5991
|
||||
User version : 5991
|
||||
ROM version : 5166
|
||||
Power state : sleeping
|
||||
Host interface : SPI
|
||||
Feature status : 0x4a
|
||||
Boot Status : 0x38: No flash installed. Host interface ready. Firmware verification done. Virtual sensor list.
|
||||
Sensor ID | Sensor Name | ID | Ver | Min rate | Max rate |
|
||||
----------+--------------------------------------+-----+-----+-----------+-----------|
|
||||
1 | Accelerometer passthrough | 205 | 1 | 1.5625 | 400.0000 |
|
||||
3 | Accelerometer uncalibrated | 203 | 1 | 1.5625 | 400.0000 |
|
||||
4 | Accelerometer corrected | 241 | 1 | 1.5625 | 400.0000 |
|
||||
5 | Accelerometer offset | 209 | 1 | 1.0000 | 1.0000 |
|
||||
6 | Accelerometer corrected wake up | 192 | 1 | 1.5625 | 400.0000 |
|
||||
7 | Accelerometer uncalibrated wake up | 204 | 1 | 1.5625 | 400.0000 |
|
||||
10 | Gyroscope passthrough | 207 | 1 | 1.5625 | 400.0000 |
|
||||
12 | Gyroscope uncalibrated | 244 | 1 | 1.5625 | 400.0000 |
|
||||
13 | Gyroscope corrected | 243 | 1 | 1.5625 | 400.0000 |
|
||||
14 | Gyroscope offset | 208 | 1 | 1.0000 | 1.0000 |
|
||||
15 | Gyroscope wake up | 194 | 1 | 1.5625 | 400.0000 |
|
||||
16 | Gyroscope uncalibrated wake up | 195 | 1 | 1.5625 | 400.0000 |
|
||||
28 | Gravity vector | 247 | 1 | 1.5625 | 400.0000 |
|
||||
29 | Gravity vector wake up | 198 | 1 | 1.5625 | 400.0000 |
|
||||
31 | Linear acceleration | 246 | 1 | 1.5625 | 400.0000 |
|
||||
32 | Linear acceleration wake up | 197 | 1 | 1.5625 | 400.0000 |
|
||||
37 | Game rotation vector | 252 | 1 | 1.5625 | 400.0000 |
|
||||
38 | Game rotation vector wake up | 200 | 1 | 1.5625 | 400.0000 |
|
||||
48 | Tilt detector | 236 | 1 | 1.0000 | 1.0000 |
|
||||
50 | Step detector | 248 | 1 | 1.0000 | 1.0000 |
|
||||
52 | Step counter | 249 | 1 | 1.0000 | 1.0000 |
|
||||
53 | Step counter wake up | 231 | 1 | 0.0005 | 25.0000 |
|
||||
55 | Significant motion | 250 | 1 | 1.0000 | 1.0000 |
|
||||
57 | Wake gesture | 232 | 1 | 1.0000 | 1.0000 |
|
||||
59 | Glance gesture | 234 | 1 | 1.0000 | 1.0000 |
|
||||
61 | Pickup gesture | 233 | 1 | 1.0000 | 1.0000 |
|
||||
63 | Activity recognition | 235 | 1 | 1.0000 | 1.0000 |
|
||||
67 | Wrist tilt gesture | 162 | 1 | 1.0000 | 1.0000 |
|
||||
69 | Device orientation | 163 | 1 | 1.0000 | 1.0000 |
|
||||
70 | Device orientation wake up | 164 | 1 | 1.0000 | 1.0000 |
|
||||
75 | Stationary detect | 161 | 1 | 1.0000 | 1.0000 |
|
||||
77 | Motion detect | 160 | 1 | 1.0000 | 1.0000 |
|
||||
94 | Step detector wake up | 230 | 1 | 1.0000 | 1.0000 |
|
||||
I (1293) gpio: GPIO[37]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:2
|
||||
I (1293) main: Run...
|
||||
I (1293) main_task: Returned from app_main()
|
||||
I (1683) SensorLib: [META EVENT] Power mode changed for sensor id 1
|
||||
I (1683) SensorLib: [META EVENT] Sample rate changed for sensor id 1
|
||||
I (1683) SensorLib: [META EVENT] Power mode changed for sensor id 10
|
||||
I (1683) SensorLib: [META EVENT] Sample rate changed for sensor id 10
|
||||
I (1683) BHI: Accelerometer passthrough: x: -0.212646, y: 0.300293, z: 0.953613;
|
||||
I (1683) BHI: Gyroscope passthrough: x: -0.671387, y: -0.732422, z: -0.122070;
|
||||
I (2313) BHI: Accelerometer passthrough: x: -0.213379, y: 0.302734, z: 0.960205;
|
||||
I (2313) BHI: Gyroscope passthrough: x: -0.610352, y: -0.671387, z: -0.061035;
|
||||
I (2953) BHI: Accelerometer passthrough: x: -0.213623, y: 0.302734, z: 0.960449;
|
||||
I (2953) BHI: Gyroscope passthrough: x: -0.671387, y: -0.732422, z: -0.061035;
|
||||
I (3583) BHI: Accelerometer passthrough: x: -0.213379, y: 0.302979, z: 0.960205;
|
||||
I (3583) BHI: Gyroscope passthrough: x: -0.610352, y: -0.610352, z: -0.061035;
|
||||
I (4223) BHI: Accelerometer passthrough: x: -0.213623, y: 0.302490, z: 0.960449;
|
||||
I (4223) BHI: Gyroscope passthrough: x: -0.610352, y: -0.671387, z: -0.122070;
|
||||
I (4853) BHI: Accelerometer passthrough: x: -0.213867, y: 0.303467, z: 0.960205;
|
||||
I (4853) BHI: Gyroscope passthrough: x: -0.610352, y: -0.671387, z: -0.122070;
|
||||
```
|
||||
|
||||
### BHI260 I2C Interface
|
||||
|
||||
```bash
|
||||
SPIWP:0xee
|
||||
mode:DIO, clock div:1
|
||||
load:0x3fce2810,len:0x178c
|
||||
load:0x403c8700,len:0x4
|
||||
load:0x403c8704,len:0xcb8
|
||||
load:0x403cb700,len:0x2d9c
|
||||
entry 0x403c8914
|
||||
I (26) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader
|
||||
I (27) boot: compile time Jan 23 2025 14:20:21
|
||||
I (28) boot: Multicore bootloader
|
||||
I (32) boot: chip revision: v0.2
|
||||
I (36) boot.esp32s3: Boot SPI Speed : 80MHz
|
||||
I (41) boot.esp32s3: SPI Mode : DIO
|
||||
I (45) boot.esp32s3: SPI Flash Size : 2MB
|
||||
I (50) boot: Enabling RNG early entropy source...
|
||||
I (55) boot: Partition Table:
|
||||
I (59) boot: ## Label Usage Type ST Offset Length
|
||||
I (66) boot: 0 nvs WiFi data 01 02 00009000 00006000
|
||||
I (74) boot: 1 phy_init RF data 01 01 0000f000 00001000
|
||||
I (81) boot: 2 factory factory app 00 00 00010000 00100000
|
||||
I (89) boot: End of partition table
|
||||
I (93) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=2abc8h (175048) map
|
||||
I (133) esp_image: segment 1: paddr=0003abf0 vaddr=3fc95300 size=02bcch ( 11212) load
|
||||
I (135) esp_image: segment 2: paddr=0003d7c4 vaddr=40374000 size=02854h ( 10324) load
|
||||
I (141) esp_image: segment 3: paddr=00040020 vaddr=42000020 size=2b8d8h (178392) map
|
||||
I (179) esp_image: segment 4: paddr=0006b900 vaddr=40376854 size=0ea24h ( 59940) load
|
||||
I (199) boot: Loaded app from partition at offset 0x10000
|
||||
I (200) boot: Disabling RNG early entropy source...
|
||||
I (211) cpu_start: Multicore app
|
||||
I (220) cpu_start: Pro cpu start user code
|
||||
I (221) cpu_start: cpu freq: 160000000 Hz
|
||||
I (221) app_init: Application information:
|
||||
I (223) app_init: Project name: ESP_IDF_SensorExamples
|
||||
I (230) app_init: App version: v0.2.5-8-gde9a1d2-dirty
|
||||
I (236) app_init: Compile time: Jan 23 2025 14:33:38
|
||||
I (242) app_init: ELF file SHA256: 54e4e1748...
|
||||
I (247) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt
|
||||
I (254) efuse_init: Min chip rev: v0.0
|
||||
I (259) efuse_init: Max chip rev: v0.99
|
||||
I (264) efuse_init: Chip rev: v0.2
|
||||
I (269) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (276) heap_init: At 3FC988C8 len 00050E48 (323 KiB): RAM
|
||||
I (282) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
|
||||
I (288) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
|
||||
I (294) heap_init: At 600FE100 len 00001EE8 (7 KiB): RTCRAM
|
||||
I (302) spi_flash: detected chip: winbond
|
||||
I (305) spi_flash: flash io: dio
|
||||
W (309) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
I (322) sleep: Configure to isolate all GPIO pins in sleep state
|
||||
I (329) sleep: Enable automatic switching of GPIO sleep configuration
|
||||
I (337) main_task: Started on CPU0
|
||||
I (347) main_task: Calling app_main()
|
||||
I (347) I2C: Implemented using read and write callback methods (Use higher version >= 5.0 API)
|
||||
W (357) i2c.master: Please check pull-up resistances whether be connected properly. Otherwise unexpected behavior would happen. For more detailed information, please read docs
|
||||
I (367) gpio: GPIO[2]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (377) gpio: GPIO[3]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (387) main: I2C initialized successfully
|
||||
Scan I2C Devices:
|
||||
0 1 2 3 4 5 6 7 8 9 a b c d e f
|
||||
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
20: -- -- -- -- -- -- -- -- 28 -- -- -- -- -- -- --
|
||||
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
50: -- 51 -- -- -- -- -- -- -- -- 5a -- -- -- -- --
|
||||
60: -- -- -- -- -- -- -- -- -- -- -- 6b -- -- -- --
|
||||
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
|
||||
|
||||
|
||||
I (437) BHI: ----DRIVER BHI260AP----
|
||||
I (447) BHI: Implemented using built-in read and write methods (Use higher version >= 5.0 API)
|
||||
I (457) SensorLib: Using ESP-IDF Driver interface.
|
||||
I (457) SensorLib: Added Device Address : 0x28 New Dev Address: 0x3fc9cc34 Speed :400000
|
||||
I (477) SensorLib: BHI260/BHA260 found. Product ID read 0x89
|
||||
I (3497) SensorLib: Boot successful. Kernel version 5991.
|
||||
I (3497) SensorLib: [META EVENT WAKE UP] Firmware initialized. Firmware version 5991
|
||||
I (3497) SensorLib: [META EVENT] Firmware initialized. Firmware version 5991
|
||||
I (3597) BHI: Initialize BHI260AP using I2C interface
|
||||
Product ID : 89
|
||||
Kernel version : 5991
|
||||
User version : 5991
|
||||
ROM version : 5166
|
||||
Power state : sleeping
|
||||
Host interface : I2C
|
||||
Feature status : 0x4a
|
||||
Boot Status : 0x38: No flash installed. Host interface ready. Firmware verification done. Virtual sensor list.
|
||||
Sensor ID | Sensor Name | ID | Ver | Min rate | Max rate |
|
||||
----------+--------------------------------------+-----+-----+-----------+-----------|
|
||||
1 | Accelerometer passthrough | 205 | 1 | 1.5625 | 400.0000 |
|
||||
3 | Accelerometer uncalibrated | 203 | 1 | 1.5625 | 400.0000 |
|
||||
4 | Accelerometer corrected | 241 | 1 | 1.5625 | 400.0000 |
|
||||
5 | Accelerometer offset | 209 | 1 | 1.0000 | 1.0000 |
|
||||
6 | Accelerometer corrected wake up | 192 | 1 | 1.5625 | 400.0000 |
|
||||
7 | Accelerometer uncalibrated wake up | 204 | 1 | 1.5625 | 400.0000 |
|
||||
10 | Gyroscope passthrough | 207 | 1 | 1.5625 | 400.0000 |
|
||||
12 | Gyroscope uncalibrated | 244 | 1 | 1.5625 | 400.0000 |
|
||||
13 | Gyroscope corrected | 243 | 1 | 1.5625 | 400.0000 |
|
||||
14 | Gyroscope offset | 208 | 1 | 1.0000 | 1.0000 |
|
||||
15 | Gyroscope wake up | 194 | 1 | 1.5625 | 400.0000 |
|
||||
16 | Gyroscope uncalibrated wake up | 195 | 1 | 1.5625 | 400.0000 |
|
||||
28 | Gravity vector | 247 | 1 | 1.5625 | 400.0000 |
|
||||
29 | Gravity vector wake up | 198 | 1 | 1.5625 | 400.0000 |
|
||||
31 | Linear acceleration | 246 | 1 | 1.5625 | 400.0000 |
|
||||
32 | Linear acceleration wake up | 197 | 1 | 1.5625 | 400.0000 |
|
||||
37 | Game rotation vector | 252 | 1 | 1.5625 | 400.0000 |
|
||||
38 | Game rotation vector wake up | 200 | 1 | 1.5625 | 400.0000 |
|
||||
48 | Tilt detector | 236 | 1 | 1.0000 | 1.0000 |
|
||||
50 | Step detector | 248 | 1 | 1.0000 | 1.0000 |
|
||||
52 | Step counter | 249 | 1 | 1.0000 | 1.0000 |
|
||||
53 | Step counter wake up | 231 | 1 | 0.0005 | 25.0000 |
|
||||
55 | Significant motion | 250 | 1 | 1.0000 | 1.0000 |
|
||||
57 | Wake gesture | 232 | 1 | 1.0000 | 1.0000 |
|
||||
59 | Glance gesture | 234 | 1 | 1.0000 | 1.0000 |
|
||||
61 | Pickup gesture | 233 | 1 | 1.0000 | 1.0000 |
|
||||
63 | Activity recognition | 235 | 1 | 1.0000 | 1.0000 |
|
||||
67 | Wrist tilt gesture | 162 | 1 | 1.0000 | 1.0000 |
|
||||
69 | Device orientation | 163 | 1 | 1.0000 | 1.0000 |
|
||||
70 | Device orientation wake up | 164 | 1 | 1.0000 | 1.0000 |
|
||||
75 | Stationary detect | 161 | 1 | 1.0000 | 1.0000 |
|
||||
77 | Motion detect | 160 | 1 | 1.0000 | 1.0000 |
|
||||
94 | Step detector wake up | 230 | 1 | 1.0000 | 1.0000 |
|
||||
I (3937) gpio: GPIO[8]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:2
|
||||
I (3947) main: Run...
|
||||
I (3947) main_task: Returned from app_main()
|
||||
I (4347) SensorLib: [META EVENT] Power mode changed for sensor id 1
|
||||
I (4347) SensorLib: [META EVENT] Sample rate changed for sensor id 1
|
||||
I (4347) SensorLib: [META EVENT] Power mode changed for sensor id 10
|
||||
I (4357) SensorLib: [META EVENT] Sample rate changed for sensor id 10
|
||||
I (4357) BHI: Accelerometer passthrough: x: 0.129395, y: 0.024658, z: 1.018799;
|
||||
I (4367) BHI: Gyroscope passthrough: x: -0.305176, y: 0.183105, z: 0.183105;
|
||||
I (4987) BHI: Accelerometer passthrough: x: 0.129639, y: 0.024414, z: 1.024902;
|
||||
I (4987) BHI: Gyroscope passthrough: x: -0.244141, y: 0.183105, z: 0.183105;
|
||||
I (5627) BHI: Accelerometer passthrough: x: 0.129639, y: 0.025391, z: 1.025635;
|
||||
I (5627) BHI: Gyroscope passthrough: x: -0.305176, y: 0.183105, z: 0.183105;
|
||||
I (6267) BHI: Accelerometer passthrough: x: 0.130127, y: 0.025146, z: 1.025391;
|
||||
I (6267) BHI: Gyroscope passthrough: x: -0.244141, y: 0.244141, z: 0.183105;
|
||||
I (6907) BHI: Accelerometer passthrough: x: 0.129883, y: 0.024902, z: 1.025635;
|
||||
I (6907) BHI: Gyroscope passthrough: x: -0.305176, y: 0.244141, z: 0.244141;
|
||||
I (7547) BHI: Accelerometer passthrough: x: 0.129883, y: 0.025635, z: 1.025635;
|
||||
I (7547) BHI: Gyroscope passthrough: x: -0.305176, y: 0.183105, z: 0.244141;
|
||||
I (8187) BHI: Accelerometer passthrough: x: 0.130127, y: 0.025146, z: 1.026123;
|
||||
I (8187) BHI: Gyroscope passthrough: x: -0.305176, y: 0.244141, z: 0.183105;
|
||||
I (8827) BHI: Accelerometer passthrough: x: 0.129883, y: 0.024902, z: 1.025879;
|
||||
I (8827) BHI: Gyroscope passthrough: x: -0.305176, y: 0.183105, z: 0.183105;
|
||||
```
|
||||
|
||||
### FT63XX
|
||||
|
||||
```bash
|
||||
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
|
||||
configsip: 0, SPIWP:0xee
|
||||
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
|
||||
mode:DIO, clock div:2
|
||||
load:0x3fff0030,len:7176
|
||||
load:0x40078000,len:15564
|
||||
ho 0 tail 12 room 4
|
||||
load:0x40080400,len:4
|
||||
0x40080400: _init at ??:?
|
||||
|
||||
load:0x40080404,len:3904
|
||||
entry 0x40080640
|
||||
I (30) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader
|
||||
I (30) boot: compile time Jan 23 2025 15:30:25
|
||||
I (33) boot: Multicore bootloader
|
||||
I (37) boot: chip revision: v1.0
|
||||
I (41) boot.esp32: SPI Speed : 40MHz
|
||||
I (45) boot.esp32: SPI Mode : DIO
|
||||
I (50) boot.esp32: SPI Flash Size : 2MB
|
||||
I (54) boot: Enabling RNG early entropy source...
|
||||
I (60) boot: Partition Table:
|
||||
I (63) boot: ## Label Usage Type ST Offset Length
|
||||
I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000
|
||||
I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000
|
||||
I (85) boot: 2 factory factory app 00 00 00010000 00100000
|
||||
I (93) boot: End of partition table
|
||||
I (97) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0b860h ( 47200) map
|
||||
I (122) esp_image: segment 1: paddr=0001b888 vaddr=3ffb0000 size=02258h ( 8792) load
|
||||
I (125) esp_image: segment 2: paddr=0001dae8 vaddr=40080000 size=02530h ( 9520) load
|
||||
I (131) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=18744h (100164) map
|
||||
I (170) esp_image: segment 4: paddr=0003876c vaddr=40082530 size=0a210h ( 41488) load
|
||||
I (193) boot: Loaded app from partition at offset 0x10000
|
||||
I (193) boot: Disabling RNG early entropy source...
|
||||
I (205) cpu_start: Multicore app
|
||||
I (214) cpu_start: Pro cpu start user code
|
||||
I (214) cpu_start: cpu freq: 160000000 Hz
|
||||
I (214) app_init: Application information:
|
||||
I (217) app_init: Project name: ESP_IDF_SensorExamples
|
||||
I (223) app_init: App version: v0.2.5-8-gde9a1d2-dirty
|
||||
I (229) app_init: Compile time: Jan 23 2025 15:44:44
|
||||
I (235) app_init: ELF file SHA256: fe7a7c460...
|
||||
I (240) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt
|
||||
I (247) efuse_init: Min chip rev: v0.0
|
||||
I (252) efuse_init: Max chip rev: v3.99
|
||||
I (257) efuse_init: Chip rev: v1.0
|
||||
I (262) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (269) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
|
||||
I (275) heap_init: At 3FFB2B78 len 0002D488 (181 KiB): DRAM
|
||||
I (281) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
|
||||
I (288) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
|
||||
I (294) heap_init: At 4008C740 len 000138C0 (78 KiB): IRAM
|
||||
I (302) spi_flash: detected chip: winbond
|
||||
I (305) spi_flash: flash io: dio
|
||||
W (309) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
I (323) main_task: Started on CPU0
|
||||
I (333) main_task: Calling app_main()
|
||||
I (333) I2C: Implemented using read and write callback methods (Use higher version >= 5.0 API)
|
||||
I (333) gpio: GPIO[23]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (343) gpio: GPIO[32]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (353) main: I2C initialized successfully
|
||||
Scan I2C Devices:
|
||||
0 1 2 3 4 5 6 7 8 9 a b c d e f
|
||||
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --
|
||||
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
|
||||
|
||||
|
||||
I (403) FT63XX: ----DRIVER FT63XX----
|
||||
I (403) FT63XX: Implemented using built-in read and write methods (Use higher version >= 5.0 API)
|
||||
I (413) SensorLib: Using ESP-IDF Driver interface.
|
||||
I (423) SensorLib: Added Device Address : 0x38 New Dev Address: 0x3ffb4f58 Speed :400000
|
||||
I (433) SensorLib: Vend ID: 0x11
|
||||
I (433) SensorLib: Chip ID: 0x64
|
||||
I (443) SensorLib: Firm Version: 0x3
|
||||
I (443) SensorLib: Point Rate Hz: 10
|
||||
I (453) SensorLib: Thresh : 60
|
||||
I (453) SensorLib: Chip library version : 0x501
|
||||
I (453) SensorLib: Chip period of monitor status : 0x28
|
||||
I (463) FT63XX: Initialization of FT63XX is successful!
|
||||
I (473) main: Run...
|
||||
I (473) main_task: Returned from app_main()
|
||||
I (6733) FT63X6: Point[00] - X:113 Y:126
|
||||
I (6743) FT63X6: Point[00] - X:113 Y:126
|
||||
I (6753) FT63X6: Point[00] - X:113 Y:126
|
||||
I (6763) FT63X6: Point[00] - X:113 Y:126
|
||||
I (6773) FT63X6: Point[00] - X:113 Y:126
|
||||
I (6783) FT63X6: Point[00] - X:113 Y:126
|
||||
I (6793) FT63X6: Point[00] - X:113 Y:128
|
||||
I (6803) FT63X6: Point[00] - X:110 Y:140
|
||||
I (6813) FT63X6: Point[00] - X:109 Y:150
|
||||
I (6823) FT63X6: Point[00] - X:107 Y:162
|
||||
I (6833) FT63X6: Point[00] - X:105 Y:176
|
||||
I (6843) FT63X6: Point[00] - X:100 Y:193
|
||||
I (6853) FT63X6: Point[00] - X:92 Y:206
|
||||
I (7273) FT63X6: Point[00] - X:88 Y:273
|
||||
I (7283) FT63X6: Point[00] - X:88 Y:273
|
||||
I (7293) FT63X6: Point[00] - X:88 Y:273
|
||||
I (7303) FT63X6: Point[00] - X:90 Y:270
|
||||
I (7313) FT63X6: Point[00] - X:93 Y:266
|
||||
I (7323) FT63X6: Point[00] - X:99 Y:259
|
||||
I (7333) FT63X6: Point[00] - X:109 Y:247
|
||||
I (7343) FT63X6: Point[00] - X:118 Y:236
|
||||
I (7353) FT63X6: Point[00] - X:128 Y:223
|
||||
I (7363) FT63X6: Point[00] - X:138 Y:209
|
||||
I (7373) FT63X6: Point[00] - X:148 Y:195
|
||||
I (7383) FT63X6: Point[00] - X:158 Y:180
|
||||
I (7393) FT63X6: Point[00] - X:165 Y:169
|
||||
I (7403) FT63X6: Point[00] - X:170 Y:160
|
||||
I (7413) FT63X6: Point[00] - X:174 Y:153
|
||||
I (7423) FT63X6: Point[00] - X:177 Y:148
|
||||
I (7433) FT63X6: Point[00] - X:178 Y:145
|
||||
```
|
||||
|
||||
### XL9555
|
||||
|
||||
```bash
|
||||
SPIWP:0xee
|
||||
mode:DIO, clock div:1
|
||||
load:0x3fce2810,len:0x178c
|
||||
load:0x403c8700,len:0x4
|
||||
load:0x403c8704,len:0xcb8
|
||||
load:0x403cb700,len:0x2d9c
|
||||
entry 0x403c8914
|
||||
I (26) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader
|
||||
I (27) boot: compile time Jan 23 2025 16:15:44
|
||||
I (28) boot: Multicore bootloader
|
||||
I (32) boot: chip revision: v0.1
|
||||
I (36) boot.esp32s3: Boot SPI Speed : 80MHz
|
||||
I (41) boot.esp32s3: SPI Mode : DIO
|
||||
I (45) boot.esp32s3: SPI Flash Size : 2MB
|
||||
I (50) boot: Enabling RNG early entropy source...
|
||||
I (55) boot: Partition Table:
|
||||
I (59) boot: ## Label Usage Type ST Offset Length
|
||||
I (66) boot: 0 nvs WiFi data 01 02 00009000 00006000
|
||||
I (74) boot: 1 phy_init RF data 01 01 0000f000 00001000
|
||||
I (81) boot: 2 factory factory app 00 00 00010000 00100000
|
||||
I (89) boot: End of partition table
|
||||
I (93) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=0c95ch ( 51548) map
|
||||
I (110) esp_image: segment 1: paddr=0001c984 vaddr=3fc93300 size=02ad8h ( 10968) load
|
||||
I (113) esp_image: segment 2: paddr=0001f464 vaddr=40374000 size=00bb4h ( 2996) load
|
||||
I (119) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=20b8ch (134028) map
|
||||
I (151) esp_image: segment 4: paddr=00040bb4 vaddr=40374bb4 size=0e6c4h ( 59076) load
|
||||
I (170) boot: Loaded app from partition at offset 0x10000
|
||||
I (170) boot: Disabling RNG early entropy source...
|
||||
I (182) cpu_start: Multicore app
|
||||
I (191) cpu_start: Pro cpu start user code
|
||||
I (191) cpu_start: cpu freq: 160000000 Hz
|
||||
I (192) app_init: Application information:
|
||||
I (194) app_init: Project name: ESP_IDF_SensorExamples
|
||||
I (200) app_init: App version: v0.2.5-8-gde9a1d2-dirty
|
||||
I (207) app_init: Compile time: Jan 23 2025 16:28:47
|
||||
I (213) app_init: ELF file SHA256: c5b0aa4bb...
|
||||
I (218) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt
|
||||
I (225) efuse_init: Min chip rev: v0.0
|
||||
I (230) efuse_init: Max chip rev: v0.99
|
||||
I (235) efuse_init: Chip rev: v0.1
|
||||
I (240) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (247) heap_init: At 3FC967E8 len 00052F28 (331 KiB): RAM
|
||||
I (253) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
|
||||
I (259) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
|
||||
I (265) heap_init: At 600FE100 len 00001EE8 (7 KiB): RTCRAM
|
||||
I (272) spi_flash: detected chip: winbond
|
||||
I (276) spi_flash: flash io: dio
|
||||
W (280) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
I (293) sleep: Configure to isolate all GPIO pins in sleep state
|
||||
I (300) sleep: Enable automatic switching of GPIO sleep configuration
|
||||
I (307) main_task: Started on CPU0
|
||||
I (317) main_task: Calling app_main()
|
||||
I (317) I2C: Implemented using read and write callback methods (Use higher version >= 5.0 API)
|
||||
I (327) gpio: GPIO[8]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (337) gpio: GPIO[48]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (347) main: I2C initialized successfully
|
||||
Scan I2C Devices:
|
||||
0 1 2 3 4 5 6 7 8 9 a b c d e f
|
||||
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --
|
||||
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
|
||||
|
||||
|
||||
I (397) XL9555: ----DRIVER XL9555 ----
|
||||
I (397) XL9555: Implemented using built-in read and write methods (Use higher version >= 5.0 API)
|
||||
I (407) SensorLib: Using ESP-IDF Driver interface.
|
||||
I (417) SensorLib: Added Device Address : 0xFF New Dev Address: 0x3fc9aad8 Speed :400000
|
||||
I (417) SensorLib: i2c_master_bus_rm_device
|
||||
I (427) SensorLib: Using ESP-IDF Driver interface.
|
||||
I (427) SensorLib: Added Device Address : 0x20 New Dev Address: 0x3fc9aad8 Speed :400000
|
||||
I (437) XL9555: Initializing XL9555 successfully!
|
||||
I (447) main: Run...
|
||||
I (447) main_task: Returned from app_main()
|
||||
```
|
||||
|
||||
## Build process example
|
||||
|
||||
Assuming you don't have esp-idf yet
|
||||
|
||||
```bash
|
||||
mkdir -p ~/esp
|
||||
cd ~/esp
|
||||
git clone --recursive https://github.com/espressif/esp-idf.git
|
||||
git clone https://github.com/lewisxhe/SensorLib.git
|
||||
cd esp-idf
|
||||
./install.sh
|
||||
. ./export.sh
|
||||
cd ..
|
||||
cd SensorLib/examples/ESP_IDF_SensorExamples
|
||||
|
||||
Configure Sensor Type
|
||||
Configure I2C Pins or SPI Pins
|
||||
...
|
||||
idf.py set-target esp32
|
||||
idf.py menuconfig
|
||||
idf.py build
|
||||
idf.py -b 921600 flash
|
||||
idf.py monitor
|
||||
|
||||
```
|
||||
@ -0,0 +1,9 @@
|
||||
idf_component_register(SRCS
|
||||
"sensor_pcf8563.cpp"
|
||||
"sensor_bma423.cpp"
|
||||
"sensor_bhi260.cpp"
|
||||
"i2c_driver.cpp"
|
||||
"touch_ft63x6.cpp"
|
||||
"sensor_xl9555.cpp"
|
||||
"main.cpp"
|
||||
INCLUDE_DIRS ".")
|
||||
@ -0,0 +1,115 @@
|
||||
menu "SensorLib Example Configuration"
|
||||
|
||||
choice SENSOR_TYPE
|
||||
prompt "Select Sensor Type"
|
||||
default PCF8563
|
||||
help
|
||||
Choose the type of sensor you are using.
|
||||
|
||||
config PCF8563
|
||||
bool "PCF8563 Sensor"
|
||||
config BMA423
|
||||
bool "BMA423 Sensor"
|
||||
config BHI260
|
||||
bool "BHI260 Sensor"
|
||||
config FT636X
|
||||
bool "FT636X Capacitive touch"
|
||||
config XL9555
|
||||
bool "XL9555 GPIO expansion"
|
||||
endchoice
|
||||
|
||||
choice BHI260_COMMUNICATION_TYPE
|
||||
prompt "Select BHI260 Communication Type"
|
||||
default USE_I2C_INTERFACE
|
||||
depends on BHI260
|
||||
help
|
||||
Choose the communication type for BHI260 sensor.
|
||||
|
||||
config USE_I2C_INTERFACE
|
||||
bool "I2C Communication"
|
||||
config USE_SPI_INTERFACE
|
||||
bool "SPI Communication"
|
||||
endchoice
|
||||
|
||||
choice I2C_COMMUNICATION_METHOD
|
||||
prompt "SensorLib read and write methods"
|
||||
default I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
depends on (PCF8563 || BMA423 || FT636X || XL9555 || (BHI260 && USE_I2C_INTERFACE))
|
||||
help
|
||||
Define SensorLib read and write methods
|
||||
|
||||
config I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
bool "Implemented using built-in read and write methods"
|
||||
config I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
bool "Implemented using read and write callback methods"
|
||||
endchoice
|
||||
|
||||
config I2C_MASTER_PORT_NUM
|
||||
int "Sensor I2C Port Number"
|
||||
default 1
|
||||
depends on (PCF8563 || BMA423 || FT636X || XL9555 || (BHI260 && USE_I2C_INTERFACE))
|
||||
help
|
||||
Port number for I2C Master device.
|
||||
|
||||
config I2C_MASTER_FREQUENCY
|
||||
int "Master Frequency"
|
||||
default 100000
|
||||
depends on (PCF8563 || BMA423 || FT636X || XL9555 || (BHI260 && USE_I2C_INTERFACE))
|
||||
help
|
||||
I2C Speed of Master device.
|
||||
|
||||
config SENSOR_SCL
|
||||
int "Sensor SCL GPIO Num"
|
||||
default 22
|
||||
depends on (PCF8563 || BMA423 || FT636X || XL9555 || (BHI260 && USE_I2C_INTERFACE))
|
||||
help
|
||||
GPIO number for I2C clock line.
|
||||
|
||||
config SENSOR_SDA
|
||||
int "Sensor SDA GPIO Num"
|
||||
default 21
|
||||
depends on (PCF8563 || BMA423 || FT636X || XL9555 || (BHI260 && USE_I2C_INTERFACE))
|
||||
help
|
||||
GPIO number for I2C data line.
|
||||
|
||||
config SPI_MISO
|
||||
int "SPI MISO GPIO Num"
|
||||
default 34
|
||||
depends on (BHI260 && USE_SPI_INTERFACE)
|
||||
help
|
||||
GPIO number for Sensor SPI MISO line.
|
||||
|
||||
config SPI_MOSI
|
||||
int "SPI MOSI GPIO Num"
|
||||
default 33
|
||||
depends on (BHI260 && USE_SPI_INTERFACE)
|
||||
help
|
||||
GPIO number for Sensor SPI MOSI line.
|
||||
|
||||
config SPI_SCK
|
||||
int "SPI SCK GPIO Num"
|
||||
default 35
|
||||
depends on (BHI260 && USE_SPI_INTERFACE)
|
||||
help
|
||||
GPIO number for Sensor SPI SCK line.
|
||||
|
||||
config SPI_CS
|
||||
int "SPI CS GPIO Num"
|
||||
default 36
|
||||
depends on (BHI260 && USE_SPI_INTERFACE)
|
||||
help
|
||||
GPIO number for Sensor SPI CS line.
|
||||
|
||||
config SENSOR_IRQ
|
||||
int "Sensor Interrupt Pin"
|
||||
default 37
|
||||
help
|
||||
GPIO number for Sensor Interrupt line.
|
||||
|
||||
config SENSOR_RST
|
||||
int "Sensor reset Pin"
|
||||
default 47
|
||||
help
|
||||
GPIO number for Sensor Reset line.
|
||||
|
||||
endmenu
|
||||
@ -0,0 +1,4 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
@ -0,0 +1,378 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file i2c_driver.cpp
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-19
|
||||
*
|
||||
*/
|
||||
#include <cstring>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "i2c_driver.h"
|
||||
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW || CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
static const char *TAG = "I2C";
|
||||
|
||||
#define I2C_MASTER_NUM (i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM
|
||||
#define I2C_MASTER_SDA_IO (gpio_num_t)CONFIG_SENSOR_SDA
|
||||
#define I2C_MASTER_SCL_IO (gpio_num_t)CONFIG_SENSOR_SCL
|
||||
#define I2C_MASTER_FREQ_HZ CONFIG_I2C_MASTER_FREQUENCY /*!< I2C master clock frequency */
|
||||
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
||||
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
#include "soc/clk_tree_defs.h"
|
||||
|
||||
i2c_master_dev_handle_t i2c_device;
|
||||
|
||||
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
|
||||
// * which is useful when the bus shares multiple devices.
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
|
||||
|
||||
bool i2c_wr_function(uint8_t addr, uint8_t reg, uint8_t *buf, size_t len, bool writeReg, bool isWrite)
|
||||
{
|
||||
if (isWrite) {
|
||||
esp_err_t ret;
|
||||
if (buf == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
if (writeReg) {
|
||||
uint8_t *write_buffer = (uint8_t *)malloc(sizeof(uint8_t) * (len + 1));
|
||||
if (!write_buffer) {
|
||||
return -1;
|
||||
}
|
||||
write_buffer[0] = reg;
|
||||
memcpy(write_buffer + 1, buf, len);
|
||||
|
||||
ret = i2c_master_transmit(
|
||||
i2c_device,
|
||||
write_buffer,
|
||||
len + 1,
|
||||
-1);
|
||||
free(write_buffer);
|
||||
} else {
|
||||
ret = i2c_master_transmit(i2c_device, buf, len, -1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, true);
|
||||
if (writeReg) {
|
||||
i2c_master_write_byte(cmd, reg, true);
|
||||
}
|
||||
i2c_master_write(cmd, buf, len, true);
|
||||
i2c_master_stop(cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "i2c_write_error.");
|
||||
}
|
||||
|
||||
#endif
|
||||
return ret == ESP_OK ? true : false;
|
||||
|
||||
} else {
|
||||
esp_err_t ret;
|
||||
if (len == 0) {
|
||||
return true;
|
||||
}
|
||||
if (buf == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
ret = i2c_master_transmit_receive(i2c_device, (const uint8_t *)®, 1, buf, len, -1);
|
||||
|
||||
#else
|
||||
|
||||
i2c_cmd_handle_t cmd;
|
||||
if (writeReg) {
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, reg, true);
|
||||
i2c_master_stop(cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "i2c_master_cmd_begin failed!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_READ, true);
|
||||
if (len > 1) {
|
||||
i2c_master_read(cmd, buf, len - 1, I2C_MASTER_ACK);
|
||||
}
|
||||
i2c_master_read_byte(cmd, &buf[len - 1], I2C_MASTER_NACK);
|
||||
i2c_master_stop(cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "i2c_read_error.");
|
||||
}
|
||||
#endif
|
||||
return ret == ESP_OK ? true : false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a sequence of bytes from a pmu registers
|
||||
*/
|
||||
int i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
|
||||
{
|
||||
esp_err_t ret;
|
||||
if (len == 0) {
|
||||
return ESP_OK;
|
||||
}
|
||||
if (data == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
ret = i2c_master_transmit_receive(
|
||||
i2c_device,
|
||||
(const uint8_t *)®Addr,
|
||||
1,
|
||||
data,
|
||||
len,
|
||||
-1);
|
||||
#else
|
||||
|
||||
i2c_cmd_handle_t cmd;
|
||||
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, regAddr, true);
|
||||
i2c_master_stop(cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "i2c_master_cmd_begin failed!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_READ, true);
|
||||
if (len > 1) {
|
||||
i2c_master_read(cmd, data, len - 1, I2C_MASTER_ACK);
|
||||
}
|
||||
i2c_master_read_byte(cmd, &data[len - 1], I2C_MASTER_NACK);
|
||||
i2c_master_stop(cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "i2c_read_error.");
|
||||
}
|
||||
#endif
|
||||
return ret == ESP_OK ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a byte to a pmu register
|
||||
*/
|
||||
int i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
|
||||
{
|
||||
esp_err_t ret;
|
||||
if (data == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
uint8_t *write_buffer = (uint8_t *)malloc(sizeof(uint8_t) * (len + 1));
|
||||
if (!write_buffer) {
|
||||
return -1;
|
||||
}
|
||||
write_buffer[0] = regAddr;
|
||||
memcpy(write_buffer + 1, data, len);
|
||||
|
||||
ret = i2c_master_transmit(
|
||||
i2c_device,
|
||||
write_buffer,
|
||||
len + 1,
|
||||
-1);
|
||||
free(write_buffer);
|
||||
#else
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, regAddr, true);
|
||||
i2c_master_write(cmd, data, len, true);
|
||||
i2c_master_stop(cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "i2c_write_error.");
|
||||
}
|
||||
#endif
|
||||
return ret == ESP_OK ? 0 : -1;
|
||||
}
|
||||
|
||||
esp_err_t i2c_drv_device_init(uint8_t address)
|
||||
{
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
i2c_device_config_t i2c_dev_conf = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = address,
|
||||
.scl_speed_hz = I2C_MASTER_FREQ_HZ,
|
||||
};
|
||||
return i2c_master_bus_add_device(bus_handle, &i2c_dev_conf, &i2c_device);
|
||||
#else
|
||||
return ESP_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif //CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
|
||||
/**
|
||||
* @brief i2c master initialization
|
||||
*/
|
||||
esp_err_t i2c_drv_init(void)
|
||||
{
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods (Use higher version >= 5.0 API)");
|
||||
|
||||
i2c_master_bus_config_t i2c_bus_config;
|
||||
memset(&i2c_bus_config, 0, sizeof(i2c_bus_config));
|
||||
i2c_bus_config.clk_source = I2C_CLK_SRC_DEFAULT;
|
||||
i2c_bus_config.i2c_port = I2C_MASTER_NUM;
|
||||
i2c_bus_config.scl_io_num = (gpio_num_t)I2C_MASTER_SCL_IO;
|
||||
i2c_bus_config.sda_io_num = (gpio_num_t)I2C_MASTER_SDA_IO;
|
||||
i2c_bus_config.glitch_ignore_cnt = 7;
|
||||
i2c_bus_config.flags.enable_internal_pullup = true;
|
||||
|
||||
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &bus_handle));
|
||||
|
||||
return ESP_OK;
|
||||
#else
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods (Use lower version < 5.0 API)");
|
||||
|
||||
i2c_config_t i2c_conf ;
|
||||
memset(&i2c_conf, 0, sizeof(i2c_conf));
|
||||
i2c_conf.mode = I2C_MODE_MASTER;
|
||||
i2c_conf.sda_io_num = I2C_MASTER_SDA_IO;
|
||||
i2c_conf.scl_io_num = I2C_MASTER_SCL_IO;
|
||||
i2c_conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
|
||||
i2c_conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
|
||||
i2c_conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
|
||||
i2c_param_config(I2C_MASTER_NUM, &i2c_conf);
|
||||
return i2c_driver_install(I2C_MASTER_NUM, i2c_conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void i2c_drv_scan()
|
||||
{
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
uint8_t address = 0x00;
|
||||
printf("Scan I2C Devices:\n");
|
||||
printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
|
||||
for (int i = 0; i < 128; i += 16) {
|
||||
printf("%02x: ", i);
|
||||
for (int j = 0; j < 16; j++) {
|
||||
fflush(stdout);
|
||||
address = i + j;
|
||||
err = i2c_master_probe(bus_handle, address, 100);
|
||||
if (err == ESP_OK) {
|
||||
printf("%02x ", address);
|
||||
} else if (err == ESP_ERR_TIMEOUT) {
|
||||
printf("UU ");
|
||||
} else {
|
||||
printf("-- ");
|
||||
}
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
printf("\n\n\n");
|
||||
#else
|
||||
uint8_t address;
|
||||
printf("Scan I2C Devices:\n");
|
||||
printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
|
||||
for (int i = 0; i < 128; i += 16) {
|
||||
printf("%02x: ", i);
|
||||
for (int j = 0; j < 16; j++) {
|
||||
fflush(stdout);
|
||||
address = i + j;
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (address << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_stop(cmd);
|
||||
esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 50 / portTICK_PERIOD_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret == ESP_OK) {
|
||||
printf("%02x ", address);
|
||||
} else if (ret == ESP_ERR_TIMEOUT) {
|
||||
printf("UU ");
|
||||
} else {
|
||||
printf("-- ");
|
||||
}
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool i2c_drv_probe(uint8_t devAddr)
|
||||
{
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
return ESP_OK == i2c_master_probe(bus_handle, devAddr, 1000);
|
||||
#else
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_stop(cmd);
|
||||
esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 50 / portTICK_PERIOD_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
return (ret == ESP_OK);
|
||||
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,54 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file i2c_driver.h
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-19
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_idf_version.h"
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
#include "driver/i2c_master.h"
|
||||
#else
|
||||
#include "driver/i2c.h"
|
||||
#endif //ESP_IDF_VERSION
|
||||
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW || CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
esp_err_t i2c_drv_init(void);
|
||||
void i2c_drv_scan();
|
||||
bool i2c_drv_probe(uint8_t devAddr);
|
||||
int i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
|
||||
int i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
|
||||
bool i2c_wr_function(uint8_t addr, uint8_t reg, uint8_t *buf, size_t len, bool writeReg, bool isWrite);
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
esp_err_t i2c_drv_device_init(uint8_t address);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,199 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file main.cpp
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-19
|
||||
*
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "i2c_driver.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
#ifdef CONFIG_PCF8563
|
||||
extern esp_err_t pcf8563_init();
|
||||
extern void pcf8563_loop();
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_BMA423
|
||||
extern esp_err_t bma423_init();
|
||||
extern void bma423_loop();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FT636X
|
||||
extern esp_err_t ft63x6_init();
|
||||
extern void ft63x6_loop();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BHI260
|
||||
extern esp_err_t bhi260_init();
|
||||
extern void bhi260_loop();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XL9555
|
||||
extern esp_err_t xl9555_init();
|
||||
extern void xl9555_loop();
|
||||
#endif
|
||||
|
||||
|
||||
static void app_task(void *args);
|
||||
|
||||
extern "C" void app_main(void)
|
||||
{
|
||||
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW || CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
ESP_ERROR_CHECK(i2c_drv_init());
|
||||
ESP_LOGI(TAG, "I2C initialized successfully");
|
||||
|
||||
// Run bus scan
|
||||
i2c_drv_scan();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCF8563
|
||||
ESP_ERROR_CHECK(pcf8563_init());
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BMA423
|
||||
ESP_ERROR_CHECK(bma423_init());
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FT636X
|
||||
ESP_ERROR_CHECK(ft63x6_init());
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BHI260
|
||||
ESP_ERROR_CHECK(bhi260_init());
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XL9555
|
||||
xl9555_init();
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Run...");
|
||||
|
||||
xTaskCreate(app_task, "App", 20 * 1024, NULL, 10, NULL);
|
||||
|
||||
}
|
||||
|
||||
static void app_task(void *args)
|
||||
{
|
||||
while (1) {
|
||||
|
||||
#ifdef CONFIG_BMA423
|
||||
bma423_loop();
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FT636X
|
||||
ft63x6_loop();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BHI260
|
||||
bhi260_loop();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XL9555
|
||||
xl9555_loop();
|
||||
#endif
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
/**
|
||||
* @brief hal_callback
|
||||
* @note SensorLib hal callback
|
||||
* @param op: Operation Code
|
||||
* @param *param1: parameter
|
||||
* @param *param2: parameter
|
||||
* @retval
|
||||
*/
|
||||
uint32_t hal_callback(SensorCommCustomHal::Operation op, void *param1, void *param2)
|
||||
{
|
||||
switch (op) {
|
||||
// Set GPIO mode
|
||||
case SensorCommCustomHal::OP_PINMODE: {
|
||||
uint8_t pin = reinterpret_cast<uintptr_t>(param1);
|
||||
uint8_t mode = reinterpret_cast<uintptr_t>(param2);
|
||||
gpio_config_t config;
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.pin_bit_mask = 1ULL << pin;
|
||||
switch (mode) {
|
||||
case INPUT:
|
||||
config.mode = GPIO_MODE_INPUT;
|
||||
break;
|
||||
case OUTPUT:
|
||||
config.mode = GPIO_MODE_OUTPUT;
|
||||
break;
|
||||
}
|
||||
config.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
config.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
config.intr_type = GPIO_INTR_DISABLE;
|
||||
ESP_ERROR_CHECK(gpio_config(&config));
|
||||
}
|
||||
break;
|
||||
// Set GPIO level
|
||||
case SensorCommCustomHal::OP_DIGITALWRITE: {
|
||||
uint8_t pin = reinterpret_cast<uintptr_t>(param1);
|
||||
uint8_t level = reinterpret_cast<uintptr_t>(param2);
|
||||
gpio_set_level((gpio_num_t )pin, level);
|
||||
}
|
||||
break;
|
||||
// Read GPIO level
|
||||
case SensorCommCustomHal::OP_DIGITALREAD: {
|
||||
uint8_t pin = reinterpret_cast<uintptr_t>(param1);
|
||||
return gpio_get_level((gpio_num_t)pin);
|
||||
}
|
||||
break;
|
||||
// Get the current running milliseconds
|
||||
case SensorCommCustomHal::OP_MILLIS:
|
||||
return (uint32_t) (esp_timer_get_time() / 1000LL);
|
||||
|
||||
// Delay in milliseconds
|
||||
case SensorCommCustomHal::OP_DELAY: {
|
||||
if (param1) {
|
||||
uint32_t ms = reinterpret_cast<uintptr_t>(param1);
|
||||
ets_delay_us((ms % portTICK_PERIOD_MS) * 1000UL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
// Delay in microseconds
|
||||
case SensorCommCustomHal::OP_DELAYMICROSECONDS: {
|
||||
uint32_t us = reinterpret_cast<uintptr_t>(param1);
|
||||
ets_delay_us(us);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,205 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file sensor_bhi260.cpp
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-23
|
||||
*
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "SensorBHI260AP.hpp"
|
||||
|
||||
#if CONFIG_BHI260
|
||||
|
||||
static const char *TAG = "BHI";
|
||||
|
||||
extern uint32_t hal_callback(SensorCommCustomHal::Operation op, void *param1, void *param2);
|
||||
|
||||
SensorBHI260AP bhy;
|
||||
|
||||
static volatile bool dataReady = false;
|
||||
|
||||
static bool init_done = false;
|
||||
|
||||
static void IRAM_ATTR bhi260_set_flag(void *arg)
|
||||
{
|
||||
dataReady = true;
|
||||
}
|
||||
|
||||
static void bhi260_isr_init()
|
||||
{
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_INTR_NEGEDGE;
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
io_conf.pin_bit_mask = (1ULL << CONFIG_SENSOR_IRQ);
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
gpio_config(&io_conf);
|
||||
gpio_set_intr_type((gpio_num_t)CONFIG_SENSOR_IRQ, GPIO_INTR_POSEDGE);
|
||||
//install gpio isr service
|
||||
gpio_install_isr_service(0);
|
||||
//hook isr handler for specific gpio pin
|
||||
gpio_isr_handler_add((gpio_num_t)CONFIG_SENSOR_IRQ, bhi260_set_flag, NULL);
|
||||
|
||||
}
|
||||
|
||||
static void accel_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
struct bhy2_data_xyz data;
|
||||
float scaling_factor = get_sensor_default_scaling(sensor_id);
|
||||
bhy2_parse_xyz(data_ptr, &data);
|
||||
ESP_LOGI(TAG, "%s: x: %f, y: %f, z: %f;", bhy.getSensorName(sensor_id),
|
||||
data.x * scaling_factor,
|
||||
data.y * scaling_factor,
|
||||
data.z * scaling_factor);
|
||||
}
|
||||
|
||||
static void gyro_process_callback(uint8_t sensor_id, uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
|
||||
{
|
||||
struct bhy2_data_xyz data;
|
||||
float scaling_factor = get_sensor_default_scaling(sensor_id);
|
||||
bhy2_parse_xyz(data_ptr, &data);
|
||||
ESP_LOGI(TAG, "%s: x: %f, y: %f, z: %f;", bhy.getSensorName(sensor_id),
|
||||
data.x * scaling_factor,
|
||||
data.y * scaling_factor,
|
||||
data.z * scaling_factor);
|
||||
}
|
||||
|
||||
esp_err_t bhi260_init()
|
||||
{
|
||||
ESP_LOGI(TAG, "----DRIVER BHI260AP----");
|
||||
|
||||
// Set the reset pin
|
||||
bhy.setPins(CONFIG_SENSOR_RST);
|
||||
|
||||
/*Set the default firmware, only 6 axes, no other functions*/
|
||||
bhy.setFirmware(bhy2_firmware_image, sizeof(bhy2_firmware_image));
|
||||
|
||||
#if CONFIG_USE_I2C_INTERFACE
|
||||
// BHI260AP_SLAVE_ADDRESS_L = 0x28
|
||||
// BHI260AP_SLAVE_ADDRESS_H = 0x29
|
||||
uint8_t address = BHI260AP_SLAVE_ADDRESS_L;
|
||||
|
||||
//* Implemented using read and write callback methods, applicable to other platforms
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
// * Provide the device address to the callback function
|
||||
i2c_drv_device_init(address);
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods");
|
||||
if (bhy.begin(i2c_wr_function, hal_callback, address)) {
|
||||
ESP_LOGI(TAG, "Initialize BHI260AP using I2C interface");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the BHI260AP !");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//* Use the built-in esp-idf communication method
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)");
|
||||
|
||||
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
|
||||
// * which is useful when the bus shares multiple devices.
|
||||
extern i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
if (bhy.begin(bus_handle, address)) {
|
||||
ESP_LOGI(TAG, "Initialize BHI260AP using I2C interface");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the BHI260AP !");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)");
|
||||
if (bhy.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, address, CONFIG_SENSOR_SDA, CONFIG_SENSOR_SCL)) {
|
||||
ESP_LOGI(TAG, "Initialize BHI260AP using I2C interface");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the BHI260AP !");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
|
||||
#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
|
||||
|
||||
#else //USE_I2C_INTERFACE
|
||||
|
||||
// Bus handle
|
||||
spi_device_handle_t spi = NULL;
|
||||
|
||||
// Using SPI interface
|
||||
if (bhy.begin(SPI2_HOST, spi, CONFIG_SPI_CS, CONFIG_SPI_MOSI, CONFIG_SPI_MISO, CONFIG_SPI_SCK)) {
|
||||
ESP_LOGI(TAG, "Initialize BHI260AP using SPI interface");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the BHI260AP !");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif //USE_SPI_INTERFACE
|
||||
|
||||
// Output all sensors info to Serial
|
||||
BoschSensorInfo info = bhy.getSensorInfo();
|
||||
info.printInfo();
|
||||
|
||||
float sample_rate = 1.0; /* Read out hintr_ctrl measured at 1Hz */
|
||||
uint32_t report_latency_ms = 0; /* Report immediately */
|
||||
|
||||
// Enable acceleration
|
||||
bhy.configure(SensorBHI260AP::ACCEL_PASSTHROUGH, sample_rate, report_latency_ms);
|
||||
// Enable gyroscope
|
||||
bhy.configure(SensorBHI260AP::GYRO_PASSTHROUGH, sample_rate, report_latency_ms);
|
||||
|
||||
// Set the acceleration sensor result callback function
|
||||
bhy.onResultEvent(SensorBHI260AP::ACCEL_PASSTHROUGH, accel_process_callback);
|
||||
|
||||
// Set the gyroscope sensor result callback function
|
||||
bhy.onResultEvent(SensorBHI260AP::GYRO_PASSTHROUGH, gyro_process_callback);
|
||||
|
||||
// Registration interruption
|
||||
bhi260_isr_init();
|
||||
|
||||
init_done = true;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void bhi260_loop()
|
||||
{
|
||||
if (!init_done) {
|
||||
return;
|
||||
}
|
||||
if (dataReady) {
|
||||
dataReady = false;
|
||||
bhy.update();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,119 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file sensor_bma423.cpp
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-19
|
||||
*
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "i2c_driver.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#ifdef CONFIG_BMA423
|
||||
|
||||
#include "SensorBMA423.hpp"
|
||||
|
||||
static const char *TAG = "BMA";
|
||||
|
||||
SensorBMA423 accel;
|
||||
|
||||
extern uint32_t hal_callback(SensorCommCustomHal::Operation op, void *param1, void *param2);
|
||||
|
||||
static bool init_done = false;
|
||||
|
||||
esp_err_t bma423_init()
|
||||
{
|
||||
uint8_t address = BMA423_I2C_ADDR_SECONDARY;
|
||||
|
||||
ESP_LOGI(TAG, "----DRIVER BMA423----");
|
||||
|
||||
//* Implemented using read and write callback methods, applicable to other platforms
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
|
||||
// * Provide the device address to the callback function
|
||||
i2c_drv_device_init(address);
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods");
|
||||
if (accel.begin(i2c_wr_function, hal_callback, address)) {
|
||||
ESP_LOGI(TAG, "Initialization of BMA423 accelerometer is successful!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the BMA423 accelerometer!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//* Use the built-in esp-idf communication method
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)");
|
||||
|
||||
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
|
||||
// * which is useful when the bus shares multiple devices.
|
||||
extern i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
if (accel.begin(bus_handle, address)) {
|
||||
ESP_LOGI(TAG, "Initialization of BMA423 accelerometer is successful!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the BMA423 accelerometer!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)");
|
||||
if (accel.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, address, CONFIG_SENSOR_SDA, CONFIG_SENSOR_SCL)) {
|
||||
ESP_LOGI(TAG, "Initialization of BMA423 accelerometer is successful!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the BMA423 accelerometer!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
|
||||
#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
|
||||
//Default 4G ,200HZ
|
||||
accel.configAccelerometer();
|
||||
|
||||
accel.enableAccelerometer();
|
||||
|
||||
init_done = true;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void bma423_loop()
|
||||
{
|
||||
if (!init_done) {
|
||||
return;
|
||||
}
|
||||
ESP_LOGI("BMA423", "Temperature:%.2f*C", accel.getTemperature(SensorBMA423::TEMP_DEG));
|
||||
ESP_LOGI("BMA423", "Temperature:%.2f*F", accel.getTemperature(SensorBMA423::TEMP_FAHRENHEIT));
|
||||
ESP_LOGI("BMA423", "Direction:%u", accel.direction());
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,137 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file sensor_pcf8563.cpp
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-19
|
||||
*
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "i2c_driver.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#ifdef CONFIG_PCF8563
|
||||
|
||||
#include "SensorPCF8563.hpp"
|
||||
|
||||
static const char *TAG = "RTC";
|
||||
|
||||
SensorPCF8563 rtc;
|
||||
|
||||
static bool init_done = false;
|
||||
|
||||
esp_err_t pcf8563_init()
|
||||
{
|
||||
ESP_LOGI(TAG, "----DRIVER PCF8563 ----");
|
||||
|
||||
//* Implemented using read and write callback methods, applicable to other platforms
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
uint8_t address = 0x51;
|
||||
|
||||
// * Provide the device address to the callback function
|
||||
i2c_drv_device_init(address);
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods");
|
||||
if (rtc.begin(i2c_wr_function)) {
|
||||
ESP_LOGI(TAG, "Initializing PCF8563 real-time clock successfully!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize PCF8563 real time clock!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//* Use the built-in esp-idf communication method
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)");
|
||||
|
||||
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
|
||||
// * which is useful when the bus shares multiple devices.
|
||||
extern i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
if (rtc.begin(bus_handle)) {
|
||||
ESP_LOGI(TAG, "Initializing PCF8563 real-time clock successfully!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize PCF8563 real time clock!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)");
|
||||
if (rtc.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, CONFIG_SENSOR_SDA, CONFIG_SENSOR_SCL)) {
|
||||
ESP_LOGI(TAG, "Initializing PCF8563 real-time clock successfully!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize PCF8563 real time clock!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
|
||||
#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
|
||||
// Unix tm structure sets the time
|
||||
struct tm timeinfo;
|
||||
timeinfo.tm_yday = 2025 - 1900; //Counting starts from 1900, so subtract 1900 here
|
||||
timeinfo.tm_mon = 1 - 1; //Months start at 0, so you need to subtract 1.
|
||||
timeinfo.tm_mday = 17;
|
||||
timeinfo.tm_hour = 4;
|
||||
timeinfo.tm_min = 30;
|
||||
timeinfo.tm_sec = 30;
|
||||
rtc.setDateTime(timeinfo);
|
||||
|
||||
init_done = true;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void pcf8563_loop()
|
||||
{
|
||||
if (!init_done) {
|
||||
return;
|
||||
}
|
||||
char buf[64];
|
||||
struct tm timeinfo;
|
||||
// Get the time C library structure
|
||||
rtc.getDateTime(&timeinfo);
|
||||
// Format the output using the strftime function
|
||||
// For more formats, please refer to :
|
||||
// https://man7.org/linux/man-pages/man3/strftime.3.html
|
||||
size_t written = strftime(buf, 64, "%A, %B %d %Y %H:%M:%S", &timeinfo);
|
||||
if (written != 0) {
|
||||
ESP_LOGI("RTC", "%s", buf);
|
||||
}
|
||||
written = strftime(buf, 64, "%b %d %Y %H:%M:%S", &timeinfo);
|
||||
if (written != 0) {
|
||||
ESP_LOGI("RTC", "%s", buf);
|
||||
}
|
||||
written = strftime(buf, 64, "%A, %d. %B %Y %I:%M%p", &timeinfo);
|
||||
if (written != 0) {
|
||||
ESP_LOGI("RTC", "%s", buf);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,107 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file sensor_xl9555.cpp
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-23
|
||||
*
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "i2c_driver.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#ifdef CONFIG_XL9555
|
||||
|
||||
#include "ExtensionIOXL9555.hpp"
|
||||
|
||||
static const char *TAG = "XL9555";
|
||||
|
||||
ExtensionIOXL9555 io;
|
||||
|
||||
static bool init_done = false;
|
||||
|
||||
esp_err_t xl9555_init()
|
||||
{
|
||||
ESP_LOGI(TAG, "----DRIVER XL9555 ----");
|
||||
|
||||
//* Implemented using read and write callback methods, applicable to other platforms
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
uint8_t address = XL9555_SLAVE_ADDRESS0;
|
||||
|
||||
// * Provide the device address to the callback function
|
||||
i2c_drv_device_init(address);
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods");
|
||||
if (io.begin(i2c_wr_function)) {
|
||||
ESP_LOGI(TAG, "Initializing XL9555 successfully!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize XL9555 failed!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//* Use the built-in esp-idf communication method
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)");
|
||||
|
||||
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
|
||||
// * which is useful when the bus shares multiple devices.
|
||||
extern i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
if (io.begin(bus_handle)) {
|
||||
ESP_LOGI(TAG, "Initializing XL9555 successfully!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize XL9555 failed!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)");
|
||||
if (io.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, CONFIG_SENSOR_SDA, CONFIG_SENSOR_SCL)) {
|
||||
ESP_LOGI(TAG, "Initializing XL9555 successfully!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize XL9555 failed!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
|
||||
#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void xl9555_loop()
|
||||
{
|
||||
if (!init_done) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,116 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file ft63x6.cpp
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-19
|
||||
*
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "i2c_driver.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#ifdef CONFIG_FT636X
|
||||
|
||||
#include "TouchDrvFT6X36.hpp"
|
||||
|
||||
static const char *TAG = "FT63XX";
|
||||
|
||||
TouchDrvFT6X36 touch;
|
||||
|
||||
extern uint32_t hal_callback(SensorCommCustomHal::Operation op, void *param1, void *param2);
|
||||
|
||||
static bool init_done = false;
|
||||
|
||||
esp_err_t ft63x6_init()
|
||||
{
|
||||
ESP_LOGI(TAG, "----DRIVER FT63XX----");
|
||||
|
||||
//* Implemented using read and write callback methods, applicable to other platforms
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
uint8_t address = FT3267_SLAVE_ADDRESS;
|
||||
|
||||
// * Provide the device address to the callback function
|
||||
i2c_drv_device_init(address);
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods");
|
||||
if (touch.begin(i2c_wr_function, hal_callback, address)) {
|
||||
ESP_LOGI(TAG, "Initialization of FT63XX is successful!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the FT63XX!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//* Use the built-in esp-idf communication method
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)");
|
||||
|
||||
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
|
||||
// * which is useful when the bus shares multiple devices.
|
||||
extern i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
if (touch.begin(bus_handle)) {
|
||||
ESP_LOGI(TAG, "Initialization of FT63XX is successful!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the FT63XX!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)");
|
||||
if (touch.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, CONFIG_SENSOR_SDA, CONFIG_SENSOR_SCL)) {
|
||||
ESP_LOGI(TAG, "Initialization of FT63XX is successful!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the FT63XX!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
|
||||
#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
|
||||
init_done = true;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void ft63x6_loop()
|
||||
{
|
||||
if (!init_done) {
|
||||
return;
|
||||
}
|
||||
int16_t x[2], y[2];
|
||||
uint8_t numPoint = touch.getPoint(x, y, 2);
|
||||
for (int i = 0; i < numPoint; ++i) {
|
||||
ESP_LOGI("FT63X6", "Point[%02d] - X:%02d Y:%02d", i, x[i], y[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
# The following five lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS ../../../SensorLib)
|
||||
|
||||
project(ESP_IDF_TouchDrvExample)
|
||||
@ -0,0 +1,10 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := ESP_IDF_TouchDrv_Example
|
||||
|
||||
EXTRA_COMPONENT_DIRS = ../../../SensorLib
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
@ -0,0 +1,154 @@
|
||||
# ESP-IDF SensorLib TouchDrv examples
|
||||
|
||||
```bash
|
||||
The current example only writes the CSTxxx series touch application.
|
||||
```
|
||||
|
||||
## Configure the Project
|
||||
|
||||
Open the project configuration menu (`idf.py menuconfig`).
|
||||
|
||||
|
||||
In the `SensorLib Example Configuration` menu:
|
||||
|
||||
* Select the communication method, will interface, callback interface, LL new version interface
|
||||
1. Implemented using built-in read and write methods (Read and write methods are provided internally by SensorLib, supporting high version esp-idf >= 5.0, and low version methods (< 5.0))
|
||||
2. Implemented using read and write callback methods (Implemented using externally provided methods, suitable for multiple platforms)
|
||||
* In `Sensor SCL GPIO Num` select the clock pin to connect to the PMU,the default is 7
|
||||
* In `Sensor SDA GPIO Num` select the data pin connected to the PMU,the default is 6
|
||||
* Select the interrupt pin connected to the PMU in `Sensor Interrupt Pin`, the default is 8
|
||||
* Select `Sensor reset Pin` , the default is 17
|
||||
* `Master Frequency` The maximum communication frequency defaults to 100000HZ, and you can decide whether to change it according to the situation.
|
||||
|
||||
## How to Use Example
|
||||
|
||||
Before project configuration and build, be sure to set the correct chip target using `idf.py set-target <chip_name>`. default use **esp32s3**
|
||||
|
||||
## Build and Flash
|
||||
|
||||
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
The output information is to configure the output voltage and enable status of the PMU
|
||||
|
||||
```bash
|
||||
SPIWP:0xee
|
||||
mode:DIO, clock div:1
|
||||
load:0x3fce2810,len:0x178c
|
||||
load:0x403c8700,len:0x4
|
||||
load:0x403c8704,len:0xc10
|
||||
load:0x403cb700,len:0x2dac
|
||||
entry 0x403c8904
|
||||
I (26) boot: ESP-IDF v5.3-beta1-105-g3f632df143-dirt 2nd stage bootloader
|
||||
I (27) boot: compile time Jan 23 2025 16:49:34
|
||||
I (27) boot: Multicore bootloader
|
||||
I (27) boot: chip revision: v0.2
|
||||
I (27) boot.esp32s3: Boot SPI Speed : 80MHz
|
||||
I (28) boot.esp32s3: SPI Mode : DIO
|
||||
I (28) boot.esp32s3: SPI Flash Size : 2MB
|
||||
I (28) boot: Enabling RNG early entropy source...
|
||||
I (28) boot: Partition Table:
|
||||
I (28) boot: ## Label Usage Type ST Offset Length
|
||||
I (29) boot: 0 nvs WiFi data 01 02 00009000 00006000
|
||||
I (29) boot: 1 phy_init RF data 01 01 0000f000 00001000
|
||||
I (30) boot: 2 factory factory app 00 00 00010000 00100000
|
||||
I (30) boot: End of partition table
|
||||
I (30) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=0ca94h ( 51860) map
|
||||
I (40) esp_image: segment 1: paddr=0001cabc vaddr=3fc92e00 size=02a38h ( 10808) load
|
||||
I (43) esp_image: segment 2: paddr=0001f4fc vaddr=40374000 size=00b1ch ( 2844) load
|
||||
I (44) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=21020h (135200) map
|
||||
I (69) esp_image: segment 4: paddr=00041048 vaddr=40374b1c size=0e254h ( 57940) load
|
||||
I (88) boot: Loaded app from partition at offset 0x10000
|
||||
I (88) boot: Disabling RNG early entropy source...
|
||||
I (88) cpu_start: Multicore app
|
||||
I (98) cpu_start: Pro cpu start user code
|
||||
I (98) cpu_start: cpu freq: 240000000 Hz
|
||||
I (98) app_init: Application information:
|
||||
I (98) app_init: Project name: ESP_IDF_TouchDrvExample
|
||||
I (98) app_init: App version: v0.2.5-8-gde9a1d2-dirty
|
||||
I (99) app_init: Compile time: Jan 23 2025 16:51:47
|
||||
I (99) app_init: ELF file SHA256: 179a53fa8...
|
||||
I (99) app_init: ESP-IDF: v5.3-beta1-105-g3f632df143-dirt
|
||||
I (99) efuse_init: Min chip rev: v0.0
|
||||
I (99) efuse_init: Max chip rev: v0.99
|
||||
I (100) efuse_init: Chip rev: v0.2
|
||||
I (100) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (100) heap_init: At 3FC96158 len 000535B8 (333 KiB): RAM
|
||||
I (100) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
|
||||
I (101) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
|
||||
I (101) heap_init: At 600FE100 len 00001EE8 (7 KiB): RTCRAM
|
||||
I (102) spi_flash: detected chip: winbond
|
||||
I (102) spi_flash: flash io: dio
|
||||
W (102) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
I (103) sleep: Configure to isolate all GPIO pins in sleep state
|
||||
I (103) sleep: Enable automatic switching of GPIO sleep configuration
|
||||
I (104) main_task: Started on CPU0
|
||||
I (114) main_task: Calling app_main()
|
||||
I (114) I2C: Implemented using read and write callback methods (Use higher version >= 5.0 API)
|
||||
I (114) gpio: GPIO[6]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (114) gpio: GPIO[7]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (114) main: I2C initialized successfully
|
||||
I (114) TOUCH: ----SensorLib TouchDrv Examples----
|
||||
Scand I2C Devices:
|
||||
0 1 2 3 4 5 6 7 8 9 a b c d e f
|
||||
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
50: -- -- -- -- -- -- -- -- -- -- 5a -- -- -- -- --
|
||||
60: -- -- -- -- -- -- -- -- -- -- 6a -- -- -- -- --
|
||||
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
|
||||
|
||||
|
||||
I (224) TOUCH: Find touch address 0x5A
|
||||
I (224) TOUCH: Implemented using built-in read and write methods (Use higher version >= 5.0 API)
|
||||
I (224) SensorLib: Using ESP-IDF Driver interface.
|
||||
I (224) SensorLib: Added Device Address : 0x5A New Dev Address: 0x3fc9a3a0 Speed :400000
|
||||
I (224) TOUCH: Initializing the capacitive touch screen successfully
|
||||
I (224) TOUCH: Using CST226SE model
|
||||
I (224) gpio: GPIO[8]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (224) main: Run...
|
||||
I (224) main_task: Returned from app_main()
|
||||
X[0]:143 Y[0]:167
|
||||
X[0]:143 Y[0]:167
|
||||
X[0]:143 Y[0]:167
|
||||
X[0]:143 Y[0]:167
|
||||
X[0]:143 Y[0]:167
|
||||
X[0]:143 Y[0]:167
|
||||
X[0]:143 Y[0]:167
|
||||
X[0]:143 Y[0]:167
|
||||
X[0]:143 Y[0]:167
|
||||
X[0]:143 Y[0]:167
|
||||
```
|
||||
|
||||
## Build process example
|
||||
|
||||
Assuming you don't have esp-idf yet
|
||||
|
||||
```bash
|
||||
mkdir -p ~/esp
|
||||
cd ~/esp
|
||||
git clone --recursive https://github.com/espressif/esp-idf.git
|
||||
git clone https://github.com/lewisxhe/SensorLib.git
|
||||
cd esp-idf
|
||||
./install.sh
|
||||
. ./export.sh
|
||||
cd ..
|
||||
cd SensorLib/examples/ESP_IDF_TouchDrvExample
|
||||
|
||||
Configure SDA,SCL,INT,RST,Pin
|
||||
...
|
||||
|
||||
idf.py menuconfig
|
||||
idf.py build
|
||||
idf.py -b 921600 flash
|
||||
idf.py monitor
|
||||
|
||||
```
|
||||
@ -0,0 +1,5 @@
|
||||
idf_component_register(SRCS
|
||||
"touch_drv.cpp"
|
||||
"i2c_driver.cpp"
|
||||
"main.cpp"
|
||||
INCLUDE_DIRS ".")
|
||||
@ -0,0 +1,52 @@
|
||||
menu "SensorLib Example Configuration"
|
||||
|
||||
choice I2C_COMMUNICATION_METHOD
|
||||
prompt "SensorLib read and write methods"
|
||||
default I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
help
|
||||
Define SensorLib read and write methods
|
||||
|
||||
config I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
bool "Implemented using built-in read and write methods"
|
||||
config I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
bool "Implemented using read and write callback methods"
|
||||
endchoice
|
||||
|
||||
config I2C_MASTER_PORT_NUM
|
||||
int "Sensor I2C Port Number"
|
||||
default 1
|
||||
help
|
||||
Port number for I2C Master device.
|
||||
|
||||
config I2C_MASTER_FREQUENCY
|
||||
int "Master Frequency"
|
||||
default 100000
|
||||
help
|
||||
I2C Speed of Master device.
|
||||
|
||||
config SENSOR_SCL
|
||||
int "Sensor SCL GPIO Num"
|
||||
default 7
|
||||
help
|
||||
GPIO number for I2C clock line.
|
||||
|
||||
config SENSOR_SDA
|
||||
int "Sensor SDA GPIO Num"
|
||||
default 6
|
||||
help
|
||||
GPIO number for I2C data line.
|
||||
|
||||
config SENSOR_IRQ
|
||||
int "Sensor Interrupt Pin"
|
||||
default 8
|
||||
help
|
||||
Sensor interrupt pin.
|
||||
|
||||
config SENSOR_RST
|
||||
int "Sensor reset Pin"
|
||||
default 17
|
||||
help
|
||||
Sensor reset pin.
|
||||
|
||||
|
||||
endmenu
|
||||
@ -0,0 +1,4 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
@ -0,0 +1,275 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file port_i2c.cpp
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-22
|
||||
*
|
||||
*/
|
||||
#include <cstring>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "i2c_driver.h"
|
||||
|
||||
static const char *TAG = "I2C";
|
||||
|
||||
#define I2C_MASTER_NUM (i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM
|
||||
#define I2C_MASTER_SDA_IO (gpio_num_t)CONFIG_SENSOR_SDA
|
||||
#define I2C_MASTER_SCL_IO (gpio_num_t)CONFIG_SENSOR_SCL
|
||||
#define I2C_MASTER_FREQ_HZ CONFIG_I2C_MASTER_FREQUENCY /*!< I2C master clock frequency */
|
||||
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
||||
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
#include "soc/clk_tree_defs.h"
|
||||
|
||||
i2c_master_dev_handle_t i2c_device;
|
||||
|
||||
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
|
||||
// * which is useful when the bus shares multiple devices.
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
/**
|
||||
* @brief Read a sequence of bytes from a pmu registers
|
||||
*/
|
||||
int i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
|
||||
{
|
||||
esp_err_t ret;
|
||||
if (len == 0) {
|
||||
return ESP_OK;
|
||||
}
|
||||
if (data == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
ret = i2c_master_transmit_receive(
|
||||
i2c_device,
|
||||
(const uint8_t *)®Addr,
|
||||
1,
|
||||
data,
|
||||
len,
|
||||
-1);
|
||||
#else
|
||||
|
||||
i2c_cmd_handle_t cmd;
|
||||
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, regAddr, true);
|
||||
i2c_master_stop(cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "PMU i2c_master_cmd_begin FAILED! > ");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_READ, true);
|
||||
if (len > 1) {
|
||||
i2c_master_read(cmd, data, len - 1, I2C_MASTER_ACK);
|
||||
}
|
||||
i2c_master_read_byte(cmd, &data[len - 1], I2C_MASTER_NACK);
|
||||
i2c_master_stop(cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "i2c_read_error.");
|
||||
}
|
||||
#endif
|
||||
return ret == ESP_OK ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a byte to a pmu register
|
||||
*/
|
||||
int i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
|
||||
{
|
||||
esp_err_t ret;
|
||||
if (data == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
uint8_t *write_buffer = (uint8_t *)malloc(sizeof(uint8_t) * (len + 1));
|
||||
if (!write_buffer) {
|
||||
return -1;
|
||||
}
|
||||
write_buffer[0] = regAddr;
|
||||
memcpy(write_buffer + 1, data, len);
|
||||
|
||||
ret = i2c_master_transmit(
|
||||
i2c_device,
|
||||
write_buffer,
|
||||
len + 1,
|
||||
-1);
|
||||
free(write_buffer);
|
||||
#else
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, regAddr, true);
|
||||
i2c_master_write(cmd, data, len, true);
|
||||
i2c_master_stop(cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "i2c_write_error.");
|
||||
}
|
||||
#endif
|
||||
return ret == ESP_OK ? 0 : -1;
|
||||
}
|
||||
|
||||
esp_err_t i2c_drv_device_init(uint8_t address)
|
||||
{
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
i2c_device_config_t i2c_dev_conf = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = address,
|
||||
.scl_speed_hz = I2C_MASTER_FREQ_HZ,
|
||||
};
|
||||
return i2c_master_bus_add_device(bus_handle, &i2c_dev_conf, &i2c_device);
|
||||
#else
|
||||
return ESP_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif //CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
|
||||
/**
|
||||
* @brief i2c master initialization
|
||||
*/
|
||||
esp_err_t i2c_drv_init(void)
|
||||
{
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods (Use higher version >= 5.0 API)");
|
||||
|
||||
i2c_master_bus_config_t i2c_bus_config;
|
||||
memset(&i2c_bus_config, 0, sizeof(i2c_bus_config));
|
||||
i2c_bus_config.clk_source = I2C_CLK_SRC_DEFAULT;
|
||||
i2c_bus_config.i2c_port = I2C_MASTER_NUM;
|
||||
i2c_bus_config.scl_io_num = (gpio_num_t)I2C_MASTER_SCL_IO;
|
||||
i2c_bus_config.sda_io_num = (gpio_num_t)I2C_MASTER_SDA_IO;
|
||||
i2c_bus_config.glitch_ignore_cnt = 7;
|
||||
i2c_bus_config.flags.enable_internal_pullup = true;
|
||||
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &bus_handle));
|
||||
|
||||
return ESP_OK;
|
||||
#else
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods (Use lower version < 5.0 API)");
|
||||
|
||||
i2c_config_t i2c_conf ;
|
||||
memset(&i2c_conf, 0, sizeof(i2c_conf));
|
||||
i2c_conf.mode = I2C_MODE_MASTER;
|
||||
i2c_conf.sda_io_num = I2C_MASTER_SDA_IO;
|
||||
i2c_conf.scl_io_num = I2C_MASTER_SCL_IO;
|
||||
i2c_conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
|
||||
i2c_conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
|
||||
i2c_conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
|
||||
i2c_param_config(I2C_MASTER_NUM, &i2c_conf);
|
||||
return i2c_driver_install(I2C_MASTER_NUM, i2c_conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void i2c_drv_scan()
|
||||
{
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
uint8_t address = 0x00;
|
||||
printf("Scand I2C Devices:\n");
|
||||
printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
|
||||
for (int i = 0; i < 128; i += 16) {
|
||||
printf("%02x: ", i);
|
||||
for (int j = 0; j < 16; j++) {
|
||||
fflush(stdout);
|
||||
address = i + j;
|
||||
err = i2c_master_probe(bus_handle, address, 1000);
|
||||
if (err == ESP_OK) {
|
||||
printf("%02x ", address);
|
||||
} else if (err == ESP_ERR_TIMEOUT) {
|
||||
printf("UU ");
|
||||
} else {
|
||||
printf("-- ");
|
||||
}
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
printf("\n\n\n");
|
||||
#else
|
||||
uint8_t address;
|
||||
printf("Scand I2C Devices:\n");
|
||||
printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
|
||||
for (int i = 0; i < 128; i += 16) {
|
||||
printf("%02x: ", i);
|
||||
for (int j = 0; j < 16; j++) {
|
||||
fflush(stdout);
|
||||
address = i + j;
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (address << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_stop(cmd);
|
||||
esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 50 / portTICK_PERIOD_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret == ESP_OK) {
|
||||
printf("%02x ", address);
|
||||
} else if (ret == ESP_ERR_TIMEOUT) {
|
||||
printf("UU ");
|
||||
} else {
|
||||
printf("-- ");
|
||||
}
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool i2c_drv_probe(uint8_t devAddr)
|
||||
{
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
return ESP_OK == i2c_master_probe(bus_handle, devAddr, 1000);
|
||||
#else
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_stop(cmd);
|
||||
esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 50 / portTICK_PERIOD_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
return (ret == ESP_OK);
|
||||
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
|
||||
}
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file i2c_driver.h
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-22
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_idf_version.h"
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
#include "driver/i2c_master.h"
|
||||
#else
|
||||
#include "driver/i2c.h"
|
||||
#endif //ESP_IDF_VERSION
|
||||
|
||||
|
||||
esp_err_t i2c_drv_init(void);
|
||||
void i2c_drv_scan();
|
||||
bool i2c_drv_probe(uint8_t devAddr);
|
||||
int i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
|
||||
int i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
|
||||
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
esp_err_t i2c_drv_device_init(uint8_t address);
|
||||
#endif
|
||||
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file main.cpp
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-22
|
||||
*
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "i2c_driver.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
extern esp_err_t sensor_drv_init();
|
||||
extern esp_err_t touch_drv_init();
|
||||
extern void touch_loop();
|
||||
static void touch_task(void *);
|
||||
|
||||
extern "C" void app_main(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(i2c_drv_init());
|
||||
ESP_LOGI(TAG, "I2C initialized successfully");
|
||||
|
||||
ESP_ERROR_CHECK(touch_drv_init());
|
||||
|
||||
xTaskCreate(touch_task, "touch", 4 * 1024, NULL, 10, NULL);
|
||||
|
||||
ESP_LOGI(TAG, "Run...");
|
||||
}
|
||||
|
||||
|
||||
static void touch_task(void *args)
|
||||
{
|
||||
while (1) {
|
||||
touch_loop();
|
||||
// vTaskDelay(pdMS_TO_TICKS(10));
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,227 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2025 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file touch_drv.cpp
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2025-01-22
|
||||
*
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "i2c_driver.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "TouchDrvCSTXXX.hpp"
|
||||
|
||||
static const char *TAG = "TOUCH";
|
||||
|
||||
#define SENSOR_INPUT_PIN (gpio_num_t)CONFIG_SENSOR_IRQ
|
||||
#define SENSOR_INPUT_PIN_SEL (1ULL<<SENSOR_INPUT_PIN)
|
||||
|
||||
TouchDrvCSTXXX touch;
|
||||
static QueueHandle_t xQueue;
|
||||
|
||||
static void touch_home_button_callback(void *user_data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Touch Home button pressed!");
|
||||
}
|
||||
|
||||
static void IRAM_ATTR sensor_irq_handler(void *arg)
|
||||
{
|
||||
uint32_t gpio_num = (uint32_t) arg;
|
||||
xQueueSendFromISR(xQueue, &gpio_num, NULL);
|
||||
}
|
||||
|
||||
static void irq_init()
|
||||
{
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
io_conf.pin_bit_mask = SENSOR_INPUT_PIN_SEL;
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
gpio_config(&io_conf);
|
||||
// gpio_set_intr_type(SENSOR_INPUT_PIN, GPIO_INTR_NEGEDGE);
|
||||
// //install gpio isr service
|
||||
// gpio_install_isr_service(0);
|
||||
// //hook isr handler for specific gpio pin
|
||||
// gpio_isr_handler_add(SENSOR_INPUT_PIN, sensor_irq_handler, (void *) SENSOR_INPUT_PIN);
|
||||
|
||||
}
|
||||
|
||||
esp_err_t touch_drv_init()
|
||||
{
|
||||
uint8_t address = 0xFF;
|
||||
|
||||
ESP_LOGI(TAG, "----SensorLib TouchDrv Examples----");
|
||||
|
||||
/*
|
||||
* CST816, CST328 Some chips have automatic sleep function.
|
||||
* If you want to scan the device address,
|
||||
* must reset the chip first. If the reset pin is not connected,
|
||||
* you may not be able to obtain the device address by scanning the bus.
|
||||
*/
|
||||
gpio_num_t gpio_num = (gpio_num_t)CONFIG_SENSOR_RST;
|
||||
ESP_ERROR_CHECK(gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT));
|
||||
|
||||
gpio_set_level(gpio_num, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(15));
|
||||
gpio_set_level(gpio_num, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(80));
|
||||
|
||||
// Run bus scan
|
||||
i2c_drv_scan();
|
||||
|
||||
// Get known address
|
||||
if (i2c_drv_probe(CST816_SLAVE_ADDRESS)) {
|
||||
address = CST816_SLAVE_ADDRESS;
|
||||
ESP_LOGI(TAG, "Find touch address 0x%X", address);
|
||||
} else if (i2c_drv_probe(CST226SE_SLAVE_ADDRESS)) {
|
||||
address = CST226SE_SLAVE_ADDRESS;
|
||||
ESP_LOGI(TAG, "Find touch address 0x%X", address);
|
||||
} else if (i2c_drv_probe(CST328_SLAVE_ADDRESS)) {
|
||||
address = CST328_SLAVE_ADDRESS;
|
||||
ESP_LOGI(TAG, "Find touch address 0x%X", address);
|
||||
}
|
||||
|
||||
if (address == 0xFF) {
|
||||
ESP_LOGE(TAG, "Could't find touch chip!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// Set reset and interrupt pin
|
||||
touch.setPins(CONFIG_SENSOR_RST, CONFIG_SENSOR_IRQ);
|
||||
|
||||
//* Implemented using read and write callback methods, applicable to other platforms
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
// * Provide the device address to the callback function
|
||||
i2c_drv_device_init(address);
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods");
|
||||
if (touch.begin(address, i2c_read_callback, i2c_write_callback)) {
|
||||
ESP_LOGI(TAG, "Initializing the capacitive touch screen successfully");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the capacitive touch screen");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//* Use the built-in esp-idf communication method
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)");
|
||||
|
||||
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
|
||||
// * which is useful when the bus shares multiple devices.
|
||||
extern i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
if (touch.begin(bus_handle, address)) {
|
||||
ESP_LOGI(TAG, "Initializing the capacitive touch screen successfully");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the capacitive touch screen");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#else
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)");
|
||||
if (touch.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, address, CONFIG_SENSOR_SDA, CONFIG_SENSOR_SCL)) {
|
||||
ESP_LOGI(TAG, "Initializing the capacitive touch screen successfully");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize the capacitive touch screen");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
|
||||
#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
|
||||
const char *model = touch.getModelName();
|
||||
ESP_LOGI(TAG, "Using %s model", model);
|
||||
if (strncmp(model, "CST8", 4) == 0) {
|
||||
ESP_LOGI(TAG, "Some CST816 will automatically enter sleep,can use the touch.disableAutoSleep() to turn off");
|
||||
// Some CST816 will automatically enter sleep,
|
||||
// can use the touch.disableAutoSleep() to turn off
|
||||
touch.disableAutoSleep();
|
||||
|
||||
/**
|
||||
* Some touch screens have touch buttons,
|
||||
* and the touch coordinates need to be given
|
||||
* before the touch button callback function can be used.
|
||||
*/
|
||||
// Example touch coordinates using T-Display-S3 touch
|
||||
touch.setCenterButtonCoordinate(85, 360);
|
||||
|
||||
touch.setHomeButtonCallback(touch_home_button_callback);
|
||||
}
|
||||
|
||||
// Set the maximum valid coordinates
|
||||
// touch.setMaxCoordinates(320, 170);
|
||||
|
||||
// Swap XY coordinates
|
||||
// touch.setSwapXY(true);
|
||||
|
||||
// Mirror XY coordinates
|
||||
// touch.setMirrorXY(false, true);
|
||||
|
||||
|
||||
// Create a queue to handle gpio event from isr
|
||||
xQueue = xQueueCreate(5, sizeof(uint32_t));
|
||||
|
||||
// Register Sensor interrupt pins
|
||||
irq_init();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
void touch_drv_isr_handler()
|
||||
{
|
||||
int16_t x[5], y[5];
|
||||
uint8_t touched = touch.getPoint(x, y, touch.getSupportTouchPoint());
|
||||
if (touched) {
|
||||
for (int i = 0; i < touched; ++i) {
|
||||
printf("X[");
|
||||
printf("%d", i);
|
||||
printf("]:");
|
||||
printf("%d", x[i]);
|
||||
printf(" ");
|
||||
printf(" Y[");
|
||||
printf("%d", i);
|
||||
printf("]:");
|
||||
printf("%d", y[i]);
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void touch_loop()
|
||||
{
|
||||
uint32_t io_num;
|
||||
// if (xQueueReceive(xQueue, &io_num, pdMS_TO_TICKS(10))) {
|
||||
// if (gpio_get_level((gpio_num_t)CONFIG_SENSOR_IRQ) == 0) {
|
||||
touch_drv_isr_handler();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
CONFIG_IDF_TARGET="esp32s3"
|
||||
CONFIG_IDF_TARGET_ESP32S3=y
|
||||
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
|
||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240
|
||||
|
||||
@ -0,0 +1,193 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2023 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file LTR553ALS_Sensor.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-09-09
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorLTR553.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 5
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 6
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 21
|
||||
#endif
|
||||
|
||||
SensorLTR553 als;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
pinMode(SENSOR_IRQ, INPUT_PULLUP);
|
||||
|
||||
if (!als.begin(Wire, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find LTR553 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("Init LTR553 Sensor success!");
|
||||
|
||||
// Set the ambient light high and low thresholds.
|
||||
// If the value exceeds or falls below the set value, an interrupt will be triggered.
|
||||
als.setLightSensorThreshold(10, 200);
|
||||
|
||||
// Set the high and low thresholds of the proximity sensor.
|
||||
// If the value exceeds or falls below the set value, an interrupt will be triggered.
|
||||
als.setProximityThreshold(10, 30);
|
||||
|
||||
// Controls the Light Sensor N number of times the measurement data is outside the range
|
||||
// defined by the upper and lower threshold limits before asserting the interrupt.
|
||||
als.setLightSensorPersists(5);
|
||||
|
||||
// Controls the Proximity N number of times the measurement data is outside the range
|
||||
// defined by the upper and lower threshold limits before asserting the interrupt.
|
||||
als.setProximityPersists(5);
|
||||
|
||||
/*
|
||||
* ALS_IRQ_ACTIVE_LOW, // INT pin is considered active when it is a logic 0 (default)
|
||||
* ALS_IRQ_ACTIVE_HIGH // INT pin is considered active when it is a logic 1
|
||||
* * */
|
||||
als.setIRQLevel(SensorLTR553::ALS_IRQ_ACTIVE_LOW);
|
||||
|
||||
/*
|
||||
* ALS_IRQ_ONLY_PS, // Only PS measurement can trigger interrupt
|
||||
* ALS_IRQ_ONLY_ALS, // Only ALS measurement can trigger interrupt
|
||||
* ALS_IRQ_BOTH, // Both ALS and PS measurement can trigger interrupt
|
||||
* * * */
|
||||
als.enableIRQ(SensorLTR553::ALS_IRQ_BOTH);
|
||||
|
||||
/*
|
||||
* ALS_GAIN_1X , -> 1 lux to 64k lux (default)
|
||||
* ALS_GAIN_2X , -> 0.5 lux to 32k lux
|
||||
* ALS_GAIN_4X , -> 0.25 lux to 16k lux
|
||||
* ALS_GAIN_8X , -> 0.125 lux to 8k lux
|
||||
* ALS_GAIN_48X , -> 0.02 lux to 1.3k lux
|
||||
* ALS_GAIN_96X , -> 0.01 lux to 600 lux
|
||||
* */
|
||||
als.setLightSensorGain(SensorLTR553::ALS_GAIN_8X);
|
||||
|
||||
/*
|
||||
* PS_LED_PLUSE_30KHZ,
|
||||
* PS_LED_PLUSE_40KHZ,
|
||||
* PS_LED_PLUSE_50KHZ,
|
||||
* PS_LED_PLUSE_60KHZ,
|
||||
* PS_LED_PLUSE_70KHZ,
|
||||
* PS_LED_PLUSE_80KHZ,
|
||||
* PS_LED_PLUSE_90KHZ,
|
||||
* PS_LED_PLUSE_100KHZ,
|
||||
* * * * * * * * * * */
|
||||
als.setPsLedPulsePeriod(SensorLTR553::PS_LED_PLUSE_100KHZ);
|
||||
|
||||
|
||||
/*
|
||||
* PS_LED_DUTY_25,
|
||||
* PS_LED_DUTY_50,
|
||||
* PS_LED_DUTY_75,
|
||||
* PS_LED_DUTY_100,
|
||||
* * * */
|
||||
als.setPsLedDutyCycle(SensorLTR553::PS_LED_DUTY_100);
|
||||
|
||||
|
||||
/*
|
||||
* PS_LED_CUR_5MA,
|
||||
* PS_LED_CUR_10MA,
|
||||
* PS_LED_CUR_20MA,
|
||||
* PS_LED_CUR_50MA,
|
||||
* PS_LED_CUR_100MA,
|
||||
* * * * * * * */
|
||||
als.setPsLedCurrent(SensorLTR553::PS_LED_CUR_50MA);
|
||||
|
||||
/*
|
||||
* PS_MEAS_RATE_50MS,
|
||||
* PS_MEAS_RATE_70MS,
|
||||
* PS_MEAS_RATE_100MS,
|
||||
* PS_MEAS_RATE_200MS,
|
||||
* PS_MEAS_RATE_500MS,
|
||||
* PS_MEAS_RATE_1000MS,
|
||||
* PS_MEAS_RATE_2000MS,
|
||||
* PS_MEAS_RATE_10MS
|
||||
* * * * * * * */
|
||||
als.setProximityRate(SensorLTR553::PS_MEAS_RATE_200MS);
|
||||
|
||||
// Number of pulses
|
||||
als.setPsLedPulses(1);
|
||||
|
||||
// Enable proximity sensor saturation indication
|
||||
als.enablePsIndicator();
|
||||
|
||||
// Enable ambient light sensor
|
||||
als.enableLightSensor();
|
||||
|
||||
// Enable proximity sensor
|
||||
als.enableProximity();
|
||||
|
||||
}
|
||||
|
||||
bool canRead()
|
||||
{
|
||||
#if SENSOR_IRQ != -1
|
||||
return digitalRead(SENSOR_IRQ) == LOW;
|
||||
#else
|
||||
static uint32_t lastReadMillis;
|
||||
if (millis() > lastReadMillis) {
|
||||
lastReadMillis = millis() + 500;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
/*
|
||||
* PS Saturation Flag is used for monitoring the internal IC saturation.
|
||||
* It will be flagged when the IC has reached saturation
|
||||
* and not able to perform any further PS measurement
|
||||
* */
|
||||
bool saturated = false;
|
||||
if (canRead()) {
|
||||
Serial.print(" ALS: CH1:"); Serial.print(als.getLightSensor(1));
|
||||
Serial.print(" - CH0:"); Serial.print(als.getLightSensor(0));
|
||||
Serial.print(" - PS:"); Serial.print(als.getProximity(&saturated));
|
||||
Serial.print(" - "); Serial.println(saturated ? "PS saturated" : "PS not saturated");
|
||||
}
|
||||
delay(5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,214 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file PCF85063_AlarmByUnits.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-12-11
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <time.h>
|
||||
#include "SensorPCF85063.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 4
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 5
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 14
|
||||
#endif
|
||||
|
||||
|
||||
SensorPCF85063 rtc;
|
||||
|
||||
|
||||
uint32_t intervalue = 0;
|
||||
uint8_t nextHour = 22;
|
||||
uint8_t nextMonth = 1;
|
||||
uint8_t nextDay = 1;
|
||||
uint8_t nextMinute = 59;
|
||||
uint8_t nextSecond = 20;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find PCF85063 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
pinMode(SENSOR_IRQ, INPUT_PULLUP);
|
||||
|
||||
rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond);
|
||||
|
||||
nextSecond = 55;
|
||||
|
||||
// First test alarm seconds
|
||||
rtc.setAlarmBySecond(30);
|
||||
|
||||
rtc.enableAlarm();
|
||||
|
||||
}
|
||||
|
||||
void printDateTime()
|
||||
{
|
||||
if (millis() - intervalue > 1000) {
|
||||
/**
|
||||
/// Format output time*
|
||||
Option:
|
||||
DT_FMT_HM, // Format Style : Hour:Minute
|
||||
DT_FMT_HMS, // Format Style : Hour:Minute:Second
|
||||
DT_FMT_YMD, // Format Style : Year-Month-Day
|
||||
DT_FMT_MDY, // Format Style : Month-Day-Year
|
||||
DT_FMT_DMY, // Format Style : Day-Month-Year
|
||||
DT_FMT_YMD_HMS, // Format Style : Year-Month-Day/Hour:Minute:Second
|
||||
Default : DT_FMT_YMD_HMS_WEEK // Format Style : Year-Month-Day/Hour:Minute:Second - Weekday
|
||||
*/
|
||||
Serial.println(rtc.strftime());
|
||||
|
||||
intervalue = millis();
|
||||
}
|
||||
}
|
||||
|
||||
// Test seconds timing
|
||||
void testAlarmSeconds()
|
||||
{
|
||||
while (1) {
|
||||
if (digitalRead(SENSOR_IRQ) == LOW) {
|
||||
Serial.println("testAlarmSeconds Interrupt .... ");
|
||||
if (rtc.isAlarmActive()) {
|
||||
Serial.println("Alarm active");
|
||||
rtc.resetAlarm();
|
||||
rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond);
|
||||
rtc.setAlarmByMinutes(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
printDateTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test minute timing
|
||||
void testAlarmMinute()
|
||||
{
|
||||
while (1) {
|
||||
if (digitalRead(SENSOR_IRQ) == LOW) {
|
||||
Serial.println("testAlarmMinute Interrupt .... ");
|
||||
if (rtc.isAlarmActive()) {
|
||||
Serial.println("Alarm active");
|
||||
rtc.resetAlarm();
|
||||
rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond);
|
||||
nextHour++;
|
||||
if (nextHour >= 24) {
|
||||
nextHour = 23;
|
||||
nextDay = 25;
|
||||
rtc.setAlarmByHours(0);
|
||||
Serial.println("setAlarmByHours");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
printDateTime();
|
||||
}
|
||||
}
|
||||
|
||||
// Test hour timing
|
||||
void testAlarmHour()
|
||||
{
|
||||
while (1) {
|
||||
if (digitalRead(SENSOR_IRQ) == LOW) {
|
||||
Serial.println("testAlarmHour Interrupt .... ");
|
||||
if (rtc.isAlarmActive()) {
|
||||
Serial.println("Alarm active");
|
||||
rtc.resetAlarm();
|
||||
rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond);
|
||||
nextDay++;
|
||||
if (nextDay >= 30) {
|
||||
nextMonth = 1;
|
||||
nextHour = 23;
|
||||
nextMinute = 59;
|
||||
nextSecond = 55;
|
||||
nextDay = rtc.getDaysInMonth(nextMonth, 2022);
|
||||
rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond);
|
||||
rtc.setAlarmByDays(1);
|
||||
Serial.println("setAlarmByDays");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
printDateTime();
|
||||
}
|
||||
}
|
||||
|
||||
// Test day timing
|
||||
void testAlarmDay()
|
||||
{
|
||||
while (1) {
|
||||
if (digitalRead(SENSOR_IRQ) == LOW) {
|
||||
Serial.println("testAlarmDay Interrupt .... ");
|
||||
if (rtc.isAlarmActive()) {
|
||||
Serial.println("Alarm active");
|
||||
rtc.resetAlarm();
|
||||
nextDay = rtc.getDaysInMonth(nextMonth, 2022);
|
||||
rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond);
|
||||
nextMonth++;
|
||||
if (nextMonth >= 12) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
printDateTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
testAlarmSeconds();
|
||||
testAlarmMinute();
|
||||
testAlarmHour();
|
||||
testAlarmDay();
|
||||
|
||||
Serial.println("Test done ...");
|
||||
while (1) {
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,101 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2024 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file PCF85063_ClockOutput.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2024-07-24
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorPCF85063.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 17
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 18
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 7
|
||||
#endif
|
||||
|
||||
|
||||
SensorPCF85063::ClockHz clock_array[] = {
|
||||
SensorPCF85063::CLK_32768HZ,
|
||||
SensorPCF85063::CLK_16384HZ,
|
||||
SensorPCF85063::CLK_8192HZ,
|
||||
SensorPCF85063::CLK_4096HZ,
|
||||
SensorPCF85063::CLK_2048HZ,
|
||||
SensorPCF85063::CLK_1024HZ,
|
||||
SensorPCF85063::CLK_1HZ,
|
||||
SensorPCF85063::CLK_LOW,
|
||||
};
|
||||
|
||||
String freq_hz_str[] = {
|
||||
"32.768KHZ",
|
||||
"16.384KHZ",
|
||||
"8.192KHZ",
|
||||
"4.096KHZ",
|
||||
"2.048KHZ",
|
||||
"1.024KHZ",
|
||||
"1HZ",
|
||||
"LOW"
|
||||
};
|
||||
|
||||
|
||||
SensorPCF85063 rtc;
|
||||
uint32_t intervalue;
|
||||
uint8_t i = 0;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find PCF85063 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (millis() - intervalue > 5000) {
|
||||
intervalue = millis();
|
||||
Serial.print("Set freq : ");
|
||||
Serial.println(freq_hz_str[i]);
|
||||
rtc.setClockOutput(clock_array[i]);
|
||||
i++;
|
||||
i %= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,184 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2023 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file PCF85063_SimpleTime.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2023-09-07
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <SensorPCF85063.hpp>
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 17
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 18
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 7
|
||||
#endif
|
||||
|
||||
SensorPCF85063 rtc;
|
||||
uint32_t interval = 0;
|
||||
uint32_t loopCount = 0;
|
||||
|
||||
void printInt(int val)
|
||||
{
|
||||
if (val < 10) {
|
||||
Serial.print("0");
|
||||
}
|
||||
Serial.print(val);
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
Serial.begin(115200);
|
||||
// Wait for the serial port to be ready
|
||||
while (!Serial);
|
||||
|
||||
// Try to initialize the RTC module using I2C with specified SDA and SCL pins
|
||||
if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find PCF85063 - check your wiring!");
|
||||
// Enter an infinite loop to halt the program
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t year = 2023;
|
||||
uint8_t month = 9;
|
||||
uint8_t day = 7;
|
||||
uint8_t hour = 11;
|
||||
uint8_t minute = 24;
|
||||
uint8_t second = 30;
|
||||
|
||||
// Set the defined date and time on the RTC
|
||||
rtc.setDateTime(year, month, day, hour, minute, second);
|
||||
|
||||
if (!rtc.isClockIntegrityGuaranteed()) {
|
||||
Serial.println("[ERROR]:Clock integrity is not guaranteed; oscillator has stopped or has been interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Check if one second has passed since the last update
|
||||
if (millis() > interval) {
|
||||
|
||||
// Update the interval to the current time
|
||||
interval = millis() + 1000;
|
||||
|
||||
// Retrieve the current date and time from the RTC
|
||||
RTC_DateTime datetime = rtc.getDateTime();
|
||||
|
||||
Serial.print("[RTC ]:");
|
||||
Serial.print(" Year :"); printInt(datetime.getYear());
|
||||
Serial.print(" Month:"); printInt(datetime.getMonth());
|
||||
Serial.print(" Day :"); printInt(datetime.getDay());
|
||||
Serial.print(" Hour:"); printInt(datetime.getHour());
|
||||
Serial.print(" Minute:"); printInt(datetime.getMinute());
|
||||
Serial.print(" Sec :"); printInt(datetime.getSecond());
|
||||
Serial.println();
|
||||
|
||||
// Convert the RTC date and time to Unix time
|
||||
struct tm info = datetime.toUnixTime();
|
||||
Serial.print("[UNIX]:");
|
||||
Serial.print(" Year :"); printInt(info.tm_year + 1900); // tm_year starts counting from 1900
|
||||
Serial.print(" Month:"); printInt(info.tm_mon + 1); // tm_mon range is 0 - 11, 0 means January
|
||||
Serial.print(" Day :"); printInt(info.tm_mday);
|
||||
Serial.print(" Hour:"); printInt(info.tm_hour);
|
||||
Serial.print(" Minute:"); printInt(info.tm_min);
|
||||
Serial.print(" Sec :"); printInt(info.tm_sec);
|
||||
Serial.println();
|
||||
|
||||
// Set a new Unix time at the 10th loop iteration
|
||||
if (loopCount == 10) {
|
||||
Serial.print("Set Unix Time:");
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
struct tm utc_tm;
|
||||
utc_tm.tm_year = 2025 - 1900; // tm_year starts counting from 1900
|
||||
utc_tm.tm_mon = 0; // tm_mon range is 0 - 11, 0 means January
|
||||
utc_tm.tm_mday = 23;
|
||||
utc_tm.tm_hour = 7;
|
||||
utc_tm.tm_min = 1;
|
||||
utc_tm.tm_sec = 28;
|
||||
rtc.setDateTime(utc_tm);
|
||||
}
|
||||
|
||||
// Set a UTC time with a time zone offset of 8 hours at the 20th loop iteration
|
||||
if (loopCount == 20) {
|
||||
Serial.print("Set UTC time to time zone offset 8 hours:");
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
struct tm utc_tm;
|
||||
utc_tm.tm_year = 2025 - 1900; // tm_year starts counting from 1900
|
||||
utc_tm.tm_mon = 0; // tm_mon range is 0 - 11, 0 means January
|
||||
utc_tm.tm_mday = 23;
|
||||
utc_tm.tm_hour = 7;
|
||||
utc_tm.tm_min = 1;
|
||||
utc_tm.tm_sec = 28;
|
||||
rtc.convertUtcToTimezone(utc_tm, 8 * 3600);
|
||||
rtc.setDateTime(utc_tm);
|
||||
}
|
||||
|
||||
if (loopCount > 30) {
|
||||
|
||||
char buf[64];
|
||||
|
||||
struct tm timeinfo;
|
||||
// Get the time C library structure
|
||||
rtc.getDateTime(&timeinfo);
|
||||
|
||||
// Format the output using the strftime function
|
||||
// For more formats, please refer to :
|
||||
// https://man7.org/linux/man-pages/man3/strftime.3.html
|
||||
|
||||
size_t written = strftime(buf, 64, "%A, %B %d %Y %H:%M:%S", &timeinfo);
|
||||
|
||||
if (written != 0) {
|
||||
Serial.println(buf);
|
||||
}
|
||||
|
||||
written = strftime(buf, 64, "%b %d %Y %H:%M:%S", &timeinfo);
|
||||
if (written != 0) {
|
||||
Serial.println(buf);
|
||||
}
|
||||
|
||||
written = strftime(buf, 64, "%A, %d. %B %Y %I:%M%p", &timeinfo);
|
||||
if (written != 0) {
|
||||
Serial.println(buf);
|
||||
}
|
||||
}
|
||||
|
||||
++loopCount;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,191 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file PCF8563_AlarmByUnits.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2022-12-11
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <time.h>
|
||||
#include "SensorPCF8563.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 42
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 41
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 14
|
||||
#endif
|
||||
|
||||
|
||||
SensorPCF8563 rtc;
|
||||
|
||||
uint32_t intervalue = 0;
|
||||
uint8_t nextHour = 22;
|
||||
uint8_t nextMonth = 1;
|
||||
uint8_t nextDay = 1;
|
||||
uint8_t nextMinute = 59;
|
||||
uint8_t nextSecond = 55;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find PCF8563 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
pinMode(SENSOR_IRQ, INPUT_PULLUP);
|
||||
|
||||
rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond);
|
||||
|
||||
// From minute timer
|
||||
rtc.setAlarmByMinutes(0);
|
||||
|
||||
rtc.enableAlarm();
|
||||
|
||||
}
|
||||
|
||||
void printDateTime()
|
||||
{
|
||||
if (millis() - intervalue > 1000) {
|
||||
/**
|
||||
/// Format output time*
|
||||
Option:
|
||||
DT_FMT_HM, // Format Style : Hour:Minute
|
||||
DT_FMT_HMS, // Format Style : Hour:Minute:Second
|
||||
DT_FMT_YMD, // Format Style : Year-Month-Day
|
||||
DT_FMT_MDY, // Format Style : Month-Day-Year
|
||||
DT_FMT_DMY, // Format Style : Day-Month-Year
|
||||
DT_FMT_YMD_HMS, // Format Style : Year-Month-Day/Hour:Minute:Second
|
||||
Default : DT_FMT_YMD_HMS_WEEK // Format Style : Year-Month-Day/Hour:Minute:Second - Weekday
|
||||
*/
|
||||
Serial.println(rtc.strftime());
|
||||
|
||||
intervalue = millis();
|
||||
}
|
||||
}
|
||||
|
||||
// Test minute timing
|
||||
void testAlarmMinute()
|
||||
{
|
||||
while (1) {
|
||||
if (digitalRead(SENSOR_IRQ) == LOW) {
|
||||
Serial.println("testAlarmMinute Interrupt .... ");
|
||||
if (rtc.isAlarmActive()) {
|
||||
Serial.println("Alarm active");
|
||||
rtc.resetAlarm();
|
||||
rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond);
|
||||
nextHour++;
|
||||
if (nextHour >= 24) {
|
||||
nextHour = 23;
|
||||
nextDay = 25;
|
||||
rtc.setAlarmByHours(0);
|
||||
Serial.println("setAlarmByHours");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
printDateTime();
|
||||
}
|
||||
}
|
||||
|
||||
// Test hour timing
|
||||
void testAlarmHour()
|
||||
{
|
||||
while (1) {
|
||||
if (digitalRead(SENSOR_IRQ) == LOW) {
|
||||
Serial.println("testAlarmHour Interrupt .... ");
|
||||
if (rtc.isAlarmActive()) {
|
||||
Serial.println("Alarm active");
|
||||
rtc.resetAlarm();
|
||||
rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond);
|
||||
nextDay++;
|
||||
if (nextDay >= 30) {
|
||||
nextMonth = 1;
|
||||
nextHour = 23;
|
||||
nextMinute = 59;
|
||||
nextSecond = 55;
|
||||
nextDay = rtc.getDaysInMonth(nextMonth, 2022);
|
||||
rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond);
|
||||
rtc.setAlarmByDays(1);
|
||||
Serial.println("setAlarmByDays");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
printDateTime();
|
||||
}
|
||||
}
|
||||
|
||||
// Test day timing
|
||||
void testAlarmDay()
|
||||
{
|
||||
while (1) {
|
||||
if (digitalRead(SENSOR_IRQ) == LOW) {
|
||||
Serial.println("testAlarmDay Interrupt .... ");
|
||||
if (rtc.isAlarmActive()) {
|
||||
Serial.println("Alarm active");
|
||||
rtc.resetAlarm();
|
||||
nextDay = rtc.getDaysInMonth(nextMonth, 2022);
|
||||
rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond);
|
||||
nextMonth++;
|
||||
if (nextMonth >= 12) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
printDateTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
testAlarmMinute();
|
||||
testAlarmHour();
|
||||
testAlarmDay();
|
||||
|
||||
Serial.println("Test done ...");
|
||||
while (1) {
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2024 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file PCF8563_ClockOutput.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2024-10-16
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorPCF8563.hpp"
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 42
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 41
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 14
|
||||
#endif
|
||||
|
||||
|
||||
SensorPCF8563::ClockHz clock_array[] = {
|
||||
SensorPCF8563::CLK_32768HZ,
|
||||
SensorPCF8563::CLK_1024HZ,
|
||||
SensorPCF8563::CLK_32HZ,
|
||||
SensorPCF8563::CLK_1HZ,
|
||||
SensorPCF8563::CLK_DISABLE,
|
||||
};
|
||||
|
||||
String freq_hz_str[] = {
|
||||
"32.768KHZ",
|
||||
"1.024KHZ",
|
||||
"32HZ",
|
||||
"1HZ",
|
||||
"DISABLE",
|
||||
};
|
||||
|
||||
|
||||
SensorPCF8563 rtc;
|
||||
uint32_t intervalue;
|
||||
uint8_t i = 0;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find PCF8563 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (millis() - intervalue > 5000) {
|
||||
intervalue = millis();
|
||||
Serial.print("Set freq : ");
|
||||
Serial.println(freq_hz_str[i]);
|
||||
rtc.setClockOutput(clock_array[i]);
|
||||
i++;
|
||||
i %= 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,184 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file PCF8563_SimpleTime.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2022-12-12
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <SensorPCF8563.hpp>
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 17
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 18
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 7
|
||||
#endif
|
||||
|
||||
SensorPCF8563 rtc;
|
||||
uint32_t interval = 0;
|
||||
uint32_t loopCount = 0;
|
||||
|
||||
void printInt(int val)
|
||||
{
|
||||
if (val < 10) {
|
||||
Serial.print("0");
|
||||
}
|
||||
Serial.print(val);
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
Serial.begin(115200);
|
||||
// Wait for the serial port to be ready
|
||||
while (!Serial);
|
||||
|
||||
// Try to initialize the RTC module using I2C with specified SDA and SCL pins
|
||||
if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find PCF85063 - check your wiring!");
|
||||
// Enter an infinite loop to halt the program
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t year = 2023;
|
||||
uint8_t month = 9;
|
||||
uint8_t day = 7;
|
||||
uint8_t hour = 11;
|
||||
uint8_t minute = 24;
|
||||
uint8_t second = 30;
|
||||
|
||||
// Set the defined date and time on the RTC
|
||||
rtc.setDateTime(year, month, day, hour, minute, second);
|
||||
|
||||
if (!rtc.isClockIntegrityGuaranteed()) {
|
||||
Serial.println("[ERROR]:Clock integrity is not guaranteed; oscillator has stopped or has been interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Check if one second has passed since the last update
|
||||
if (millis() > interval) {
|
||||
|
||||
// Update the interval to the current time
|
||||
interval = millis() + 1000;
|
||||
|
||||
// Retrieve the current date and time from the RTC
|
||||
RTC_DateTime datetime = rtc.getDateTime();
|
||||
|
||||
Serial.print("[RTC ]:");
|
||||
Serial.print(" Year :"); printInt(datetime.getYear());
|
||||
Serial.print(" Month:"); printInt(datetime.getMonth());
|
||||
Serial.print(" Day :"); printInt(datetime.getDay());
|
||||
Serial.print(" Hour:"); printInt(datetime.getHour());
|
||||
Serial.print(" Minute:"); printInt(datetime.getMinute());
|
||||
Serial.print(" Sec :"); printInt(datetime.getSecond());
|
||||
Serial.println();
|
||||
|
||||
// Convert the RTC date and time to Unix time
|
||||
struct tm info = datetime.toUnixTime();
|
||||
Serial.print("[UNIX]:");
|
||||
Serial.print(" Year :"); printInt(info.tm_year + 1900); // tm_year starts counting from 1900
|
||||
Serial.print(" Month:"); printInt(info.tm_mon + 1); // tm_mon range is 0 - 11, 0 means January
|
||||
Serial.print(" Day :"); printInt(info.tm_mday);
|
||||
Serial.print(" Hour:"); printInt(info.tm_hour);
|
||||
Serial.print(" Minute:"); printInt(info.tm_min);
|
||||
Serial.print(" Sec :"); printInt(info.tm_sec);
|
||||
Serial.println();
|
||||
|
||||
// Set a new Unix time at the 10th loop iteration
|
||||
if (loopCount == 10) {
|
||||
Serial.print("Set Unix Time:");
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
struct tm utc_tm;
|
||||
utc_tm.tm_year = 2025 - 1900; // tm_year starts counting from 1900
|
||||
utc_tm.tm_mon = 0; // tm_mon range is 0 - 11, 0 means January
|
||||
utc_tm.tm_mday = 23;
|
||||
utc_tm.tm_hour = 7;
|
||||
utc_tm.tm_min = 1;
|
||||
utc_tm.tm_sec = 28;
|
||||
rtc.setDateTime(utc_tm);
|
||||
}
|
||||
|
||||
// Set a UTC time with a time zone offset of 8 hours at the 20th loop iteration
|
||||
if (loopCount == 20) {
|
||||
Serial.print("Set UTC time to time zone offset 8 hours:");
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
struct tm utc_tm;
|
||||
utc_tm.tm_year = 2025 - 1900; // tm_year starts counting from 1900
|
||||
utc_tm.tm_mon = 0; // tm_mon range is 0 - 11, 0 means January
|
||||
utc_tm.tm_mday = 23;
|
||||
utc_tm.tm_hour = 7;
|
||||
utc_tm.tm_min = 1;
|
||||
utc_tm.tm_sec = 28;
|
||||
rtc.convertUtcToTimezone(utc_tm, 8 * 3600);
|
||||
rtc.setDateTime(utc_tm);
|
||||
}
|
||||
|
||||
if (loopCount > 30) {
|
||||
|
||||
char buf[64];
|
||||
|
||||
struct tm timeinfo;
|
||||
// Get the time C library structure
|
||||
rtc.getDateTime(&timeinfo);
|
||||
|
||||
// Format the output using the strftime function
|
||||
// For more formats, please refer to :
|
||||
// https://man7.org/linux/man-pages/man3/strftime.3.html
|
||||
|
||||
size_t written = strftime(buf, 64, "%A, %B %d %Y %H:%M:%S", &timeinfo);
|
||||
|
||||
if (written != 0) {
|
||||
Serial.println(buf);
|
||||
}
|
||||
|
||||
written = strftime(buf, 64, "%b %d %Y %H:%M:%S", &timeinfo);
|
||||
if (written != 0) {
|
||||
Serial.println(buf);
|
||||
}
|
||||
|
||||
written = strftime(buf, 64, "%A, %d. %B %Y %I:%M%p", &timeinfo);
|
||||
if (written != 0) {
|
||||
Serial.println(buf);
|
||||
}
|
||||
}
|
||||
|
||||
++loopCount;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file PCF8563_TimeLib.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2022-12-12
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorPCF8563.hpp"
|
||||
#include <time.h>
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 42
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 41
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 14
|
||||
#endif
|
||||
|
||||
SensorPCF8563 rtc;
|
||||
uint32_t intervalue;
|
||||
char buf[64];
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
pinMode(SENSOR_IRQ, INPUT_PULLUP);
|
||||
|
||||
if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find PCF8563 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// The simplest way to set up
|
||||
rtc.setDateTime(2024, 1, 17, 4, 21, 30);
|
||||
|
||||
// Unix tm structure sets the time
|
||||
struct tm timeinfo;
|
||||
timeinfo.tm_yday = 2025 - 1900; //Counting starts from 1900, so subtract 1900 here
|
||||
timeinfo.tm_mon = 1 - 1; //Months start at 0, so you need to subtract 1.
|
||||
timeinfo.tm_mday = 17;
|
||||
timeinfo.tm_hour = 4;
|
||||
timeinfo.tm_min = 30;
|
||||
timeinfo.tm_sec = 30;
|
||||
rtc.setDateTime(timeinfo);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (millis() - intervalue > 1000) {
|
||||
|
||||
intervalue = millis();
|
||||
|
||||
struct tm timeinfo;
|
||||
// Get the time C library structure
|
||||
rtc.getDateTime(&timeinfo);
|
||||
|
||||
// Format the output using the strftime function
|
||||
// For more formats, please refer to :
|
||||
// https://man7.org/linux/man-pages/man3/strftime.3.html
|
||||
|
||||
size_t written = strftime(buf, 64, "%A, %B %d %Y %H:%M:%S", &timeinfo);
|
||||
|
||||
if (written != 0) {
|
||||
Serial.println(buf);
|
||||
}
|
||||
|
||||
written = strftime(buf, 64, "%b %d %Y %H:%M:%S", &timeinfo);
|
||||
if (written != 0) {
|
||||
Serial.println(buf);
|
||||
}
|
||||
|
||||
|
||||
written = strftime(buf, 64, "%A, %d. %B %Y %I:%M%p", &timeinfo);
|
||||
if (written != 0) {
|
||||
Serial.println(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,167 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file PCF8563_TimeSynchronization.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2022-12-12
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
#include <time.h>
|
||||
#include <WiFi.h>
|
||||
#include <esp_sntp.h>
|
||||
#include <SensorPCF8563.hpp>
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 42
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 41
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_IRQ
|
||||
#define SENSOR_IRQ 14
|
||||
#endif
|
||||
|
||||
const char *ssid = "YOUR_SSID";
|
||||
const char *password = "YOUR_PASS";
|
||||
|
||||
const char *ntpServer1 = "pool.ntp.org";
|
||||
const char *ntpServer2 = "time.nist.gov";
|
||||
const long gmtOffset_sec = 3600;
|
||||
const int daylightOffset_sec = 3600;
|
||||
|
||||
const char *time_zone = "CST-8"; // TimeZone rule for Europe/Rome including daylight adjustment rules (optional)
|
||||
|
||||
SensorPCF8563 rtc;
|
||||
uint32_t intervalue;
|
||||
|
||||
|
||||
// Callback function (get's called when time adjusts via NTP)
|
||||
void timeavailable(struct timeval *t)
|
||||
{
|
||||
Serial.println("Got time adjustment from NTP, Write the hardware clock");
|
||||
|
||||
// Write synchronization time to hardware
|
||||
rtc.hwClockWrite();
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
pinMode(SENSOR_IRQ, INPUT_PULLUP);
|
||||
|
||||
if (!rtc.begin(Wire, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find PCF8563 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// set notification call-back function
|
||||
sntp_set_time_sync_notification_cb( timeavailable );
|
||||
|
||||
/**
|
||||
* NTP server address could be acquired via DHCP,
|
||||
*
|
||||
* NOTE: This call should be made BEFORE esp32 acquires IP address via DHCP,
|
||||
* otherwise SNTP option 42 would be rejected by default.
|
||||
* NOTE: configTime() function call if made AFTER DHCP-client run
|
||||
* will OVERRIDE acquired NTP server address
|
||||
*/
|
||||
sntp_servermode_dhcp(1); // (optional)
|
||||
|
||||
/**
|
||||
* This will set configured ntp servers and constant TimeZone/daylightOffset
|
||||
* should be OK if your time zone does not need to adjust daylightOffset twice a year,
|
||||
* in such a case time adjustment won't be handled automagically.
|
||||
*/
|
||||
// configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);
|
||||
|
||||
/**
|
||||
* A more convenient approach to handle TimeZones with daylightOffset
|
||||
* would be to specify a environment variable with TimeZone definition including daylight adjustment rules.
|
||||
* A list of rules for your zone could be obtained from https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h
|
||||
*/
|
||||
configTzTime(time_zone, ntpServer1, ntpServer2);
|
||||
|
||||
//connect to WiFi
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(ssid);
|
||||
WiFi.begin(ssid, password);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println(" CONNECTED");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (millis() - intervalue > 1000) {
|
||||
|
||||
intervalue = millis();
|
||||
|
||||
// hardware clock
|
||||
struct tm hwTimeinfo;
|
||||
rtc.getDateTime(&hwTimeinfo);
|
||||
Serial.print("Hardware clock :");
|
||||
Serial.println(&hwTimeinfo, "%A, %B %d %Y %H:%M:%S");
|
||||
|
||||
// system clock
|
||||
struct tm timeinfo;
|
||||
if (!getLocalTime(&timeinfo)) {
|
||||
Serial.println("No time available (yet)");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("System clock :");
|
||||
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
|
||||
Serial.println();
|
||||
|
||||
}
|
||||
}
|
||||
#else
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.println("Examples only ESP32"); delay(1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -0,0 +1,280 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file QMC6310_CalibrateExample.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2022-10-16
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorQMC6310.hpp"
|
||||
#ifdef ARDUINO_T_BEAM_S3_SUPREME
|
||||
#include <XPowersAXP2101.tpp> //PMU Library https://github.com/lewisxhe/XPowersLib.git
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 17
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 18
|
||||
#endif
|
||||
|
||||
SensorQMC6310 qmc;
|
||||
|
||||
void beginPower()
|
||||
{
|
||||
// T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor
|
||||
#if defined(ARDUINO_T_BEAM_S3_SUPREME)
|
||||
XPowersAXP2101 power;
|
||||
power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41);
|
||||
power.disableALDO1();
|
||||
power.disableALDO2();
|
||||
delay(250);
|
||||
power.setALDO1Voltage(3300);
|
||||
power.enableALDO1();
|
||||
power.setALDO2Voltage(3300);
|
||||
power.enableALDO2();
|
||||
#endif
|
||||
}
|
||||
|
||||
void calibrate()
|
||||
{
|
||||
qmc.setDataOutputRate(SensorQMC6310::DATARATE_200HZ);
|
||||
|
||||
int32_t x_min = 65535;
|
||||
int32_t x_max = -65535;
|
||||
int32_t y_min = 65535;
|
||||
int32_t y_max = -65535;
|
||||
int32_t z_min = 65535;
|
||||
int32_t z_max = -65535;
|
||||
Serial.println("Place the sensor on the plane and slowly rotate the sensor...");
|
||||
|
||||
int32_t range = 1000;
|
||||
int32_t i = 0;
|
||||
int32_t x = 0, y = 0, z = 0;;
|
||||
float a = 0.5 ;
|
||||
float x_offset = 0;
|
||||
float y_offset = 0;
|
||||
float z_offset = 0;
|
||||
|
||||
while (i < range) {
|
||||
i += 1;
|
||||
|
||||
if (qmc.isDataReady()) {
|
||||
|
||||
qmc.readData();
|
||||
|
||||
x = a * qmc.getRawX() + (1 - a) * x;
|
||||
y = a * qmc.getRawY() + (1 - a) * y;
|
||||
z = a * qmc.getRawZ() + (1 - a) * z;
|
||||
if (x < x_min) {
|
||||
x_min = x;
|
||||
i = 0;
|
||||
}
|
||||
if (x > x_max) {
|
||||
x_max = x;
|
||||
i = 0;
|
||||
}
|
||||
if (y < y_min) {
|
||||
y_min = y;
|
||||
i = 0;
|
||||
}
|
||||
if (y > y_max) {
|
||||
y_max = y;
|
||||
i = 0;
|
||||
}
|
||||
if (z < z_min) {
|
||||
z_min = z;
|
||||
i = 0;
|
||||
}
|
||||
if (z > z_max) {
|
||||
z_max = z;
|
||||
i = 0;
|
||||
}
|
||||
int j = round(10 * i / range);
|
||||
|
||||
Serial.print("[");
|
||||
for (int k = 0; k < j; ++k) {
|
||||
Serial.print("*");
|
||||
}
|
||||
Serial.println("]");
|
||||
}
|
||||
delay(5);
|
||||
}
|
||||
|
||||
x_offset = (x_max + x_min) / 2;
|
||||
y_offset = (y_max + y_min) / 2;
|
||||
z_offset = (z_max + z_min) / 2;
|
||||
|
||||
Serial.print("x_min:");
|
||||
Serial.print(x_min);
|
||||
|
||||
Serial.print("x_max:");
|
||||
Serial.print(x_max);
|
||||
|
||||
Serial.print("y_min:");
|
||||
Serial.print(y_min);
|
||||
|
||||
Serial.print("y_max:");
|
||||
Serial.print(y_max);
|
||||
|
||||
Serial.print("z_min:");
|
||||
Serial.print(z_min);
|
||||
|
||||
Serial.print("z_max:");
|
||||
Serial.println(z_max);
|
||||
|
||||
|
||||
|
||||
Serial.print("x_offset:");
|
||||
Serial.print(x_offset);
|
||||
|
||||
Serial.print("y_offset:");
|
||||
Serial.print(y_offset);
|
||||
|
||||
Serial.print("z_offset:");
|
||||
Serial.print(z_offset);
|
||||
|
||||
|
||||
// Set the calibration value and the user calculates the deviation
|
||||
qmc.setOffset(x_offset, y_offset, z_offset);
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
beginPower();
|
||||
|
||||
if (!qmc.begin(Wire, QMC6310U_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find QMC6310 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get Magnetometer chip id*/
|
||||
Serial.print("Device ID:");
|
||||
Serial.println(qmc.getChipID(), HEX);
|
||||
|
||||
/* Config Magnetometer */
|
||||
qmc.configMagnetometer(
|
||||
/*
|
||||
* Run Mode
|
||||
* MODE_SUSPEND
|
||||
* MODE_NORMAL
|
||||
* MODE_SINGLE
|
||||
* MODE_CONTINUOUS
|
||||
* * */
|
||||
SensorQMC6310::MODE_CONTINUOUS,
|
||||
/*
|
||||
* Full Range
|
||||
* RANGE_30G
|
||||
* RANGE_12G
|
||||
* RANGE_8G
|
||||
* RANGE_2G
|
||||
* * */
|
||||
SensorQMC6310::RANGE_8G,
|
||||
/*
|
||||
* Output data rate
|
||||
* DATARATE_10HZ
|
||||
* DATARATE_50HZ
|
||||
* DATARATE_100HZ
|
||||
* DATARATE_200HZ
|
||||
* * */
|
||||
SensorQMC6310::DATARATE_200HZ,
|
||||
/*
|
||||
* Over sample Ratio1
|
||||
* OSR_8
|
||||
* OSR_4
|
||||
* OSR_2
|
||||
* OSR_1
|
||||
* * * */
|
||||
SensorQMC6310::OSR_1,
|
||||
|
||||
/*
|
||||
* Down sample Ratio1
|
||||
* DSR_8
|
||||
* DSR_4
|
||||
* DSR_2
|
||||
* DSR_1
|
||||
* * */
|
||||
SensorQMC6310::DSR_1);
|
||||
|
||||
// Calibration algorithm reference from
|
||||
// https://github.com/CoreElectronics/CE-PiicoDev-QMC6310-MicroPython-Module
|
||||
calibrate();
|
||||
|
||||
Serial.println("Calibration done .");
|
||||
delay(5000);
|
||||
|
||||
Serial.println("Read data now...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Wait data ready
|
||||
if (qmc.isDataReady()) {
|
||||
|
||||
qmc.readData();
|
||||
|
||||
Serial.print("GYR: ");
|
||||
Serial.print("X:");
|
||||
Serial.print(qmc.getX());
|
||||
Serial.print(" Y:");
|
||||
Serial.print(qmc.getY());
|
||||
Serial.print(" Z:");
|
||||
Serial.print(qmc.getZ());
|
||||
Serial.println(" uT");
|
||||
Serial.print("RAW: ");
|
||||
Serial.print("X:");
|
||||
Serial.print(qmc.getRawX());
|
||||
Serial.print(" Y:");
|
||||
Serial.print(qmc.getRawY());
|
||||
Serial.print(" Z:");
|
||||
Serial.println(qmc.getRawZ());
|
||||
|
||||
/*
|
||||
float x, y, z;
|
||||
qmc.getMag(x, y, z);
|
||||
Serial.print("X:");
|
||||
Serial.print(x);
|
||||
Serial.print(" Y:");
|
||||
Serial.print(y);
|
||||
Serial.print(" Z:");
|
||||
Serial.println(x);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
delay(100);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,254 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file QMC6310_GetDataExample.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2022-10-16
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
#include "SensorQMC6310.hpp"
|
||||
#include "SH1106Wire.h" //Oled display from https://github.com/ThingPulse/esp8266-oled-ssd1306
|
||||
#ifdef ARDUINO_T_BEAM_S3_SUPREME
|
||||
#include <XPowersAXP2101.tpp> //PMU Library https://github.com/lewisxhe/XPowersLib.git
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 17
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 18
|
||||
#endif
|
||||
|
||||
#ifndef OLED_SDA
|
||||
#define OLED_SDA 22 // Display Wire SDA Pin
|
||||
#endif
|
||||
|
||||
#ifndef OLED_SCL
|
||||
#define OLED_SCL 21 // Display Wire SCL Pin
|
||||
#endif
|
||||
|
||||
SH1106Wire display(0x3c, OLED_SDA, OLED_SCL);
|
||||
SensorQMC6310 qmc;
|
||||
|
||||
int last_dx, last_dy, dx, dy, angle;
|
||||
|
||||
const int centreX = 32;
|
||||
const int centreY = 30;
|
||||
const int radius = 22;
|
||||
|
||||
//Compass application from https://github.com/G6EJD/ESP8266_micro_compass_HMC5883_OLED
|
||||
void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, OLEDDISPLAY_COLOR color)
|
||||
{
|
||||
display.setColor(color);
|
||||
float distance;
|
||||
int dx, dy, x2o, y2o, x3, y3, x4, y4, k;
|
||||
distance = sqrt(pow((x1 - x2), 2) + pow((y1 - y2), 2));
|
||||
dx = x2 + (x1 - x2) * alength / distance;
|
||||
dy = y2 + (y1 - y2) * alength / distance;
|
||||
k = awidth / alength;
|
||||
x2o = x2 - dx;
|
||||
y2o = dy - y2;
|
||||
x3 = y2o * k + dx;
|
||||
y3 = x2o * k + dy;
|
||||
x4 = dx - y2o * k;
|
||||
y4 = dy - x2o * k;
|
||||
display.drawLine(x1, y1, x2, y2);
|
||||
display.drawLine(x1, y1, dx, dy);
|
||||
display.drawLine(x3, y3, x4, y4);
|
||||
display.drawLine(x3, y3, x2, y2);
|
||||
display.drawLine(x2, y2, x4, y4);
|
||||
}
|
||||
|
||||
|
||||
void beginPower()
|
||||
{
|
||||
// T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor
|
||||
#if defined(ARDUINO_T_BEAM_S3_SUPREME)
|
||||
XPowersAXP2101 power;
|
||||
power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41);
|
||||
power.disableALDO1();
|
||||
power.disableALDO2();
|
||||
delay(250);
|
||||
power.setALDO1Voltage(3300);
|
||||
power.enableALDO1();
|
||||
power.setALDO2Voltage(3300);
|
||||
power.enableALDO2();
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
beginPower();
|
||||
|
||||
if (!qmc.begin(Wire, QMC6310U_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find QMC6310 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
display.init();
|
||||
|
||||
last_dx = centreX;
|
||||
last_dy = centreY;
|
||||
|
||||
/* Get Magnetometer chip id*/
|
||||
Serial.print("Device ID:");
|
||||
Serial.println(qmc.getChipID(), HEX);
|
||||
|
||||
/* Config Magnetometer */
|
||||
int r = qmc.configMagnetometer(
|
||||
/*
|
||||
* Run Mode
|
||||
* MODE_SUSPEND
|
||||
* MODE_NORMAL
|
||||
* MODE_SINGLE
|
||||
* MODE_CONTINUOUS
|
||||
* * */
|
||||
SensorQMC6310::MODE_NORMAL,
|
||||
/*
|
||||
* Full Range
|
||||
* RANGE_30G
|
||||
* RANGE_12G
|
||||
* RANGE_8G
|
||||
* RANGE_2G
|
||||
* * */
|
||||
SensorQMC6310::RANGE_2G,
|
||||
/*
|
||||
* Output data rate
|
||||
* DATARATE_10HZ
|
||||
* DATARATE_50HZ
|
||||
* DATARATE_100HZ
|
||||
* DATARATE_200HZ
|
||||
* * */
|
||||
SensorQMC6310::DATARATE_100HZ,
|
||||
/*
|
||||
* Over sample Ratio1
|
||||
* OSR_8
|
||||
* OSR_4
|
||||
* OSR_2
|
||||
* OSR_1
|
||||
* * * */
|
||||
SensorQMC6310::OSR_1,
|
||||
|
||||
/*
|
||||
* Down sample Ratio1
|
||||
* DSR_8
|
||||
* DSR_4
|
||||
* DSR_2
|
||||
* DSR_1
|
||||
* * */
|
||||
SensorQMC6310::DSR_1);
|
||||
|
||||
if (r < 0) {
|
||||
Serial.println("Device config failed!");
|
||||
while (1)delay(1000);
|
||||
}
|
||||
|
||||
// Print register configuration information
|
||||
qmc.dumpCtrlRegister();
|
||||
|
||||
Serial.println("Read data now...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
//Wait data ready
|
||||
if (qmc.isDataReady()) {
|
||||
|
||||
qmc.readData();
|
||||
|
||||
|
||||
display.drawString(29, 0, "N");
|
||||
display.drawString( 0, 28, "W");
|
||||
display.drawString(60, 28, "E");
|
||||
display.drawString(29, 53, "S");
|
||||
|
||||
display.drawLine(1, 1, 7, 7);
|
||||
display.drawLine(62, 1, 56, 7);
|
||||
display.drawLine(1, 62, 7, 56);
|
||||
display.drawLine(56, 56, 62, 62);
|
||||
|
||||
//Compass application from https://github.com/G6EJD/ESP8266_micro_compass_HMC5883_OLED
|
||||
float heading = atan2(qmc.getY(), qmc.getX()); // Result is in radians
|
||||
// Now add the 'Declination Angle' for you location. Declination is the variation in magnetic field at your location.
|
||||
// Find your declination here: http://www.magnetic-declination.com/
|
||||
// At my location it is : -2° 20' W, or -2.33 Degrees, which needs to be in radians so = -2.33 / 180 * PI = -0.041 West is + E is -
|
||||
// Make declination = 0 if you can't find your Declination value, the error is negible for nearly all locations
|
||||
float declination = -0.041;
|
||||
heading = heading + declination;
|
||||
|
||||
if (heading < 0) heading += 2 * PI; // Correct for when signs are reversed.
|
||||
if (heading > 2 * PI) heading -= 2 * PI; // Correct for when heading exceeds 360-degree, especially when declination is included
|
||||
angle = int(heading * 180 / M_PI); // Convert radians to degrees for more a more usual result
|
||||
// For the screen -X = up and +X = down and -Y = left and +Y = right, so does not follow coordinate conventions
|
||||
dx = (0.7 * radius * cos((angle - 90) * 3.14 / 180)) + centreX; // calculate X position for the screen coordinates - can be confusing!
|
||||
dy = (0.7 * radius * sin((angle - 90) * 3.14 / 180)) + centreY; // calculate Y position for the screen coordinates - can be confusing!
|
||||
arrow(last_dx, last_dy, centreX, centreY, 2, 2, BLACK); // Erase last arrow
|
||||
arrow(dx, dy, centreX, centreY, 2, 2, WHITE); // Draw arrow in new position
|
||||
|
||||
display.setColor(BLACK);
|
||||
display.fillRect(80, 50, 25, 48);
|
||||
display.setColor(WHITE);
|
||||
display.drawString(80, 50, String(angle) + "°");
|
||||
display.display();
|
||||
|
||||
last_dx = dx;
|
||||
last_dy = dy;
|
||||
|
||||
// for debug.
|
||||
Serial.print("GYR: ");
|
||||
Serial.print("X:");
|
||||
Serial.print(qmc.getX());
|
||||
Serial.print(" Y:");
|
||||
Serial.print(qmc.getY());
|
||||
Serial.print(" Z:");
|
||||
Serial.print(qmc.getZ());
|
||||
Serial.println(" uT");
|
||||
}
|
||||
|
||||
|
||||
delay(100);
|
||||
}
|
||||
#else
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.println("The graphics library may not be supported on the esp32 platform"); delay(1000);
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,170 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file QMC6310_GetDataExample.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2022-10-16
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorQMC6310.hpp"
|
||||
#ifdef ARDUINO_T_BEAM_S3_SUPREME
|
||||
#include <XPowersAXP2101.tpp> //PMU Library https://github.com/lewisxhe/XPowersLib.git
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 17
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 18
|
||||
#endif
|
||||
|
||||
SensorQMC6310 qmc;
|
||||
|
||||
void beginPower()
|
||||
{
|
||||
// T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor
|
||||
#if defined(ARDUINO_T_BEAM_S3_SUPREME)
|
||||
XPowersAXP2101 power;
|
||||
power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41);
|
||||
power.disableALDO1();
|
||||
power.disableALDO2();
|
||||
delay(250);
|
||||
power.setALDO1Voltage(3300);
|
||||
power.enableALDO1();
|
||||
power.setALDO2Voltage(3300);
|
||||
power.enableALDO2();
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
beginPower();
|
||||
|
||||
if (!qmc.begin(Wire, QMC6310U_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find QMC6310 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get Magnetometer chip id*/
|
||||
Serial.print("Device ID:");
|
||||
Serial.println(qmc.getChipID(), HEX);
|
||||
|
||||
/* Config Magnetometer */
|
||||
qmc.configMagnetometer(
|
||||
/*
|
||||
* Run Mode
|
||||
* MODE_SUSPEND
|
||||
* MODE_NORMAL
|
||||
* MODE_SINGLE
|
||||
* MODE_CONTINUOUS
|
||||
* * */
|
||||
SensorQMC6310::MODE_CONTINUOUS,
|
||||
/*
|
||||
* Full Range
|
||||
* RANGE_30G
|
||||
* RANGE_12G
|
||||
* RANGE_8G
|
||||
* RANGE_2G
|
||||
* * */
|
||||
SensorQMC6310::RANGE_8G,
|
||||
/*
|
||||
* Output data rate
|
||||
* DATARATE_10HZ
|
||||
* DATARATE_50HZ
|
||||
* DATARATE_100HZ
|
||||
* DATARATE_200HZ
|
||||
* * */
|
||||
SensorQMC6310::DATARATE_200HZ,
|
||||
/*
|
||||
* Over sample Ratio1
|
||||
* OSR_8
|
||||
* OSR_4
|
||||
* OSR_2
|
||||
* OSR_1
|
||||
* * * */
|
||||
SensorQMC6310::OSR_1,
|
||||
|
||||
/*
|
||||
* Down sample Ratio1
|
||||
* DSR_8
|
||||
* DSR_4
|
||||
* DSR_2
|
||||
* DSR_1
|
||||
* * */
|
||||
SensorQMC6310::DSR_1);
|
||||
|
||||
Serial.println("Read data now...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
//Wiat data ready
|
||||
if (qmc.isDataReady()) {
|
||||
|
||||
qmc.readData();
|
||||
|
||||
Serial.print("GYR: ");
|
||||
Serial.print("X:");
|
||||
Serial.print(qmc.getX());
|
||||
Serial.print(" Y:");
|
||||
Serial.print(qmc.getY());
|
||||
Serial.print(" Z:");
|
||||
Serial.print(qmc.getZ());
|
||||
Serial.println(" uT");
|
||||
Serial.print("RAW: ");
|
||||
Serial.print("X:");
|
||||
Serial.print(qmc.getRawX());
|
||||
Serial.print(" Y:");
|
||||
Serial.print(qmc.getRawY());
|
||||
Serial.print(" Z:");
|
||||
Serial.println(qmc.getRawZ());
|
||||
|
||||
/*
|
||||
float x, y, z;
|
||||
qmc.getMag(x, y, z);
|
||||
Serial.print("X:");
|
||||
Serial.print(x);
|
||||
Serial.print(" Y:");
|
||||
Serial.print(y);
|
||||
Serial.print(" Z:");
|
||||
Serial.println(x);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
delay(100);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,148 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file QMC6310_GetPolarExample.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2022-10-16
|
||||
*
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Arduino.h>
|
||||
#include "SensorQMC6310.hpp"
|
||||
#ifdef ARDUINO_T_BEAM_S3_SUPREME
|
||||
#include <XPowersAXP2101.tpp> //PMU Library https://github.com/lewisxhe/XPowersLib.git
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 17
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 18
|
||||
#endif
|
||||
|
||||
SensorQMC6310 qmc;
|
||||
|
||||
void beginPower()
|
||||
{
|
||||
// T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor
|
||||
#if defined(ARDUINO_T_BEAM_S3_SUPREME)
|
||||
XPowersAXP2101 power;
|
||||
power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41);
|
||||
power.disableALDO1();
|
||||
power.disableALDO2();
|
||||
delay(250);
|
||||
power.setALDO1Voltage(3300);
|
||||
power.enableALDO1();
|
||||
power.setALDO2Voltage(3300);
|
||||
power.enableALDO2();
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
beginPower();
|
||||
|
||||
if (!qmc.begin(Wire, QMC6310U_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL)) {
|
||||
Serial.println("Failed to find QMC6310 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get Magnetometer chip id*/
|
||||
Serial.print("Device ID:");
|
||||
Serial.println(qmc.getChipID(), HEX);
|
||||
|
||||
/* Config Magnetometer */
|
||||
qmc.configMagnetometer(
|
||||
/*
|
||||
* Run Mode
|
||||
* MODE_SUSPEND
|
||||
* MODE_NORMAL
|
||||
* MODE_SINGLE
|
||||
* MODE_CONTINUOUS
|
||||
* * */
|
||||
SensorQMC6310::MODE_NORMAL,
|
||||
/*
|
||||
* Full Range
|
||||
* RANGE_30G
|
||||
* RANGE_12G
|
||||
* RANGE_8G
|
||||
* RANGE_2G
|
||||
* * */
|
||||
SensorQMC6310::RANGE_8G,
|
||||
/*
|
||||
* Output data rate
|
||||
* DATARATE_10HZ
|
||||
* DATARATE_50HZ
|
||||
* DATARATE_100HZ
|
||||
* DATARATE_200HZ
|
||||
* * */
|
||||
SensorQMC6310::DATARATE_200HZ,
|
||||
/*
|
||||
* Over sample Ratio1
|
||||
* OSR_8
|
||||
* OSR_4
|
||||
* OSR_2
|
||||
* OSR_1
|
||||
* * * */
|
||||
SensorQMC6310::OSR_8,
|
||||
|
||||
/*
|
||||
* Down sample Ratio1
|
||||
* DSR_8
|
||||
* DSR_4
|
||||
* DSR_2
|
||||
* DSR_1
|
||||
* * */
|
||||
SensorQMC6310::DSR_1);
|
||||
|
||||
qmc.dumpCtrlRegister();
|
||||
|
||||
// Declination is the difference between magnetic-north and true-north ("heading") and depends on location
|
||||
qmc.setDeclination(-2.77); // Found with: https://www.magnetic-declination.com/CHINA/SHENZHEN/475119.html
|
||||
|
||||
Serial.println("Read data now...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Polar data;
|
||||
// Wait for data ready
|
||||
if (qmc.readPolar(data)) {
|
||||
Serial.print(" polar:"); Serial.print(data.polar); Serial.print("°");
|
||||
Serial.print(" Gauss:"); Serial.print(data.Gauss);
|
||||
Serial.print(" uT:"); Serial.println(data.uT);
|
||||
}
|
||||
|
||||
delay(100);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,289 @@
|
||||
/**
|
||||
*
|
||||
* @license MIT License
|
||||
*
|
||||
* Copyright (c) 2022 lewis he
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file QMI8658_BlockExample.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2022-10-16
|
||||
*
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#include "SensorQMI8658.hpp"
|
||||
#include <MadgwickAHRS.h> //MadgwickAHRS from https://github.com/arduino-libraries/MadgwickAHRS
|
||||
#include "SH1106Wire.h" //Oled display from https://github.com/ThingPulse/esp8266-oled-ssd1306
|
||||
#ifdef ARDUINO_T_BEAM_S3_SUPREME
|
||||
#include <XPowersAXP2101.tpp> //PMU Library https://github.com/lewisxhe/XPowersLib.git
|
||||
#endif
|
||||
|
||||
|
||||
// #define USE_I2C //Using the I2C interface
|
||||
|
||||
#ifdef USE_I2C
|
||||
#ifndef SENSOR_SDA
|
||||
#define SENSOR_SDA 17
|
||||
#endif
|
||||
|
||||
#ifndef SENSOR_SCL
|
||||
#define SENSOR_SCL 18
|
||||
#endif
|
||||
|
||||
#else /* SPI interface*/
|
||||
|
||||
#ifndef SPI_MOSI
|
||||
#define SPI_MOSI (35)
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK
|
||||
#define SPI_SCK (36)
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO
|
||||
#define SPI_MISO (37)
|
||||
#endif
|
||||
|
||||
#endif /* USE_I2C*/
|
||||
|
||||
#ifndef IMU_CS
|
||||
#define IMU_CS 34 // IMU CS PIN
|
||||
#endif
|
||||
|
||||
#ifndef IMU_IRQ
|
||||
#define IMU_IRQ 33 // IMU INT PIN
|
||||
#endif
|
||||
|
||||
#ifndef OLED_SDA
|
||||
#define OLED_SDA 22 // Display Wire SDA Pin
|
||||
#endif
|
||||
|
||||
#ifndef OLED_SCL
|
||||
#define OLED_SCL 21 // Display Wire SCL Pin
|
||||
#endif
|
||||
|
||||
|
||||
SH1106Wire display(0x3c, OLED_SDA, OLED_SCL);
|
||||
SensorQMI8658 qmi;
|
||||
|
||||
IMUdata acc;
|
||||
IMUdata gyr;
|
||||
|
||||
Madgwick filter;
|
||||
|
||||
|
||||
float posX = 64;
|
||||
float posY = 32;
|
||||
float lastPosX = posX;
|
||||
float lastPosY = posY;
|
||||
uint32_t microsPerReading, microsPrevious;
|
||||
const uint8_t rectWidth = 10;
|
||||
|
||||
void beginPower()
|
||||
{
|
||||
// T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor
|
||||
#if defined(ARDUINO_T_BEAM_S3_SUPREME)
|
||||
XPowersAXP2101 power;
|
||||
power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41);
|
||||
power.disableALDO1();
|
||||
power.disableALDO2();
|
||||
delay(250);
|
||||
power.setALDO1Voltage(3300);
|
||||
power.enableALDO1();
|
||||
power.setALDO2Voltage(3300);
|
||||
power.enableALDO2();
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
beginPower();
|
||||
|
||||
display.init();
|
||||
|
||||
bool ret = false;
|
||||
#ifdef USE_I2C
|
||||
ret = qmi.begin(Wire, QMI8658_L_SLAVE_ADDRESS, SENSOR_SDA, SENSOR_SCL);
|
||||
#else
|
||||
#if defined(SPI_MOSI) && defined(SPI_SCK) && defined(SPI_MISO)
|
||||
ret = qmi.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK);
|
||||
#else
|
||||
ret = qmi.begin(SPI, IMU_CS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
Serial.println("Failed to find QMI8658 - check your wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get chip id*/
|
||||
Serial.print("Device ID:");
|
||||
Serial.println(qmi.getChipID(), HEX);
|
||||
|
||||
display.flipScreenVertically();
|
||||
|
||||
qmi.configAccelerometer(
|
||||
/*
|
||||
* ACC_RANGE_2G
|
||||
* ACC_RANGE_4G
|
||||
* ACC_RANGE_8G
|
||||
* ACC_RANGE_16G
|
||||
* */
|
||||
SensorQMI8658::ACC_RANGE_2G,
|
||||
/*
|
||||
* ACC_ODR_1000H
|
||||
* ACC_ODR_500Hz
|
||||
* ACC_ODR_250Hz
|
||||
* ACC_ODR_125Hz
|
||||
* ACC_ODR_62_5Hz
|
||||
* ACC_ODR_31_25Hz
|
||||
* ACC_ODR_LOWPOWER_128Hz
|
||||
* ACC_ODR_LOWPOWER_21Hz
|
||||
* ACC_ODR_LOWPOWER_11Hz
|
||||
* ACC_ODR_LOWPOWER_3H
|
||||
* */
|
||||
SensorQMI8658::ACC_ODR_1000Hz,
|
||||
/*
|
||||
* LPF_MODE_0 //2.66% of ODR
|
||||
* LPF_MODE_1 //3.63% of ODR
|
||||
* LPF_MODE_2 //5.39% of ODR
|
||||
* LPF_MODE_3 //13.37% of ODR
|
||||
* */
|
||||
SensorQMI8658::LPF_MODE_0);
|
||||
|
||||
|
||||
qmi.configGyroscope(
|
||||
/*
|
||||
* GYR_RANGE_16DPS
|
||||
* GYR_RANGE_32DPS
|
||||
* GYR_RANGE_64DPS
|
||||
* GYR_RANGE_128DPS
|
||||
* GYR_RANGE_256DPS
|
||||
* GYR_RANGE_512DPS
|
||||
* GYR_RANGE_1024DPS
|
||||
* */
|
||||
SensorQMI8658::GYR_RANGE_256DPS,
|
||||
/*
|
||||
* GYR_ODR_7174_4Hz
|
||||
* GYR_ODR_3587_2Hz
|
||||
* GYR_ODR_1793_6Hz
|
||||
* GYR_ODR_896_8Hz
|
||||
* GYR_ODR_448_4Hz
|
||||
* GYR_ODR_224_2Hz
|
||||
* GYR_ODR_112_1Hz
|
||||
* GYR_ODR_56_05Hz
|
||||
* GYR_ODR_28_025H
|
||||
* */
|
||||
SensorQMI8658::GYR_ODR_896_8Hz,
|
||||
/*
|
||||
* LPF_MODE_0 //2.66% of ODR
|
||||
* LPF_MODE_1 //3.63% of ODR
|
||||
* LPF_MODE_2 //5.39% of ODR
|
||||
* LPF_MODE_3 //13.37% of ODR
|
||||
* */
|
||||
SensorQMI8658::LPF_MODE_3);
|
||||
|
||||
|
||||
/*
|
||||
* If both the accelerometer and gyroscope sensors are turned on at the same time,
|
||||
* the output frequency will be based on the gyroscope output frequency.
|
||||
* The example configuration is 896.8HZ output frequency,
|
||||
* so the acceleration output frequency is also limited to 896.8HZ
|
||||
* */
|
||||
qmi.enableGyroscope();
|
||||
qmi.enableAccelerometer();
|
||||
|
||||
// Print register configuration information
|
||||
qmi.dumpCtrlRegister();
|
||||
|
||||
// start filter
|
||||
filter.begin(25);
|
||||
|
||||
// initialize variables to pace updates to correct rate
|
||||
microsPerReading = 1000000 / 25;
|
||||
microsPrevious = micros();
|
||||
|
||||
Serial.println("Read data now...");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
float roll = 0, pitch = 0, heading = 0;
|
||||
|
||||
// check if it's time to read data and update the filter
|
||||
if (micros() - microsPrevious >= microsPerReading) {
|
||||
|
||||
// read raw data from IMU
|
||||
if (qmi.getDataReady()) {
|
||||
|
||||
qmi.getAccelerometer(acc.x, acc.y, acc.z);
|
||||
qmi.getGyroscope(gyr.x, gyr.y, gyr.z);
|
||||
|
||||
// update the filter, which computes orientation
|
||||
filter.updateIMU(gyr.x, gyr.y, gyr.z, acc.x, acc.y, acc.z);
|
||||
|
||||
// print the heading, pitch and roll
|
||||
roll = filter.getRoll();
|
||||
pitch = filter.getPitch();
|
||||
heading = filter.getYaw();
|
||||
|
||||
posX -= roll * 2;
|
||||
posY += pitch;
|
||||
|
||||
posX = constrain(posX, 0, display.width() - rectWidth);
|
||||
posY = constrain(posY, 0, display.height() - rectWidth);
|
||||
|
||||
display.setColor(BLACK);
|
||||
display.fillRect(lastPosX, lastPosY, 10, 10);
|
||||
display.setColor(WHITE);
|
||||
display.fillRect(posX, posY, 10, 10);
|
||||
display.display();
|
||||
|
||||
lastPosX = posX;
|
||||
lastPosY = posY;
|
||||
}
|
||||
// increment previous time, so we keep proper pace
|
||||
microsPrevious = microsPrevious + microsPerReading;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.println("The graphics library may not be supported on the esp32 platform");
|
||||
delay(1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user