Counting Elapsed Time with micros(). Please help.

Hello, the issue I’m having when counting elapsed time is that the program uses the time at which I reference the variable. For instance, here is some sample code that shows my issue:

unsigned long t1;
unsigned long t2;
double dt;
boolean detected = false;
//IRRELEVANT VARIABLES OMITTED

void setup()
{
}

void loop()
{
   //IRRELEVANT CODE OMITTED
    delay(100);

    if(detected != true) {
      t1=micros();
      detected=true;
    }
    if(change >= minChange && detected == true) {
      t2 = micros();
      dt = t2-t1; //change in time
      
      Serial.println(dt);

      dt = (double) (dt/1000); //to convert to seconds
    }
}

The println in the second if statement above always outputs 8 or 12, something like that, when it should be in the thousands.

If I print the t1 in both if statements, it’s different, when it should be the same. It gets the time when the variable is referenced. It doesn’t actually save the value of the time, it just saves the “method” attached to the variable.

How do I fix this?? Thanks.

Here is my full code:

#include <elapsedMillis.h>
#include <SoftwareSerial.h>
#include <SF02.h>

#define TERMINAL_MONITOR_BAUDRATE  9600

#define SERIAL_RX_PIN      11
#define SERIAL_TX_PIN      10
#define SERIAL_RX_PIN_2     6
#define SERIAL_TX_PIN_2     5
#define ANALOG_PIN_1        1
#define ANALOG_PIN_2        2

SF02 RF1;
SoftwareSerial rf1Serial(SERIAL_RX_PIN, SERIAL_TX_PIN);
SF02 RF2;
SoftwareSerial rf2Serial(SERIAL_RX_PIN_2, SERIAL_TX_PIN_2);

#define interval 20
unsigned long t1, t2;
unsigned long dt;
double timeElapsed;
float curReading1, curReading2;
float prevReading1 = 0.0, prevReading2 = 0.0;
float d1, d2, dx;
float v = 0.0;
float x = 0.127; //distance in meters between rangefinders
float minChange = 0.7;
float minVelocity = 2.0;
boolean detected = false;

void setup()
{
  Serial.begin(TERMINAL_MONITOR_BAUDRATE);
  rf1Serial.begin(RF1.getAuxUartBaudRate());
  RF1.begin(rf1Serial);
  RF1.set00vDistance(0.0);
  RF1.setAnalogInputPin(ANALOG_PIN_1);
  rf2Serial.begin(RF2.getAuxUartBaudRate());
  RF2.begin(rf2Serial);
  RF2.set00vDistance(0.0);
  RF2.setAnalogInputPin(ANALOG_PIN_2);
}

void loop()
{
    dx = 0;
    delay(100);
    curReading1 = RF1.getAnalogDistance()-2.8;
    curReading2 = RF2.getAnalogDistance()-2.8;
    if(prevReading1 < 0.05 && prevReading2 < 0.05) {
      prevReading1 = curReading1;
      prevReading2 = curReading2;
    }
    float change1 = prevReading1-curReading1;
    float change2 = prevReading2-curReading2;
    dt = 0;
    if(change1 >= minChange && detected != true) {
      t1=micros();
      Serial.println(t1); 
      d1 = curReading1;
      detected=true;
    }
    if(change2 >= minChange && detected == true) {
      t2 = micros();
      Serial.println(t1); //prints different value than before
      dt = t2-t1;
      timeElapsed = (double) (dt/1000);
      d2 = curReading2;
      double diff = d1-d2;
      if(diff < 0) {
        diff = -1*diff;
      }
      dx = sqrt(pow(x,2)+pow(diff,2));
      v = dx/(timeElapsed);

      detected = false;
    }
    prevReading1 = curReading1;
    prevReading2 = curReading2;
}

How about you un-omit irrelevant variables and code, like "change" and "minChange"?

Like always, try not to use floats. make dt a unsigned long as well. Floats are slow, stupid and not needed. And to print in seconds just do

print(dt/1000);
print(".");
println(dt%1000);

@AWOL, other code literally has no bearing on the time so it should not matter. We're using this with a range finder sensor, but I can put everything if you really think it would help.

I edited my post and at the bottom have my full code.

@septillion, I had the same issue while making dt and unsigned long as well.

Why do you think t2 - t1 should be very much greater than 12?

Have you tried printing t1 and t2 ?

...R

@Robin2, I updated my post with full code at the bottom, t1 is set when one sensor senses an object and the other when another senses an object. I'm the one setting the sensors off and so I'm in control of the time.

Like I said, if I print t1 right after setting the variable and print t1 in another part of the code, it's different, which should not be the case. t1 should be the same throughout.

if I print t1 right after setting the variable and print t1 in another part of the code, it’s different, which should not be the case. t1 should be the same throughout.

Can you please post a complete program that shows this problem ?

@UKHeliBob, it's at the bottom of my original post. The second code block.

There is a chance that you are seeing the second print before the first one, hence the change.

Add some text labels to the prints so that you can distinguish one from the other.

SoftwareSerial rf1Serial(SERIAL_RX_PIN, SERIAL_TX_PIN);
SoftwareSerial rf2Serial(SERIAL_RX_PIN_2, SERIAL_TX_PIN_2);

One of the limitations of SoftwareSerial is that only one SoftwareSerial port can be looking for input at a time. When you call rf1Serial.available() then it will watch for a start bit on rf1Serial. If you then call rf2Serial.available() it will STOP looking for a start bit on rf1Serial and start looking for one on rf2Serial.

johnwasser: SoftwareSerial rf1Serial(SERIAL_RX_PIN, SERIAL_TX_PIN); SoftwareSerial rf2Serial(SERIAL_RX_PIN_2, SERIAL_TX_PIN_2);

One of the limitations of SoftwareSerial is that only one SoftwareSerial port can be looking for input at a time. When you call rf1Serial.available() then it will watch for a start bit on rf1Serial. If you then call rf2Serial.available() it will STOP looking for a start bit on rf1Serial and start looking for one on rf2Serial.

Is there any way to fix it? Any alternative? Thanks.

nishilshah17: Is there any way to fix it? Any alternative? Thanks.

You could use an Arduino MEGA and use hardware serial (Serial1, Serial2, or Serial3) for one or both of the devices. You could use an Arduino Leonardo and use hardware serial (Serial1) for one of the devices.

nishilshah17:
@Robin2, I updated my post with full code at the bottom, t1 is set when one sensor senses an object and the other when another senses an object. I’m the one setting the sensors off and so I’m in control of the time.

Like I said, if I print t1 right after setting the variable and print t1 in another part of the code, it’s different, which should not be the case. t1 should be the same throughout.

It makes it very difficult to make sense of a Thread if you update the code in an earlier Post. Put updated code in a new Post to maintain the flow of the discussion.

As said in Reply #9 your code provides no way to know what value is being printed.

You MIGHT be able to run yet another software serial alongside SoftwareSerial to have two functioning software ports. That’s not why I wrote it and I never tested it like that.

…R