How to stop/do something if analog value has not changed in a certain amount of time

The following code is for testing the lifetime of an actuator.

When the actuator is contracted, it outputs a value of 0.4V based on hall sensors that I can tap into.
When it's going up or down, it outputs a value of 2.4V
When it's extended, it outputs a value of 1.4V

I use two relays to control the direction of the actuator.

It takes about 9 sec for the actuator to extend and contract again.

I want the code to do the following:

Extend and contract (one loop).
Count the loop and display it.
Pause for a desired time (after one loop) and then do it again, until the actuator motor breaks.

The following code does all the above.

What I want is when the actuator motor breaks, the count should stop and the LCD should display the count and stop both replays.

I have researched and came to the conclusion that I should use a State Change detection.

So when the analog voltage value does not change in 5 or 10 min, then the actuator motor must've stopped working.

So I need a few lines of code that stop the counter when the analog value does not change in a certain amount of time. I tried different stuff, but It can't seem to make it work.


// include the library code til LCD skærm
#include <LiquidCrystal.h>


// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


//Millis function
const unsigned long eventInterval_1 = 14000; //14 sec delay. 
unsigned long previousTime_1 = 0;




//voltage sensor
int value = 0;
float voltage;
int offset =4;// set the correction offset value

//Relay
int Relay_1 = 9;
int Relay_2 = 10;

int counter;


void setup() 
{
 // indstil LCD skærmens rækker og kolonner 
 lcd.begin(16, 2);

 Serial.begin(9600);

 pinMode(Relay_1,OUTPUT); //pin 10 defineret som output til relæ 1
 pinMode(Relay_2,OUTPUT); //Pin 11 defineret som output til relæ 2 

}





void loop() 
{

 delay(500);

  //for analog sensor
  int volt = analogRead(A0);//analog input fra pin A0
  double voltage = map(volt,0,1023, 0, 2500) + offset;// dele spændingen fra 0-1023 til 0-2500 of tilføj correction offset
  

  
  voltage /=100;
  Serial.print("Spænding: ");
  Serial.print(voltage); //print voltage
  Serial.println(" V");

  


  //millis timer  
  unsigned long currentTime = millis();
 


    if ((voltage > 0.0) && (voltage <= 0.7)) //if voltage is between these values, aktuator will to up
          {
            if (currentTime - previousTime_1 >= eventInterval_1) //millis counter
            { 
             digitalWrite(Relay_1,HIGH); 
             digitalWrite(Relay_2,LOW);
             counter++;                     //count should go up everytime a loop is complete (up and down onnce).
             previousTime_1 = currentTime; // til millis funktionen
            }
              
              //if voltage is > 1.75V, the actuator should keep going up until it reaches a voltage between 1.2 and 1.7V
             if (voltage > 1.75 && Relay_1==HIGH)  
                {
                   digitalWrite(Relay_1,HIGH);
                   digitalWrite(Relay_2,LOW);
                }
           
           }
    

     //when the voltage is between 1.2 and 1.7V, the actuator is in the top and it should not come back down again. 
    else if(voltage > 1.2 && voltage < 1.7) //når spænding
            {
             digitalWrite(Relay_1,LOW);
             digitalWrite(Relay_2,HIGH);
            }
                //when it's going down, it should keep doing down.
               if(voltage>1.75 && Relay_2==HIGH)
              {
                 digitalWrite(Relay_1,LOW);
                 digitalWrite(Relay_2,HIGH);
              }
              


/*
 * missing code
 * 
 * it the value (in this case the voltage), has not changed in, let's say 5 min, I 
 * want the counter to stop counting and display the latest count and stop both relays and. 
 * 
 * 
 * 
 *This is the part that I have troube programming.
 * 
 */



  lcd.setCursor(8, 0);
  lcd.print(counter); //print counter on lcd display

  
} // void loop

Hint: map does not make a floating point number

Save the value of millis() when the value has changed since the last time it was read. Next time you read the value if it has not changed then compare the current value of millis() with the previously saved (last change time) value and if it is longer that the required period then do what you want

I'm a total newbie. Would you please explain this?

You have defined variable named "volt" as variable-type float
and then you use this variable "volt" inside the map-function

double voltage = map(volt,0,1023, 0, 2500) + offset;

the function map can only work properly with variables of type integer.
So you should define variable "volt" as integer.

If you don't know anything about variable-types it is about time to learn it now.

best regards Stefan

as an additional hint: you posted this questions three times.
This is against forum-rules. You are in danger to get temporarily banned from the forum through cross-posting.

so please report the two other posts to the moderator to delete the yet unanswered threads

best regards Stefan

Hello
You can use this simple function template for your project:

template<typename T>
T map(T x, T in_min, T in_max, T out_min, T out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Have a nice day and enjoy coding in C++.

well it would be much easier to understand if you would post a complete example-code which shows how to use it with floats.

and to realise what the general pattern is
a second example using integers
and a third example with longs

The variations that become obvious through the three examples
and the things that stay constant do this job of explaining.

best regards Stefan

How would you write if a value has not changed since last time?


void setup()
{
  Serial.begin(115200);
}

void loop()
{
  static int previousValue = analogRead(7);  //compiled for a Nano
  static int currentValue = previousValue;
  int deadband = 10;
  previousValue = currentValue;
  currentValue = analogRead(7);
  Serial.print(previousValue);
  Serial.print("\t");
  Serial.println(currentValue);
  if (abs(previousValue - currentValue) > deadband) //detect a change
  {
    Serial.print("value has changed by at least ");
    Serial.println(deadband);
  }
  else
  {
    Serial.println("no significant change");
  }
  previousValue = currentValue;
  delay(1000);
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.