Storing random values of millis() while inside a loop?

Is it possible to store a value of time while you're inside a loop? Entertain the condition:

if (condition && value > 0)
{
timeTrans = millis() + 2000;
timeTrans - millis() = value;
}

basically i want it to begin counting down from 2 to 0 no matter what time it is at, but the problem is if it's inside the loop tineTrans will update as millis counts up, and value will always be 2000 and will never count down to 0. And the condition stated in the if function cannot be called in void setup(), so there's no hope in that direction. I'd post my code but it's a little long, if it will help find a solution i will post it and point around to what i'm working on.

I also tried using for loops as well but it counts wayyyy too fast for it to be viable, and obviously i cant delay it while its inside a void loop(). Is there any other way i can go about with this?

The demo Several Things at a Time illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

…R

yeah i took a look at those before posting, but the thing that got me confused/made me think it wouldnt work in my example is that while you guys use preset intervals to save the times to, my intervals come at random. If i tried to apply the example to my case

if (currentTime - previousTime < (the time that my pressure went lower than 2000)
        previousTime = that time;
    (use previousTime here for whatever function i want to run as it is now a constant digit)

but the thing is, before that, I do not know at what time the period/interval is, or when the pressure is going to go below 2000

so i get that we’re setting previous time equal to a constant digit (in your example) that is related to time but doesnt change with it, but the thing is, how am i supposed to know what that time is going to be in this case?

Am i understanding all of this correctly by the way?

Okay well, i've been toying around with it and here's where i'm at right now, this is about as clear and concise as this question is going to get

is there any way to make "time-2000" a constant variable in this example?

unsigned long time, timeNow, timePast, timeStart, value;
unsigned long period;

void setup() {
  Serial.begin(9600);
  timeStart = 0;
    
}

void loop() {
  time = millis();
  if (time > 3000) //Using time bigger than 3 sec as a condition substitute to trigger my event
  period = time-2000; //Since in my example, we'll know at what time the condition was triggered (once it's triggered), I set the "period" to that.
    if ((time - timeStart) > period) //aaaaannndd the attempt
      timePast = period;

  Serial.print("Time: "); //debugging
  Serial.print(time);
  Serial.print(" please work ");
  Serial.println(timePast);
}

that "time-2000" just needs to be turned into a constant somehow. After that, i'll be golden. Anybody know a way around this?

"time-2000" just needs to be turned into a constant somehow

You cannot turn it into a constant because it will keep changing and cannot, therefore, be a constant. You could, however, save its value as it is now in a variable for use later.

unsigned long timeMinus2000 = time - 2000;

Solved. really simple solution.. no idea why i didnt try this earlier.

unsigned long time, timeNow, timePast, timeStart, value;
unsigned long period, trans, transStop;
int x1 = 0;

void setup() {
  Serial.begin(9600);
  timeStart = 0;
    
}

void loop() {
  time = millis();      
  if (time > 3000)
  {
    if (x1 == 0) 
    {
      trans = time;
      transStop = time + 2000;
      x1++;
    }
    //place your function here
  }

  Serial.print("Time: ");
  Serial.print(time);
  Serial.print(" Trans ");
  Serial.print(trans);
  Serial.print(" please work ");
  Serial.println(transStop);
  
}

Basically you set an if statement, and set it to loop only once and inside that loop you set the time equal to whatever variable you want. You can change the condition (time > 3000) to whatever second you want and trans/transStop changes based on that and sets itself equal to time at that point and exits the loop right after. You're going to be off by 1ms (trans = 3001 instead of 3000) but that doesnt matter.

One potential downfall i see is that i'm going to have to make multiple x1, x2, x3, x4, etc variables and set them all equal to 0. Maybe there's a way to "automate" this process and recycle the variable? maybe set all other time related if statements to (if x1 == 1) or (if x1 == 2) and etc? feel like that'd work fine.

Thanks for all the help guys

Once you start numbering variables, arrays!

And not all varaibles need to be global. Define then where you need them ;)

And I don't know what you want to do with the variable transStop but you can't use it for timing if you don't want to have trouble with rollovers.

so basically the program i’m making is a little flight controller for gliders. it’s supposed to pick and choose when it’s going to dip for more velocity, or lose/gain altitude based on how its doing, and the way i make it change its attitude is i basically just change what angle it’s stabilizing itself to. if i have the program change this instantly, the aircraft has a high chance it could stall out, and so to smooth the inputs i’m having the program change the attitude over time. TransStop was the variable used for the end time of the “transition”, and trans is the time i use to begin the “transition”.

it’s a really simple y=mx+b formula. here’s the initial code i had for it to begin transition based on time. Now i’m having it transition based on altitude but you get the idea:

 if (time >= trans && time < transStop)
  {
    m = (desiredAngle-(currentAngle))/((transStop-trans)/1000);
    x = (time/1000);
    b = (-m*(transStop/1000)+desiredAngle);
    pid_pitch_setpoint = m*x+b;
  }

Any rhyme or reason as to why i should move the declared variables? I’m not trying to start a debate, i’m new to programming so i genuinely want to know the reason behind it. and also right now i’m declaring waaaaayyy too much stuff up at the top, it looks hella cluttered.

I havent gotten into arrays either, but would i just put multiple desired values into the array and “index” them (is that the right term?) to pull my desired time? That’s actually pretty smart, thanks for pointing that out.

I'm a glider pilot myself so I know how that works. But the other part just sounds like filtering / averaging to me, correct? I think I would do that with a rolling average.

Problem with storing [u]end[/u] times and checking like currentTime > endTime is that it breaks when millis rolls over. Where storing the start time and checking if the interval you want has passed does not (currentTime - startTime > interval).

OhItsTarik: and also right now i'm declaring waaaaayyy too much stuff up at the top, it looks hella cluttered.

That's one of the reasons. Other reason is that every global declaration takes up memory where a local declaration only takes memory when it's needed. Also, because you encapsulate it better, the program is safer to use. You can't accidentally change a variable from some place you don't want to change it.

OhItsTarik: I havent gotten into arrays either, but would i just put multiple desired values into the array and "index" them (is that the right term?) to pull my desired time? That's actually pretty smart, thanks for pointing that out.

yep, that's exactly right! That way you don't have to write out every possible index but just a general way.

Problem with storing end times and checking like currentTime > endTime is that it breaks when millis rolls over.

That can be a real problem on those 49+ day glider flights, eh?

He, I don't know if he powers the system off or not. It's not in the specsheet! :D