Files
Mqtt-Dcc/README.md
T
2026-08-05 11:51:54 +02:00

180 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MQTT-DCC ESP32 PlatformIO Project
Ce projet cible un ESP32 sous PlatformIO et permet de :
- se connecter à un réseau Wi-Fi
- se connecter à un broker MQTT
- recevoir des commandes d'accessoires DCC au format JSON sur le topic `dcc/command`
- générer un paquet DCC et le transmettre sur une alimenation à base de LM18200 via sortie GPIO
- publier des retours d'état sur le topic `dcc/status`
## Fonctionnalités principales
- Configuration Wi-Fi via un portail web AP si la connexion Wi-Fi échoue
- Stockage des identifiants Wi-Fi dans la mémoire non volatile (NVS)
- Stockage des identifiants MQTT et nom d'hôte dans la mémoire non volatile (NVS)
- Séparation du code Wi-Fi et MQTT dans des modules dédiés
- Génération de paquets d'accessoire DCC
## Configuration
1. Ouvrir `include/config.h`.
2. Vérifier ou modifier les paramètres MQTT :
- `MQTT_SERVER`
- `MQTT_PORT`
- `MQTT_TOPIC_CMD`
- `MQTT_TOPIC_STATUS`
- `MQTT_TOPIC_RESPONSE`
3. Si nécessaire, ajuster les pins DCC :
- `DCC_DIR_PIN`
- `DCC_PWM_PIN`
4. Le SSID et le mot de passe Wi-Fi sont stockés dans la mémoire non volatile et sont configurables via le portail AP.
> Ce projet utilise désormais la librairie `locoduino/DCCpp` pour générer un vrai signal DCC NMRA compatible avec un driver LM18200.
> `DCC_DIR_PIN` est utilisé pour le signal DCC et `DCC_PWM_PIN` pour l'activation de l'interface.
- Au démarrage, l'ESP tente de se connecter au Wi-Fi avec les identifiants enregistrés.
- Si l'accès Wi-Fi n'est pas disponible, il démarre un point d'accès nommé `DCC_Config`. Et permet via un smartphone de définir les SSID / Key à l'aide d'un portail captif
- Ouvrir le navigateur à l'adresse IP affichée dans la console série pour configurer le SSID et le mot de passe.
- Après enregistrement, l'ESP redémarre et tente de se reconnecter au Wi-Fi.
## Format de commande MQTT
Publier un message JSON sur le topic `dcc/command` :
```json
{
"id": "1234",
"address": 123,
"state": true
}
```
- `id` : identifiant éventuel pour corrélation
- `address` : adresse de l'accessoire
- `state` : `true` pour activer / `false` pour désactiver
## Exemple Node-RED
Dans Node-RED, utilisez un noeud `inject` puis un noeud `mqtt out` :
1. Configurez un noeud `mqtt broker` avec l'adresse de votre broker MQTT.
2. Ajoutez un noeud `inject` et définissez la charge utile (`payload`) avec le JSON ci-dessus.
3. Mettez le `topic` du noeud `mqtt out` à `dcc/command`.
4. Connectez le noeud `inject` au noeud `mqtt out`.
Exemple de flux simple :
```json
[{"id":"inject_dcc","type":"inject","z":"flow","name":"Commande DCC","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"dcc/command","payload":"{\"id\":\"1234\",\"address\":123,\"state\":true}","payloadType":"json","wires":[["mqtt_out"]]},{"id":"mqtt_out","type":"mqtt out","z":"flow","name":"Envoi MQTT","topic":"dcc/command","qos":"0","retain":"false","broker":"mqtt_broker"}]
```
Cela permet dintégrer facilement le projet dans un système global basé sur Node-RED.
## Déploiement
Compiler et téléverser avec PlatformIO :
```bash
pio run -e esp32dev --target upload
```
## Structure du projet
- `src/main.cpp` : programme principal
- `src/WifiManager.cpp` : gestion du Wi-Fi et du portail de configuration
- `src/MqttManager.cpp` : gestion de la connexion MQTT
- `lib/Dcc/` : génération de paquets DCC
- `include/config.h` : paramètres de configuration
## Améliorations possibles
- ajout d'un vrai générateur NMRA DCC avec horloge de sortie
- interface web de configuration plus complète
- gestion OTA
- publication d'un message de statut plus riche
# Annexe - Le DCC
Le pilotage des accessoires en DCC classique (NMRA) et via l'écosystème DCC-EX repose sur le même principe fondamental : l'envoi de paquets de données numériques sur les rails (ou un bus dédié) à destination de décodeurs d'accessoires (aiguillages, signaux, relais).
Cependant, la manière de spécifier l'Adresse et la Valeur (Commande/État) diffère légèrement selon qu'il s'agit du protocole bas niveau sur les rails ou des commandes textuelles envoyées à une centrale DCC-EX.
## Le Pilotage DCC Classique
Dans le standard NMRA (S-9.2.1), les accessoires sont pilotés via des paquets d'accessoires de base (Basic Accessory Decoder Packet).
### L'Adresse
Contrairement aux locomotives qui ont une adresse simple (1 à 10239), l'adressage des accessoires en DCC est historiquement découpé :
- **L'Adresse de Décodeur** (Decoder Address) : Un décodeur physique d'accessoires (ex: une carte à 4 sorties) possède une adresse principale (1 à 511).
- **La Sortie / Pair** (Sub-address / Output) : Chaque décodeur gère généralement 4 sorties (paires d'adresses).
- **L'Adresse Unitaire** (Linear / Output Address) : Pour simplifier, les centrales et logiciels traduisent cela en une adresse linéaire continue (1, 2, 3, 4, 5, 6...).
On a :
```
Adresse Linéaire = ((AdresseDécodeur - 1) * 4) + Numéro de Sortie
```
### La Valeur (Position et État)
Un paquet d'accessoire DCC ne transmet pas une vitesse (0-128) comme une locomotive, mais un bit de direction et un bit d'activation :
- Direction / Position (1 bit) :
- 1 = Dévie / Closed / Red / Active (ex: Aiguillage en déviation)
- 0 = Droit / Thrown / Green / Inactive (ex: Aiguillage en voie directe)
- Power / Enable (1 bit) :
- 1 = Bobine sous tension (Commande envoyée)
- 0 = Bobine coupée (Relâchement de l'impulsion pour éviter de brûler le moteur solénoïde)
## Le Pilotage avec DCC-EX
DCC-EX est un système open-source pour Arduino/ESP32. Il simplifie la complexité des octets NMRA en proposant une API texte très simple via port série, Wi-Fi ou Bluetooth.
Dans DCC-EX, les accessoires sont pilotés selon deux approches : **Directe** (numéro de pin ou paquet DCC) ou **Virtuelle** (Turnouts/Routes).
### Méthode 1 : Commande Directe d'Aiguillage / Accessoire DCC
Pour envoyer une commande DCC d'accessoire directement sur les rails à une adresse linéaire
```
a <ADRESSE> <SUB_ADDR> <ACTIF>
```
ou plus communément pour un aiguillage (Turnout) :
```
<T <ADRESSE> <VALEUR>>
```
Paramètres :
- **ADRESSE** : L'adresse linéaire de l'accessoire (ex: 1 à 2048).
- **VALEUR / ÉTAT** :
- 1 : Thrown (Dévié / Actif)
- 0 : Closed (Droit / Inactif)
- C : Toggle / Inverser la position actuelle.
Exemple :
- <T 1 12> -> Met l'aiguillage DCC N°12 en position Déviée (Thrown).
- <T 0 12> -> Met l'aiguillage DCC N°12 en position Directe (Closed).
### Méthode 2 : Définition des "Turnouts" (Accessoires déclarés dans DCC-EX)
DCC-EX permet d'associer des adresses virtuels ou des broches physiques (Servomoteurs, Relais sur Arduino) à des objets "Turnout".
Dans le fichier de configuration myAutomations.cpp ou config.h, vous définissez vos accessoires :
```cpp
// Aiguillage sur décodeur DCC à l'adresse 5
Turnout::createDCC(5, "Aiguillage Gare");
// Aiguillage piloté directement par un Servomoteur connecté sur la Pin 9 de l'Arduino
Turnout::createSERVO(6, 9, 100, 400, 1, "Aiguillage Servo");
```
Une fois définis, ils se pilotent via le protocole API texte :
```
<T <ID> <COMMANDE>>
```
- Exemple : <T 5 T> (Mettre le Turnout 5 en Thrown).
- Exemple : <T 5 C> (Mettre le Turnout 5 en Closed).