Guidance needed for External Pin Interrupt (maybe millies() too!)

Hallo everyone!
I’m trying to implement interrupts in a program I’m working on and I would appreciate some help!
The program is pretty simple. I want to measure a 49kbits/s digital signal and LED a light when there is no voltage for more than 3 seconds.

As I don’t have access to this signal yet, I’m experimenting with pwm output from Arduino.

Now, I’m thinking the program to be something like the following. I have connected pin11 to pin4 and pin8 to pin2.

int sensorVal = 0;  //the value that pin 2 reads
int lastSensorVal = 0;  //the value that pin2 read in the previous loop


void setup() {
  Serial.begin(9600);
  pinMode(11, OUTPUT);  //pwm output connected to pin 4
  pinMode(4, INPUT_PULLUP); //pin that reads the pwm signal from pin 11   --> reads HIGH for no voltage!
  pinMode(13, OUTPUT);  //LED output
  pinMode(8, OUTPUT); //output gives power to pin2 if we have more than two successive HIGHs
  pinMode(2, INPUT_PULLUP);  //our interrupt pin   --> reads LOW for no voltage!
 
  attachInterrupt(0, react, FALLING); //attach the interrupt  
}


void loop() {
  analogWrite(11, 191);
  sensorVal = digitalRead(4); 
  Serial.println(sensorVal);


  if (sensorVal == lastSensorVal && sensorVal == HIGH) {
    digitalWrite(8, HIGH);                
    }
  else {
    digitalWrite(8, LOW);
  }     
  lastSensorVal = sensorVal;
}

void react () {
  long time = millis(); //the duration of successive 0s (or LOWSs) -> zero voltage 

  Serial.print("The duration of no voltage is: ");
  Serial.println(time);
  
}

Of course my problem is that millis() keep increasing and I’ve read that resetting milis() every time the interrupt starts isn’t an option (or is it? you know better..)

Secondly, I’ve also read that interrupts should not have many commands and that also shouldn’t return any values.. So ok, let’s say I measure the time and it’s bigger than 3 seconds.. then how I light the LED? With commands within the interrupt?

Should variable “time” be long or volatile?

And lastly, should I also implement commands to add the time values that I measure in react() till I see a one again, right? That means, if we have 6 successive zeros, the program would run 6 times the interrupt and so I should add the values from every loop to find the total, right?
P.S. I use two pullup pins, so at the end when voltage from pwm pin11 is zero, then interrupt pin2 reads LOW, and that’s why I used mode FALLING.

Thanks in advance!

Don't do serial stuff inside your interrupt routine. That can lock up your program.

You don't need to reset millis. You need to keep track of millis twice. Get it at the beginning of an interval of time and again at the end and subtract to find out how long it has been.

You should have a global time variable, fallingTime. In the ISR:

void react ()
{
   fallingTime = millis();
}

In loop:

void loop()
{
   if(fallingTime > 0)
   {
       unsigned long delta = millis() - fallingTime;
       if(delta > interval)
       {
          Serial.print("It's been ");
          Serial.print(delta);
          Serial.println(" milliseconds since the last transition to LOW...");
       }
   }

    // other stuff
}

I love you..! And you know that women don’t say that often! Works like charm!

Now, some more quick questions! If the program was meant to run from now till forever, is there any danger of millis rollover or something like that?

I want to implement some more things now, like an LCD to print there the ”delta” or to save all that data in a file. Can all these work together or are there limitations due to the use of interrupt or serial?

As long as you are using subtraction to handle intervals there is no issue from millis rolling over. You just have to understand how to take advantage of unsigned math. Do some searching on the forum as the topic has come up a few thousand times before.