Problème sur les interruptions !!!

Bonjour à tous,
je dois réaliser un projet se greffant sur la sortie d’un autre appareil.

Je dois capter 3 modes d’alarmes sur un niveau haut:

  • Les 4 première seconde: Mode Pré-détection.

  • de le 4ème à la 60ème seconde: Mode Alarme.

  • après 60 secondes: Mode Sabotage.

Le projet fonctionnera sur pile et dois donc être base consommation,
ce qui requiert l’utilisation de l’Interrupt Request et de se fait le début de mes problèmes;
car les interruptions ne permettent pas l’utilisation du Timer millis().

J’ai ainsi créé une fonction interrupt et mis le reste du programme en Loop et
je passe le niveau via une variable volatile.

Seulement voilà cela ne fonctionne pas,
j’ai des problèmes lors de changements rapides de niveau sur l’entrée.
L’arduino ne suit pas et souvent je me retrouve avec un niveau haut et l’arduino qui reste en Sleep mode !
J’ai également essayé avec un fonction debounce mais cela ne change rien au problème.

Je vous remercie d’avance pour les idées ou l’aide que vous pourriez me fournir concernant se problème.

Voici le code:

//** LIBRARY **********************************************************************************
#include <NeoPixelBus.h>            //Pixel Led library
#include <avr/sleep.h>              //Sleep Mode Library

//**PINs Definition ***************************************************************************
#define InterruptButtonPIN  2       //Input Pin from Device Output
#define BuzzerPIN           3       //Output Pin to Buzzer
#define RelayPIN            4       //Output Pin to Relay
#define LedPIN              5       //Output Pin to Led


//**Time Setup ***************************************************************************
#define debouncing_time     50      //Debouncing Time in Milliseconds
#define PreAlarmeTime       4       //Pre-Alarm time (seconds)
#define AlarmeTime          10      //Alarm time (seconds)
#define MemAlarmeTime       15      //Memory-Alarm time (seconds)  
#define colorSaturation     128     //Color saturation for Leds

//**VARIABLES SETUP ***************************************************************************
const uint16_t NumberOfLED =    5;    //Number of Leds
//long debouncing_time =        50;   //Debouncing Time in Milliseconds
const int FreqBuzzer =          1000; //Tone Frequency for buzzer (Hz) 

//**VARIABLES *********************************************************************************
volatile boolean PreAlarmStates = 0;         //State for Pre-Alarm
boolean AlarmStates = 0;            //State for Alarm
boolean AlarmMemoryStates = 0;      //State for Alarm Memory
boolean CounterStart = 0;           //Sate for time counter
boolean BuzzerON = false;           //State for Buzzer
boolean Relay = 1;                  //State for Relay
uint8_t SaveSREG;

// TIMERS
extern volatile unsigned long timer0_millis;  //Var for reset timer
unsigned long new_value = 0;                  //New value for reset timer
volatile unsigned long last_millis;
volatile unsigned long MainTimer;
volatile unsigned long WaitDelay=                 0; 
volatile unsigned long BeepDelay=                 0;
volatile unsigned long pulse;
volatile unsigned long seconds;

//**INITIALISATION ***************************************************************************
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(NumberOfLED, LedPIN); //Leds initialisation

//Colors Definitions
RgbColor red(colorSaturation, 0, 0);
RgbColor green(0, colorSaturation, 0);
RgbColor blue(0, 0, colorSaturation);
RgbColor white(colorSaturation);
RgbColor black(0);

//** SETUP ************************************************************************************
void setup() {
  Serial.begin(9600);                 //serial port starting

  //Outputs Pins Definitions
  pinMode(LedPIN, OUTPUT);
  digitalWrite(LedPIN, LOW);
  pinMode(RelayPIN, OUTPUT);
  digitalWrite(RelayPIN, Relay); 
  
  //Inputs Pins Definitions
  pinMode(InterruptButtonPIN, INPUT);//INPUT_PULLUP
  
  //Init Interrupt 
  attachInterrupt(digitalPinToInterrupt(InterruptButtonPIN), Interrupt, RISING);

  //Init Leds
  strip.Begin();  //Init Leds
  strip.Show();   //Turn Leds 'off'
  TestLED();      //Start Function to Test Leds 
}

