Particle EEPROM and digital pin HIGH and Low time calculation,

Hi All,

I am trying to calculate the time of my digital input (D0) ON and OFF in particle electron and save that time so when i comeback or if my device went off i can start calculation from the last value stored in seconds or minutes. basically i need to know how many minutes and hours my digital input stayed ON.

could you please help me with that code.

Thank you

We can help refine your code but we like to see some effort from your side first.

If you struggle with the concept of EEPROM you could go for retained variables instead too.

1 Like

thanks and please have a look and let me know

double startTime = 0;  
double stopTime = 0;  
double runTime = 0;  
double totTime = 0;  
int led1 = D0;
int led2 = D7;  
  
boolean ledLastState = false; // if it was in the main loop it would be reset every time thorough the code  
boolean ledRunning = false; // if it was in the main loop it would be reset every time thorough the code  
  
void setup()  
{                 
  Serial.begin(9600); // initialize serial port to 9600 baud  
  // initialize the digital pin as an output.  
  pinMode(led2, OUTPUT);  
  pinMode(led1, INPUT);  
  digitalWrite(led1, HIGH); // turn on pull up resistor  
  totTime = 0 ;  
  
}  
  
void loop()  
{  
  ledLastState = digitalRead(led1); 
  if (ledRunning == false && ledLastState==HIGH)  
  {  
 
     digitalWrite(led2, HIGH);  
     ledRunning = true;  
     runTime = 0; // reset as were just turning on again and its already added to accumilator  
     startTime = millis();  
     Serial.print("led on, Starting Timer. ");  
     Particle.publish("Runing","led on, Starting Timer.  ");
   }  
   else if (ledRunning == true && ledLastState ==LOW) 
   {  
       
     digitalWrite(led2, LOW);  
     ledRunning = false;  
     stopTime = millis();  
     runTime +=(stopTime - startTime)/1000; // last run time in seconds  
     totTime += runTime;  
     Serial.print("led off ");Serial.print(runTime);Serial.print(" seconds. ");  
     Serial.print("Total time = ");Serial.println(totTime); 
      Particle.publish("Runing_Hours","Total time = ");
   }  
}

OK, that’s something to start with.

First, it’s important to know that applying a pull-up resistor on the Particle devices is not done that way

  pinMode(led1, INPUT);  
  digitalWrite(led1, HIGH); // turn on pull up resistor  

but so

  pinMode(led1, INPUT_PULLUP);  

And for the logic of the code I’m not pretending to provide the only correct way but just some hints I found useful for my own way of coding.

One thing I try to avoid is the “hassle” of multi variant conditions like your if (ledRunning == false && ledLastState==HIGH) and it’s counterpart(s).
In case of state changes I like to first check whether the state has actually changed and only proceed with the extra work if it has.

e.g. like this

void loop()
{
  static int prevState = -1; // start of with a "tri-state" condition - static var will keep value across calls
  int currState = digitalRead(led1);

  // do whatever needs to be done independent of state change

  if (currState == prevState) return;
  prevState = currState;
  delay(50);  // lazy debounce

  // do what needs to happen on state change 
}

This way you can concentrate on the actual meaning of the state rather than having to consider the change vs. no-change in all possible combinations of variants.

Also if you use a Particle.variable() you could keep updating the accumulated on-time in the “change independent part” and wouldn’t need to wait for led1 to go out.

Another hint would be this
You are (in essence - forget about the details for the moment) writing this

  if (ledLastState == HIGH) 
  {
    digitalWrite(led2, HIGH);
    ledRunning = true;
    ...
  }
  else
  {
    digitalWrite(led2, LOW);
    ledRunning = false;
    ...
  }

In combination with the explicit state-change-check, this could be reduced to

  digitalWrite(led2, ledLastState);
  ledRunning = ledLastState;  // LOW is equivalent to false, and everything NOT false is considered true

Like in maths, try to “factor out” the things that are common to all cases and write them only once. This makes the code easier to read and also stresses the actual dependencies more direct than by having them nested in some conditional branches.
Here in particular this approach reveals the fact that ledRunning is actually superfluous as it’s always the same as ledLastState (or prevState in my code) and hence can be dropped.

3 Likes

In addition to what @ScruffR said, you should change your time variables (at least startTime and stopTime) to be unsigned long instead of double, since that's what millis() returns. With a signed variable like double, you could get a large negative number from stopTime - startTime when millis() rolls over to 0 (in ~49.7 days of continuous running).

As a side note, you can replace those 5 print statements with a single printlnf() statement

Serial.printlnf("led off %f seconds. Total time = %f", runTime, totTime);

That's assuming that runTIme and totTime are doubles. If you change them to unsigned long, you would replace the %f with %lu.

4 Likes

Thanks a lot, really appreciate it, can you help me in how to make this start from zero when it reaches 50 hours for example?

i need it to count the time till it reach 50 hours then go back and start from zero again (clear memory data).

thank you

Sorry, but what?
Have you thought about this for any more than two seconds?

1 Like

sorry what you mean?

The forum is here for if you need help with your code, but we really shouldn’t be here to write it for you. The answers given are more than generous, and had you put in some effort of your own, you would’ve figured out an answer to your question already.
Again, we’re happy to help if you’re struggling with a specific aspect of your code, but the “cool, thanks, whatever, can you now write this/that for me?” is not really the best way to go.

Try something on your own, see what it does, troubleshoot it, and if you then still can’t figure it out, by all means do ask. But then also show what you’ve tried, what it does, what it doesn’t do, and what you expect it to do.

2 Likes

yea that is ok and i didnt ask for code writing to be honest , excuse my language, i asked about the idea to clear the memory that is what i meant,

thank you

How would you clear (aka reset or "initialise") a variable to a "fresh" starting state?
Your original code even features multiple lines that do exactly that - hence my question

If the original code was yours, you should already know how you did it in the first place, so what is the new challenge?

2 Likes

Thanks Scruffr,

its not my code, i did some changes on it to meet my requirements and it was originally used for Arduino.

any way i got the message so yea i understand now.