

Esp32-pool controller
Contrôleur automatique de piscine ESP32 avec gestion pH, ORP, température, filtration, éclairage, app web locale, MQTT (HomeAssistant auto-discovery), API
- Size
- 119.4 × 119.4 mm
- Copper layers
- 2
- Thickness
- 1.6 mm
- Parts
- 93
- Nets
- 63
- Pads
- 252
- Tracks, vias
- 315, 12
- Pours
- 4
- Routed
- Yes
- KiCad
- KiCad 9.0 (file 20241229)
- Created
- 23 Dec 2025
- Updated
- 21 Oct 2026
Overview
Esp32-pool controller is an open-source printed circuit board by niko34, from the niko34/esp32-pool-controller repository on GitHub, published under the MIT licence. It is a 2-layer board of 119.4 × 119.4 mm with 93 parts on 63 nets, routed with 315 tracks and 12 vias.
It is built around the ESP32-DEVKITC-VE, DS18B20 and ADUM1250AR, with the DG301-5.0-02P-12-00A(H), IRLZ44N and B6252HB-NPP3G-50 among its other parts. Its parts include 32 capacitors, 20 resistors, 14 connectors, 7 diodes and 6 ICs. It belongs with the home automation and IoT boards and the ESP32 and RISC-V boards of this library.
Main components
11ESP32-DEVKITC-VE
-- WiFi Modules ROHSEspressif SystemsWiFi ModulesDS18B20
TO-92-55℃~+125℃ 12bit 3V~5.5V 750ms Single-bus ±0.4℃ TO-92 Temperature Sensors ROHSUMWTemperature SensorsADUM1250AR
SOIC8Hot Swappable, Dual I2C IsolatorAnalog DevicesUncategorisedDG301-5.0-02P-12-00A(H)
插件,P=5mm-30℃~+120℃ 1 17.5A 1x2P 2 250V 2P 5mm Blue Through Hole 插件,P=5mm Screw Terminal Blocks ROHSDEGSONScrew Terminal BlocksIRLZ44N
TO-22055V 47A N-Channel HEXFET® Power MOSFETInfineon TechnologiesUncategorisedB6252HB-NPP3G-50
-- Coaxial Connectors (RF) ROHSAmphenolCoaxial Connectors (RF)BBPY00321611601Y00
1206Ferrite BeadsPulse Elec1N5245B
DO-35-65℃~+200℃ 1 Independent 100nA@11V 14.25V~15.75V 15V 16Ω 500mW 600Ω DO-35 Zener Diodes ROHSonsemiZener DiodesB3F-1000
插件-4P,6x6mm-25℃~+70℃ 1,000,000 cycles 1N 24V 4.3mm 50mA 6mm 6mm PC Pin Round Button SPST-NO Through Hole 插件-4P,6x6mm Tactile Switches ROHSOmronTactile SwitchesIRF4905
TO-220-35℃~+175℃ 1 P-Channel 12nF 150nC@10V 1nF 2.5V 200W 450pF 60V 75A 9mΩ P-Channel TO-220 MOSFETs ROHSCmosMOSFETsP6KE13A
DO-15-55℃~+150℃ 11.1V 12.35V 18.2V 1uA 32.97A 600W@10/1000us TVS Unidirectional DO-15 ESD and Surge Protection (TVS/ESD) ROHSDOWOESD And Surge Protection (TVS/ESD)
README
README.md
ESP32 Pool Controller
Disclaimer : projet en cours de construction.
Contrôleur automatique de piscine basé sur ESP32 :
- mesure : température, pH, ORP
- pilotage : pompe de filtration, éclairage
- correction avec pompes doseuses : pH et ORP
- interfaces : application web locale, MQTT, API
🎯 Fonctionnalités
Mesures et Contrôle
- pH : Mesure via module numérique Atlas Scientific EZO pH (I²C). La température de l'eau est transmise au module pour la compensation de température de la mesure.
- ORP (Redox) : Mesure via module numérique Atlas Scientific EZO ORP (I²C)
- Température : Deux sondes Dallas DS18B20 (eau + circuit/boîtier), identification automatique des rôles sur le bus OneWire
- Historique : Historique des mesures
- Mode d'installation : Décrit le câblage réel du contrôleur et garantit qu'aucun produit n'est injecté sans circulation d'eau — PoolController pilote la filtration (sortie 12 V), Alimenté par le circuit de filtration, ou Filtration externe signalée (une domotique tierce signale l'état via HTTP/MQTT ; dosage suspendu sans signal récent)
- Filtration : Programmation automatique en fonction de la température de l'eau, programmation horaire, manuel
- Eclairage : Programmation horaire, manuel
- Régulation automatique de pH et ORP : Injection de produit de correction (pH-, chlore liquide) par régulation proportionnelle temporisée (P) avec pause de mélange et contrôle de débit PWM. Les mesures sont lissées (médiane + EMA) avant d'alimenter la régulation. (pH+ : option de configuration présente mais non gérée actuellement.)
- Consommation de produits : Estimation de la consommation de produit
- Application Web locale : Configuration et visualisation temps réel. Accessible sur le réseau Wifi configuré (
http://poolcontroller.local) ou un réseau Wifi de en mode point d'accès (http://192.168.4.1). Aucune dépendance au Cloud. Voir les screenshots - API : Toutes les fonctionnalités sont exposées avec une API
- MQTT : Exposition des données sur MQTT. Auto-discovery HomeAssistant.
- Mise à jour OTA : Mise à jour firmware via interface web
Sécurité
- ⚠️ Limites journalières : Protection contre le surdosage
- ⚠️ Limites horaires : Temps maximum d'injection par heure configurable
- ⚠️ Watchdog : Redémarrage automatique en cas de blocage du système (30s)
- ⚠️ Alertes MQTT : Notifications en cas d'anomalie
📋 Matériel Requis
Module ESP32 — ⚠️ PSRAM requise
Utiliser un ESP32-DevKitC-VE (module WROVER-E, ESP32 classique avec 8 Mo de PSRAM) — cf. kicad/esp32-pool-controller/BOM.xlsx, repère U2.
⚠️ Pourquoi la PSRAM est nécessaire : la mise à jour en ligne depuis GitHub (onglet Système → « Vérifier les mises à jour ») ouvre une session TLS qui réclame plusieurs blocs de mémoire contigus d'environ 16 Ko. Sur un module sans PSRAM (WROOM-32), la RAM interne ne les fournit plus de façon fiable une fois le système démarré : la vérification échoue de manière intermittente (
BIGNUM - Memory allocation failed). Avec la PSRAM, ces allocations y sont placées automatiquement (seuil 4 Ko) et la fonction redevient fiable.Le firmware fonctionne sur un WROOM-32 sans PSRAM (binaire unique, détection automatique au démarrage, dégradation gracieuse — depuis la v2.18.0) : régulation, interface web, MQTT et mise à jour manuelle par upload de fichier restent pleinement opérationnels. Seule la vérification/installation automatique depuis GitHub est concernée.
Modules déconseillés : l'ESP32-S3 n'est pas supporté (architecture différente, brochage incompatible avec le PCB v2 — les GPIO 22 et 25 utilisés par l'I²C et la pompe pH n'y existent pas).
PCB
Les sources KiCad sont versionnées dans kicad/ :
- Schéma électronique
- PCB
kicad/esp32-pool-controller/esp32-pool-controller.kicad_sch— schémakicad/esp32-pool-controller/esp32-pool-controller.kicad_pcb— routagekicad/esp32-pool-controller/BOM.xlsx— nomenclature (source ; leBOM.csvs'en déduit avecpython3 tools/bom_export.py)
Les fichiers de fabrication (gerbers, perçage) ne sont pas versionnés : ils se
régénèrent avec ./scripts/build-gerbers.sh et sont publiés comme assets des
releases pcb-vX. Voir « Fichiers générés et releases » dans CLAUDE.md.

Boîtier
Les sources FreeCAD et les STL d'impression 3D sont conservés hors du dépôt.
🧭 Reprendre le projet
Cette section s'adresse à quiconque récupère le dépôt — y compris son auteur dans deux ans. Elle dit où est quoi et comment on travaille ici.
Outils nécessaires
| Outil | Pour quoi | Indispensable ? |
|---|---|---|
| PlatformIO | compiler, téléverser, lancer les tests | oui |
| Node.js | minify.js, appelé par build_fs.sh | oui |
| Chrome / Chromium | générer les PDF de documentation | pour les releases |
gh (GitHub CLI) | publier les releases | pour les releases |
| KiCad 7+ | ouvrir le PCB, générer les gerbers | pour le matériel |
| Python 3 | tools/*.py (BOM, coredump, couverture) | ponctuel |
⚠️ Sur macOS, kicad-cli et Chrome ne sont pas dans le PATH : les scripts
scripts/*.sh sondent aussi les emplacements .app.
Repartir d'un clone (conteneur, autre machine)
# Debian / Ubuntu
sudo apt install -y python3 python3-pip nodejs npm chromium imagemagick zip gh
pip install --user platformio
# facultatif, seulement pour le PCB :
sudo apt install -y kicad
git clone https://github.com/niko34/esp32-pool-controller.git
cd esp32-pool-controller
pio pkg install -e esp32dev_core3 # télécharge la plateforme et les libs
pio test -e native # doit être vert
pio run # doit compilerCe qui fonctionne depuis un clone nu : les agents, les skills et les
commandes, les specs, les tests natifs, la compilation, la génération des PDF et
celle des gerbers. Trois workflows GitHub Actions rejouent les trois premiers à
chaque push et à chaque PR — tests natifs + couverture, compilation
pio run -e esp32dev_core3, et hygiène des specs (./tools/check_specs.sh,
lançable en local) : ce n'est pas une promesse, c'est une preuve. Voir
docs/BUILD.md. Les scripts détectent leurs outils et échouent avec un message explicite
si l'un manque.
Ce qui ne fonctionne pas à distance : le déploiement sur l'appareil. Son mot de passe n'est pas dans le dépôt — délibérément — et il vit sur un réseau local. Il faut être sur le même réseau, et fournir le mot de passe :
./ota_update.sh firmware <adresse-ip> <mot-de-passe>Confort dégradé : .claude/settings.local.json n'est pas versionné (il
contient des chemins absolus propres à une machine). Le settings.json partagé
couvre l'essentiel — y compris les garde-fous deny et ask — mais vous
confirmerez plus de commandes qu'en local. C'est le prix d'une configuration
qui ne présume rien de la machine.
Où est quoi
src/ firmware C++ (ESP32, Arduino) data/ interface web (vanilla JS)
test/ tests natifs — logique pure docs/ doc technique, ADR, guides
specs/ LA SOURCE DE VÉRITÉ des demandes kicad/ sources du PCB
scripts/ livrables de release (PDF, gerbers) tools/ utilitaires de développement
.claude/ agents, skills et commandes builds/ archive LOCALE des binairesComment on travaille
Le cycle est décrit en détail dans CLAUDE.md. En résumé :
- Une demande = une spec dans
specs/features/todo/, au format du template. Elle se déplace versdoing/quand le travail commence,done/quand il finit, enrichie des notes techniques et des décisions prises. - Le travail passe par des agents spécialisés (
.claude/agents/) : conception, implémentation firmware ou web, tests, revue, documentation. ⚠️pool-chemistryest obligatoire dès qu'on touche au dosage, à la régulation ou à la calibration des sondes — ce sont les pompes qui injectent de l'acide et du chlore dans un bassin. - Les tests natifs sont non négociables :
pio test -e nativedoit rester vert, et tout test neuf est validé par mutation — on casse volontairement le code qu'il protège pour vérifier qu'il meurt. Plusieurs défauts réels de ce projet n'ont été trouvés que comme ça. - Toute décision structurante devient un ADR dans
docs/adr/. Les ADR sont immuables : on les amende d'une bannière, on ne réécrit pas leur histoire.
Les commandes utiles
pio run # compiler (env unique esp32dev_core3)
pio test -e native # 33 suites, ~1 286 cas
./build_fs.sh # construire le filesystem web
./deploy.sh all # flasher par USB (firmware + filesystem)
./deploy.sh ota-firmware # mettre à jour par WiFi
./tools/coverage.sh # couverture des tests
/release # publier une version firmware + doc
/release-pcb # publier des fichiers de fabrication PCBIl n'y a qu'un seul environnement matériel, esp32dev_core3. L'ancien repli
core Arduino 2.x a été retiré en v2.42.1 : il n'était plus compilable, plus
flashable, et aucun binaire de secours n'avait jamais été archivé
(ADR-0069).
Ce qui n'est pas dans le dépôt, et pourquoi
Les fichiers générés n'y sont pas : PDF de documentation, gerbers de fabrication, firmware compilé. Ils sont attachés aux releases GitHub, où ils sont horodatés et associés à un tag. Voir « Fichiers générés et releases » dans CLAUDE.md.
Deux exceptions volontaires, parce que ces fichiers ne sont pas générés mais relevés — rien ne les régénère :
docs/incidents/— les coredumps de production et leurs traces décodées. Un coredump n'existe qu'une fois : il est écrasé au crash suivant.- L'ELF est attaché à chaque release (~29 Mo) en plus du
.bin.esp-coredumpvérifie le SHA256 de l'image et refuse un ELF qui ne correspond pas : sans celui de la version exacte, un crash reste indéchiffrable.
builds/ contient l'archive locale des ELF de tous les builds (2,6 Go) et
n'est pas versionné.
Les sources FreeCAD du boîtier et les exports STL sont conservés hors dépôt.
🚀 Installation
PlatformIO (Recommandé)
-
Cloner le projet
bash git clone https://github.com/niko34/esp32-pool-controller.git cd esp32-pool-controller -
Ouvrir avec VS Code + PlatformIO
bash code . -
Compiler et déployer
L'unique environnement de build est
esp32dev_core3(core Arduino 3.x / ESP-IDF 5 via pioarduino) — bootloader et application, depuis la v2.20.4 (ADR-0042). L'environnement de repli core 2 a été retiré en v2.42.1 (ADR-0069) :bash pio run # core 3, env unique ./deploy.sh all # firmware + filesystemℹ️ Premier build sur une machine neuve :
pio pkg install -e esp32dev_core3(téléchargement du framework). Voir BUILD.md.Via USB (obligatoire pour la première installation, et pour tout changement de bootloader ou de table de partitions) :
bash ./deploy.sh all # Compile et upload firmware + filesystem ./deploy.sh firmware # Firmware uniquement ./deploy.sh fs # Filesystem uniquementVia WiFi OTA (mises à jour suivantes, une fois la première installation USB effectuée) :
bash ./deploy.sh ota-all # Compile et envoie firmware + filesystem ./deploy.sh ota-firmware # Firmware uniquement ./deploy.sh ota-fs # Filesystem uniquementVoir UPDATE_GUIDE.md pour plus de détails sur les méthodes de mise à jour.
-
Moniteur série
bash pio device monitor -b 115200
Première connexion et accès à l'interface Web
-
Première connexion
- Au démarrage, l'ESP32 crée un point d'accès WiFi
PoolControllerAP - Le mot de passe WiFi AP est unique par appareil, généré aléatoirement au premier boot et stocké en NVS
- Il s'affiche en clair dans le moniteur série tant que le wizard de configuration n'est pas complété :
text [INFO] AP démarré: PoolControllerAP [INFO] AP Password: XXXXXXXX [INFO] IP AP: 192.168.4.1 - Le flash USB (
./deploy.sh all) enchaîne le moniteur série : l'ouverture du port redémarre l'ESP32, le boot est donc capté depuis sa première ligne, sans manœuvre particulière - Coller le mot de passe sur une étiquette sur le boîtier
- Se connecter au réseau
PoolControllerAPavec ce mot de passe et accéder à l'assistant de configuration http://192.168.4.1
Après le wizard complété, si l'AP redémarre (ex : perte WiFi), le mot de passe n'est plus affiché en clair dans les logs pour des raisons de sécurité. Utiliser l'étiquette ou l'API :
text GET http://poolcontroller.local/auth/ap-passwordForcer la génération d'un nouveau mot de passe AP (ex : fabrication d'un nouvel appareil, remplacement d'étiquette) : utiliser l'option
factory, qui efface la flash, réinstalle, ré-efface la NVS en dernier, puis ouvre le moniteur série automatiquement. Le mot de passe s'affiche dans les premières lignes de boot — inutile d'ouvrir un moniteur à la main, et inutile de le lancer avant d'alimenter l'appareil.bash ./deploy.sh factorytext === MOT DE PASSE AP WIFI: XXXXXXXX ===⚠️ Efface toute la flash (firmware, filesystem, NVS, historique). À n'utiliser que sur un appareil qu'on réinitialise complètement. Voir UPDATE_GUIDE.md.
- Au démarrage, l'ESP32 crée un point d'accès WiFi
-
Accès interface web
http://poolcontroller.localsi réseau wifi configuré, sinon se connecter au réseau AP PoolControllerAP et utiliser l'adresse http://192.168.4.1- Onglets disponibles:
- Tableau de bord : Visualisation temps réel pH/ORP/Température
- Filtration : Contrôle et programmation de la pompe de filtration
- Éclairage : Contrôle et programmation de l'éclairage
- Température : Historique et calibration de la sonde de température
- pH : Mesure, historique, calibration et réglages dosage pH
- ORP : Mesure, historique, calibration et réglages dosage chlore
- Produits : Suivi de la consommation des produits chimiques
- Paramètres : WiFi, MQTT, heure, sécurité, régulation, système
Calibration Capteurs
Calibration pH (Atlas Scientific EZO pH)
La calibration est gérée en interne par le module EZO (commandes I²C Cal,...), mémorisée dans le module lui-même — il n'y a ni offset/pente stockés côté ESP32, ni EEPROM, ni librairie analogique. Elle se déclenche depuis l'interface web, onglet pH → carte Calibration (deux sous-blocs indépendants). Le module EZO pH accepte les points milieu (pH 7.0), bas (pH 4.0) et, optionnellement, haut. La régulation automatique du pH est inhibée tant que les 2 points (mid + low) ne sont pas calibrés.
Calibration via l'interface web :
- Aller dans l'onglet pH → carte Calibration
- Rincer la sonde à l'eau distillée, la plonger dans la solution tampon pH 7.00, attendre stabilisation (~1 min)
- Cliquer sur « Calibrer le point 7.0 » (sous-bloc Point milieu)
- Rincer la sonde, la plonger dans la solution pH 4.00, attendre stabilisation
- Cliquer sur « Calibrer le point 4.0 » (sous-bloc Point bas)
Compensation de température : la température de l'eau mesurée par la DS18B20 est transmise au module EZO pour compenser la mesure de pH.
Détails du workflow et des cas d'erreur : voir docs/features/page-ph.md.
Calibration ORP (Atlas Scientific EZO ORP)
La calibration ORP est une commande interne au module EZO (Cal,<référence>, un seul point), déclenchée depuis l'interface web, onglet ORP → carte Calibration. Comme pour le pH, aucun offset/date n'est calculé ni stocké côté ESP32. La régulation automatique de l'ORP est inhibée tant que le module n'est pas calibré.
Calibration via l'interface web :
- Aller dans l'onglet ORP → carte Calibration
- Rincer la sonde à l'eau déminéralisée, la plonger dans la solution de référence ORP
- Saisir la valeur de référence de la solution dans le champ (ex : 470 mV ; plage acceptée 0–1000 mV)
- Attendre stabilisation (~1 min), puis cliquer sur « Calibrer »
Détails du workflow et des cas d'erreur : voir docs/features/page-orp.md.
Tuning de la régulation (Avancé)
La régulation est temporisée : la mesure d'entrée est la valeur lissée (médiane + EMA), et le dosage est bloqué tant que le filtre de mesure n'est pas amorcé/prêt. Kd = 0 est impératif sur les deux chimies (pas de dérivée : elle n'amplifierait que le bruit résiduel du filtre).
Depuis la v2.26.0, la boucle pH est une PI : un proportionnel pur sous charge permanente (dégazage du CO₂) ne peut structurellement pas rejoindre sa consigne — il se stabilise sur un écart résiduel. La boucle ORP reste proportionnelle pure (Ki = 0). Voir applyRegulationSpeed(), ADR-0016 et ADR-0052.
Coefficients par vitesse (sélectionnable dans Paramètres → Régulation) :
| Vitesse | Kp pH | Ti pH | Kp ORP |
|---|---|---|---|
| Lente | 4.0 | 8 h | 0.15 |
| Normale | 8.0 | 6 h | 0.30 |
| Rapide | 12.0 | 4 h | 0.50 |
Côté pH,
Ki = Kp / Tiet le plafond d'anti-windup se dérive de l'autorité posée pour le terme intégral (6,0 mL/min) :integralMax = U × Ti / Kp, soit 43 200 / 16 200 / 7 200 pH·s. Il varie donc avec la vitesse, comme Kp. L'intégrale n'est jamais persistée : un redémarrage repart de zéro.
Protection anti-cycling (prolonge durée de vie des pompes) :
- Injection minimum : 30 secondes par cycle
- Pause de mélange : 15 min (pH) / 20 min (ORP) après chaque injection (
kPhMixingDelayMs/kOrpMixingDelayMs) - Seuils de démarrage : pH ±0.05 / ORP ±15 mV
- Seuils d'arrêt : pH ±0.01 / ORP ±2 mV
- Maximum : 20 cycles par jour
🏠 Intégration Home Assistant
Auto-Discovery
Le contrôleur publie automatiquement sa configuration MQTT pour Home Assistant :
| Type | Entité | Description |
|---|---|---|
| Sensor | Température | Température de l'eau (°C) |
| Sensor | pH | Valeur pH |
| Sensor | ORP | Valeur ORP (mV) |
| Binary Sensor | Filtration active | État de la pompe de filtration (ON/OFF) |
| Binary Sensor | Dosage pH actif | Pompe doseuse pH en cours d'injection |
| Binary Sensor | Dosage chlore actif | Pompe doseuse ORP en cours d'injection |
| Binary Sensor | Limite journalière pH | Limite de dosage pH atteinte |
| Binary Sensor | Limite journalière chlore | Limite de dosage ORP atteinte |
| Binary Sensor | Statut contrôleur | Disponibilité du contrôleur (online/offline) |
| Select | Mode filtration | Sélection du mode (auto / manual / force / off) |
| Switch | Filtration ON/OFF | Forçage marche/arrêt de la filtration |
| Switch | Éclairage ON/OFF | Contrôle de l'éclairage |
| Number | Consigne pH | Valeur cible pH (7.2 – 7.5, pas 0.1 — bornes resserrées en v2.25.0, ADR-0048) |
| Number | Consigne ORP | Valeur cible ORP en mV (400 – 900, pas 10) |
Exemple Automation
automation:
- alias: "Alerte pH Anormal"
trigger:
- platform: numeric_state
entity_id: sensor.piscine_ph
above: 7.6
for: "00:15:00"
action:
- service: notify.mobile_app
data:
title: "Piscine - pH Élevé"
message: "pH: {{ states('sensor.piscine_ph') }}"
- alias: "Notification Limite Injection"
trigger:
- platform: mqtt
topic: "pool/sensors/alerts"
condition:
- condition: template
value_template: "{{ 'limit' in trigger.payload_json.type }}"
action:
- service: notify.mobile_app
data:
title: "Piscine - Alerte Sécurité"
message: "{{ trigger.payload_json.message }}"🔐 Sécurité
Factory Reset (bouton physique)
En cas d'oubli du mot de passe ou de nécessité de réinitialisation complète, utiliser le bouton factory reset situé à côté de l'ESP32 sur la carte électronique.
Procédure de réinitialisation:
Le factory reset se déclenche pendant le fonctionnement normal de l'ESP32 (pas besoin de couper l'alimentation) :
- Appuyer et maintenir le bouton factory reset
- Le log série affiche :
Bouton reset enfoncé - maintenir 10s pour factory reset
- Le log série affiche :
- Maintenir 10 secondes
- Relâcher avant 10s annule la réinitialisation (log :
factory reset annulé)
- Relâcher avant 10s annule la réinitialisation (log :
- L'ESP32 redémarre automatiquement
- Suivre les instructions données plus haut dans la partie "1ère connexion"
Ce qui est réinitialisé (partition NVS effacée entièrement) :
- ✅ Mot de passe admin (retour à
admin) - ✅ Token API régénéré
- ✅ Credentials WiFi supprimés (retour en mode AP)
- ✅ Configuration MQTT effacée
- ✅ Calibrations des sondes (pH, ORP) effacées
Ce qui N'EST PAS effacé :
- ✅ Mot de passe WiFi AP — préservé intentionnellement (l'étiquette sur le boîtier reste valide)
- ✅ Fichiers JSON sur LittleFS (consignes, limites, config) — préservés
- ✅ Historique des mesures (partition séparée) — préservé
📈 Changelog
Voir CHANGELOG.md pour l'historique complet des versions.
📁 Fichiers et Scripts
Scripts de Build et Déploiement
-
deploy.sh- Script de déploiement principal./deploy.sh all- Compile et upload USB firmware + filesystem (NVS préservée)./deploy.sh factory- Efface toute la flash, compile et upload firmware + filesystem (génère un nouveau mot de passe AP)./deploy.sh firmware- Compile et upload USB firmware uniquement./deploy.sh fs- Compile et upload USB filesystem uniquement./deploy.sh ota-all- Compile et envoie OTA (WiFi) firmware + filesystem./deploy.sh ota-firmware- Compile et envoie OTA firmware uniquement./deploy.sh ota-fs- Compile et envoie OTA filesystem uniquement- Les modes USB détectent le port série (surcharge :
PORT=/dev/cu.usbserial-10 ./deploy.sh all) et enchaînent le moniteur série —NO_MONITOR=1pour s'en passer - L'environnement PlatformIO utilisé est celui de
PIO_ENV(défaut et seule valeur valide :esp32dev_core3)
-
build_fs.sh- Construction du filesystem LittleFS- Minifie automatiquement HTML/CSS/JS
- Construit LittleFS avec la bonne taille (512 KB — 524 288 octets, layout v5)
- Utilise
data-build/comme source (généré par minify.js)
-
minify.js- Minification des fichiers web- Utilise des outils professionnels standards de l'industrie:
- html-minifier-terser - Minification HTML
- Terser - Minification JavaScript
- CleanCSS - Minification CSS
- Source:
data/→ Destination:data-build/ - Exécuté automatiquement par
build_fs.sh
- Utilise des outils professionnels standards de l'industrie:
Configuration
-
platformio.ini- Configuration PlatformIO- Définit les dépendances, ports, partitions
default_envs = esp32dev_core3(core Arduino 3.x / IDF 5), seul environnement matériel ;native= tests unitaires- Port série: détecté par
deploy.sh(surchargePORT=...)
-
partitions.csv- Table de partitions ESP32 8 Mo (layout v5, ADR-0068)- 2× slots OTA app0/app1 (3648 KB chacun) — occupation ≈ 49 %
- LittleFS/spiffs (512 KB) pour l'interface web
- History (256 KB) partition séparée préservée lors des mises à jour à table constante
- Coredump (64 KB) ; la table couvre la flash en entier, de 0x0 à 0x800000
Documentation
docs/API.md- Documentation de l'API RESTdocs/MQTT.md- Documentation des topics MQTTdocs/BUILD.md- Instructions de compilation détailléesdocs/UPDATE_GUIDE.md- Guide de mise à jour (USB, WiFi OTA, GitHub)README.md- Ce fichier
Dossiers
src/- Code source C++ du firmwaredata/- Fichiers web sources (HTML/CSS/JS) — versionnésdata-build/- Fichiers web minifiés — générés automatiquement (ignoré par git)kicad/- Sources KiCad du PCB (schéma, routage, BOM.xlsx) — versionnées ; les gerbers et le BOM.csv en sont dérivés et ne le sont passcripts/- Génération des livrables de release (PDF, gerbers)docs/- Documentation technique complémentairescreenshots/- Captures d'écran de l'interfacetools/- Scripts utilitaires (couverture de tests, déploiement)specs/- Demandes et décisions :todo/à faire,doing/en cours,done/terminées avec leurs notes techniques. La source de vérité du projet.claude/- Agents spécialisés, skills et commandes de releasetest/- Tests natifs (logique pure, exécutés hors matériel)logo/- Fichiers logo du projet
📄 Licence
MIT License - Voir fichier LICENSE
⚠️ Avertissement
Ce projet est fourni "tel quel" sans garantie. L'utilisation de produits chimiques et d'équipements électriques près de l'eau présente des risques. L'utilisateur est seul responsable de:
- La conformité aux réglementations locales
- La sécurité de l'installation
- Le bon dosage des produits chimiques
- La surveillance du système
En cas de doute, consulter un professionnel.
Parts
93| Qty | Value | Footprint | References |
|---|---|---|---|
| 19 | 100nF | Capacitor_THT:C_Disc_D3.8mm_W2.6mm_P2.50mm | C1, C2, C3, C10, C11, C12, C14, C16, C18, C20, C22, C24, C25, C26, C27, C29 +3 |
| 12 | 10 µF | Capacitor_THT:C_Disc_D6.0mm_W4.4mm_P5.00mm | C4, C5, C8, C9, C13, C17, C19, C21, C23, C28, C31, C32 |
| 9 | 10KΩ | Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal | R5, R6, R8, R10, R12, R14, R16, R17, R18 |
| 6 | DG301-5.0-02P-12-00A | TerminalBlock_Altech:Altech_AK100_1x02_P5.00mm | J1, J2, J5, J8, J9, J14 |
| 5 | 100Ω | Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal | R3, R4, R7, R13, R15 |
| 5 | 1N5819 | Diode_THT:D_DO-15_P10.16mm_Horizontal | D2, D3, D4, D6, D7 |
| 5 | 4.7KΩ | Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal | R1, R2, R9, R19, R20 |
| 5 | IRLZ44N | Package_TO_SOT_THT:TO-220-3_Vertical | Q1, Q2, Q4, Q6, Q7 |
| 4 | Conn_01x03 | Connector_PinSocket_2.54mm:PinSocket_1x03_P2.54mm_Vertical | J3, J6, J12, J13 |
| 4 | MountingHole | MountingHole:MountingHole_3.2mm_M3 | H1, H2, H3, H4 |
| 2 | B6252HB-NPP3G-50 | Connector_Coaxial:BNC_Amphenol_B6252HB-NPP3G-50_Horizontal | J7, J10 |
| 2 | BBPY00321611601Y00 | Resistor_SMD:R_1206_3216Metric | FB1, FB2 |
| 1 | 100KΩ | Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal | R11 |
| 1 | 1N5245B | Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal | D1 |
| 1 | 470µF | Capacitor_THT:CP_Radial_D10.0mm_P5.00mm | C15 |
| 1 | ADuM1250 | Package_DIP:DIP-8_W7.62mm | U1 |
| 1 | B3F-1000 | Button_Switch_THT:SW_PUSH_6mm | SW1 |
| 1 | Conn_01x06_Socket | Connector_PinSocket_2.54mm:PinSocket_1x06_P2.54mm_Vertical | J11 |
| 1 | D24V10F3 | MyLibrary:Pololu_D24V10F3 | U3 |
| 1 | DG301-5.0-03P-12-00AH | Connector_JST:JST_XH_B3B-XH-A_1x03_P2.50mm_Vertical | J4 |
| 1 | DS18B20 | Package_TO_SOT_THT:TO-92_Inline | U6 |
| 1 | ESP32-DevKitC | Espressif:ESP32-DevKitC | U2 |
| 1 | FX200-16 | Fuse:Fuse_Bourns_MF-RHT200 | F1 |
| 1 | IRF4905 | Package_TO_SOT_THT:TO-220-3_Vertical | Q5 |
| 1 | OKI-78SR-5_1.5-W36-C | Converter_DCDC:Converter_DCDC_Murata_OKI-78SR_Vertical | U4 |
| 1 | P6KE13A | Diode_THT:D_DO-15_P10.16mm_Horizontal | D5 |
| 1 | TMA-0505S | Converter_DCDC:Converter_DCDC_TRACO_TMA-05xxS_12xxS_Single_THT | U5 |
Questions
How big is the Esp32-pool controller PCB?
It measures 119.4 × 119.4 mm and has 2 copper layers, 1.6 mm thick.
What parts does the Esp32-pool controller use?
93 parts, built around the ESP32-DEVKITC-VE, DS18B20, ADUM1250AR and DG301-5.0-02P-12-00A(H). The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
Where can I download the Esp32-pool controller KiCad files?
From the niko34/esp32-pool-controller repository on GitHub, at the commit this page was made from: the board is kicad/esp32-pool-controller/esp32-pool-controller.kicad_pcb and its schematic kicad/esp32-pool-controller/esp32-pool-controller.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Can I use the Esp32-pool controller design in my own project?
Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).
Similar boards
- 4 layers130 × 90 mm

- 2 layers100 × 75 mm

Cloudline controller
seesharp15/cloudline-fan-controller
The controller on a printed circuit board instead of perfboard:
28 parts - 2 layers72 × 66 mm

- 2 layers80 × 80 mm

Campv2
notazizelse/camp
CAMP v2: an all-through-hole CubeSat-style payload board I designed for my Technocamp 2026 circuitry class (200 students)
23 parts - 2 layers52.8 × 25.5 mm

Boost dc converter tps61088rhlr
voloviq/boost_dc_converter_tps61088rhlr
Development Board of TPS61088 Boost DC-DC Converter
25 parts - 2 layers129.8 × 92.5 mm

Signalization by fireplace
RomLab/pcb-system-for-underfloor-heating-v2.0
PCB for underfloor heating system
204 parts1 - 2 layers190 × 75 mm

Q17-TURBO
stefaweb/Q17-Amplifier
The Q17 is an error correction HIFI amplifier based on the QUAD405 current dumping principle.
109 parts25GPL-3.0 - 2 layers101.3 × 102.4 mm

Opamp front
prydin/opamp-frontend-class-ab
The result is a fast amplifier (>80V/us slew rate) with low distortion (0.00045% meadured @ 1kHz/1W/8ohm resistive load). It's undergone some preliminary measurements and looks quite promising.
93 parts4