Réalisation code initial
This commit is contained in:
+41
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
// ============================================================================
|
||||
Reference in New Issue
Block a user