Reading a PWM signal - how's it done?


I’m trying to hook up a SRF05 ultrsonic range sensor. The legth of the pulse says how far away the object is - sounds good, but I can’t work out how to read the pulse length?

I’ve looked at some Arduino code samples but they seem to have a command ‘PULSIN’ to read the length of a pulse (and PULSOUT to send one).

When I look at the GT.Interfaces library it seems PWM can only be output !?!?

So how can I read the pulse length?

Many thanks

You could use an interrupt port and handle the up and down edge interrupts. The timestamp passed in the interrupt event is fairly accurate.

1 Like

Or a PulseInOut module.

1 Like

Be carefull on the fact that NETMF is not an RTOS, so that if the pulse length definition must be very precise, the timestamp should differ from one mesure to another !

Mike’s and ianlee74 suggestions are probably better, but you can also use an ADC input to monitor time above threshold for the srf05 echo pulse. I use a similar loop to measure a duration above threshold for an analog signal. In your case it might look like this:

[ol]send the trigger pulse and start monitoring ADC channel
start counting ticks when ADC rises above threshold
when ADc drops below threshold calculate elapsed ticks and convert to distance [/ol]

Also need to consider that garbage collection needs to be stopped temporarily since it will skew ~ 3ms

The timestamp on the interrupt events is very accurate, since it is done in an actual hardware interrupt.

Of course, the actual determination of frequency would have to be done over a number samples.

There is also a limitation as to the maximum frequency that could be supported using the interrupt method. It
should be around 700-800Hz. Anything faster would backup the interrupt event queue and cause an out of
memory condition.

I already used the interrupt mechanism for WIEGAND smart card reader, and the clock line is about 1KHZ, and It still go right on Chipworkx. Did not try til then on the STM32…

Using a DL40 with custom firmware is also another option.

I have done something very similar with an ultrasonic range sensor. Easiest way is as suggested, set up a single interrupt pin.

  1. Set an event to trigger when the signal goes high, store the start time in a variable

  2. Have an interrupt to trigger when the pin goes low and subtract the start time from the end time. Its important that you use the time passed in via the event and not the DateTime.Now variable as it could have a slight delay between the event being triggered and the event actually being fired in your code and this can skew your results.

  3. Do a bit of math (cant recall it off the top of my head, should be in the documentation for the ultasonic sensor) to calculate the distance travelled by the signal and divide it by 2 to get the distance from your sensor(Remember it goes out, bounces and then comes back so its half the total distance).

I need to do some big improvements to mine as its unreliable below 8 inches, could be the module I am using though. In principle it works though, If I get time I will find my project out for you when I get home :o). Its pretty simple. I bought the new In/Out module last week but havent managed to try it yet to see if I can improve the accuracy


@ ChimpBrain - using MF 4.1 have a look at the class PinCapture or for MF 4.2 to SignalCapture

@ Bodwad - Thanks for this it works a treat.

My only other question is how do you get the timestamp in the event? I use extender.SetupInterruptInput to set up an interrupt but the callback code created doesn’t have a timestamp - void intinp_Interrupt(GT.Interfaces.InterruptInput sender, bool value)

I have a workaround by using Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks but if I could use your method I’d prefer it.

Any chance you could post your code?


@ Bodwad - Can you please put your code ?