Give a temporization if condition is ON

Hello everyone!
I am working on a solar tracker with 3 photoresistors (north, east and west).
I want this one turn east when the night come over in order to make it ready for the next day and facing sunrise.
In this way i would like to write this condition in my code : If eastsensor<10 AND westsensor<10 AND northsensor<10 FOR 15 min (10 is a random value considering sensors don't get light anymore) THEN turn on the linear actor to face east.
I don't really know how to add this temporization of 15 min in my condition..
Do you have any ideas how I could write it in my code?
I would be grateful if you can help me on this topic!
Thanks
PS: Here is the part of the code I am talking about

 
  if(capteurest<10 && capteurouest<10 && capteurnord<10)  // Check if night is here
  {
    digitalWrite(dirPin2,LOW);    // Engine turn one way to face east
    digitalWrite(freinPin2,LOW);  //Brake is off
    digitalWrite(vitessePin2, 5);    //Speed of the motor
  }

If your condition is true,

  1. set a timer (based on millis()) once,
  2. set a flag that the timer is started

You will have to incorporate the flag in the condition

If the condition is false

  1. reset the flag

If the flag is true

  1. check the millis() time to see if a certain duration has lapsed and take the desired action.

Your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advice on) your project :wink: See About the Installation & Troubleshooting category.

Use a local clock to follow the sun.

Combining the two ideas - your condition test looks like it's just determining whether it's night time. I had to make a guess since you didn't say. Even if you don't use an RTC to determine the solar position (which is certainly possible), you can use the local time in combination with the readings to control behaviour.

Else, there are use cases that break. Example, suppose it is night time and the required time out has set the array pointing east. Now, a parking car's headlights hit the west sensor, the array turns west and stays there for 15 minutes before pointing east again.

That won't happen if you are just using clock time.

Thank you for your advices guys!
I finally decided to make it with millis()...

unsigned long startmillis;  //Create variables for timer
unsigned long currentmillis;
unsigned long interval = 60000; //Set an interval of 1 min
 if(capteurest<10 && capteurouest<10 && capteurnord<10)  // Check if night is here
                        {
                          startmillis = 0;    //start the timer
                          currentmillis = millis();  //get the current time
                          
                          if(((currentmillis - startmillis) > interval) && capteurest<10 && capteurouest<10 && capteurnord<10)
                                     {
                                      digitalWrite(dirPin2,LOW);    // Engine turn one way to face east
                                      digitalWrite(freinPin2,LOW);  //Brake is off
                                      digitalWrite(vitessePin2, 5);    //Speed of the motor
                                      currentmillis = 0;
                                     }
                        }

But I face a new problem:
When my condition is true and the solar tracker turns east the current time is still moving on.. Then when the night come over again, my current time already overtook the interval I set (here 1 min), so it's like my timer is not taken into account anymore.
I would like to know if it's possible to reset this millis for the next time night come over? I put currentmillis = 0 but no doubts it looks too easy. :sweat_smile:
Thank you for your help

That would be creating a time stamp of the instant when the MCU booted up.

when you want to reset the tracker to face east, why not

  • recognize when night occur
  • check if the tracker needs to be repositioned

if need to be reposition

  • run the motor with a delay for the amount of time required
  • remember the position (e.g. flag)

the value to digitalWrite () is binary, 0/1. i don't believe 5 is doing what you expect


also curious if you're tracking west by comparing the east and west sensors and moving until they are equal?

Yee, as soon as west and east sensors (photoresistors) have the same amount of light, i stop my motor.

But my question is how could i set my millis() to 0? My millis still keep going then the next day my timer condition won't be true anymore. Maybe if i i can't reset it, can i force it to do the roll over earlier? Like i force millis to 4 294 967 294 (just before the roll over that reset the millis to 0 again).

if you need to measure/know the time from some specific point, you capture a timestamp at the point and subtract the current from the timestamp to know the relative time

Ok I see what you mean then I did it like that:

unsigned long startmillis;  //Create variables for timer
unsigned long currentmillis;
unsigned long interval = 60000; //Set an interval of 1 min
unsigned long previousmillis;

 if(capteurest<10 && capteurouest<10 && capteurnord<10)  // Check if night is here
                        {
                          
                          startmillis = 0;    //start the timer
                          previousmillis = currentmillis;  //timestamp of the current time
                          currentmillis = millis();  //get the current time
                               

                          Serial.print("startmillis = ");
                          Serial.println(startmillis);

                           Serial.print("previousmillis = ");
                          Serial.println(previousmillis);
                          
                          Serial.print("currentmillis = ");
                          Serial.println(currentmillis);
                          
                                            if(((previousmillis - startmillis) > interval) && capteurest<10 && capteurouest<10 && capteurnord<10)
                                                 {
                                                  digitalWrite(dirPin2,LOW);    // Engine turn one way to face east
                                                  digitalWrite(freinPin2,LOW);  //Brake is off
                                                  digitalWrite(vitessePin2, 5);    //Speed of the motor
                                      
                                                  }
                               
                               
                                                  
                               
                        }

