Using Millis for condition

Hi guys, so basically i’m using millis as a condition. The whole idea is when the data that is achieved is within 1second(1000mS), my serial monitor will show me how long it took for it to achieve. The problem i faced is, it seems that the only 2-3 numbers i see is 41mS,42mS or 225mS when it is working.

below is the code that i run and was wondering if there is anything wrong with it or it is just so coincidental that it only happens at this 3 timing.

unsigned long newMillis;
unsigned long oldMillis;
void setup() {
  BeanHid.enable();
   Serial.begin(57600);
   newMillis = millis();  //initial start time
}

void loop() 
{
 
static int16_t x_last;

AccelerationReading accel = Bean.getAcceleration();
int16_t x = abs(accel.xAxis/2);

 oldMillis = millis();  //current time


  if (x >= x_last + 50) {
  if (oldMillis - newMillis <= 1000) { ;
  Bean.setLed(0, 255, 0); //Green Led
   
     
       Serial.print("Time=");
       Serial.println(oldMillis - newMillis);
       Serial.print("x=");
       Serial.println(x);
    
  }
     
  }
  
  x_last = x;
  newMillis = oldMillis;
}

It looks like exactly the same code is being executed in one loop cycle, so it should not be surprising that it takes the same length of time to execute.

Of course, it is not clear what is going on in your accel object but if the values of mS were more random than you have found them to be, the answer would probably have been found there.

6v6gt: It looks like exactly the same code is being executed in one loop cycle, so it should not be surprising that it takes the same length of time to execute.

Of course, it is not clear what is going on in your accel object but if the values of mS were more random than you have found them to be, the answer would probably have been found there.

ok i realised it now. in that case, is it possible for me to create a millis that would reset everytime i enter a loop? from what i read online, it seems like it is quite impossible.

the code logic is,

1)get X axis acceleration value 2)compares the previous X value to the current X value 3)"if" condition, if the current x is more than or equals to the previous x value+50 4)"if" condition, compare old time and new time, if it uses less then 1 seconds to achieve it, print my current x value. 5)previous value = current value

and i could achieve the above, but i would like to add in the condition that of line 4 which needs to utilise "millis". which in turn creates a timer to compare the timing of the new value and when it achieves the "old value + 50".

is it possible for me to create a millis that would reset everytime i enter a loop?

No need. Just save the value of millis() when the start action happens

Have you read Using millis() for timing. A beginners guide ?

UKHeliBob: No need. Just save the value of millis() when the start action happens

Have you read Using millis() for timing. A beginners guide ?

yeap i read the whole 3 parts but it don't seems like i could utilise the idea? or maybe im missing something here.

Can I confirm what you want to do ?

when the data that is achieved is within 1second(1000mS), my serial monitor will show me how long it took for it to achieve.

Seems to imply that you acquire data during a 1 second period and once inquired you report on the time take to acquire it. If that is the case then you should save the value of millis() when the period starts and start reading data. If your criteria are met before 1 second has elapsed then save the value of millis() at that time

Now you have a start and end value from which you can calculate the elapsed time.

Maybe something like this

report = false
save millis() value as start time

start of loop()
  if millis()) - start time >= period
    save millis() value as start time  //start again
  end if

  read data
  if criteria are met
    save millis() value as end time
    report = true
  end if

  if report
    calculate elapsed time
    report on elapsed time
    report = false
    save millis() value as start time  //start again
  end if
end of loop()

Crossed with @UKHeliBob’s post

I think I get it.
You are trying to measure the length of time (in mS) that it takes for ‘x’ to increase (or change?) by 50 units.
If that time is less than 1000 mS, you want to print out the value of x and the time it took to get there.

I guess your loop should be something like this:

void loop()
{

  static int16_t x_last;

  AccelerationReading accel = Bean.getAcceleration();
  int16_t x = abs(accel.xAxis / 2);

  oldMillis = millis();  //current time


  if (x >= x_last + 50) {
    if (oldMillis - newMillis <= 1000) {
      Bean.setLed(0, 255, 0); //Green Led

      Serial.print("Time=");
      Serial.println(oldMillis - newMillis);
      Serial.print("x=");
      Serial.println(x);

    }
    x_last = x;
    newMillis = oldMillis;
  }
}

6v6gt:
Crossed with @UKHeliBob’s post

I think I get it.
You are trying to measure the length of time (in mS) that it takes for ‘x’ to increase (or change?) by 50 units.
If that time is less than 1000 mS, you want to print out the value of x and the time it took to get there.

I guess your loop should be something like this:

void loop()

{

static int16_t x_last;

AccelerationReading accel = Bean.getAcceleration();
 int16_t x = abs(accel.xAxis / 2);

oldMillis = millis();  //current time

if (x >= x_last + 50) {
   if (oldMillis - newMillis <= 1000) {
     Bean.setLed(0, 255, 0); //Green Led

Serial.print(“Time=”);
     Serial.println(oldMillis - newMillis);
     Serial.print(“x=”);
     Serial.println(x);

}
   x_last = x;
   newMillis = oldMillis;
 }
}

