initial commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
+10
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
*.hpp linguist-language=C++
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -0,0 +1,11 @@
|
||||
.pio
|
||||
.vscode
|
||||
test
|
||||
.travis.yml
|
||||
test
|
||||
assets
|
||||
*.bk
|
||||
*.test
|
||||
build
|
||||
*.old
|
||||
sdkconfig
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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) | ❌ | ❌ |
|
||||
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+319
@@ -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;
|
||||
}
|
||||
+276
@@ -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 |
+346
@@ -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);
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 244 KiB |
+348
@@ -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);
|
||||
}
|
||||
+303
@@ -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);
|
||||
}
|
||||
|
||||
+290
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+292
@@ -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
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+295
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+356
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+414
@@ -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;
|
||||
}
|
||||
+282
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+284
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+92
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+147
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+102
@@ -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);
|
||||
}
|
||||
|
||||
+260
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+98
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+158
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+297
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+219
@@ -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 ".")
|
||||
+115
@@ -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.)
|
||||
+378
@@ -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
|
||||
+205
@@ -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
|
||||
+119
@@ -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
|
||||
+137
@@ -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
|
||||
+107
@@ -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
|
||||
+116
@@ -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
|
||||
|
||||
```
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
idf_component_register(SRCS
|
||||
"touch_drv.cpp"
|
||||
"i2c_driver.cpp"
|
||||
"main.cpp"
|
||||
INCLUDE_DIRS ".")
|
||||
+52
@@ -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.)
|
||||
+275
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+227
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+214
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+101
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+184
@@ -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;
|
||||
}
|
||||
}
|
||||
+191
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+95
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+184
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+167
@@ -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
|
||||
|
||||
|
||||
+280
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+254
@@ -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
|
||||
+170
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+148
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+289
@@ -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
|
||||
|
||||
|
||||
+284
@@ -0,0 +1,284 @@
|
||||
/**
|
||||
*
|
||||
* @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_CalibrationExample.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @date 2024-09-23
|
||||
*
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include "SensorQMI8658.hpp"
|
||||
#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
|
||||
|
||||
|
||||
|
||||
SensorQMI8658 qmi;
|
||||
IMUdata acc;
|
||||
IMUdata gyr;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
delay(3000);
|
||||
|
||||
beginPower();
|
||||
|
||||
|
||||
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);
|
||||
|
||||
uint16_t gX_gain = 0, gY_gain = 0, gZ_gain = 0;
|
||||
|
||||
// Call internal calibration to calibrate the sensor
|
||||
ret = false;
|
||||
|
||||
while (!ret) {
|
||||
|
||||
// Calibrate only once, do not obtain calibration value
|
||||
// result = qmi.calibration();
|
||||
|
||||
// Get the calibration value after calibration
|
||||
ret = qmi.calibration(&gX_gain, &gY_gain, &gZ_gain);
|
||||
if (ret) {
|
||||
Serial.println("All calibrations are completed");
|
||||
break;
|
||||
}
|
||||
int i = 5;
|
||||
while (i--) {
|
||||
Serial.print("Calibration failed, please leave the sensor alone and keep quiet! , Will try again in ");
|
||||
Serial.print(i);
|
||||
Serial.println(" seconds");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Save the calibration data to EEPROM or flash, and then write the calibration value directly to the next run
|
||||
// Here only print
|
||||
Serial.print("Calibration data ->");
|
||||
Serial.print("Gyro-X gain : "); Serial.println(gX_gain);
|
||||
Serial.print("Gyro-Y gain : "); Serial.println(gY_gain);
|
||||
Serial.print("Gyro-Z gain : "); Serial.println(gZ_gain);
|
||||
|
||||
// The example only provides a method for writing calibration values
|
||||
ret = qmi.writeCalibration(gX_gain, gY_gain, gZ_gain);
|
||||
if (ret) {
|
||||
Serial.println("Write calibrations successfully");
|
||||
} else {
|
||||
Serial.println("Write calibrations failed!");
|
||||
}
|
||||
|
||||
|
||||
qmi.configAccelerometer(
|
||||
/*
|
||||
* ACC_RANGE_2G
|
||||
* ACC_RANGE_4G
|
||||
* ACC_RANGE_8G
|
||||
* ACC_RANGE_16G
|
||||
* */
|
||||
SensorQMI8658::ACC_RANGE_4G,
|
||||
/*
|
||||
* 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
|
||||
* LPF_OFF // OFF Low-Pass Fitter
|
||||
* */
|
||||
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_64DPS,
|
||||
/*
|
||||
* 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
|
||||
* LPF_OFF // OFF Low-Pass Fitter
|
||||
* */
|
||||
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();
|
||||
|
||||
Serial.println("Read data now...");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (qmi.getDataReady()) {
|
||||
if (qmi.getAccelerometer(acc.x, acc.y, acc.z)) {
|
||||
Serial.print("ACCEL.x:");
|
||||
Serial.print(acc.x);
|
||||
Serial.print(",ACCEL.y:");
|
||||
Serial.print(acc.y);
|
||||
Serial.print(",ACCEL.z:");
|
||||
Serial.print(acc.z);
|
||||
Serial.println("");
|
||||
}
|
||||
if (qmi.getGyroscope(gyr.x, gyr.y, gyr.z)) {
|
||||
Serial.print("GYRO.x:");
|
||||
Serial.print(gyr.x);
|
||||
Serial.print(",GYRO.y:");
|
||||
Serial.print(gyr.y);
|
||||
Serial.print(",GYRO.z:");
|
||||
Serial.print(gyr.z);
|
||||
Serial.println("");
|
||||
}
|
||||
}
|
||||
delay(100);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user