Store time, compare, reset

Okay how the code should work:

  1. digitalRead(2) LOW = start timer

  2. etc. 126 seconds

  3. digitalRead(2) HIGH = stop/reset timer

  4. store time 1

  5. digitalRead(2) LOW = start timer

  6. etc. 126 seconds

  7. digitalRead(2) HIGH = stop/reset timer

  8. store time 2

  9. compare time 1 and time 2

  10. if (time 1 == time 2) = GreenLEDpin(ON)

  11. digitalRead(2) LOW = start timer

  12. !!!digitalRead(2) never gets HIGH!!!

  13. etc. 130 seconds

  14. RedLEDpin(ON)

I have made the code for the timer so it starts when digitalRead(2) LOW and just used the resetfunc(); when digitalRead(2) HIGH

But the rest I can't wrap my head around.

#include <Time.h>
#include <TimeLib.h>

void setup() 
{
pinMode(2, INPUT); // this is the start button

  Serial.begin(9600);
}
void(* resetFunc) (void) = 0;

void loop() 
{
  if(digitalRead(2)==LOW)
  {
  static byte lastSecond = 0;
  uint32_t currentSeconds = now();
  if(lastSecond != second(currentSeconds))
  {
    lastSecond = second(currentSeconds);
    char elapsedTime[32] = "";

    sprintf(elapsedTime, "%02d", 
      (currentSeconds)
    );
    Serial.println(elapsedTime);
  }


    if(digitalRead(2)==HIGH){
      resetFunc();
    }
  }
  }

Why should it?

What is connected to pin 2?

If you Auto format teh loop() function it looks like this

void loop()
{
    if (digitalRead(2) == LOW)
    {
        static byte lastSecond = 0;
        uint32_t currentSeconds = now();
        if (lastSecond != second(currentSeconds))
        {
            lastSecond = second(currentSeconds);
            char elapsedTime[32] = "";

            sprintf(elapsedTime, "%02d",
                    (currentSeconds));
            Serial.println(elapsedTime);
        }

        if (digitalRead(2) == HIGH)
        {
            resetFunc();
        }
    }
}

All of the code is inside a while loop that runs only when pin 2 is LOW, including the code that checks to see whether pin 2 is HIGH. Can you see a problem ?

What is the resetFunc() function meant to achieve ?

What I try to achieve:
I am having a machine that opens and closes then I will put a proximity sensor at the end.
If the machine should get stuck the sensor should detect that the normal time it takes for a cycle is exceeded and gives a warning light.

The machine will take like 160 seconds for a cycle and sometimes 165 second. It very with within some few seconds. But a cycle can also be 300 seconds it depends on the setting.

But it will never jump from 160 seconds to 300 unless something is wrong.

If it has calculated that a cycle normally takes 160 seconds but the cycle suddenly exceedes 160 seconds a warning light should go off that there is a problem.

What is connected to pin 2, and how? Please post a link to the sensor, and a wiring diagram.

You need to fix the problem in the code described in post #3.

It is just a proximity sensor. It acts like a button.

Just simply HIGH LOW signal.

Yeah I see the problem now.
It helps me a little bit.

But at the moment I use the resetfunc(); to reset the timer so it starts counting from zero again.

But I understand if I want to achieve my goal the resetfunc() is not the way to do it.

The concept of if-conditions is test for a certain condition to be true.

There is something similar to if-conditions for multiple = more than two cases.

This is called switch-case-break;

This means the wanted functionality is

State A. Setting normal operation time.
Steps
State A1 wait for sensor going from high to low
If sensor goes from high to low start measuring time

Statd A2
If sensor goes from low to high stop measuring time
Store measured time for later use
State A3 wait for pressing confirmation button

If confimation button is pressed change to

State b1 which is monitor cycletime

wait for sensor high low
If sensor goes from high to low start measuring time

State b2

Change from mode measuring to
normal cycletime
to
mode monitor cycletime

Check if cycletime exceeds normal operation time for more than 5 seconds change to alertmode C switch on red alarm led