But it looks when I run the code that previousmillis is not fixed in the time, still moving on like currentmillis.


Any ideas guys about how to "freeze" previousmillis?
Thanks for your help

when would you like to "reset" millis() and what event from the reset point are you trying to time?

i don't see where you capture the timestamp and use it. i see the following

currentmillis = millis();

but i don't see "currentmillis" used anywhere and i don't see "millis()" called anywhere else

consider

const unsigned long Interval = 60000; //Set an interval of 1 min

unsigned long msec;
unsigned long msecLst;
bool          moveEast;

enum { West, East };
enum { BrakeOff, BrakeOn };

void
func (void)
{
    msec = millis ();

    // enable some action and capture timeStamp
    if (capteurest<10 && capteurouest<10 && capteurnord<10) {
        moveEast = true;
        msecLst  = msec;

        digitalWrite (freinPin2,   BrakeOff);
        digitalWrite (dirPin2,     East);
        analogWrite  (vitessePin2, 255);        // motor fast
    }

    // execute some action for a fixed amount of time
    if (moveEast) {
        if (msec - msecLst >= Interval) {
            moveEast = false;
            analogWrite  (vitessePin2, 0);      // stop motor
            digitalWrite (freinPin2,   BrakeOn);
            digitalWrite (dirPin2,     West);
        }
    }

    // guess !! at normal sunlight operation
    else  {
        if (capteurest < capteurouest)          // East < West
            analogWrite (vitessePin2, 20);      // motor slow
        else
            analogWrite (vitessePin2, 0);       // stop motor
    }
}

You just need to study some working examples using millis(). Your conceptualization is incorrect, you will not make any progress until you abandon your present misunderstanding of how it should be used, and begin to understand the correct usage.

Time stamps are really simple in concept. They are just some time read from a timer, and captured in some variable.

*Please refer to the code in the post 5"
I would like to reset my millis() as soon as the 3 sensors are below 10.
For example,first day my solar tracker works, night come, sensors are below 10. I want to make sure it's the night so I want to use a temporization of 60 seconds and control sensors are still below 10 after one minute (like that i am sure it's the night and not just a temporary shadow)

if(((currentmillis - startmillis) > interval) && capteurest<10 && capteurouest<10 && capteurnord<10)

Let's say it's my first day the solar tracker run.. He gonna experienced the first sunset, then sensors<10, timers start, startmillis = 0 and currentmillis get the current time. After 60 seconds, we are above interval (set to 60 seconds) then solar tracker faces east again to prepare the sunrise for the next day (so far ok)
BUT!
my problem is the next day when the sunrise come again, (sensors get below 10, so far no problem) but my current time was still running for (24 hours+60 seconds=86460 seconds!) So already above the interval! Then my condition with a timer of 60 seconds is already useless after 2 days... :expressionless:
That's why I want to reset the millis() as soon as night is coming in order to respect my condition again.

the time is always relative to some "setpoint" which i think (??) should be set each day when all your captures are < 10. in the code i posted, that set point is msecLst.

so the relative time is always millis() - msecLst

Thank you for your help Gcjr,
I totally get what you say about the relative time millis() - mseclst.
But when I run your code, it looks like mseclst is still not fixed.

unsigned long msec;
unsigned long interval = 60000; //Set an interval of 1 min
unsigned long msecLst;
bool moveEast;

msec = millis ();
 
       if(capteurest<10 && capteurouest<10 && capteurnord<10)  // Check if night is here
                        {
                          moveEast = true;
                          msecLst = msec;
                           
                          if (moveEast) {
                                                  Serial.print("msec = ");
                                                  Serial.println(msec);
                                                  Serial.print("msecLst = ");
                                                  Serial.println(msecLst);
                                                     
                                            if(((msec - msecLst) >= interval))
                                                 {
                                                  
                                                  digitalWrite(dirPin2,LOW);    // Engine turn one way to face east
                                                  digitalWrite(freinPin2,LOW);  //Brake is off
                                                  digitalWrite(vitessePin2, 5);    //Speed of the motor
                                      
                                                  }
                               
                               
                                        } 
                                             
                                
                        }

