« Close

Datasheets and User Guides

App Notes

Software & Driver


13.1.5 Frequency In

Capable DIO: FIO0, FIO1

Requires Clock Source: Yes

Index: 3 (positive edges) or 4 (negative edges)

Frequency In will measure the period/frequency of a digital input signal by counting the number of clock source ticks between two edges ... rising-to-rising (index=3) or falling-to-falling (index=4).  The number of ticks can be read from DIO#_EF_READ_A.

Clock#Frequency = CoreFrequency / DIO_EF_CLOCK#_DIVISOR    //typically 80M/Divisor
Period (s) = DIO#_EF_READ_A / Clock#Frequency
Frequency (Hz) = Clock#Frequency / DIO#_EF_READ_A

Resolution (s) = 1 / Clock#Frequency
Max Period (s) =
DIO_EF_CLOCK#_ROLL_VALUE / Clock#Frequency

CoreFrequency is always 80 MHz at this time, but in the future some low-power operational modes might result in different core frequencies.  The valid values for DIO_EF_CLOCK#_DIVISOR are 1, 2, 4, 8, 16, 32, 64, or 256, and a value of 0 (default) equates to a divisor of 1.  For more details about Clock#Frequency and DIO_EF_CLOCK#_DIVISOR, see the DIO-EF Clock Source section.

Roll value for this feature would typically be left at the default of 0, which is the max value (2^32 for the 32-bit Clock0), but you might be using a lower roll value for another feature such as PWM output.

A couple typical scenarios with roll value = 0 and using the 32-bit clock (Clock0):

Divisor = 1, Resolution = 12.5 nanoseconds, MaxPeriod = 53.7 seconds
Divisor = 256, Resolution = 3.2 microseconds, MaxPeriod = 229 minutes

Once this feature is enabled, a new measurement happens on every applicable edge and the result registers are updated.  If you do another read before a new edge has occurred, you will get the same value as before.  Many applications will want to use the read-and-reset option so that a value is only read once and extra reads will return 0.

DIO#_EF_ENABLE: 0 = Disable, 1 = Enable
DIO#_EF_INDEX: 3 or 4
DIO#_EF_OPTIONS: Bits 0-2 specify which clock source to use ... 000 for Clock0, 001 for Clock1, and 010 for Clock2. All other bits reserved and should be set to 0.
DIO#_EF_CONFIG_A: Bit 1: 1=continuous, 0=OneShot. All other bits reserved.
DIO#_EF_CONFIG_B: Not used.
DIO#_EF_CONFIG_C: Not used.
DIO#_EF_CONFIG_D: Not used.

No update operations can be performed on Frequency In.

DIO#_EF_READ_A: Returns the period in ticks. If a full period has not yet been observed this value will be zero.
DIO#_EF_READ_B: Starting with firmware 1.0114, READ_B will return the same value as READ_A.  This is a capture register ... it is only updated when one of the READ_A registers is read.
DIO#_EF_READ_A_F: Returns the period in seconds. If a full period has not yet been observed this value will be zero.
DIO#_EF_READ_B_F: Returns the frequency in Hz. If a full period has not yet been observed this value will be zero.  This is a capture register ... it is only updated when one of the READ_A registers is read.

Stream Read:
All operations discussed in this section are supported in command-response mode.  In stream mode, you can read from the integer READ registers (A, B, A_AND_RESET), but as mentioned in the Stream Section those reads only return the lower 16 bits so you need to also use STREAM_DATA_CAPTURE_16 in the scan list to get the upper 16 bits.

DIO#_EF_READ_A_AND_RESET: Returns the same data as DIO#_EF_READ_A and then clears the result so that zero is returned by subsequent reads until another full period is measured.


 Most applications can use default clock settings, so to configure frequency input on DIO0 you can simply write to 3 registers:


Now you can read the period in seconds from a 4th register DIO0_EF_READ_A_F.


Sometimes, other DIO-EF might interact with this feature.  For example, roll value would usually be set to 0 to provide the maximum measurable period, but assume for this example that we have to use 10000 because it is set to that for PWM output on another channel:

DIO_EF_CLOCK0_DIVISOR = 8    // Clock0Frequency = 80M/8 = 10 MHz

This clock configuration results in Resolution = 1 / 10M = 0.1 us and MaxPeriod = 10000 / 10M = 1 ms.

Now configure the DIO_EF on FIO0 as frequency input.

DIO0_EF_INDEX = 3 or 4  // Select rising or falling edges.
DIO0_EF_OPTIONS = 0   // Select the clock source.
DIO0_EF_ENABLE = 1      // Turn on the DIO_EF

