Measure Time between pin low and high

Hi,

I have attached a digital distance sensor to my Arduino Uno. If there is an object in front of the sensor the signal is "LOW", otherwise it is "HIGH". That works already and I can see this on the LED of the sensor and on the serial monitor.
In the end I would like to be able to put the arduino in sleep mode, awake it when something is in front of the sensor and measure how long (~5 to ~120 seconds) it is there.
The problem is that I get random values if I put my hand in front of the sensor.

My Code with attachInterrupt:

volatile int16_t time = 0; //pwm value
volatile int16_t trig = 0; //timer value
int pin = 2;
//#define pin 2 //pin the interrupt is attached to

void intHandler() //function to call on interrupt
{
if(digitalRead(pin)==LOW) //if the pin is HIGH, note the time
{
trig = micros();
}
else
{
time = micros()-trig; //if it is low, end the time
}
}

void setup(){
pinMode(pin, INPUT); //set the pin to input
attachInterrupt(0,intHandler,CHANGE); //attach the interrupt function "intHandler" to "pin" whenever the state changes
Serial.begin(9600); //begin serial comms
}

void loop()
{

Serial.print("Time = ");
Serial.println(time);
}

Output:

Time = 0
Time = 0
Time = 0
Time = 0
Time = 0
Time = 0
Time = 0
Time = 0
Time = 0
Time = 0
Time = 0
Time = 0
Time = 0
Time = 0
Time = 0
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = -24088
Time = 27628
Time = 27628
Time = 27628
Time = 27628
Time = 30540
Time = 30540
Time = 30540
Time = 30540
Time = 30540
Time = 30540

My code with pulseIn:

int ledPin = 13; // LED connected to digital pin 13
int inPin = 7; // pushbutton connected to digital pin 7
int val = 0; // variable to store the read value

void setup()
{
Serial.begin(9600);

pinMode(ledPin, OUTPUT); // sets the digital pin 13 as output
pinMode(inPin, INPUT); // sets the digital pin 7 as input
}

void loop()
{
long duration;
val = digitalRead(inPin); // read the input pin
digitalWrite(ledPin, val); // sets the LED to the button's value
duration = pulseIn(inPin, LOW);
Serial.println(val);
Serial.print("Dauer: ");
Serial.print(duration);
}

Output:

1
Time: 01
Time: 01
Time: 01
Time: 01
Time: 01
Time: 01
Time: 00
Time: 650451
Time: 325211
Time: 43041
Time: 5961891
Time: 21531
Time: 21531
Time: 280251
Time: 260231
Time: 4986941
Time: 21671
Time: 259421
Time: 01
Time: 01
Time: 01
Time: 01
Time: 0

I really don't know where the problem is and how to solve it. I really appreciate your help.

Kind regards,
rookie

    if(digitalRead(pin)==LOW) //if the pin is HIGH, note the time
  {
    trig = micros();
  }

Explain the comment!

The pulseIn() function is blocking. It waits for a change in pin state, or for the time-put period to elapse, Your other code simply prints the value in time as fast as it can. I think you would see more useful values if you printed time only when it changed.

Thank you very much for your answer! The comment was a mistake, I have changed High to Low and did not correct the comment.
I think I have changed the code as you suggested but it does not seem to work all the time.

I use a stop watch to see if the values are correct. Sometimes i get this output, but i should be ~1000 to 3000 milliseconds. When the result should be above 20000 ms i often get no result or a few milliseconds.

equal
equal
equal
equal
Time = 24 ms
equal
equal
equal
equal
equal
equal
equal
equal
equal
equal
equal
equal
equal
equal
equal
equal
Time = 9 ms
equal
equal
equal
equal
equal
equal
equal
equal
equal
equal
Time = 2 ms
equal
equal
equal
equal

My code:

volatile unsigned long trig = 0; //timer value
volatile unsigned long length = 0;
unsigned long previousTime = 0;
int pin = 2;

void intHandler() //function to call on interrupt
{
if(digitalRead(pin)==LOW) //if the pin is LOW, note the time
{
trig = millis();
}
else
{
length = millis()-trig; //if it is low, end the time
}
}

void setup(){
pinMode(0, INPUT); //set the pin to input
attachInterrupt(pin, intHandler, CHANGE); //attach the interrupt function "intHandler" to "pin" whenever the state changes
Serial.begin(9600); //begin serial communication
}

void loop()
{
if (previousTime == length){
Serial.println("equal");

}else {

Serial.print("Time = ");
Serial.print(length);
Serial.println(" ms");
previousTime = length;

}

delay(200);

}

I would be really grateful if you could help me :slight_smile:

If you only print the changes, you won't need that delay().

What kind of sensor is that? Ultrasonic sensors need timing in micros to measure less than 30-some centimeters.

  if (previousTime == length){

If 3:30 equals 2 feet 7 inches...

I really don't think that will work. Meaningful names!!

They've removed the code tags link from the edit window!
Someone asked to change the symbol so now it's gone.

WTF Arduino?

The code tag is now the first symbol on the row, before the B and the I and the U

Hi,
Now they need to print CODE instead of using silly little symbols that aren't even remotely indicating CODE.

What sensor are you using and how have you got it connected?

Tom.... :slight_smile:

Hi,

thank you very mich for your efforts! :slight_smile:
I am using this sensor: Pololu Carrier with Sharp GP2Y0D815Z0F Digital Distance Sensor 15cm
length means length oft time, sorry for confusing!
The sensor does not tell me the distance to the object. It only tells me that there is an object or not.

HI,

The problem is that I get random values if I put my hand in front of the sensor.

If you use a piece of wood, or a jar or a can, are the readings stable?
Is your hand the only thing that produces the erratic readings.

Tom...... :slight_smile:

Should this: pinMode(0, INPUT); //set the pin to input
Be: pinMode(pin, INPUT); //set the pin to input

The module output may be open collector, try:
pinMode(pin, INPUT_PULLUP); //set the pin to input

The pin change interrupt may be causing unintended interrupts, try your sketch without the interrupt routine.

Hi,
Have you read some of the conditions regarding the target on page 6 of the specs?

If the object is inside 15cm the output is LOW.

Tom..... :slight_smile:

Try this quick sketch just to see if your sensor works as you expect.

unsigned long trig = 0;
unsigned long length = 0;
unsigned long previousTime = 0;
int pin = 2;
byte tgl = 0;

void setup()
{
  pinMode(pin,INPUT_PULLUP);
  Serial.begin(9600);

}

void loop()
{
  if(!digitalRead(pin) && !tgl){
    trig = millis();
    tgl = 1;
  }  
  if(digitalRead(pin) && tgl){
    length = millis() - trig;
    tgl = 0;
    Serial.println(length);
  }
    
}

Thank you all very much for your kind help! I really appreciate that :slight_smile:
@TomGeorge my sketch produces much better results when I don't use my hand. I think that is because a hand is not flat.

@klubfingers: it does not seem to make any difference when I use pinMode(pin, INPUT_PULLUP);
But using pinMode(pin, INPUT); helped. I was confused because of interrupt 0 and pin 2.
I have also used your short sketch and my sensor works as I expect.
I would like to use the interrupt function because I would like to send the arduino to sleep and wake it up when there is something in front of the sensor to save battery. I have all the parts for a breadboard arduino, so I am just testing on the UNO to eliminate mistakes.