10 years, 10 months ago.

Pulse Width measurement trouble

Hi, can anyone help me please cause i'm really struggling.

I am trying to get an ultrasonic range sensor working. The sensor I have gives a pulse output relating to distance (58us per cm, simple enough), I need to measure this pulse time and display it and the use it for other things. I was wondering if I could somehow start a timer when the pulse input goes high and stop the timer when it goes low. I could really use some help.

The sensor is a XL-Maxsonar WR1 MB7060 I'm using a LPC11U24

Many Thanks

Rob

1 Answer

10 years, 10 months ago.

Yes you can do that, that would be the normal way to measure those things.

This program for example does it using interrupts:

Import librarySRF05

Library for the SRF05 Ultrasonic Rangefinder

And this one just waits during the pulse:

Import libraryHCSR04

Library for controlling ultrasonic ranging module HCSR04 Ported by hiawoood from arduino library orgininally created by ITead studio.

They are different modules than you have, but the measurement part should be fairly similar.

Hi Thanks for the reply. I have seen those examples of code before and to be honest its a bit over my head. I wouldn't know where to start when importing them and trying to use them. Things like setting up the pins to use, knowing which bits of code are relevant. Sorry, but i'm a bit new to this :) I think my first problem is the data sheet for the sensor doesn't tell you whether the sensor constantly puts out the pulse signal or if its every second?? The data sheet is a bit confusing for me concerning that. It does state that for best results use the pulse width method. But looking at the sheet it also has a pin (pin 5) which gives out a asynchronous serial RS232 format output which gives characters representing the distance. If this could be used surely that would be easier??

Many Thanks

posted by robert heaney 28 Jul 2013

Problem with the RS232 port of that IC is that the data is inverted. So you would first need to place an inverter after it to get it normal again.

According to the datasheet each period is 99ms. So every 99ms a pulse signal is generated. What you then need to do is measure the time the output pulse is 'high'. So similar to how the second library I linked does it:

//I assume here you got 'range' defined as DigitalIn on the correct pin
Timer timer;  //Define a timer we can use

while(range == 1);    //This blocks the program as long as your range pin is high.

//So here the range pin must be low

while(range == 0);    //This blocks the program as long as your range pin is low.

//When we get here it means the range pin just went from low to high
timer.start();             //So start measuring the time

//Wait as long as the pin is high:
while(range == 1);

//Here the output is low again, so we can stop the timer.
timer.stop();

int time_us = timer.read_us()
float cm = time_us/58;

Can be alot more efficient than that, but something like that should work as basic example.

posted by Erik - 28 Jul 2013

Hi Thanks for the reply. What you've put makes sense but i'm having trouble getting it going. I have changed a few bits to try and clear the errors I get but there is still a lot of errors I don't know how to clear. After the while statements do I need to have some more code in there?? Here is what I have:

#include "mbed.h"
#include "Terminal.h"

Terminal term(USBTX, USBRX);
Timer t;
DigitalIn range(p10);
int range;
int time_us = t.read_us()
float cm = time_us/58;

//I assume here you got 'range' defined as DigitalIn on the correct pin
//Timer timer;  //Define a timer we can use
 
   while(range == 1);    //This blocks the program as long as your range pin is high.
 
//So here the range pin must be low
 
   while(range == 0);    //This blocks the program as long as your range pin is low.
 
//When we get here it means the range pin just went from low to high
t.start();             //So start measuring the time
 
//Wait as long as the pin is high:
while(range == 1);
 
//Here the output is low again, so we can stop the timer.
t.stop();
 

term.printf(" distance is: %f", cm);
wait(1);
}

}
posted by robert heaney 28 Jul 2013

Sorry, I left out some very obvious stuff. I now have it downloaded to the microcontroller but it just gives me a value of 0.0000 on the tera term screen. Any ideas?? I've put the new code below. Thanks

#include "mbed.h"
#include "Terminal.h"

Terminal term(USBTX, USBRX);
Timer t;
DigitalIn range(p10);

int main() {

//while (1);


//I assume here you got 'range' defined as DigitalIn on the correct pin
//Timer timer;  //Define a timer we can use
 
   while(range == 1)    //This blocks the program as long as your range pin is high.
 
//So here the range pin must be low
 
   while(range == 0)    //This blocks the program as long as your range pin is low.
 
//When we get here it means the range pin just went from low to high
t.start();             //So start measuring the time
 
//Wait as long as the pin is high:
while(range == 1);
 
//Here the output is low again, so we can stop the timer.
t.stop();
 
float time_us = t.read_us();
float cm = time_us/58;
term.printf(" distance is: %f", cm);
//wait(1);


}
posted by robert heaney 28 Jul 2013

Few things:

Better end the printf with '\n', prevents some issues with buffering (although if you get something on teraterm then that goes fine.

Then the while needs its ';' in the end. With that you close the while statement, and it will keep doing nothing as long as the while statement is true. Without the ';' it will apply the while statement on the next one, and then it soon doesn't make sense anymore ;).

Btw, do you have an oscilloscope to check if your IC does make its pulse output?

posted by Erik - 28 Jul 2013

I've put the \n in and also put the ; at the end of each while statement. The code now gives a value but it does not change. When loaded and starting tera term I get one value. To get a new value i need to press the reset button on the microcontroller, each time i press it i get a new value but its like it won't 'cycle' through the program on its own and give a new value, say every second or so. Unfortunately i don't have an oscilloscope to check it, its something i think i need to get so i can. But there quite expensive so i'll have to see what i can do about getting one. Many thanks for the help. Any ideas about getting it to refresh the value?

posted by robert heaney 28 Jul 2013

Your program is now made to run once, that is correct. To keep it running forever uncomment your top 'while(1)'. Replace the ';' with an {, and at the end of your code place an }. That way it while forever run the code between the accolades.

Don't forget to also add timer.reset(), otherwise it won't start the timer at zero.

posted by Erik - 28 Jul 2013

That's brilliant, thanks ever so much for your help, its very appreciated. As i'm sure you'll understand, it can be very frustrating at times, especially when you've got very limited understanding of c language like myself. I shall play around and see if i can get it going. Thanks again :)

posted by robert heaney 28 Jul 2013