diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4bd2076 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.pio +.vscode/* + diff --git a/README.fr.md b/README.fr.md index c490b24..39b62cb 100644 --- a/README.fr.md +++ b/README.fr.md @@ -48,3 +48,45 @@ Récapitulatif des CVs standards NMRA pour accessoires (S-9.2.2) | CV 519 | Version du décodeur (Lecture seule) | | CV 520 | Identifiant fabricant (Lecture seule) | | CV 512/8 | Reset d'usine (Écrire la valeur 8 réinitialise souvent le décodeur à l'adresse 1) | + + +Je vous réponds concrètement sur la compatibilité de la LED et la valeur de résistance à choisir. + +Oui, vous pouvez brancher une LED blanche directement sur la broche LED_PIN, à condition de mettre une résistance en série. + +Pour une LED blanche sur une sortie Arduino Nano à 5 V : + +tension de la LED blanche : environ 3,0 à 3,3 V +courant souhaité : 5 mA +résistance idéale : +𝑅 += +5 +𝑉 +− +3.2 +𝑉 +0.005 +𝐴 +≈ +360 +  +𝛺 +R= +0.005A +5V−3.2V +​ + ≈360 Ω + +Valeur pratique recommandée : + +330 Ω si vous voulez un peu plus de luminosité +470 Ω si vous voulez être plus prudent +En pratique : + +330 Ω est un bon choix pour 5 mA +470 Ω est encore correct et plus sûr pour la broche +Conseil : + +si vous utilisez une LED blanche très brillante, commencez avec 470 Ω +si elle est trop faible, passez à 330 Ω diff --git a/platformio.ini b/platformio.ini index c5c09ba..0ccf31b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -2,6 +2,7 @@ platform = atmelavr board = nanoatmega328 framework = arduino +monitor_speed = 115200 build_flags = -D DCC_SIGNAL_PIN=2 diff --git a/src/main.cpp b/src/main.cpp index bef9436..9917195 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,12 +21,24 @@ #define DEFAULT_MAX_UP 180 #define DEFAULT_MAX_DOWN 0 #define DEFAULT_ADDRESS 1 -#define VITESSE 20 // Temps en millisecondes entre chaque pas de servo +#define VITESSE 40 // Temps en millisecondes entre chaque pas de servo #define EEPROM_SIG_ADDR 0 #define EEPROM_SIG_VALUE 0xA5 #define DIY_MANUFACTURER_ID 13 +#define DEBUG 1 + +#ifdef DEBUG + #define DEBUG_INITIALIZE_SERIAL Serial.begin(115200) + #define DEBUG_PRINT(x) Serial.print(x) + #define DEBUG_PRINTLN(x) Serial.println(x) +#else + #define DEBUG_INITIALIZE_SERIAL + #define DEBUG_PRINT(x) + #define DEBUG_PRINTLN(x) +#endif + struct DCCAccessoryConfig { byte Sig; // Signature pour vérifier la validité de la structure (0x45) byte ManufacturerID; // Manufacturer ID (0-255) @@ -62,7 +74,8 @@ void notifyCVAck(void) } /** - * Notifie le changement d'une CV. + * Notifie le changement d'une CV. Appelé par le décodeur DCC lorsque la valeur d'une CV est modifiée. + * par la centrale DCC. Cette fonction met à jour les variables correspondantes et peut effectuer des actions supplémentaires si nécessaire. * @param CV Le numéro de la CV à modifier. * @param Value La nouvelle valeur de la CV. */ @@ -107,6 +120,17 @@ uint8_t notifyCVValid (uint16_t CV, uint8_t Writable) return 0; } +void initDefaultConfig() +{ + MyConfig.Sig = EEPROM_SIG_VALUE; + MyConfig.ManufacturerID = DIY_MANUFACTURER_ID; + MyConfig.Version = 1; + MyConfig.address = DEFAULT_ADDRESS; + MyConfig.MotorSpeed = DEFAULT_PALES_SPEED; + MyConfig.ServoMaxUp = DEFAULT_MAX_UP; + MyConfig.ServoMaxDown = DEFAULT_MAX_DOWN; +} + /** * Notifie la demande de réinitialisation des valeurs par défaut de la CV. */ @@ -117,10 +141,8 @@ void notifyCVResetFactoryDefault() Dcc.setCV(CV_MAX_DOWN, DEFAULT_MAX_DOWN); Dcc.setCV(CV_ACCESSORY_DECODER_ADDRESS_LSB, DEFAULT_ADDRESS & 0xFF); Dcc.setCV(CV_ACCESSORY_DECODER_ADDRESS_MSB, (DEFAULT_ADDRESS >> 8) & 0x07); - MyConfig.address = DEFAULT_ADDRESS; - MyConfig.MotorSpeed = DEFAULT_PALES_SPEED; - MyConfig.ServoMaxUp = DEFAULT_MAX_UP; - MyConfig.ServoMaxDown = DEFAULT_MAX_DOWN; + initDefaultConfig(); + EEPROM.write(EEPROM_SIG_ADDR, EEPROM_SIG_VALUE); EEPROM.put(1, MyConfig); } @@ -130,27 +152,37 @@ void notifyCVResetFactoryDefault() */ void loadCv() { - // Vérifie si les valeurs par défaut ont déjà été initialisées dans l'EEPROM - if (EEPROM.read(EEPROM_SIG_ADDR) != EEPROM_SIG_VALUE) - { - // Non, pas de valeurs par défaut initialisées, donc on les initialise maintenant - MyConfig.Sig = EEPROM_SIG_VALUE; - MyConfig.ManufacturerID = DIY_MANUFACTURER_ID; - MyConfig.Version = 1; - MyConfig.address = DEFAULT_ADDRESS; - MyConfig.MotorSpeed = DEFAULT_PALES_SPEED; - MyConfig.ServoMaxUp = DEFAULT_MAX_UP; - MyConfig.ServoMaxDown = DEFAULT_MAX_DOWN; - // Enregistrer la structure de configuration dans l'EEPROM + bool configValid = EEPROM.read(EEPROM_SIG_ADDR) == EEPROM_SIG_VALUE; + + if (!configValid) { + DCCAccessoryConfig storedConfig; + EEPROM.get(1, storedConfig); + if (storedConfig.Sig == EEPROM_SIG_VALUE) { + MyConfig = storedConfig; + EEPROM.write(EEPROM_SIG_ADDR, EEPROM_SIG_VALUE); + configValid = true; + } + } + + if (!configValid) { + DEBUG_PRINTLN("EEPROM not initialized, setting default values..."); + initDefaultConfig(); + DEBUG_PRINTLN("Writing default configuration to EEPROM..."); + EEPROM.write(EEPROM_SIG_ADDR, EEPROM_SIG_VALUE); EEPROM.put(1, MyConfig); } else { - // Lire la structure de configuration depuis l'EEPROM + DEBUG_PRINTLN("EEPROM already initialized, loading configuration..."); EEPROM.get(1, MyConfig); } + // Charger les valeurs des CV depuis la structure de configuration + DEBUG_PRINTLN(" MotorSpeed: " + String(MyConfig.MotorSpeed)); Dcc.setCV(CV_PALES_SPEED, MyConfig.MotorSpeed); + DEBUG_PRINTLN(" ServoMaxUp: " + String(MyConfig.ServoMaxUp)); + DEBUG_PRINTLN(" ServoMaxDown: " + String(MyConfig.ServoMaxDown)); + DEBUG_PRINTLN(" Address: " + String(MyConfig.address)); Dcc.setCV(CV_MAX_UP, MyConfig.ServoMaxUp); Dcc.setCV(CV_MAX_DOWN, MyConfig.ServoMaxDown); Dcc.setCV(CV_ACCESSORY_DECODER_ADDRESS_LSB, MyConfig.address & 0xFF); @@ -229,6 +261,8 @@ void notifyDccSigOutputState(uint16_t Addr, uint8_t State) */ void setup() { + DEBUG_INITIALIZE_SERIAL; + DEBUG_PRINTLN("DCC Helico system initialized..."); // Sens des PINs pinMode(LED_PIN, OUTPUT); pinMode(PWM_PIN, OUTPUT); @@ -236,6 +270,11 @@ void setup() servoMotor.attach(SERVO_PIN); servoMotor.write(90); + // Initialise les valeurs de la platine + STROBE_ON = 1; + HelicoUP = 0; + currentServoPos = 0; + targetServoPos = 180; // Attache l'interruption pour le signal DCC #ifdef digitalPinToInterrupt Dcc.pin(DCC_SIGNAL_PIN, 0); @@ -243,12 +282,13 @@ void setup() Dcc.pin(0, DCC_SIGNAL_PIN, 1); #endif // Lire les valeurs des CV depuis l'EEPROM et les charger dans le décodeur DCC + DEBUG_PRINTLN("Loading CVs from EEPROM..."); loadCv(); // Initialise le décodeur DCC en mode accessoire avec filtrage d'adresse sur l'adresse DCC courante. - Dcc.init(DIY_MANUFACTURER_ID, 10, FLAGS_MY_ADDRESS_ONLY | FLAGS_DCC_ACCESSORY_DECODER | FLAGS_OUTPUT_ADDRESS_MODE, 0); + Dcc.init(MyConfig.ManufacturerID, MyConfig.Version, FLAGS_MY_ADDRESS_ONLY | FLAGS_DCC_ACCESSORY_DECODER | FLAGS_OUTPUT_ADDRESS_MODE, 0); - loadCvFromDcc(); + // loadCvFromDcc(); } @@ -276,17 +316,20 @@ void loop() servoMotor.write(currentServoPos); } } + // servoMotor.write(90); if (STROBE_ON) { switch (strobePhase) { case 0: digitalWrite(LED_PIN, HIGH); + digitalWrite(LED_BUILTIN, HIGH); strobePhase = 1; strobeNextMillis = now + 100; break; case 1: if (now >= strobeNextMillis) { digitalWrite(LED_PIN, LOW); + digitalWrite(LED_BUILTIN, LOW); strobePhase = 2; strobeNextMillis = now + 100; } @@ -294,6 +337,7 @@ void loop() case 2: if (now >= strobeNextMillis) { digitalWrite(LED_PIN, HIGH); + digitalWrite(LED_BUILTIN, HIGH); strobePhase = 3; strobeNextMillis = now + 100; } @@ -301,6 +345,7 @@ void loop() case 3: if (now >= strobeNextMillis) { digitalWrite(LED_PIN, LOW); + digitalWrite(LED_BUILTIN, LOW); strobePhase = 4; strobeNextMillis = now + 1000; } @@ -314,5 +359,6 @@ void loop() } else { strobePhase = 0; digitalWrite(LED_PIN, LOW); + digitalWrite(LED_BUILTIN, LOW); } }