yeap! i managed to somehow got it also, but thanks!! i was just wondering why the code would not work if i were to use “newMillis - oldMillis” even when i set “oldMillis = newMillis”? shouldn’t the logic be the same?

& to add on, if i were to use the oldMillis - newMillis, wouldn’t the first loop be a false detection as the first value of the oldMillis will always be smaller then the newMillis, since newMillis is declared at the setup which is before the oldMillis is being declared?

That could be your choice of names newMillis and oldMillis. It is very confusing since oldMillis in your sketch can be newer than newMillis. Better would have been currentMillis and oldMillis or even not use currentMillis at all, but simply millis()

6v6gt:
That could be your choice of names newMillis and oldMillis. It is very confusing since oldMillis in your sketch can be newer than newMillis.
Better would have been currentMillis and oldMillis or even not use currentMillis at all, but simply millis()

maybe i have the wrong understanding of millis();

am i write to say the millis(); that are declared at each line are run accordingly to their lines? meaning the millis() at setup is run first, then the millis() at the loop is run?

KJJ: maybe i have the wrong understanding of millis();

am i write to say the millis(); that are declared at each line are run accordingly to their lines? meaning the millis() at setup is run first, then the millis() at the loop is run?

No, there's only one millis running. It's like a clock on the wall: you only need one. You look at it every now and then, and note the time. You don't need 3 clocks to time 3 things. You make a note of the time when the first thing starts, and look at the clock in a while to see if the new time minus the time at which it started is as long the time you want it to run for. If it is,you stop doing the thing; if not look again in a while. That "while" is how quickly it gets through loop(). But you can have 3 start times in your head, or 10, all with different start times, the start time being the value of millis() you saved into ISwitchedThelightOnAt or ILetTheDogOutAt or whatever.

In the same way that your wall clock shows you hours, minutes and seconds, which could easily be reduced to just seconds, since midnight, millis() is milliseconds since power on or reset.

wilfredmedlin: No, there's only one millis running. It's like a clock on the wall: you only need one. You look at it every now and then, and note the time. You don't need 3 clocks to time 3 things. You make a note of the time when the first thing starts, and look at the clock in a while to see if the new time minus the time at which it started is as long the time you want it to run for. If it is,you stop doing the thing; if not look again in a while. That "while" is how quickly it gets through loop(). But you can have 3 start times in your head, or 10, all with different start times, the start time being the value of millis() you saved into ISwitchedThelightOnAt or ILetTheDogOutAt or whatever.

In the same way that your wall clock shows you hours, minutes and seconds, which could easily be reduced to just seconds, since midnight, millis() is milliseconds since power on or reset.

so if i were to have 2 millis() in my code, mainly one in the setup and one in the loop, the system will start the counting during the setup or loop? does it means one is redundant?

KJJ: so if i were to have 2 millis() in my code,

It seems to me you have a fundamental misunderstanding.

Whenever your program calls the millis() function it gets the latest value. The value starts incrementing when your Arduino is reset (or started) and it keeps counting for about 49 days and then it rolls over to zero and starts counting up again.

The millis() function behaves exactly like the clock on your kitchen wall. Every time you call the millis() function it is the same as looking at your clock. Now the clock says 13:34. When I look at it again in 5 minutes time it will say 13:39.

In a well written program the loop() function will repeat hundreds or maybe thousands of times per second. It can be useful at the start of loop() to capture the latest value of millis() into a variable called currentMillis so that all the tests for elapsed time in that iteration of loop() use the same time value. Even though loop() repeats very quickly it is possible that the change from a millis() value of (say) 124,367 to 124,368 could happen during one iteration of loop(). If that level of precision does not matter then your program can do all its comparisons against the latest value.

Have a look at how millis() is used in Several Things at a Time. It may help with understanding the technique.

...R

Just in case I introduced more confusion for the OP by remarking on the already confusing choice of variable names, I’ve rewritten the code I supplied with a more easily understandable (imho) choice of names for these variables.

void loop()
{
  static uint32_t last50UnitChangeinXatMs ;  // this the value of millis() the last time we
                                             // noticed a >= 50 unit change in x
  static int16_t x_last;

  AccelerationReading accel = Bean.getAcceleration();
  int16_t x = abs(accel.xAxis / 2);

  if (x >= x_last + 50) {
    if (millis() - last50UnitChangeinXatMs <= 1000) {
      Bean.setLed(0, 255, 0); //Green Led

      Serial.print("Time=");
      Serial.println(millis() - last50UnitChangeinXatMs );
      Serial.print("x=");
      Serial.println(x);

    }
    x_last = x;
    last50UnitChangeinXatMs = millis() ;
  }
}