Bonsoir
Dans le cadre de la gestion du traitement en mode LOOP avec le montage décrit précédemment le code suivant doit pouvoir tourner.
Il faut savoir que le moment ou les interruptions vont se produire lors du chevauchement des roues par dessus les coupures des rails des sections fixe et commutable, ne sont pas identiques.
Il y en aura toujours une qui arrivera quelques tantièmes de secondes plus tôt que l'autre.( même avec des coupure bien parallèles, et encore plus vrai avec des coupures en quinconce!)
Afin d'éviter un double changement qui conduirait de fait à n'en produire aucun (ordre et contre ordre quasi immédiat) il faut neutraliser les effets de l'interruption arrivant en seconde position puisque la bascule est (déjà) en cours pour aligner les polarités des sections.
On rejette l utilisation de detachinterrupt() qui prendrait trop de temps en lui préférant une variable stockée ( bool) dans un registre (ca va très vite ainsi) et qui sera considérée dans les operations à mener.
Lors du changement des états de pin de commande on désactive aussi toute autre interruption pour garder une séquence de commutation rapide et groupée.
Si une temporisation est requise (temps de commutation des états au niveau CPU et de réaction de l'électronique) on utilisera une boucle while() pour incrémenter une valeur jusqu'à un seuil défini avant de conclure!
Voici la trame d'un code pouvant mener ces opérations.
Cela vous semble t il "convenable"?
#include <Arduino.h>
/*
DCC ADVANCED AUTO LOOP REVERSER: V1.0
Author: Laurent ROEKENS LTR
Version 1.0.0
Date rev: 07/02/2024: initial release design for MOSFET BACK TO BACK DESIGN
Specially designed for MEGATINY x06 (806,1606,816,1616,826,1626,3226 CPU Parts)
SWAP PIN NAMES OF ANY AVRx CPU. ( ex AVR Serie0 (NANO_EVERY), AVR Dx, ...)
*/
//VARIABLES:
#if !defined(PIN_PA1)
#define PIN_PA1 2
#endif
#if !defined(PIN_PA2)
#define PIN_PA2 3
#endif
#if !defined(PIN_PC0)
#define PIN_PC0 10
#endif
#if !defined(PIN_PC1)
#define PIN_PC0 11
#endif
#if !defined(PIN_PC2)
#define PIN_PC0 12
#endif
#if !defined(PIN_PC3)
#define PIN_PC0 13
#endif
#define TOGGLE GPIOR0 //use global register GPRIOR0 to store value for faster speed reaction
#define CHANGING GPIOR1 //same for CHANGING state value
#define CDE_SET1 PIN_PC0
#define CDE_SET2 PIN_PC1
#define CDE_SET3 PIN_PC2
#define CDE_SET4 PIN_PC3
#define RST_PIN_1 PIN_PA1
#define RST_PIN_2 PIN_PA2
#define CDE_SET1_SET_ON PORTC.OUTSET = PIN0_bm //faster than PORTC.OUT |= PIN0_bm
#define CDE_SET1_SET_OFF PORTC.OUTCLR = PIN0_bm //faster than PORTC.OUT &= ~PIN0_bm
#define CDE_SET2_SET_ON PORTC.OUTSET = PIN1_bm //faster than PORTC.OUT |= PIN1_bm
#define CDE_SET2_SET_OFF PORTC.OUTCLR = PIN1_bm //faster than PORTC.OUT &= ~PIN1_bm
#define CDE_SET3_SET_ON PORTC.OUTSET = PIN2_bm //faster than PORTC.OUT |= PIN2_bm
#define CDE_SET3_SET_OFF PORTC.OUTCLR = PIN2_bm //faster than PORTC.OUT &= ~PIN2_bm
#define CDE_SET4_SET_ON PORTC.OUTSET = PIN3_bm //faster than PORTC.OUT |= PIN3_bm
#define CDE_SET4_SET_OFF PORTC.OUTCLR = PIN3_bm //faster than PORTC.OUT &= ~PIN3_bm
void toggle_state();
void toggle_state()
{
if(CHANGING == true) //no new change till current one is not over so lock it beacause change is in progress
{
return;
}
if(CHANGING == false)
{
TOGGLE = !TOGGLE;
CHANGING = true;
}
}
///////////////////////////////
//SETUP
///////////////////////////////
void setup()
{
pinMode(CDE_SET1, OUTPUT);
pinMode(CDE_SET2, OUTPUT);
pinMode(CDE_SET3, OUTPUT);
pinMode(CDE_SET4, OUTPUT);
pinMode(RST_PIN_1, INPUT);
pinMode(RST_PIN_2, INPUT);
//init STATE:
TOGGLE = false; //init state NORMAL
CHANGING = false; //no change in progress
//NORMAL MODE: SET STATES FOR EACH DRIVING PINS:
CDE_SET1_SET_ON;
CDE_SET2_SET_OFF;
CDE_SET3_SET_OFF;
CDE_SET4_SET_ON;
attachInterrupt(digitalPinToInterrupt(RST_PIN_1),toggle_state,FALLING); //ANY STATE DOWN DETECTED ON RST_PIN WILL SWAP STATE
attachInterrupt(digitalPinToInterrupt(RST_PIN_2),toggle_state,FALLING); //ANY STATE DOWN DETECTED ON RST_PIN WILL SWAP STATE
}
void tempo() //tempo 10us
{
uint16_t i = 0;
//@20Mhz ==> 1 cycle = 0.000 000 050 sec = 50ns (50 nano seconds)
// 200 cycle give 10us
//need adjustements may be
while(i < 200)
{
i++;
}
}
////////////////////////////////
//LOOP
////////////////////////////////
void loop(){
switch(TOGGLE)
{
case false:
if(CHANGING == true)
{
noInterrupts(); //stop any new interrup if any
//SET ALL PINS OFF:
//CDE_SET1_SET_OFF; //ALREADY OFF
CDE_SET2_SET_OFF;
CDE_SET3_SET_OFF;
//CDE_SET4_SET_OFF; //ALREADY OFF
// tempo();
//SET NEW STATE:
CDE_SET1_SET_ON;
//CDE_SET2_SET_OFF; //ALREADY DONE
//CDE_SET3_SET_OFF; //ALREADY DONE
CDE_SET4_SET_ON;
CHANGING = false;
// tempo();
interrupts(); // inerrupt are now allowed
}
break;
case true:
if(CHANGING == true)
{
noInterrupts();
//SET ALL PINS OFF:
CDE_SET1_SET_OFF;
//CDE_SET2_SET_OFF; //ALREADY OFF
//CDE_SET3_SET_OFF; //ALREADY OFF
CDE_SET4_SET_OFF;
// tempo();
//SET NEW STATE:
//CDE_SET1_SET_OFF; //ALREADY OFF
CDE_SET2_SET_ON;
CDE_SET3_SET_ON;
//CDE_SET4_SET_OFF; //ALREADY OFF
CHANGING = false;
// tempo();
interrupts();
}
break;
}
}
Ltr