Réalisation code initial

This commit is contained in:
Serge NOEL
2026-08-13 12:04:15 +02:00
parent 1cd64b2a5d
commit 50437c6c19
4 changed files with 349 additions and 1 deletions
+41
View File
@@ -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/
+1 -1
View File
@@ -10,7 +10,7 @@ Coté logiciel, il utilise platform.io, et est très simple, il permet uniquemen
- Arduino Nano avec câble USB - Arduino Nano avec câble USB
- Pont en H LM18220 - Pont en H LM18220
- Module de mesure de courant (ex : ACS712 ou INA219) - Module de mesure de courant (ex : ACS712 )
- Rails DCC pour test - Rails DCC pour test
- Décodeurs à programmer - Décodeurs à programmer
- Platform.io (CLI ou extension VS Code) - Platform.io (CLI ou extension VS Code)
+20
View File
@@ -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
+287
View File
@@ -0,0 +1,287 @@
#include <Arduino.h>
// ============================================================================
// 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 <num> : Lit la valeur du CV <num>");
Serial.println(" Exemple: READ_CV 1");
Serial.println("WRITE_CV <num> <val> : Ecrit <val> dans CV <num>");
Serial.println(" Exemple: WRITE_CV 1 3");
Serial.println("SET_ADDR <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
// ============================================================================