At this point the LabJack is watching the IO lines for the specified edge. After the first two edges have been observed the time between them is stored, and this repeats for each subsequent edge.  Results can be read from the READ registers defined above.


I recently updated firmware to 1.0146 and I am not sure where this got in, but it looks like Frequency-In is no longer starting a new count on the edge that finished the last read, but waiting for a new edge. That is it reads one cycle (say rising edge 1 to rising edge 2), waits one cycle (rising edge 2 to rising edge 3), and then reads the third cycle (rising edge 3 to rising edge 4) rather than reading in each cycle (rising edge 1 to 2, and then 2 to 3). Every other read is accurate; however, readings occur half as often as they should. I am unable to affect this with the one-shot/continuous config or the _Read_A_Reset / Read_A (any of the 4 combinations).

You are correct. That solution was necessary to prevent several conditions that were causing erroneous results.

Would you please tell me what those conditions were and the resulting erroneous results, as well the release that contained the relevant feature? It may be that those conditions will not apply to my project and I can roll back the firmware to the one before it to avoid the problem.

The problem was caused by changing the hardware configuration. When doing so, the first value reported (time-stamp of the first edge) could be wrong (probably a binary error because vales were often 4x or 1/4 expected). In continuous mode it is possible to encounter this error the measurement after DIO_EF is first configured and after a reset register is read. First discovered in 1.0138.

To Support,

If I don’t read a reset I should be able to rollback my firmware and I will get my old read speed back, correct?  Are there any instances that I may be reading a reset register without knowing it, say if I just do a standard _ Read_A, this will not activate a reset register, correct?  Please, what was the last firmware version before the patch that cut the update rate in half?  Lastly, I would like to put in a request to put the update rate change under a config in future releases so that I can use them without cutting the update rate, will that be possible?


What is the range of frequencies you are interested in?

I am reading 2.4 kHz to 6 Hz.  The issue however isn’t the frequency being read in, but the system response time.  The code I working on performs feedback control.  The system goes unstable when the frequency is slow enough that the feedback program updates commands more often that 8 times per read (approximately).  I can and will add code to slow my feedback update rate down in this case, but the end result will be that my system response time will be about twice as slow when coming out of or going into low frequencies.  I try a few other hammers like gain scheduling to try to get my system response back up to speed in these conditions, but it is most likely that I will need to roll back my firmware.


Could I please get a few confirmations or corrections for the above as well as the correct version to roll back to?  The control is stable, but still slow and I am beginning to hit accuracy limitations for another chunk due to the same issue.


Your previous request ignited a debate. Hopefully we will reach a conclusion soon. I'll try to get you something to work with in the meantime.

Still working on a firmware solution. In the meantime you can try DIO_EF 11: http://labjack.com/support/datasheets/t7/digital-io/extended-features/in...

The new beta firmware, 1.0150, will measure every period when in continuous mode.

I got a chance to test the Frequency-In feature of Beta of 1.0150 and it works well for me. I have a few notes if you are interested.  I could not tell the difference between continuous and one-shot mode, but this doesn’t matter as they work well.

I tested out read-reset and was sometimes getting (2^32-2^16+some small error) on what it should have read.  I am using two clocks and had the roll value set to 0 for max roll and said “ahah, that must be glitching,” so I set my roll value to 65535. It cleaned the results up somewhat but I was still getting some values that were just a bit off once in a while. Once I noticed, I saw the same in plain read mode. So I dug in some more and it looks like I am seeing errors every time the clock rolls over. Likely it is either reporting an unfinished period or it thinks that a period started at the instant of the clock roll. My code has no problem with it but you may want to carry over partial readings or report 0 or last good reading during clock rolls.

Also, as noted I was using 0 for max roll value with a 16 bit clock. I may have misunderstood how 0 was supposed to be used.  If so, you may want to change your description in the clock section a bit. If not, you have a bit of a bug there too (0 = 2^32 or 2^32-1, even when using 16 bit clock).

Thank you for the update to Frequency-In, it works well.


A bug was causing calculation errors during the clock source the timer overflow while the period was set to zero. Fixed in 1.0156.

Thank you for pointing this out and all the detail in your description!

I put 1.0150 on the live stand and it is not reading DIO1 (before I only did my checks on DIO0).  I rolled to 1.0156 and it is not reading Freq-In on DIO1 either.  I rolled back to 1.0146 and it has the both channels working.

DIO_EF1 got left behind during all the recent changes. 1.0159 brings it up to speed with DIO_EF0.