//** LOOP ************************************************************************************* 
void loop()
{

    //if (digitalRead(InterruptButtonPIN) == HIGH && PreAlarmStates == 1) 
    if (millis() - last_millis >= debouncing_time && PreAlarmStates == 1 && digitalRead(InterruptButtonPIN) == HIGH) 
    {
        last_millis = millis();
        Serial.println("------------  Button pressed -------------");
        if (CounterStart == false )               //If counter not started
        { 
            Serial.println("Counter Start");
            setMillis(new_value); //reset internal counter Millis to new_value (0)
            MainTimer = millis(); //Start the time counter for button
            CounterStart = true;  //Change state for counter
        }
        else             //Counter is already started
        {
            seconds = (millis() - MainTimer)/1000; 
            Serial.print("Counter=");   
            Serial.println(seconds);
            
            if (seconds > AlarmeTime)  // Alarm Detection 60s
            {
                Serial.println("***********  Alarm Memory ***************");
                strip.SetPixelColor(0, blue);
                strip.Show();
            }
            else if (seconds > PreAlarmeTime)  // Sabotage Detection 4s
            {
                Serial.println("*************  Alarm  ******************");
                strip.SetPixelColor(0, red);
                strip.Show();
            }
            else
            {
                Serial.println("*********** Pre Alarm  *****************");
                strip.SetPixelColor(0, green);
                strip.Show();
            }
        }  
    }
    else
    {
        Serial.println("----------- No Button pressed ------------");
        Serial.println("- All variable reseting");
        CounterStart   = 0;
        PreAlarmStates = 0;
        AlarmStates    = 0;
        AlarmMemoryStates    = 0;
        Relay = 1;
        noTone(BuzzerPIN);     // Stop sound...
        BuzzerON == false;
        strip.SetPixelColor(0, black); // Turn LED off
        strip.Show();
        Serial.println("-  and going to power down Mode.");
        sleepNow();
    }
}

//** FUNCTIONS ******************************************************************************** 
void Interrupt() 
{
    PreAlarmStates = 1;
}
/*****************************************************************/

void TestLED()
{
    strip.SetPixelColor(0, green);
    strip.Show();
    delay(150);
    strip.SetPixelColor(0, red);
    strip.Show();
    delay(150);
    strip.SetPixelColor(0, blue);
    strip.Show();
    delay(150);
    strip.SetPixelColor(0, white);
    strip.Show();
    delay(150);
    strip.SetPixelColor(0, black);
    strip.Show();
}
/*****************************************************************/

void sleepNow()
{
      
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set here
    //set_sleep_mode(SLEEP_MODE_STANDBY);   // sleep mode is set here

    sleep_enable();          // enables the sleep bit in the mcucr register
                             // so sleep is possible. just a safety pin 

    attachInterrupt(digitalPinToInterrupt(InterruptButtonPIN), Interrupt, RISING); // use interrupt 0 (pin 2) and run function
                                       // wakeUpNow when pin 2 gets LOW 
    sleep_mode();            // here the device is actually put to sleep!!
//*****************************
                             // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
//*****************************
    sleep_disable();         // first thing after waking from sleep:
                             // disable sleep...
    detachInterrupt(digitalPinToInterrupt(InterruptButtonPIN));      // disables interrupt 0 on pin 2 so the 
                             // wakeUpNow code will not be executed 
                             // during normal running time.
}
/*****************************************************************/

void setMillis(unsigned long new_millis)
{
  uint8_t oldSREG = SREG;
  cli();
  timer0_millis = new_millis;
  SREG = oldSREG;
}
/*****************************************************************/

Je n’ai pas lu le code mais si votre seul soucis c’est millis() qui ne fonctionne pas dans l’ISR alors utilisez micros()...

Pour la vitesse du code passez en 115200 bauds sur la voie série, pas la peine de traîner si vous remplissez le buffer alors print Devient bloquant ou virez carrément tous les print pour voir si ça change quelque chose

Merci J-M-L, en effet, après simplement être passé de 9600bps à 115200bps pour la transmission RS232, tous mes problèmes de réactivité sur les interruptions ont tous simplement disparu.

Mille fois merci pour votre réponse claire et précise.

Cool :)