180 lines
7.3 KiB
Markdown
180 lines
7.3 KiB
Markdown
# 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 d’inté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). |