Here is what I get when my sensors are below 10:


msecLst is not fixed, my relative time is always equal to 0, then I never exceed my interval in my condition:/

i'm not sure what you're expecting to see -- the code prints msec and msecLst immediately after msecLst is set to msec.

when moving east, you can simply start the motor and stop it after a delay. a flag is needed to only do this once east nightfall

but by capturing msec in msecLst, all times after moving east can be measured relative to msecLst if moving east only occur once

it's difficult to say more without seeing more of the code

please examine the following output and code. do i understand what you are trying to do correctly?

msec 0, msecLst 0, rest 100, ouest 100, night 0, moveEast 0
msec 1000, msecLst 0, rest 100, ouest 100, night 0, moveEast 0
msec 2001, msecLst 0, rest 100, ouest 100, night 0, moveEast 0
msec 3002, msecLst 0, rest 100, ouest 100, night 0, moveEast 0
msec 4003, msecLst 0, rest 100, ouest 100, night 0, moveEast 0
msec 5004, msecLst 0, rest 100, ouest 100, night 0, moveEast 0
msec 6005, msecLst 0, rest 100, ouest 0, night 0, moveEast 0
msec 7006, msecLst 0, rest 100, ouest 0, night 0, moveEast 0
 night:
 moveEast:
msec 8007, msecLst 8007, rest 0, ouest 0, night 1, moveEast 1
 moveEast:
msec 9027, msecLst 8007, rest 0, ouest 0, night 1, moveEast 1
 day:
 moveEast:
msec 10038, msecLst 8007, rest 100, ouest 100, night 0, moveEast 1
 moveEast:
msec 11061, msecLst 8007, rest 100, ouest 100, night 0, moveEast 1
 moveEast:
msec 12076, msecLst 8007, rest 100, ouest 100, night 0, moveEast 1
 moveEast:
msec 13091, msecLst 8007, rest 100, ouest 100, night 0, moveEast 1
 moveEast:
msec 14107, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 15123, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 16126, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 17129, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 18132, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 19136, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 20139, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 21142, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 22146, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 23148, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 24152, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 25155, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
 moveWest: 18151
msec 26158, msecLst 8007, rest 0, ouest 100, night 0, moveEast 0
msec 27177, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 28181, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
 moveWest: 21177
msec 29184, msecLst 8007, rest 0, ouest 100, night 0, moveEast 0
msec 30203, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 31207, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
 moveWest: 24203
msec 32210, msecLst 8007, rest 0, ouest 100, night 0, moveEast 0
msec 33230, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 34233, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
 moveWest: 27229
msec 35236, msecLst 8007, rest 0, ouest 100, night 0, moveEast 0
msec 36256, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 37259, msecLst 8007, rest 100, ouest 100, night 0, moveEast 0
msec 38262, msecLst 8007, rest 100, ouest 0, night 0, moveEast 0
 night:
 moveEast:
msec 39264, msecLst 39264, rest 0, ouest 0, night 1, moveEast 1
 day:
 moveEast:
msec 40286, msecLst 39264, rest 100, ouest 100, night 0, moveEast 1
 moveEast:
msec 41310, msecLst 39264, rest 100, ouest 100, night 0, moveEast 1
 moveEast:
msec 42327, msecLst 39264, rest 100, ouest 100, night 0, moveEast 1
 moveEast:
msec 43342, msecLst 39264, rest 100, ouest 100, night 0, moveEast 1
 moveEast:
msec 44359, msecLst 39264, rest 100, ouest 100, night 0, moveEast 1
 moveEast:
msec 45376, msecLst 39264, rest 100, ouest 100, night 0, moveEast 0
msec 46393, msecLst 39264, rest 100, ouest 100, night 0, moveEast 0
msec 47397, msecLst 39264, rest 100, ouest 100, night 0, moveEast 0
msec 48401, msecLst 39264, rest 100, ouest 100, night 0, moveEast 0
msec 49405, msecLst 39264, rest 100, ouest 100, night 0, moveEast 0
unsigned long msec;
unsigned long msecLst;
unsigned long interval = 6000;

bool moveEast;
bool night;

int capteurest;
int capteurouest;
int capteurnord;

const byte PinFakeInpE  = A1;
const byte PinFakeInpW  = A2;

const byte dirPin2      = 12;
const byte freinPin2    = 11;
const byte vitessePin2  = 10;

