SensorLib
A multi-platform sensor driver library for Arduino / PlatformIO / ESP-IDF.
Highlights
- 45+ devices across 11 categories — Touch, PMIC, IMU, Magnetometer, Accelerometer, RTC, Gauge, Haptic, Light Sensor, I/O Expander, LED
- Ready-to-run examples covering supported devices and common workflows
- Full PMIC subsystem — charger, ADC, GPIO, IRQ, LED, power channels, coulomb counter, BC1.2, Type-C/USB-PD where supported
- One library for Arduino / PlatformIO / ESP-IDF
- Supports both I2C and SPI buses
See the changelog for release details. Projects upgrading from
v0.4.x should also read the v0.5 migration guide.
Contents
Upgrading from v0.4.x
v0.5.x reorganizes driver headers and expands several common interfaces. Most
legacy top-level headers remain as deprecated compatibility wrappers, but some
projects require source changes. Review the v0.5 migration guide
before upgrading.
Installation
Arduino IDE
Install from Library Manager (recommended):
- Open Arduino IDE
- Go to
Tools → Manage Libraries...
- Search for SensorLib
- Click Install
Alternative install methods
From ZIP
- GitHub page →
Code → Download ZIP
- Arduino IDE →
Sketch → Include Library → Add .ZIP Library...
- Select the downloaded ZIP file
With Git
- Clone this repository into your Arduino libraries folder:
- Windows:
Documents/Arduino/libraries/
- macOS:
~/Documents/Arduino/libraries/
- Linux:
~/Arduino/libraries/
- Folder name should be
SensorLib
- Restart Arduino IDE
Add to your platformio.ini:
[env:your_env]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps =
lewisxhe/SensorLib@^0.5.1
Alternative: install from GitHub or local lib
From GitHub (latest)
lib_deps =
https://github.com/lewisxhe/SensorLib.git
Local library
Copy/clone this repository into <your_project>/lib/SensorLib/. PlatformIO will auto-detect it.
ESP-IDF
SensorLib is published in the ESP-IDF Component Registry. Supports ESP-IDF v4.4+ (recommended v5.1+).
1. Add dependency in project root idf_component.yml:
dependencies:
lewisxhe/sensorlib:
version: "^0.5.1"
2. Use in your code:
#include "TouchDrvGoodix.hpp"
// or for PMIC:
// #include "PmicXPowers.hpp"
Build Options
Driver Exclusion
SensorLib can exclude unused driver families or individual drivers at build time.
This is useful when a project only uses one sensor and should not compile the
rest of the library.
For ESP-IDF, configure exclusions from menuconfig:
idf.py menuconfig
Then open:
Component config -> SensorLib Configuration -> Driver exclusion
Select family-level options such as SENSORLIB_EXCLUDE_IMU,
SENSORLIB_EXCLUDE_TOUCH, SENSORLIB_EXCLUDE_PMIC, or select individual
drivers such as SENSORLIB_EXCLUDE_BHI260, SENSORLIB_EXCLUDE_TOUCH_GT911,
SENSORLIB_EXCLUDE_PCF85063.
Example: build an ESP-IDF project that only uses SensorPCF8563:
CONFIG_SENSORLIB_EXCLUDE_IMU=y
CONFIG_SENSORLIB_EXCLUDE_ACCELEROMETER=y
CONFIG_SENSORLIB_EXCLUDE_MAGNETOMETER=y
CONFIG_SENSORLIB_EXCLUDE_LIGHT_SENSOR=y
CONFIG_SENSORLIB_EXCLUDE_TOUCH=y
CONFIG_SENSORLIB_EXCLUDE_HAPTIC=y
CONFIG_SENSORLIB_EXCLUDE_PMIC=y
CONFIG_SENSORLIB_EXCLUDE_GAUGE=y
CONFIG_SENSORLIB_EXCLUDE_IO_EXPANDER=y
CONFIG_SENSORLIB_EXCLUDE_ACTUATOR=y
CONFIG_SENSORLIB_EXCLUDE_FINGER_NAVIGATION=y
CONFIG_SENSORLIB_EXCLUDE_WIRE_HELPER=y
CONFIG_SENSORLIB_EXCLUDE_PCF85063=y
Leave CONFIG_SENSORLIB_EXCLUDE_RTC and
CONFIG_SENSORLIB_EXCLUDE_PCF8563 disabled so the PCF8563 driver remains
available.
For Arduino or PlatformIO source builds, define the same macros in
src/SensorBuildOptUser.h before including SensorLib headers:
#define SENSORLIB_EXCLUDE_IMU 1
#define SENSORLIB_EXCLUDE_TOUCH 1
#define SENSORLIB_EXCLUDE_PMIC 1
#define SENSORLIB_EXCLUDE_PCF85063 1
SENSORLIB_EXCLUDE_ALL can be used to disable every optional driver controlled
by SensorLib build options. Prefer the family or per-driver options when you
want to keep one driver from the same category enabled.
Bosch Firmware Files
Raw Bosch *.fw files are not required by the build and are not included.
BHI260/BHI360 examples use generated firmware headers under
src/bosch/firmware/. If you use a custom Bosch firmware image, convert it to a
C/C++ header or provide your own firmware byte array, then pass it with
setFirmware().
Quick Start
SensorLib provides two ways to include drivers in your sketch:
Option A: Vendor-specific Include (Recommended)
Include only the vendor group you need. Best balance of granularity and convenience.
// Touch — by vendor
#include "TouchDrvGoodix.hpp" // GT911, GT9895
#include "TouchDrvCST.hpp" // CST226, CST816, CST9217, CST3530, CST3240
#include "TouchDrvFocalTech.hpp" // FT6X36
#include "TouchDrvJadard.hpp" // HI8561
#include "TouchDrvChipshine.hpp" // CHSC5816
// PMIC — by vendor
#include "PmicXPowers.hpp" // AXP192, AXP202, AXP2101, AXP517
#include "PmicSilergy.hpp" // SY6970
#include "PmicTI.hpp" // BQ25896
// Other categories — by device type
#include "MagnetometerDrv.hpp" // All magnetometers
#include "ImuDrv.hpp" // All IMUs
#include "RtcDrv.hpp" // All RTCs
#include "GaugeDrv.hpp" // All gauges
#include "IoExpanderDrv.hpp" // All I/O expanders
#include "HapticDrivers.hpp" // All haptic drivers
#include "LightSensorDrv.hpp" // All light sensors
#include "AccelerometerDrv.hpp" // All accelerometers
Option B: Aggregate Include (Quick Prototyping)
One header pulls in all drivers for a category. Convenient for prototyping,
but brings in extra macros and classes you may not need.
#include "TouchDrv.hpp" // All touch drivers (all vendors)
#include "PmicDrv.hpp" // All PMIC drivers (all vendors)
Note: All include paths are flat filenames in src/. This works on
Arduino IDE, PlatformIO, and ESP-IDF without subdirectory paths.
Minimal Example: Touch
GT911 on ESP32 (Arduino)
#include <Wire.h>
#include "TouchDrvGoodix.hpp"
TouchDrvGT911 touch;
void setup() {
Serial.begin(115200);
touch.setPins(15, 18); // INT pin = 15, IRQ pin = 18
touch.begin(Wire, GT911_SLAVE_ADDRESS_L, 21,22); // SDA=21,SCL=22
Serial.println("GT911 ready");
}
void loop() {
TouchPoints touch_points = touch.getTouchPoints();
if (touch_points.hasPoints()) {
for (int i = 0; i < touch_points.getPointCount(); ++i) {
const TouchPoint &point = touch_points.getPoint(i);
Serial.print("X[");
Serial.print(i);
Serial.print("]:");
Serial.print(point.x);
Serial.print(" ");
Serial.print(" Y[");
Serial.print(i);
Serial.print("]:");
Serial.print(point.y);
Serial.print(" ");
}
Serial.println();
}
delay(10);
}
Minimal Example: PMIC
AXP2101 on ESP32 (Arduino)
#include <Wire.h>
#include "PmicXPowers.hpp"
PmicAXP2101 pmic;
void setup() {
Serial.begin(115200);
if (!pmic.begin(Wire, AXP2101_SLAVE_ADDRESS, 3, 2)) { // SDA=3, SCL=2
Serial.println("AXP2101 not found!");
while (1) delay(1000);
}
Serial.print("Chip ID: 0x");
Serial.println(pmic.getChipID(), HEX);
// Set DCDC1 to 3.3V
pmic.getChannel()->setVoltage(AXP2101Channel::CH_DCDC1, 3300);
pmic.getChannel()->enable(AXP2101Channel::CH_DCDC1, true);
// Read battery voltage
pmic.enableModule(PmicAXP2101::Module::GENERAL_ADC, true);
float vbusMv = 0;
Serial.print("VBUS: ");
if (pmic.getAdc().read(PmicAdcBase::Channel::VBUS_VOLTAGE, vbusMv)) {
Serial.print(vbusMv);
} else {
Serial.print("read failed");
}
Serial.println(" mV");
}
void loop() {
float batteryMv = 0;
Serial.print("Battery: ");
if (pmic.getAdc().read(PmicAdcBase::Channel::BAT_VOLTAGE, batteryMv)) {
Serial.print(batteryMv);
} else {
Serial.print("read failed");
}
Serial.println(" mV");
delay(2000);
}
AXP517 USB-C PD
AXP517 includes Type-C/TCPC support and a simple USB-PD sink negotiator for requesting fixed PDO voltages.
PD negotiation is interrupt-driven. Hardware must connect PMIC_IRQ to an MCU GPIO, and the application must pass that pin to begin(..., irqPin) or initPdSink(irqPin) before calling requestPd(). Without a valid IRQ pin, the TCPC RX FIFO cannot be serviced reliably and PD voltage requests cannot complete.
#include <Wire.h>
#include "PmicXPowers.hpp"
PmicAXP517 pmic;
AXP517PdNegotiator::SourceCaps caps;
static constexpr int PMIC_SDA = 3; // Adjust for your board.
static constexpr int PMIC_SCL = 2; // Adjust for your board.
static constexpr int PMIC_IRQ = 44; // Must be connected to PMIC_IRQ.
void setup() {
Serial.begin(115200);
if (!pmic.begin(Wire, AXP517_SLAVE_ADDRESS, PMIC_SDA, PMIC_SCL, PMIC_IRQ)) {
Serial.println("AXP517 or PMIC_IRQ init failed");
while (1) delay(1000);
}
if (pmic.requestPd(9000, 6000, &caps)) {
Serial.println("9V PD contract ready");
}
}
void loop() {
}
Relevant examples:
examples/power/axp517_pd_voltage/
examples/power/axp517_pd_auto_request/
examples/power/axp517_interrupt/
Examples
Examples are organized by category in the examples/ directory:
Directory names and .ino files use lowercase snake_case; folder names do not use hyphens.
examples/
├── actuator/ # Haptic motors, LED drivers
├── io/ # GPIO expanders and bus helper demos
├── platform/ # ESP-IDF framework projects
│ ├── esp_idf_sensor_hub/
│ └── esp_idf_touch/
├── power/ # PMIC, charger, gauge examples
├── sensor/ # IMU, accelerometer, light, magnetometer, navigation
├── touch/ # Touch panel drivers and touch interface examples
├── rtc/ # PCF85063, PCF8563, RTC helpers
└── utility/ # Callback and I2C scan/debug helpers
Using Examples
PlatformIO: Edit platformio.ini and set src_dir to the example you want:
[platformio]
src_dir = examples/sensor/qmi8658_basic_read
Arduino IDE: File → Open → navigate to the .ino file in examples/.
ESP-IDF: See examples/platform/ for ESP-IDF specific projects.
Supported Devices
45 supported devices (click to expand)
| Device |
Description |
I2C |
SPI |
Header |
| RTC |
|
|
|
|
| PCF8563 / HYM8563 |
Real-time clock |
✔️ |
❌ |
SensorPCF8563.hpp |
| PCF85063 |
Real-time clock |
✔️ |
❌ |
SensorPCF85063.hpp |
| IMU |
|
|
|
|
| QMI8658 |
6-axis IMU |
✔️ |
✔️ |
ImuDrv.hpp |
| BHI260AP |
Smart IMU (Bosch) |
✔️ |
✔️ |
SensorBHI260AP.hpp |
| BHI360 |
Smart IMU (Bosch) |
✔️ |
✔️ |
SensorBHI360.hpp |
| Magnetometer |
|
|
|
|
| QMC6309 |
Magnetic Sensor |
✔️ |
❌ |
SensorQMC6309.hpp |
| QMC6310U/N |
Magnetic Sensor |
✔️ |
❌ |
SensorQMC6310.hpp |
| QMC5883P |
Magnetic Sensor |
✔️ |
❌ |
SensorQMC5883P.hpp |
| QMC5883L |
Magnetic Sensor |
✔️ |
❌ |
SensorQMC5883L.hpp |
| BMM150 |
Magnetic Sensor |
✔️ |
❌ |
MagnetometerDrv.hpp |
| Accelerometer |
|
|
|
|
| BMA422 |
Accelerometer |
✔️ |
❌ |
SensorBMA422.hpp |
| BMA423 |
Accelerometer |
✔️ |
❌ |
SensorBMA423.hpp |
| BMA456H |
Accelerometer |
✔️ |
❌ |
SensorBMA456H.hpp |
| I/O Expander |
|
|
|
|
| XL9555 |
16-bit I/O Expander |
✔️ |
❌ |
IoExpanderDrv.hpp |
| PCA9570 |
4-bit I/O Expander |
✔️ |
❌ |
IoExpanderDrv.hpp |
| AW9523 / AW9523B |
16-bit I/O Expander and LED Driver |
✔️ |
❌ |
IoExpanderDrv.hpp |
| Haptic |
|
|
|
|
| DRV2605 |
Haptic Driver (TI) |
✔️ |
❌ |
HapticDrivers.hpp |
| AW86224 |
Haptic Driver (Awinic) |
✔️ |
❌ |
HapticDrivers.hpp |
| Light Sensor |
|
|
|
|
| CM32181 |
Ambient Light Sensor |
✔️ |
❌ |
LightSensorDrv.hpp |
| LTR553 |
Light & Proximity |
✔️ |
❌ |
LightSensorDrv.hpp |
| Touch |
|
|
|
|
| GT911 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvGoodix.hpp |
| GT9895 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvGoodix.hpp |
| FT3267 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvFocalTech.hpp |
| FT5206 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvFocalTech.hpp |
| FT6206 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvFocalTech.hpp |
| FT6236 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvFocalTech.hpp |
| CST226SE |
Capacitive Touch |
✔️ |
❌ |
TouchDrvCST.hpp |
| CST820 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvCST.hpp |
| CST816S/T/D |
Capacitive Touch |
✔️ |
❌ |
TouchDrvCST.hpp |
| CST9217 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvCST.hpp |
| CST9220 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvCST.hpp |
| CST3240 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvCST.hpp |
| CST3530 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvCST.hpp |
| CHSC5816 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvChipshine.hpp |
| HI8561 |
Capacitive Touch |
✔️ |
❌ |
TouchDrvJadard.hpp |
| LED |
|
|
|
|
| AW9364 |
LED Driver (GPIO) |
❌ |
❌ |
AW9364LedDriver.hpp |
| PMIC |
|
|
|
|
| AXP192 |
PMIC (XPowers) |
✔️ |
❌ |
PmicXPowers.hpp |
| AXP202 |
PMIC (XPowers) |
✔️ |
❌ |
PmicXPowers.hpp |
| AXP2101 |
PMIC (XPowers) |
✔️ |
❌ |
PmicXPowers.hpp |
| AXP517 |
PMIC (XPowers, Type-C/USB-PD sink) |
✔️ |
❌ |
PmicXPowers.hpp |
| BQ25896 |
Charger (TI) |
✔️ |
❌ |
PmicTI.hpp |
| SY6970 |
Charger (Silergy) |
✔️ |
❌ |
PmicSilergy.hpp |
| Gauge |
|
|
|
|
| BQ27220 |
Battery Gauge (TI) |
✔️ |
❌ |
GaugeDrv.hpp |
| AXP2602 |
Battery Gauge (XPowers) |
✔️ |
❌ |
GaugeDrv.hpp |
| Other |
|
|
|
|
| PAW-A350 |
Finger Navigation (PixArt) |
✔️ |
❌ |
FingerNavigationDrv.hpp |
| Platform |
Status |
Notes |
| ESP32 |
✔️ |
Primary target, full support |
| ESP32-S2 |
✔️ |
Single-core, USB OTG |
| ESP32-S3 |
✔️ |
Dual-core, USB OTG |
| ESP32-C3 |
✔️ |
RISC-V single-core |
| ESP32-C6 |
✔️ |
RISC-V, Wi-Fi 6 |
Other Arduino-compatible boards (RP2040, nRF52, etc.) may work for I2C devices
but are not actively tested.
Notes
- I2C pull-ups: Most I2C devices require proper pull-up resistors (4.7kΩ typical) on SDA/SCL lines.
- I2C speed: Default is 100kHz. For faster transfers, use
Wire.setClock(400000) before begin().
- SPI devices: QMI8658, BHI260AP, BHI360 support SPI. Touch and PMIC devices are I2C only.
- I2C addresses: Some devices have configurable addresses (e.g., GT911 has
GT911_SLAVE_ADDRESS_L / GT911_SLAVE_ADDRESS_H). Check the header file for available constants.
- AXP517 USB-PD: PD voltage negotiation requires
PMIC_IRQ wiring. Pass the IRQ pin during initialization and use pmic.irq().readStatus(true) in interrupt-driven code so normal PMIC IRQs and TCPC PD alerts are both drained.
- Troubleshooting: If a device is not detected, verify wiring, address selection, and I2C speed. Use
examples/utility/wire_helper/ to scan the I2C bus.
License
SensorLib is licensed under the MIT License. See LICENSE.
Third-party licenses
This repository includes third-party code under src/bosch/ from Bosch Sensortec, licensed under the BSD 3-Clause License (BSD-3-Clause).
See THIRD_PARTY_NOTICES.md for details.
评论