From 50437c6c19c64b56f32f89f95bbb907bfc428c78 Mon Sep 17 00:00:00 2001 From: Serge NOEL Date: Thu, 13 Aug 2026 12:04:15 +0200 Subject: [PATCH] =?UTF-8?q?R=C3=A9alisation=20code=20initial?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 41 +++++++ README.fr.md | 2 +- platformio.ini | 20 ++++ src/main.cpp | 287 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 platformio.ini create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..69488d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Platformio +.pio/ +.vscode/ +build/ +.env +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +venv/ +ENV/ + +# IDE +.DS_Store +.AppleDouble +.LSOverride +*.swp +*.swo +*~ +.idea/ + +# Compilés +*.o +*.a +*.so +*.so.* +*.dylib +*.exe +*.bin +*.hex + +# Docs +.vscode-server/ diff --git a/README.fr.md b/README.fr.md index 0cdd49f..5b58c64 100644 --- a/README.fr.md +++ b/README.fr.md @@ -10,7 +10,7 @@ Coté logiciel, il utilise platform.io, et est très simple, il permet uniquemen - Arduino Nano avec câble USB - Pont en H LM18220 -- Module de mesure de courant (ex : ACS712 ou INA219) +- Module de mesure de courant (ex : ACS712 ) - Rails DCC pour test - Décodeurs à programmer - Platform.io (CLI ou extension VS Code) diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..7a60f84 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,20 @@ +[env:nanoatmega328] +platform = atmelavr +board = nanoatmega328 +framework = arduino +monitor_speed = 9600 +upload_speed = 115200 + +; Dépendances +lib_deps = + +; Options de compilation +build_flags = + -Wall + -Wextra + +; Définitions du moniteur série +monitor_port = /dev/ttyUSB0 +monitor_filters = + log2file + colorize diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..f4af022 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,287 @@ +#include + +// ============================================================================ +// Programmateur DCC pour Arduino Nano +// Décodeurs de locomotive et accessoires +// ============================================================================ + +// Configuration des broches +const uint8_t PIN_H_BRIDGE_DIR1 = 9; // IN1 du pont en H +const uint8_t PIN_H_BRIDGE_DIR2 = 10; // IN2 du pont en H +const uint8_t PIN_H_BRIDGE_PWM = 11; // PWM du pont en H +const uint8_t PIN_CURRENT_SENSOR = A0; // Capteur de courant + +// Configuration DCC +const uint16_t DCC_BIT_TIME = 116; // Microsecondes (±10%) +const uint8_t DCC_PREAMBLE = 16; // Nombre de 1 avant adresse +const uint8_t MAX_ATTEMPTS = 5; // Tentatives de programmation + +// Variables de programmation +uint8_t current_address = 0; +uint8_t programming_mode = 0; // 0=normal, 1=programmation +bool device_responding = false; + +// ============================================================================ +// Fonction d'initialisation +// ============================================================================ +void setup() { + // Initialiser les broches + pinMode(PIN_H_BRIDGE_DIR1, OUTPUT); + pinMode(PIN_H_BRIDGE_DIR2, OUTPUT); + pinMode(PIN_H_BRIDGE_PWM, OUTPUT); + pinMode(PIN_CURRENT_SENSOR, INPUT); + + // Arrêter le pont en H + digitalWrite(PIN_H_BRIDGE_DIR1, LOW); + digitalWrite(PIN_H_BRIDGE_DIR2, LOW); + analogWrite(PIN_H_BRIDGE_PWM, 0); + + // Initialiser la communication série + Serial.begin(9600); + + delay(1000); + Serial.println("======================================"); + Serial.println("Programmateur DCC - Arduino Nano"); + Serial.println("======================================"); + Serial.println("Pret pour la programmation"); + Serial.println(""); + Serial.println("Commandes disponibles:"); + Serial.println(" HELP - Affiche l'aide"); + Serial.println(" INFO - Informations du système"); + Serial.println(" READ_CV n - Lire le CV n"); + Serial.println(" WRITE_CV n v - Ecrire v dans CV n"); + Serial.println(" SET_ADDR a - Configurer l'adresse a"); + Serial.println(" CURRENT - Mesurer le courant"); + Serial.println(""); +} + +// ============================================================================ +// Fonction de boucle principale +// ============================================================================ +void loop() { + if (Serial.available()) { + String command = Serial.readStringUntil('\n'); + command.trim(); + + if (command.length() > 0) { + processCommand(command); + } + } + + // Lecture périodique du courant en mode programmation + if (programming_mode) { + measureCurrent(); + } + + delay(10); +} + +// ============================================================================ +// Traitement des commandes série +// ============================================================================ +void processCommand(String cmd) { + Serial.print("> "); + Serial.println(cmd); + + if (cmd == "HELP") { + printHelp(); + } + else if (cmd == "INFO") { + printInfo(); + } + else if (cmd == "CURRENT") { + measureCurrentAndPrint(); + } + else if (cmd.startsWith("READ_CV ")) { + uint16_t cv = cmd.substring(8).toInt(); + readCV(cv); + } + else if (cmd.startsWith("WRITE_CV ")) { + int space = cmd.indexOf(' ', 9); + uint16_t cv = cmd.substring(9, space).toInt(); + uint8_t value = cmd.substring(space + 1).toInt(); + writeCV(cv, value); + } + else if (cmd.startsWith("SET_ADDR ")) { + uint16_t addr = cmd.substring(9).toInt(); + setAddress(addr); + } + else { + Serial.println("ERREUR: Commande inconnue. Tapez 'HELP' pour l'aide."); + } + + Serial.println(""); +} + +// ============================================================================ +// Fonctions d'aide +// ============================================================================ +void printHelp() { + Serial.println("=== Aide du Programmateur DCC ==="); + Serial.println(""); + Serial.println("HELP : Affiche cette aide"); + Serial.println("INFO : Affiche les informations du système"); + Serial.println("READ_CV : Lit la valeur du CV "); + Serial.println(" Exemple: READ_CV 1"); + Serial.println("WRITE_CV : Ecrit dans CV "); + Serial.println(" Exemple: WRITE_CV 1 3"); + Serial.println("SET_ADDR : Configure l'adresse courte (1-127)"); + Serial.println(" Exemple: SET_ADDR 42"); + Serial.println("CURRENT : Affiche le courant mesuré en mA"); + Serial.println(""); + Serial.println("Notes:"); + Serial.println("- Les CVs vont de 1 à 1024"); + Serial.println("- Les valeurs vont de 0 à 255"); + Serial.println("- Placer le décodeur seul sur les rails de programmation"); + Serial.println("- Attendre la confirmation après chaque opération"); +} + +void printInfo() { + Serial.println("=== Informations du Système ==="); + Serial.println("Plate-forme: Arduino Nano ATmega328"); + Serial.println("Vitesse série: 9600 baud"); + Serial.println("Pin H-Bridge DIR1 (IN1): " + String(PIN_H_BRIDGE_DIR1)); + Serial.println("Pin H-Bridge DIR2 (IN2): " + String(PIN_H_BRIDGE_DIR2)); + Serial.println("Pin H-Bridge PWM: " + String(PIN_H_BRIDGE_PWM)); + Serial.println("Pin Capteur courant: " + String(PIN_CURRENT_SENSOR)); + Serial.println("Adresse actuelle: " + String(current_address)); + Serial.println("Mode programmation: " + String(programming_mode ? "OUI" : "NON")); + + // Afficher le voltage alimenté + int raw = analogRead(PIN_CURRENT_SENSOR); + Serial.println("Tension capteur brute: " + String(raw) + " (0-1023)"); +} + +// ============================================================================ +// Fonctions de programmation DCC +// ============================================================================ +void readCV(uint16_t cv) { + Serial.println("Lecture CV " + String(cv) + "..."); + + if (cv < 1 || cv > 1024) { + Serial.println("ERREUR: CV doit être entre 1 et 1024"); + return; + } + + programming_mode = 1; + enableProgramming(); + + // Simulation de la lecture (implémentation réelle nécessite DCC bit-banging) + delay(500); + uint8_t value = readCVSimulated(cv); + + disableProgramming(); + programming_mode = 0; + + Serial.println("CV " + String(cv) + " = " + String(value)); + Serial.println("OK"); +} + +void writeCV(uint16_t cv, uint8_t value) { + Serial.println("Ecriture CV " + String(cv) + " = " + String(value) + "..."); + + if (cv < 1 || cv > 1024) { + Serial.println("ERREUR: CV doit être entre 1 et 1024"); + return; + } + + if (value < 0 || value > 255) { + Serial.println("ERREUR: Valeur doit être entre 0 et 255"); + return; + } + + programming_mode = 1; + enableProgramming(); + + // Simulation de l'écriture + delay(500); + writeCVSimulated(cv, value); + + disableProgramming(); + programming_mode = 0; + + Serial.println("CV " + String(cv) + " ecrit avec " + String(value)); + Serial.println("OK"); +} + +void setAddress(uint16_t addr) { + Serial.println("Configuration adresse " + String(addr) + "..."); + + if (addr < 1 || addr > 127) { + Serial.println("ERREUR: Adresse doit être entre 1 et 127"); + return; + } + + current_address = addr; + writeCV(1, addr); // CV1 = adresse courte + + Serial.println("Adresse configuree a " + String(addr)); +} + +// ============================================================================ +// Fonctions de contrôle du pont en H +// ============================================================================ +void enableProgramming() { + // Mettre en place une tension de programmation + digitalWrite(PIN_H_BRIDGE_DIR1, HIGH); + digitalWrite(PIN_H_BRIDGE_DIR2, LOW); + analogWrite(PIN_H_BRIDGE_PWM, 200); // ~78% puissance + Serial.println("Tension de programmation active"); +} + +void disableProgramming() { + // Couper la tension + digitalWrite(PIN_H_BRIDGE_DIR1, LOW); + digitalWrite(PIN_H_BRIDGE_DIR2, LOW); + analogWrite(PIN_H_BRIDGE_PWM, 0); + Serial.println("Tension de programmation coupee"); +} + +// ============================================================================ +// Fonction de mesure de courant +// ============================================================================ +void measureCurrentAndPrint() { + float current_ma = measureCurrent(); + Serial.println("Courant: " + String(current_ma, 1) + " mA"); +} + +float measureCurrent() { + // Lire plusieurs fois et faire une moyenne + float sum = 0; + const uint8_t samples = 10; + + for (uint8_t i = 0; i < samples; i++) { + int raw = analogRead(PIN_CURRENT_SENSOR); + // Conversion : 5V / 1023 * courant_sensor_factor + // Exemple avec ACS712-5A : 185 mV/A + float voltage = (raw * 5.0) / 1023.0; + float current = (voltage - 2.5) / 0.185; // 0.185V/A pour ACS712-5A + sum += abs(current); + delay(10); + } + + return sum / samples; +} + +// ============================================================================ +// Fonctions simulées (à remplacer par vrai DCC bit-banging) +// ============================================================================ +uint8_t readCVSimulated(uint16_t cv) { + // Simulation : retourner une valeur basée sur le CV + if (cv == 1) return current_address; // CV1 = adresse + if (cv == 7) return 0x02; // CV7 = Version + if (cv == 8) return 0xAB; // CV8 = Fabricant + return 0xFF; // Valeur par défaut +} + +void writeCVSimulated(uint16_t cv, uint8_t value) { + // Simulation d'écriture + if (cv == 1) { + current_address = value; + } + // Les autres CVs sont acceptés +} + +// ============================================================================ +// Fin du programme +// ============================================================================