// -----------------------------------------------------------------------------
void
loop (void)
{
    msec = millis ();

    capteurest                 = digitalRead (PinFakeInpE) ? 100 : 0;
    capteurouest = capteurnord = digitalRead (PinFakeInpW) ? 100 : 0;
    
    // -------------------------------------
    if (! night && capteurest<10 && capteurouest<10 && capteurnord<10)
    {
        Serial.println (" night:");
        msecLst  = msec;
        night    = moveEast = true;
    }
    else if (night && capteurest > 20)  {
        Serial.println (" day:");
        night = false;
    }

    // -------------------------------------
    if (moveEast) {
        Serial.println (" moveEast:");

        if(((msec - msecLst) >= interval))
        {
            digitalWrite (dirPin2,    LOW);
            digitalWrite (freinPin2,  LOW);
            analogWrite  (vitessePin2, 5);    //Speed of the motor

            moveEast = false;
        }
    }
    else if (capteurest < capteurouest)  {
        Serial.print   (" moveWest: ");
        Serial.print   (msec - msecLst);
        Serial.println ();

        digitalWrite (dirPin2,    HIGH);
        digitalWrite (freinPin2,  HIGH);
        analogWrite  (vitessePin2, 200);
    }
    else {
        analogWrite  (vitessePin2, 0);
    }

    // -------------------------------------
    Serial.print  ("msec ");
    Serial.print  (msec);
    Serial.print  (", msecLst ");
    Serial.print  (msecLst);
    Serial.print  (", rest ");
    Serial.print  (capteurest);
    Serial.print  (", ouest ");
    Serial.print  (capteurouest);
    Serial.print  (", night ");
    Serial.print  (night);
    Serial.print  (", moveEast ");
    Serial.print  (moveEast);
    Serial.println ();

    delay (1000);
}

void setup (void)
{
    Serial.begin (9600);
    pinMode (PinFakeInpE, INPUT_PULLUP);
    pinMode (PinFakeInpW, INPUT_PULLUP);
}

Hello Gcjr!
Yes what you get on the monitor is exactly what I want!
But still when I integrate your code into mine, mine still acting differently and msec and msecLst are identic..


Here is my complete code after modifications:


int dirPin1 = 12;  //Assign the digital pins moteur linéaire 1 est/nord
int vitessePin1 = 3;
int freinPin1 = 9;

int dirPin2 = 13;  //Assign the digital pins moteur linéaire 2 est/ouest
int vitessePin2 = 11;
int freinPin2 = 8;

int capteurest = 0;   //Create variables for the east and west sensor values
int capteurouest = 0;
int capteurnord = 0;
int errorestouest = 0;
int absoluterrorestouest = 0;
int errorestnord = 0;
int absoluterrorestnord = 0;
int calibration = 0;


unsigned long msec;
unsigned long msecLst;
unsigned long interval = 6000;

bool moveEast;
bool night;

/*int capteurest;
int capteurouest;
int capteurnord;*/

const byte PinFakeInpE  = A1;
const byte PinFakeInpW  = A2;

/*const byte dirPin2      = 12;
const byte freinPin2    = 11;
const byte vitessePin2  = 10;*/

