accumulate time an input is state HIGH

Hi all,
I search without answer, so resigniate I post here for help.
I want an output variable giving me the accumulate time the input (pin 3) pass to the HIGH state.
The below code give me the time between a state change of the input, that's good, but now I want acumulate the time.
Please help me to complete the ????????????????????????????????????????
Thanks a lot in advance

const int inPin = 3;                   // the number of the input pin


void setup()
{
   pinMode(inPin, INPUT);
  digitalWrite(inPin, LOW);
  Serial.begin(9600);
  

void loop()
{
  unsigned long duration = switchTime();
  
  ????????????????????????????????????????      
   
  delay(300);
}


// return the time in milliseconds that the switch has been in pressed (LOW)
long switchTime()
{
  // these variables are static  - see Discussion for an explanation
  static unsigned long startTime = 0;  // the time the switch state change was first detected
  static boolean state;                // the current state of the switch
  long a;

  if(digitalRead(inPin) != state) // check to see if the switch has changed state
  {
    state = ! state;       // yes, invert the state
    startTime = millis();  // store the time
  }
  if( state == HIGH)
   {
   a = (millis() - startTime)/1000;
   return  a;
   }
  else{
     return 0;// return 0 if the switch is not pushed (in the LOW state);
}
   }

Each time the state goes from Low to High, remember what the millis() time is, when that happens.

Each time the state goes from high to low, get the current millis() time, and subtract from it the time when
the high period started. That will tell you the duration of the most recent high event instance.

Add this duration to another variable which will then contain the accumulated total time of all the high instances.

Note this will only update the total accumulated high time, after each high event has ended. If you want to
continually update the accumulated high time during the current high event, it gets more complicated.

Thanks a lot michinyon,

I will try the first solution :slight_smile: right, it's enough for me to have the cumulate n-1.
I was affectively trying to make a real time cumulating into the void loop, I didn't find the way ... nevertheless, if you know how to do it, let me know

Hi,
For somebody interesting, the code below give the accumulated total time of all the high instances of the input 3, i.e.
the "duration_min" is total n-1 high instance, with a filtering of 1 minute state HIGH minimum (in order to avoid overstack of the counter of secondes)

Thanks to michinyon

here is the code :

const int inPin = 3;                   // the number of the input pin
 
unsigned long duration_sec; 
unsigned long duration_min;
unsigned long duration_hour; 

static unsigned long startTime = 0;  // the time the switch state change was first detected
static boolean state;                // the current state of the switch
unsigned long a;


void setup()
{
   pinMode(inPin, INPUT);
  digitalWrite(inPin, LOW); // turn on pull-up resistor
  Serial.begin(9600);
}



void loop()
{
 
 if(digitalRead(inPin) != state) // check to see if the switch has changed state
  {
    state = ! state;
      if(state == HIGH){
           startTime = millis();  // store the time
             
      }
      if(state == LOW){
           a = (millis() - startTime)/1000;
           duration_sec = duration_sec + a;
           duration_min += duration_sec/60;
           duration_hour += duration_min/60;
           if (duration_sec >= 60){
             duration_sec = 0;
           }
           if (duration_min >= 60){
             duration_min = 0;
           }
           startTime = 0;
      }
  }
  
  Serial.print(duration_sec);
  Serial.print("sec-");
  Serial.print(duration_min);
  Serial.print("min-");
  Serial.print(duration_hour);
  Serial.println("hour");

  
  delay(500);
}

The state-maintenance for this sort of thing could be done in an external interrupt or
a pin-change interrupt, then loop() won't have to check the pin at all.

Here its pin 3 which is external interrupt channel 1, so attachInterrupt could
be used

void setup()
{
  startTime = millis () ;    // in case pin 3 already high
  attachInterupt (1, handler, CHANGE) ;
}

void handler ()
{
  if (digitalRead (3))
     startTime = millis();  // store the time
  else
     add_duration (millis () - startTime) ;  // however its done
}