A multi-platform sensor driver library for Arduino / PlatformIO / ESP-IDF.
- 44+ 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
- Contents
- Installation
- Build Options
- Quick Start
- Examples
- Supported Devices
- Platform Compatibility
- Notes
- License
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/
- Windows:
- 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.4.0Alternative: install from GitHub or local lib
From GitHub (latest)
lib_deps =
https://github.com/lewisxhe/SensorLib.gitLocal library
Copy/clone this repository into <your_project>/lib/SensorLib/. PlatformIO will auto-detect it.
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.4.0"2. Use in your code:
#include "TouchDrvGoodix.hpp"
// or for PMIC:
// #include "PmicXPowers.hpp"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 menuconfigThen 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 1SENSORLIB_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.
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().
SensorLib provides two ways to include drivers in your sketch:
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 accelerometersOne 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.
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);
}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 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 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
PlatformIO: Edit platformio.ini and set src_dir to the example you want:
[platformio]
src_dir = examples/sensor/qmi8658_basic_readArduino IDE: File → Open → navigate to the .ino file in examples/.
ESP-IDF: See examples/platform/ for ESP-IDF specific projects.
44 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 |
| 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.
- 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)beforebegin(). - 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_IRQwiring. Pass the IRQ pin during initialization and usepmic.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.
SensorLib is licensed under the MIT License. See LICENSE.
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.