PulseIn function

Hey everyone,

I have a project with a LM555 timer and need to calculate how much time it takes for an input to go from LOW to HIGH and then to LOW again.

Basically, I want to know the period of a square wave generated by the LM555 timer.

I did it with Arduino using the function Pulseln. But I need to do this using a Beaglebone and programming in C++ (Using QtCreator).

Is there a way to “open” the function PulseIn so I know what it does? Moreover, do you guys have any piece of code that might help me?

Thank you in advance.

The code in pulsein is pretty simple really - interrupt occurs on the first edge at time T1; second interrupt occurs on next edge at time T2; third interrupt occurs on same edge as first sample at time T3. From those three points you can figure out the period you need - T3-T1 is the full wave cycle time, T2-T1=half wave. In your scenario you want T1/T3 to be triggered on rising edge and T2 is the falling edge. All of those are achievable with hardware capable of using interrupts on a GPIO pin.

How to do that on a BBB is an exercise left to the reader (ie I have no idea :slight_smile: )

Believe it or not, arduino will do better at these simple tasks than a full blown Linux. Thankfully, there are PRUs on the processor that are specifically made for this. That is what you need to look up.

@ arthuki -
Just for simple way and it may not accurate, but in case you want give it a try.
From QTCreator, C++:

  • Create an input pin. Let say pin 60.
  • Open a file stream and point to /sys/class/gpio/gpio60/value
  • Read data of the file value. It will change 0 or 1 that tell status of pin 60.
    As Brett said, you can calculate the time by scanning the change in this file. For more accurate, just keep the stream open when scanning.

I don’t think that the stream interfaces offer deterministic timing. That is, other threads and processes can get a chance to run when you are doing things like the stream read. That can lead to a lot of jitter in the timing, and jitter that will vary with system load. I think you need a tight timing loop that can run with interrupts off, or a dedicated piece of timer hardware like the Arduino and other MCUs offer.

Looks like the AM3358 used in the BBB and Octavo has a PRU that you can use for real-time timing and counting : http://beagleboard.org/pru

More real-time info here, including a deep dive on the PRU : http://exploringbeaglebone.com/chapter13/

Thank you all for the great answers. I believe that the best way will be through PRU. But I was thinking, what if I used PWM reading libraries (black lib for example) on this square wave?

Any thoughts?

@ arthuki -

If you want a simple way to count a pulse width, you have another option besides programming the PRUs. The AM335x device includes “eCAP” peripherals that are actually designed for this purpose, without wasting CPU cycles.

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/230131.html
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/thread.html#230131

The crude documentation for the interface is at:
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/229348.html

In Linux, everything is a file, so you’d just read/write these control files to count pulse widths.

Read more about eCAP in the massive AM335x Technical Reference Manual:
http://www.ti.com/lit/ug/spruh73o/spruh73o.pdf

You can also note there is an eCAP module WITHIN the PRU subsystem (PRU-ICSS), so you could use hardware to count the pulse width, rather than software, even on the PRU.

Anyway, if there is significant interest in trying this with BeagleBone, I could probably compile this driver into the kernel if someone would test it out. It was tested back against the 3.14 kernel, but we ship with 4.4 now. I doubt there would be a problem, but you never know unless you test it. I’d have to find a free moment to do this and you might have quicker luck bringing it up on the Beagle list (http://beagleboard.org/discuss).

3 Likes