// -----------------------------------------------------------------------------
void setup (void)
{
    Serial.begin(9600);
  pinMode(dirPin1,OUTPUT);
  pinMode(vitessePin1,OUTPUT);
  pinMode(freinPin1, OUTPUT);
  digitalWrite(dirPin1,LOW);
  digitalWrite(vitessePin1,LOW);
  digitalWrite(freinPin1,LOW);

}
void loop (void)
{

   int capteurest = calibration + analogRead(capteurestPin);    //Read the sensors values
 int capteurouest = analogRead(capteurouestPin);
 int capteurnord = analogRead(capteurnordPin);


errorestouest = capteurest - capteurouest;       //Compare west and east values
absoluterrorestouest = abs(errorestouest);
//Serial.print("errorestouest = ");
    //Serial.println(errorestouest); 
Serial.print("absoluterrorestouest = ");
    Serial.println(absoluterrorestouest);  //just inform about light's difference between west and east

 Serial.print("capteurest = ");
   Serial.print(capteurest);
   Serial.print("capteurouest = ");
   Serial.print(capteurouest);
   Serial.print("capteurnord = ");
   Serial.print(capteurnord);      //give north and east value


errorestnord = capteurest - capteurnord;     //Compare value between east and north
//Serial.print("errorestnord = ");
// Serial.println(errorestnord);       // give one idea about light difference between north and east
absoluterrorestnord = abs(errorestnord);
Serial.print("absoluterrorestnord = ");
    Serial.println(absoluterrorestnord);
    Serial.println(); //saut de ligne*/
    msec = millis ();

    /*capteurest                 = digitalRead (PinFakeInpE) ? 100 : 0;
    capteurouest = capteurnord = digitalRead (PinFakeInpW) ? 100 : 0;*/
    
    // -------------------------------------
    if (capteurest<10 && capteurouest<10 && capteurnord<10)
    {
        Serial.println (" night:");
        msecLst  = msec;
        night    = moveEast = true;
        
           if (moveEast) {
            Serial.println (" moveEast:");

                  if(((msec - msecLst) >= interval))
                         {
                           digitalWrite (dirPin2,    LOW);
                           digitalWrite (freinPin2,  LOW);
                           analogWrite  (vitessePin2, 5);    //Speed of the motor

                           moveEast = false;
                          }
                        }
        
    }
    else if (absoluterrorestouest < 200)   //we consider east and west get almost same quantity of light so move direclty to north/east comparison
                      { 
                        digitalWrite(freinPin1, HIGH);
                        
                        if(absoluterrorestnord < 200) // mean east and north have same light so no need to move engine
                                                     {
                                                      delay(2000);
                                                     }
                        else if (absoluterrorestnord > 200) //east and north don't get same light so we move engine up or down
                                                            {
                                                             if(errorestnord > 200)  //east sensor get too much light in comparison with north so engine down
                                                                           {
                                                                           digitalWrite(dirPin1, HIGH);    
                                                                           digitalWrite(freinPin1, LOW);
                                                                           digitalWrite(vitessePin1, 5);
                                                                           //position++;
                                                                           delay(1000);
                                                                           digitalWrite(vitessePin1,0); 
                                                                           }
                                                             else if(errorestnord < -200) //north sensor get too much light in comparison with east so engine up
                                                                           {
                                                                           digitalWrite(dirPin1, LOW);     
                                                                           digitalWrite(freinPin1, LOW);
                                                                           digitalWrite(vitessePin1, 5);
                                                                          // position++;
                                                                           delay(1000);
                                                                           digitalWrite(vitessePin1,0); 
                                                                               }
                                                            }
                        }
  
                     
           else if(absoluterrorestouest > 200)  //east and west don't have same light so turn east or west
                             {
                                                            if(errorestouest > 200 )     //westt don't get too much light with respect to east sensor so turn east
                                                            {
                                                             digitalWrite(dirPin2, LOW);     //Moteur tourne en sens inverse pour placer le panneau face à l'est
                                                             digitalWrite(freinPin2, LOW);
                                                             digitalWrite(vitessePin2, 10);
                                                             //position++;
                                                             delay(1000);
                                                             digitalWrite(vitessePin2,0);  // Mettre a 1 si l'on veut une course continue, mettre à 0 si l'on veut une course limitée//
                                                             }
                                                             
                                                             else if(errorestouest < -200 ) //west has too much light with respect to east so turn west
                                                             {
                                                             digitalWrite(dirPin2, HIGH);     //Moteur tourne en sens normal pour placer le panneau face à l'ouest
                                                             digitalWrite(freinPin2, LOW);
                                                             digitalWrite(vitessePin2, 10);
                                                             //position++;
                                                             delay(1000);
                                                             digitalWrite(vitessePin2,0); // Mettre a 1 si l'on veut une course continue, mettre à 0 si l'on veut une course limitée//
                                                             }
                           }
    
    

    // -------------------------------------
    
   /* else if (capteurest < capteurouest)  {
        Serial.print   (" moveWest: ");
        Serial.print   (msec - msecLst);
        Serial.println ();

        digitalWrite (dirPin2,    HIGH);
        digitalWrite (freinPin2,  HIGH);
        analogWrite  (vitessePin2, 200);
    }
    else {
        analogWrite  (vitessePin2, 0);*/
    

    // -------------------------------------
    Serial.print  ("msec ");
    Serial.print  (msec);
    Serial.print  (", msecLst ");
    Serial.print  (msecLst);
    Serial.print  (", rest ");
    Serial.print  (capteurest);
    Serial.print  (", ouest ");
    Serial.print  (capteurouest);
    Serial.print  (", night ");
    Serial.print  (night);
    Serial.print  (", moveEast ");
    Serial.print  (moveEast);
    Serial.println ();

    delay (3000);
}

this is a problem with simulation, i only simulated the condition for night momentarily. but even the somewhat bogus simulation output confirmed my understanding of what you're trying to do.

looks like msecLst is constantly being updated. msecLst should only be set to msec once each night. in other words, it should only be captured once when night is first recognized

please try this

    if (capteurest<10 && capteurouest<10 && capteurnord<10)
    {
        Serial.println (" night:");
        if (! night) 
            msecLst  = msec;
        night    = moveEast = true;