{"id":18756791,"url":"https://github.com/kike-canaries/canairio_sensorlib","last_synced_at":"2025-08-22T03:32:40.330Z","repository":{"id":38197969,"uuid":"300847700","full_name":"kike-canaries/canairio_sensorlib","owner":"kike-canaries","description":"Particle sensor manager for multiple sensors: Honeywell, Plantower, Panasonic, Sensirion, etc. This is sensors layer of CanAirIO project too.","archived":false,"fork":false,"pushed_at":"2025-06-29T13:49:28.000Z","size":873,"stargazers_count":38,"open_issues_count":9,"forks_count":14,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-29T14:36:05.962Z","etag":null,"topics":["arduino","co2","esp32","esp8266","library","pm25","sensor"],"latest_commit_sha":null,"homepage":"https://canair.io/docs/sensorlib.html","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kike-canaries.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"liberapay":"CanAirIO","github":"hpsaturn"}},"created_at":"2020-10-03T09:53:25.000Z","updated_at":"2025-06-29T13:49:30.000Z","dependencies_parsed_at":"2023-02-12T10:00:47.714Z","dependency_job_id":"e43a804f-8292-4513-9bf8-e8fe1ec085ae","html_url":"https://github.com/kike-canaries/canairio_sensorlib","commit_stats":null,"previous_names":[],"tags_count":47,"template":false,"template_full_name":null,"purl":"pkg:github/kike-canaries/canairio_sensorlib","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kike-canaries%2Fcanairio_sensorlib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kike-canaries%2Fcanairio_sensorlib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kike-canaries%2Fcanairio_sensorlib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kike-canaries%2Fcanairio_sensorlib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kike-canaries","download_url":"https://codeload.github.com/kike-canaries/canairio_sensorlib/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kike-canaries%2Fcanairio_sensorlib/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271579447,"owners_count":24784251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-22T02:00:08.480Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","co2","esp32","esp8266","library","pm25","sensor"],"created_at":"2024-11-07T17:38:05.411Z","updated_at":"2025-08-22T03:32:40.323Z","avatar_url":"https://github.com/kike-canaries.png","language":"C++","funding_links":["https://liberapay.com/CanAirIO","https://github.com/sponsors/hpsaturn","https://www.buymeacoffee.com/hpsaturn"],"categories":["Libraries"],"sub_categories":["Others"],"readme":"\n[![PlatformIO](https://github.com/kike-canaries/canairio_sensorlib/workflows/PlatformIO/badge.svg)](https://github.com/kike-canaries/canairio_sensorlib/actions/) ![ViewCount](https://views.whatilearened.today/views/github/kike-canaries/canairio_sensorlib.svg) [![Telegram Group](https://img.shields.io/endpoint?color=neon\u0026style=flat-square\u0026url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fcanairio)](https://t.me/canairio)\n\n# Air Quality Sensors Library\n\nGeneric sensor manager, abstractions and bindings of multiple sensors [libraries](https://github.com/kike-canaries/canairio_sensorlib/blob/master/unified-lib-deps.ini): Honeywell, Plantower, Panasonic, Sensirion, etc. and CO2 sensors. Also it's handling others environment sensors. This library is for general purpose, but also is the sensors library base of [CanAirIO project](https://canair.io/docs).\n\nFor developers also you can check the complete library documentation [here](http://hpsaturn.com/canairio_sensorlib_doc/html/classSensors.html)\n\n\u003ctable\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e\n\t\t\tDon't forget to star ⭐ this repository\n\t\t\u003c/td\u003e\n\t\u003c/tr\u003e\n\u003c/table\u003e\n\n# Supported sensors\n\n### PM sensors\n\n| Sensor model  | UART  | I2C  | Detection mode | Status |  \n|:----------------------- |:-----:|:-----:|:-------:|:----------:|\n| Honeywell HPMA115S0 | Yes | --- | Auto | DEPRECATED |\n| Panasonic SN-GCJA5L | Yes | Yes | Auto | STABLE |\n| Plantower models    | Yes | --- | Auto | STABLE |\n| Nova SDS011         | Yes | --- | Auto | STABLE |\n| IKEA Vindriktning   | Yes | --- | Select | STABLE |\n| Sensirion SPS30     | Yes | Yes | Select / Auto | STABLE |\n\nNOTE:  \nPanasonic via UART in ESP8266 maybe needs select in detection.  \n\n### CO2 sensors\n\n| Sensor model  | UART  | I2C | Detection mode | Status |  \n|:----------------------- |:-----:|:-----:|:-------:|:----------:|\n| Sensirion SCD30    | --- | Yes | Auto | STABLE |\n| Sensirion SCD4x    | --- | Yes | Auto | TESTING |\n| MHZ19      | Yes | --- | Select | STABLE |\n| CM1106    | Yes | --- | Select | STABLE |\n| SenseAir S8 | Yes | --- | Select | STABLE |\n\n### Environmental sensors\n\n| Sensor model  | Protocol  | Detection mode | Status |  \n|:----------------------- |:-----:|:-------:|:----------:|\n| AM2320      | i2c |  Auto | STABLE |\n| SHT31       | i2c |  Auto | STABLE |\n| AHT10       | i2c |  Auto | STABLE |\n| BME280      | i2c |  Auto | STABLE |\n| BMP280      | i2c |  Auto | STABLE |\n| BME680      | i2c |  Auto | STABLE |\n| DfRobot SEN0469 NH3  | i2c |  Auto | TESTING |\n| DFRobot SEN0466 CO | i2c |  Auto | TESTING |\n| DFRobot SEN0471 NO2 | i2c |  Auto | TESTING |\n| Geiger CAJOE | GPIO | Select | TESTING |\n| DHTxx       | TwoWire |  Select | DISABLED |\n\nNOTE:  \nDHT22 is supported but is not recommended. Please see the documentation.  \n\n### Platforms supported\n\n| Platform  | Variants  | Notes | Status |  \n|:----------------------- |:-----:|:-------:|:----------:|\n| ESP32  | WROVER* | ESP32Devkit and similar (recommended) | STABLE  |\n| ESP32S3  | LilyGo TDisplay | In testing | STABLE |\n| ESP32C3  | Devkit v3 | In testing | STABLE |\n| ESP8266  | 12 |  D1MINI tested and similar (old) | STABLE |\n| Atmelsam  | seeed_wio_terminal | Only works via i2c on left port | STABLE |\n| Arduino | Atmel  | Some third party libraries fails | IN PROGRESS |\n\n\n\n# Features\n\n- Unified variables and getters for all sensors \n- Auto UART port selection (Hw, Sw, UART1, UART2, etc)\n- Multiple i2c sensors and one UART sensor supported at the same time\n- Two I2C channel supported (Wire and Wire1)\n- Real time registry of sensor units (see multivariable)\n- Get vendor names of all devices detected\n- Preselected main stream UART pins from popular boards\n- Auto config UART port for Plantower, Honeywell and Panasonic sensors\n- Unified calibration trigger for all CO2 sensors\n- Unified CO2 Altitude compensation\n- Unified temperature offset for CO2 and environment sensors\n- Add support for Kelvin and Fahrenheit on environment and CO2 sensors\n- Public access to main objects of each library (full methods access)\n- Get unit symbol and name and each sub-sensor\n- Get the main group type: NONE, PM, CO2 and ENV.\n- Basic debug mode support toggle in execution\n\nFull list of all sub libraries supported [here](https://github.com/kike-canaries/canairio_sensorlib/blob/master/unified-lib-deps.ini)\n\n# Quick implementation\n\n```Java\nsensors.setOnDataCallBack(\u0026onSensorDataOk);   // all data read callback\nsensors.init();                               // start all sensors and\n```\n\n# Full implementation\n\nYou can review a full implementation on [CanAirIO project firmware](https://github.com/kike-canaries/canairio_firmware/blob/master/src/main.cpp), but a little brief is the next:\n\n```Java\n/// sensors data callback\nvoid onSensorDataOk() {\n    Serial.print(\"PM2.5: \" + String(sensors.getPM25()));\n    Serial.print(\" CO2: \"  + String(sensors.getCO2()));\n    Serial.print(\" CO2H: \" + String(sensors.getCO2humi()));\n    Serial.print(\" CO2T: \" + String(sensors.getCO2temp()));\n    Serial.print(\" H: \"    + String(sensors.getHumidity()));\n    Serial.println(\" T: \"  + String(sensors.getTemperature()));\n}\n\n/// sensors error callback\nvoid onSensorDataError(const char * msg){\n    Serial.println(\"Sensor read error: \"+String(msg));\n}\n\nvoid setup() {\n\n    sensors.setOnDataCallBack(\u0026onSensorDataOk);     // all data read callback\n    sensors.setOnErrorCallBack(\u0026onSensorDataError); // [optional] error callback\n    sensors.setSampleTime(15);                      // [optional] sensors sample time (default 5s)\n    sensors.setTempOffset(cfg.toffset);             // [optional] temperature compensation\n    sensors.setCO2AltitudeOffset(cfg.altoffset);    // [optional] CO2 altitude compensation\n    sensors.setSeaLevelPressure(1036.25);           // [optional] Set sea level pressure in hpa\n    sensors.setDebugMode(false);                    // [optional] debug mode to get detailed msgs\n    sensors.detectI2COnly(true);                    // [optional] force to only i2c sensors\n    sensors.setTemperatureUnit(TEMPUNIT::KELVIN);   // comment it for Celsius or set Fahrenheit\n    sensors.init();                                 // Auto detection to UART and i2c sensors\n\n    // Alternatives only for UART sensors (TX/RX):\n\n    // sensors.init(SENSORS::Auto);                 // Auto detection to UART sensors (Honeywell, Plantower, Panasonic)\n    // sensors.init(SENSORS::SGCJA5);               // Force UART detection to Panasonic sensor\n    // sensors.init(SENSORS::SSPS30);               // Force UART detection to Sensirion sensor\n    // sensors.init(SENSORS::SMHZ19);               // Force UART detection to Mhz14 or Mhz19 CO2 sensor\n    // sensors.init(SENSORS::SDS011);               // Force UART detection to SDS011 sensor\n    // sensors.init(SENSORS::IKEAVK);               // Force UART detection to IKEA Vindriktning sensor\n    // sensors.init(SENSORS::SCM1106);              // Force UART detection to CM1106 CO2 sensor\n    // sensors.init(SENSORS::SAIRS8);               // Force UART detection to SenseAirS8 CO2 sensor\n    // sensors.init(SENSORS::Auto,PMS_RX,PMS_TX);   // Auto detection on custom RX,TX\n  \n    // Also you can access to sub-library objects, and perform for example calls like next:\n\n    // sensors.sps30.sleep()\n    // sensors.bme.readPressure();\n    // sensors.mhz19.getRange();\n    // sensors.scd30.getTemperatureOffset();\n    // sensors.aht10.readRawData();\n    // sensors.s8.set_ABC_period(period)\n    // ...\n\n    delay(500);\n}\n\nvoid loop() {\n    sensors.loop();  // read sensor data and showed it\n}\n```\n\n## Multivariable demo\n\nIn this [demo](https://www.youtube.com/watch?v=-5Va47Bap48) on two different devices with multiple sensors, you can choose the possible sub sensors units or variables:\n\n[![CanAirIO multivariable demo](https://img.youtube.com/vi/-5Va47Bap48/0.jpg)](https://www.youtube.com/watch?v=-5Va47Bap48)\n\nIn this [demo](https://www.youtube.com/watch?v=uxlmP905-FE) on a simple sketch you could have a dinamyc list of variables of multiple sensors brands:\n\n[![CanAirIO Sensors Lib DEMO with M5CoreInk](https://img.youtube.com/vi/i15iEF47CbY/0.jpg)](https://youtu.be/i15iEF47CbY)\n\n## Multivariable alternative implementation\n\nThe last version added new getters to have the current status of each unit of each sensor connected to the device in real time. Also you can retrieve the list of device names and other stuff:  \n\nFor example:\n\n```cpp\n#include \u003cArduino.h\u003e\n#include \u003cSensors.hpp\u003e\n\nvoid printSensorsDetected() {\n    uint16_t sensors_count =  sensors.getSensorsRegisteredCount();\n    uint16_t units_count   =  sensors.getUnitsRegisteredCount();\n    Serial.println(\"--\u003e[MAIN] Sensors detected count\\t: \" + String(sensors_count));\n    Serial.println(\"--\u003e[MAIN] Sensors units count  \\t: \"  + String(units_count));\n    Serial.print(  \"--\u003e[MAIN] Sensors devices names\\t: \");\n    int i = 0;\n    while (sensors.getSensorsRegistered()[i++] != 0) {\n        Serial.print(sensors.getSensorName((SENSORS)sensors.getSensorsRegistered()[i - 1]));\n        Serial.print(\",\");\n    }\n    Serial.println();\n}\n\nvoid printSensorsValues() {\n    Serial.println(\"\\n--\u003e[MAIN] Preview sensor values:\");\n    UNIT unit = sensors.getNextUnit();\n    while(unit != UNIT::NUNIT) {\n        String uName = sensors.getUnitName(unit);\n        float uValue = sensors.getUnitValue(unit);\n        String uSymb = sensors.getUnitSymbol(unit);\n        Serial.print(\"--\u003e[MAIN] \" + uName + \": \" + String(uValue) + \" \" + uSymb);\n        unit = sensors.getNextUnit();\n    }\n}\n\nvoid onSensorDataOk() {\n    Serial.println(\"======= E X A M P L E   T E S T =========\");\n    printSensorsDetected();\n    printSensorsValues(); \n    Serial.println(\"=========================================\");\n}\n\n/******************************************************************************\n*  M A I N\n******************************************************************************/\n\nvoid setup() {\n    Serial.begin(115200);\n    delay(100);\n    sensors.setSampleTime(5);                       // config sensors sample time interval\n    sensors.setOnDataCallBack(\u0026onSensorDataOk);     // all data read callback\n    sensors.setDebugMode(true);                     // [optional] debug mode\n    sensors.detectI2COnly(false);                   // disable force to only i2c sensors\n    sensors.init();                                 // Auto detection to UART and i2c sensors\n}\n\nvoid loop() {\n    sensors.loop();  // read sensor data and showed it\n}\n```\n\n## UART detection demo\n\n[![CanAirIO auto configuration demo](https://img.youtube.com/vi/hmukAmG5Eec/0.jpg)](https://www.youtube.com/watch?v=hmukAmG5Eec)\n\nCanAirIO sensorlib auto configuration demo on [Youtube](https://www.youtube.com/watch?v=hmukAmG5Eec)\n\n# Wiring\n\nThe current version of library supports 3 kinds of wiring connection, UART, i2c and TwoWire, in the main boards the library using the defaults pins of each board, but in some special cases the pins are:\n\n## UART\n\n### Predefined UART\n\nThe library has [pre-defined some UART pin configs](https://github.com/kike-canaries/canairio_sensorlib/blob/master/src/Sensors.hpp#L19-L52), these are selected on compiling time. Maybe you don't need change anything with your board, and maybe the nexts alternatives works for you:\n\n| Board model    |  TX   | RX  |      Notes |\n|:---------------|:---:|:---:|:------------------:|\n| ESP32GENERIC   | 1  | 3  | ESP32 Pio defaults\n| TTGOT7 / ESP32DEVKIT / D1MINI / NODEFINED | 16 | 17 | CanAirIO devices **\n| TTGO_TDISPLAY  | 12 | 13 | |\n| M5COREINK      | 14 | 13 | |\n| TTGO TQ        | 18 | 13 | |\n| HELTEC         | 18 | 17 | |\n| WEMOSOLED      | 15 | 13 | |\n| ESP32PICOD4    | 3  | 1  | |\n  \n** This pines are when you compile your project without specific any build variable or you board isn't in the list.  \n\n### Custom UART\n\nAlso you could define a custom UART pins in the init() method and select specific sensors model, like this:\n\n```cpp\nsensors.init(SENSORS::SDS011,yourRX,yourTX); // custom RX, custom TX pines.\n```\n\n## I2C (recommended)\n\nWe are using the default pins for each board, some times it's pins are 21,22, please check your board schematic.\n\n## TwoWire (deprecated soon)\n\nFor now we are using it only for DHT sensors in PIN 23. For more info please review the next lines [here](https://github.com/kike-canaries/canairio_sensorlib/blob/master/src/Sensors.hpp#L19-L52).\n\n# Examples\n\n### PlatformIO (recommended)\n\nWe recommended PlatformIO because is more easy than Arduino IDE. For that, please install first [PlatformIO](http://platformio.org/) and its command line tools (Windows, MacOs and Linux), **pio** command, then connect your compatible board to the USB and run the next command:\n\n```python\npio run -e esp32 --target upload\n```\n\nAlso you can see some examples than have `platformio.ini` files for your project.\n\n### Arduino IDE\n\nOnly import the `ino` file of the sample and install the libraries listed on `library.json` and this library. Complete list of libraries used [here](https://github.com/kike-canaries/canairio_sensorlib/blob/master/unified-lib-deps.ini)\n\n### Arduino CLI\n\nFor run the examples, you first need to  install **arduino-cli** or the **Arduino IDE** with the libraries referenced in **lib_deps** on the file [platformio.ini](https://github.com/kike-canaries/canairio_sensorlib/blob/master/platformio.ini), becuase **Arduino don't install it automatically** like PlatformIO. Then put CanAirIO sensor library in your library directory, you can download it from [releases](https://github.com/kike-canaries/canairio_sensorlib/releases) section.\n\nAlso you need to add the **alternative links** for supporting the ESP32 boards:\n\n```bash\narduino-cli config init\n```\n\nin the `.arduino15/arduino-cli.yaml` file add:\n\n```yml\nboard_manager:\n  additional_urls:\n    - https://arduino.esp8266.com/stable/package_esp8266com_index.json\n    - https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json\n```\n\nFrom `arduino-cli` you can run the basic example in a ESP32 board following these steps:\n\n```javascript\narduino-cli core update-index\narduino-cli core install esp32:esp32:lolin32\narduino-cli compile --fqbn esp32:esp32:lolin32 basic\narduino-cli upload --fqbn esp32:esp32:lolin32:UploadSpeed=115200 -p /dev/ttyUSB0 basic\n```\n\nwhere `basic` is the basic example on examples directory.\n\n# Supporting the project\n\nIf you want to contribute to the code or documentation, consider posting a bug report, feature request or a pull request.\n\nWhen creating a pull request, we recommend that you do the following:\n\n- Clone the repository\n- Create a new branch for your fix or feature. For example, git checkout -b fix/my-fix or git checkout -b feat/my-feature.\n- Run to any clang formatter if it is a code, for example using the `vscode` formatter. We are using Google style. More info [here](https://clang.llvm.org/docs/ClangFormatStyleOptions.html)\n- Document the PR description or code will be great\n- Target your pull request to be merged with `devel` branch\n\nAlso you can make a donation, be a patreon or buy a device:  \n\n\u003ca href=\"https://raw.githubusercontent.com/kike-canaries/canairio_firmware/master/images/ethereum_donation_address.png\" target=\"_blank\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/kike-canaries/canairio_firmware/master/images/ethereum_donation_address.png\" align=\"right\" width=\"220\" margin-left=\"10px\" \u003e\u003c/a\u003e\n\n- Via **Ethereum**: `0x1779cD3b85b6D8Cf1A5886B2CF5C53a0E072C108`\n- Via **Liberapay**: [CanAirIO in LiberaPay](https://liberapay.com/CanAirIO)\n- **Buy a device**: [CanAirIO Bike in Tindie](https://www.tindie.com/products/hpsaturn/canairio-bike/)\n- [Inviting us **a coffee**](https://www.buymeacoffee.com/hpsaturn) \n\n# TODO\n\n- [x] Auto detection for UART sensors (Honeywell, Panasonic and Plantower)\n- [x] Added SPS30 library with auto UART detection\n- [x] Disable/enable logs (debug mode flag)\n- [x] Added bme280, bmp280, aht10, sht31, am2320 i2c sensors\n- [x] Exposed public sub-libraries objects, sps30, aht10, etc.\n- [x] Added old DHT sensors\n- [x] Added CO2 sensors: MHZ19, SCD30, CM1106 via UART\n- [x] Added SDS011 particle metter\n- [x] BME680 support\n- [x] Added Sensirion SPS30 and Panasonic SN-GCJA5 via i2c\n- [x] Enable/Disable UART detection for force only i2c\n- [x] Temperature and Altitude compensation\n- [x] SenseAir S8 via UART support\n- [x] Multivariable selection (getNextUnit(),getUnitName(),etc)\n- [x] Two I2C channel supported for M5Stack Devices (M5StickC tested)\n- [x] Added CO, NO2 and NH3 sensors\n- [x] Added Geiger sensor support\n- [ ] New IKEA VINDSTYRKA device support\n- [ ] Sea level setting for Pressure sensors and others\n- [ ] Support to second UART port\n\n# Projects using this Library\n\n- [CanAirIO Device](https://github.com/kike-canaries/canairio_firmware): ESP32 Air quality device for mobile and fixed stations. (PM2.5 and CO2)\n- [CO2 Gadget](https://emariete.com/medidor-co2-display-tft-color-ttgo-t-display-sensirion-scd30): Un medidor de CO2 de alta calidad con pantalla en color. (CO2)  \n- [M5CoreInk Multi Sensor](https://github.com/hpsaturn/co2_m5coreink#readme): Wall CO2, T, H, P, Alt, sensor with low consumption (30 days)\n\n# Credits\n\nThanks to all collaborators and [CanAirIO](https://canair.io) community for testing and reports. Visit us on [Telegram](https://t.me/canairio)\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkike-canaries%2Fcanairio_sensorlib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkike-canaries%2Fcanairio_sensorlib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkike-canaries%2Fcanairio_sensorlib/lists"}