If sensor goes from low to high within normal cycletime switch on green led and switch back to state
b1

If you reset the normal cycletime with each low to high you can't measure anything.

You can code your wanted functionalugy with a lot of if-conditions.
Writing the code will be easier if you learn how state-machines work.

best regards Stefan

Thanks :pray:
Is there a video you would recommend to learn state-machine or is it called switch-case-break?

The statement described is called the switch case statement.

Here's one hit if you google

switch case statement c++

It's geeks for geeks, but not geeky at all.

switch case statement

The general programming paradigm mentioned exploits an general concept and codes FSMs or finite state machines. Sometime people omit the finite part, so you might see "state machine".

You will or see already that the switch case statement is a good language feature to use when coding a finite state machine.

google

finite state machine arduion 

or leave off the arduino term. Poke around, there are as many ways of teaching this as there are people convinced they have written or filmed the ultimate guide. Find a few sites that don't annoy you, maybe google

arduino traffic lights state machine

and see some fun stuff.

No time spent thinking about this will be wasted. Promise.

a7

Sound interesting, a little complicated and maybe a little intimidating, but I will try look into it. Thank you.

There are two states for your button: (1) Starting a timer when pressed and (2) Resetting when not pressed. That does not let much else happen. Maybe only look for button LOW to start and stop and reset. Let button HIGH to do nothing.

I can't tell from your #1 list of steps where this is going to repeat itself.

It seems like you have a training run to get a normal elapsed time, then you want to react if the time is exceeded on following runs.

Is the training a manual thing? Does the training get adjusted, like if the run was taking a bit longer each time would the allowed period be increased? Or similarly decreased?

How much longer than the trained period should a period be of it is to raise the alarm or whatever you call brining your attention to the fact? Are shorter runs always OK?

When and how does the alarm condition get reset?

The code in this case is going to be easier than unambiguously stating the desired functionality.

a7

Okay I am looking into Arduino as a state machine, and I begins to see that this might be my solution.

So I have made a layout of what is going to happen.
Does it seem possible?

Remember that the Arduino is going to be an attachment for the big machine.

Basically you have a piston,
You push a button,
The Arduino detects the piston moves away from position A,
Starts a timer,
The piston comes back to position A,
The Arduino stops the timer and saves the result,
Next time the piston gets stuck
The Arduino detects that it takes longer for the piston to get back to position A and gives a Warning light.

Say, I bet a clever person could figure it out, but I would be helped if your diagram arcs had arrows on them showing which way the flow goes.

It also isn't yet clear to me when and how the training run is handled. Does the training time gleaned need to be stored across resets or power downs and ups?

Now this

Next time the piston gets stuck

Do you mean that subsequent to a training run (pushbutton lets Arduino time A to A again piston time) the Arduino observes leaving A and hits the panic condition if the process doesn't get back to A?

Is there some slightly longer period that would be OK?

Rigging it up first for a fixed time might be easier. Then add to that code a way to say, and do, a training run.

a7


With arrows

I got some ideas to solve this. I don't know if it is better.
But let's say instead having a stop-watch measuring the time and compare two cycles with each other, then put the measured value into a countdown that trigger the red led if it doesn't get a new measurement before reaching 0.

The other idea was using a speedometer sketch to measure speed. If the speed becomes too slow it will trigger red led.

THX. I used an additional state just for the measurement, otherwise the code got cluttered with mode stuff. When you have modal states, it's really just news that you need more states. That can be decided on a case by case basis.

I have the paths out of IDLE operating on the rising edge. The pushbutton held down at that time initiates a measurement cycle. Usually it's the real deal and we are checking the time and maybe going to the FAULT state. I have FAULT exit to IDKE when the button is seen.

The Xs with up and down arrows indicate transitions that are taken on the leading and trialing edges of the input signal.

A state machine might be overkill here, but I always say why just kill when you can over kill?

HTH

a7

Just out of scientific interest can you post a version without statemachine ?
My estimation is the non-statemachine-solution will be "overkill" with many flags and extra if-conditions