Files
Dcc-Prog/DCC_NMRA_GUIDE.md
2026-08-13 12:10:59 +02:00

200 lines
6.2 KiB
Markdown

# 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