Files
nebuleair_pro_4g/CCS811
PaulVua 46c73acb7e v1.10.1: OTA installe les deps pip + filtre lectures parasites CCS811
Découvert en vérif SSH sur nebuleair-pro100 : le timer CCS811 échouait en
ModuleNotFoundError car l'OTA fait git pull mais ne réinstallait jamais les
dépendances pip (installation_part1.sh ne tourne qu'à l'install neuve).

- requirements.txt: source unique de vérité des deps Python
- installation_part1.sh: install via requirements.txt (chemin relatif au script,
  le repo n'est pas encore cloné dans /var/www à cette étape)
- update_firmware.sh: nouvelle étape 2a, pip install -r requirements.txt
  (idempotent) -> les capteurs déjà déployés récupèrent les libs manquantes à l'OTA
- CCS811/write_data.py + get_data.py: skip des lectures eCO2 < 400 ppm
  (échantillon 0/0 parasite juste après init du driver, plancher physique = 400)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 15:51:58 +02:00
..

CCS811 — Capteur qualité d'air (eCO2 / TVOC)

Capteur de gaz MOX (oxyde métallique) AMS CCS811. Connecté en I2C.

⚠ À lire avant de câbler

Le CCS811 n'est pas un capteur CO2 NDIR comme le Senseair S88. C'est un capteur de COV (composés organiques volatils) qui mesure :

  • TVOC (Total Volatile Organic Compounds) — en ppb. C'est la mesure réellement utile / fiable du capteur, et celle qui nous intéresse ici.
  • eCO2 (CO2 équivalent) — en ppm, plage 4008192. Valeur calculée à partir du TVOC par un algorithme interne, ce n'est pas une mesure directe du CO2. Pour un vrai CO2, utiliser le S88. On stocke quand même l'eCO2 (gratuit, vient de la même lecture) mais ne pas le confondre avec une mesure NDIR.

⚠ Clock-stretching I2C sur Raspberry Pi

Le CCS811 utilise massivement le clock-stretching I2C. Le contrôleur I2C matériel du Raspberry Pi (BSC) gère mal le clock-stretching (bug matériel documenté). Sans mitigation, les lectures échouent typiquement en OSError / Remote I/O error.

Mitigation : ralentir le bus I2C dans /boot/firmware/config.txt :

dtparam=i2c_arm_baudrate=10000

(10 kHz au lieu de 100 kHz par défaut.) Reboot ensuite. À valider au bench — sur certains modules/CM4 ça passe à 100 kHz, sur d'autres non.

Vérifier la présence du capteur :

sudo i2cdetect -y 1   # doit montrer 5a (ou 5b selon la broche ADDR)

Adresse I2C

  • 0x5A : ADDR à GND — défaut des breakouts Adafruit. Valeur par défaut du firmware.
  • 0x5B : ADDR à VDD — défaut des breakouts SparkFun / modules génériques.

Configurable dans admin.html (clé config CCS811_address, dropdown 0x5A / 0x5B).

Câblage I2C

CCS811 Raspberry Pi
VCC / VIN 3.3V
GND GND
SDA SDA (GPIO2)
SCL SCL (GPIO3)
WAK / nWAKE GND (réveil permanent ; sinon laisser le module gérer)
ADDR GND → 0x5A, VDD → 0x5B

⚠ La plupart des breakouts CCS811 sont en 3.3V logique. Ne pas alimenter en 5V sans level-shifter sauf si le module embarque son propre régulateur + shifter.

Burn-in / conditionnement

  • Burn-in initial : ~48 h de fonctionnement continu avant des valeurs stables (1ère mise en service).
  • Warm-up à chaque démarrage : ~20 min pour des valeurs fiables. Au démarrage le capteur renvoie souvent eCO2=400 ppm / TVOC=0 ppb (valeurs de repos).

Implémentation NebuleAir

  • CCS811/get_data.py — lecture live (bouton "Get Data" du web). Affiche {"eCO2": <ppm>, "TVOC": <ppb>} ou {"error": "..."}.
  • CCS811/write_data.py — lecture périodique (timer systemd, toutes les 10 s), écrit dans la table data_CCS811 (timestamp, eCO2, TVOC).

Librairie Python : adafruit-circuitpython-ccs811 (installée par installation_part1.sh). La table est créée par sqlite/create_db.py et self-healée par write_data.py (CREATE TABLE IF NOT EXISTS) — garder les deux schémas synchro.

Activation : admin.html → case "Send VOC sensor data (CCS811)".

Pistes d'amélioration (non implémentées)

Le CCS811 supporte une compensation température/humidité (SET_ENV_DATA). Comme le boîtier embarque déjà un BME280, on pourrait lui pousser temp/hum à chaque lecture pour améliorer la précision. Non fait en v1 pour garder le script simple et autonome.