# Implémentation DCC NMRA - Guide Technique ## Vue d'ensemble Ce programmateur implémente le protocole DCC (Digital Command Control) selon la norme NMRA S-9.2. Il permet de programmer les décodeurs des locomotives et accessoires via une interface de commande série. ## Architecture DCC ### Norme NMRA S-9.2 Le protocole DCC est un standard d'électrotechnique pour les modèles ferroviaires. Les principales caractéristiques sont : - **Fréquence des bits** : - Bit "1" : 116 µs (durée minimale) - période totale 232 µs - Bit "0" : 232 µs (durée minimale) - période totale 464 µs - **Format des paquets** : ``` Préambule(14x1) + 0 + Adresse + 1 + [Données]... + 1 + Checksum + 0 ``` - **Signe du signal** : Alterne chaque moitié de bit pour garantir la symétrie ### Modes de programmation #### Mode CV Byte (Lecture/Écriture complète) - Opération la plus courante - Adresse programmation : `0x7C` - Format : ``` [0x7C] [Commande] [CV Hi] [CV Lo] [Valeur] ``` - Commandes : - `0x64` : Lire CV - `0x74` : Écrire CV #### Détection ACK (Accusé de Réception) Le décodeur répond à une commande de programmation en augmentant sa consommation de courant pendant 6 ms, ce qui produit une augmentation mesurable sur le capteur de courant. - Seuil ACK configuré : 60 mA de différence - Permet de détecter si le décodeur a bien reçu et exécuté la commande ## Architecture Matérielle ### Schéma simplifié ``` Arduino Nano ├── Pin 9 (DIR1) → Pont en H LM18220 (IN1) ├── Pin 10 (DIR2) → Pont en H LM18220 (IN2) ├── Pin 11 (PWM) → Pont en H LM18220 (Enable) └── Pin A0 → Capteur de courant (ACS712-5A) ↓ Rail de programmation DCC ↓ Décodeur à programmer ``` ### Pont en H LM18220 - Génère le signal DCC symétrique - Amplitude contrôlée par PWM (pin 11) - Direction contrôlée par DIR1/DIR2 (pins 9-10) ### Capteur de courant ACS712-5A - Mesure la consommation du décodeur - Sortie : 0V à 5V (2.5V = 0A) - Sensibilité : 185 mV/A ## Fonctionnement ### Flux de programmation ``` 1. Lecture du courant de base (sans signal) 2. Activation du signal DCC 3. Envoi du paquet 5 fois (assure la réception) 4. Attendre ~10ms la réaction du décodeur 5. Mesurer le courant pour détecter l'ACK 6. Désactiver le signal DCC 7. Afficher le résultat ``` ### Chronogramme d'un bit DCC Pour un bit "1" (116 µs + 116 µs) : ``` 116µs 116µs ┌─────────┐ ┌─────────┐ ───┤ └────────┤ └──── Signal+ Signal- ``` Pour un bit "0" (232 µs + 232 µs) : ``` 232µs 232µs ┌──────────────┐ ┌──────────────┐ ───┤ └────────┤ └──── Signal+ Signal- ``` ## CVs Importants | CV | Description | Plage | Par défaut | |----|-------------|-------|-----------| | 1 | Adresse courte | 1-127 | 3 | | 7 | Version décodeur | 0-255 | Variable | | 8 | Fabricant | 0-255 | Variable | | 17-18 | Adresse longue | 128-10239 | 0 | ## Communication Série **Port série** : - Débit : 9600 baud - Format : 8N1 (8 bits, pas de parité, 1 bit de stop) **Commandes disponibles** : ``` READ_CV 1 → Lire CV 1 WRITE_CV 1 42 → Écrire 42 dans CV 1 SET_ADDR 42 → Configurer adresse 42 TEST_DCC → Test du signal DCC CURRENT → Mesurer courant instantané INFO → Infos système HELP → Aide ``` ## Détails d'Implémentation ### Génération du signal (sendDCCBit) - Utilise `delayMicroseconds()` pour précision (± quelques µs) - Alterne DIR1/DIR2 pour la symétrie - Pulse PWM à 100% pour amplitude maximale ### Envoi de paquet (sendDCCPacket) ```cpp void sendDCCPacket(uint8_t *packet, uint8_t length) { // 14 bits de préambule (tout à 1) for (int i = 0; i < 14; i++) sendDCCBit(1); // Bit de démarrage (0) sendDCCBit(0); // Données avec bits de séparation (1) entre chaque for (int i = 0; i < length-1; i++) { sendDCCByte(packet[i], 1); } // Dernier octet et bit de fin (0) sendDCCByte(packet[length-1], 0); } ``` ### Lecture/Écriture CV (Mode Byte) Les CV sont codées sur 10 bits en NMRA : ``` CV 1-256 : Octet bas = CV-1, Octet haut = 0x00 CV 257-512 : Octet bas = CV-257, Octet haut = 0x04 CV 513-768 : Octet bas = CV-513, Octet haut = 0x08 ... ``` Formule de codage : ```cpp cv_addr = cv - 1; octet_haut = 0xE4 | ((cv_addr >> 8) & 0x03); octet_bas = cv_addr & 0xFF; ``` ## Limitations et Considérations 1. **Timing précis** : Le timing DCC est critique (±10%). Les `delayMicroseconds()` sont généralement précis à ±4µs sur Arduino Nano. 2. **Détection ACK simple** : Le système détecte uniquement la présence d'ACK, pas sa durée. Un vrai décodeur DCC ferait une réponse plus complexe. 3. **Mémoire CV simulée** : Pour le test, une mémoire locale simule les CVs du décodeur. Un vrai décodeur implémenterait la mémoire EEPROM. 4. **Pas de répéteur** : Le système envoie chaque paquet 5 fois pour assurer la réception (NMRA recommande 5-20 fois). 5. **Alimentation** : Le pont en H LM18220 doit être correctement alimenté (12-18V) et délivrer assez de courant pour le décodeur et le capteur. ## Extension Future Pour une implémentation complète, on pourrait ajouter : - **Mode CV Bit** : Programmation bit par bit (utile pour CV8 Fabricant) - **Mode Adresse Seule** : Configuration rapide de l'adresse - **Lecture de réponses décorées** : Analyser les réponses DCC du décodeur - **Interface graphique** : Via terminal Web ou application - **Programmation par service track vs. main track** : Deux modes de programmation - **Gestion d'erreurs avancée** : Détection de courts-circuits, décodeur absent, etc. - **Logs détaillés** : Enregistrement de tous les paquets envoyés/reçus - **Calibration automatique** : Ajustement des timings en fonction du CPU ## Références - NMRA S-9.2 : DCC Electrical Standards - https://www.nmra.org/dcc - Arduino Nano Datasheet - LM18220 H-Bridge Datasheet - ACS712 Current Sensor Datasheet