Files
2026-08-05 11:51:54 +02:00

7.3 KiB
Raw Permalink Blame History

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 :

{
  "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 :

[{"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 :

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 :

// 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).