2.9 - Timers/Counters [U6 Datasheet] | LabJack
« Close

Datasheets and User Guides

App Notes

Software & Driver


2.9 - Timers/Counters [U6 Datasheet]

Timers / Counters Overview

The U6 has 4 timers (Timer0-Timer3) and 2 counters (Counter0-Counter1). See our Configuration and Timers & Counters pseudocode pages for programming guidance.

When any of these timers or counters are enabled, they take over an FIO/EIO line in sequence (Timer0, Timer1, Timer2, Timer3, Counter0, then Counter1), starting with FIO0+TimerCounterPinOffset. The valid range for TimerCounterPinOffset is 0-8, so Timer0 can appear on FIO0-EIO0, and the highest I/O ever used would be EIO5 for Counter1 if all 4 timers and both counters are enabled. Some examples:

1 Timer enabled, Counter0 disabled, Counter1 disabled, and TimerCounterPinOffset=0:

1 Timer enabled, Counter0 disabled, Counter1 enabled, and TimerCounterPinOffset=0:

2 Timers enabled, Counter0 enabled, Counter1 enabled, and TimerCounterPinOffset=8:

Timers and counters can appear on various pins, but other I/O lines never move. For example, Timer1 can appear anywhere from FIO1 to EIO1, depending on TimerCounterPinOffset. On the other hand, FIO2 (for example), is always on the screw terminal labeled FIO2.

Applicable digital I/O are automatically configured as input or output as needed when timers and counters are enabled, and stay that way when the timers/counters are disabled.

Timers and counters use digital I/O hardware so the digital I/O specs from Appendix A apply.  An input recognizes 0.0-0.8V as low and 2.0-5.8V as high, so rising and falling edges must transition between those levels.  For more information about signal connections see Section 2.8.1.

There are special channels numbers that can be used to read timer and counter values.  These channel numbers can be used most places where you would use analog input channel numbers, such as LJLogUD and LJStreamUD.  See Section 3.2.1 for more information.



The timers (Timer0-Timer3) have various modes available.  These are listed in the following table and more details can be found in Section 2.9.1.

Table 2.9-1. U6 Timer modes

Index (Low-level & UD) 
0 16-bit PWM output
1 8-bit PWM output
2 Period input (32-bit, rising edges)
3 Period input (32-bit, falling edges)
4 Duty cycle input
5 Firmware counter input
6 Firmware counter input (with debounce)
7 Frequency output
8 Quadrature input
9 Timer stop input (odd timers only)
10 System timer low read (Default mode)
11 System timer high read
12 Period input (16-bit, rising edges)
13 Period input (16-bit, falling edges)
14 Line-to-Line input


All timers use the same timer clock. There are 7 choices for the timer base clock:

Table 2.9-2. U6 Timer clock base options

Index (Low-level/UD) 
0/20 4 MHz
1/21 12 MHz
2/22 48 MHz (Default)
3/23 1 MHz /Divisor
4/24 4 MHz /Divisor
5/25 12 MHz /Divisor
6/26 48 MHz /Divisor

The first 3 clocks have a fixed frequency, and are not affected by TimerClockDivisor. The frequency of the last 4 clocks can be further adjusted by TimerClockDivisor, but when using these clocks Counter0 is not available. When Counter0 is not available, it does not use an external FIO/EIO pin. The divisor has a range of 0-255, where 0 corresponds to a division of 256.



Each counter (Counter0 or Counter1) consists of a 32-bit register that accumulates the number of falling edges detected on the external pin. If a counter is reset and read in the same function call, the read returns the value just before the reset.

Note that Counter0 is not available with certain timer clock base frequencies. In such a case, it does not use an external FIO/EIO pin. An error will result if an attempt is made to enable Counter0 when one of these frequencies is configured. Similarly, an error will result if an attempt is made to configure one of these frequencies when Counter0 is enabled.



Usage for all timers & counters is pretty much the same.  First you configure, then you read and/or write.  The effect of the parameters can vary depending on timer mode, so see the timer mode descriptions for more details.

Test using the Test panel in LJControlPanel

Before attempting to use LJLogUD or your own software, first test in LJControlPanel as described in our configuring counters and configuring timers tutorials and confirm the results are as expected.


To configure counters, write to the following:

To configure timers, write to the following:

There are 2 basic ways to configure:

1. Configure the power-up defaults of device as desired, then power cycle the device.  On Windows this can be done using the Config Defaults screen in LJControlPanel.

2. Configure at the start of your program.  For the Windows UD library see Sections 4.3.6 and 4.3.9.  Find any timer example for your programming language and it should demonstrate writes to the above parameters.

Read & Write

Depending on the timer/counter, you might want to do reads of TimerValue or do updates of TimerValue.



"...AIN3 is always on the screw terminal labeled FIO3."

Is this a typo?  I don't see where AIN3 was mentioned anywhere before in the article.  

Fixed.  I think that was a copy/past mistake from the U3 User's Guide.  On the U3, AIN3/FIO3 share the same terminal.

"Both timers use the same timer clock."

Another copy/paste error I guess, assuming there are really four timers. 

Fixed it.  Thanks.

Hello, back again.  Just want to clarify something.

The way I'm reading the documentation,

"For example, Timer1 can appear anywhere from FIO1 to EIO1, depending on TimerCounterPinOffset"

by inference, counter0's max offset puts it on EI04,  counter1 on EI05.  

And nothing can be assigned on EI06 and above.   So the max TimerCounterPinOffset must be a

f(numberofactivetimers + numberofactivecounters)

Is this correct?  I ask because such a rule that seems arbitrary would merit extra description.

At least a statement to the effect 'no timers and counters may have an offset the puts their assignment on EI06 or higher' 



I think the missing detail was that the valid range for TimerCounterPinOffset is 0-8.  That is the constraining rule and the reason that Timers/Counters will never be above EIO5 on the U6.  I added this to the first paragraph above.

Thanks.  Still have a question though.  If I tried to config all four timers and both counters at offset 7 ie FIO7 (non-division base), which error code would be returned because the last assignment, counter1 I assume, would have to be on EIO4?


There would be no error generated in this condition.

  • FIO7 - T0
  • EIO0 - T1
  • EIO1 - T2
  • EIO2 - T3
  • EIO3 - C0
  • EIO4 - C1

That is a valid setup. Even setting the offset to 8 is still a valid setup.

My response from yesterday and the text added to the section was from the standpoint of only having 2 timers, like the U3, but the U6 has 4 timers so I corrected the section text and the comment.

jthurbs's picture

What is the speed of the counters? How close can two falling edges be before the counter is unable to register both of them?

Thanks much

labjack support's picture

The limit for hardware counters is stated in Appendix A as an 8 Mhz 0/3.3V square wave, so the low time and high time must both be at least 125ns.  Speed is worse at less than 3.3V and better at greater than 3.3V.

For timers, including timers configured in the Firmware Counter mode, see Section 2.9.2.

ElectroLund's picture

I've got a problem with a PWM output.  On a U6, I have timer 2 set up as LJ_tmPWM16 to change a servo motor position.  I also have timers 0-1 set up as a 32-bit system timer, LJ_tmSYSTIMERLOW and LJ_tmSYSTIMERHIGH.

What I'm seeing is that amidst doing system timer calls and then setting the PWM output, my servo doesn't move.  I'm having to reinit the servo timer for LJ_tmPWM16 to garauntee proper driving.

Can you verify and help me understand why?

labjack support's picture

No obvious problem jumps out at me with what you are doing.  Should be able to read Timer0 & Timer1 while Timer2 continues to output pwm16.  Can you recreate the same issue with the Test panel in LJControlPanel?

ElectroLund's picture

Hmm, I'll have to give that a try with the control panel.  I mentioned the sys timer only as a theory, since those are the only other timers I am using in this fixture.

The trouble with using the control panel as a method of test is that it's obviously unclear to us what the control panel is doing behind the scenes in terms of initial setup but also during runtime.

But I can take a look to rule it out.

labjack support's picture

If you can cause the same problem, then we can try to do the same thing and if then we can explain it or address it.

If you can't cause the same problem, it tells us the LJCP can do it but something is different in your software and we know to focus on the details of what your software is doing.

Also, you might enable a counter also and wire the PWM output to the counter.  That gives an easy way to see if the PWM output is still pulsing.


ElectroLund's picture

Well, I wasn't able to repeat this in the LJControlPanel.  But in my own code, I found the issue.  It had to do with the servo drive requirements.  Turns out once you set the new PWM, you have to then toggle power high-low.  Doesn't work any other scenario.

Thanks for your help!

ElectroLund's picture

Well, I know I'm beating this dead horse, but here I am again on this issue.

I'm in the middle of a big refactor of this codebase.  My LabJack wrapper got a lot of rewrites in the process.  What I found is that when I initialize the above timer #2 as LJ_tmPWM16 after setting up the clock base and clock divisor for the U6, my servo doesn't quite work as expected.  PWM output does get generated, but my servo doesn't get to the needed position.

Now, if I init that timer and then afterward set clock base and clock divisor, then the servo will be driven to the correct position. I'm verifying "correct" servo positions independently with an X-ray counter which gives very accurate count rate.

So, is this just a quirk of the LabJack that clock base and divisor must be re-initted with the timer set up?

labjack support's picture

I believe both configuration orders are valid from the U6's standpoint.

Do I understand correctly that the U6 generates the desired PWM signal regardless of the configuration order, but the servo only responds to one order, not the other? Does the PWM look any different on an oscilloscope? My first guess is that something about the precondition is getting the servo into an unresponsive state. We might be able to test this by gating or disconnecting the signal during configuration and hold the servo side list with a resistor, then connect the, already running, signal.

I will test to see if I can detect any differences in the U6's PWM generate when changing the configuration order.


labjack support's picture

I don't see any difference in the waveform when changing the configuration order. I'm hoping that precondition idea pans out.

ElectroLund's picture

Ok, I do see where I may have gone wrong.  The value of my LJ_chTIMER_CLOCK_BASE was corrupted.  Having learned that hard lesson, I am now reading back what I write to verify.

In my application, I need 48MHz_DIV (26).  I attempted a LJ_ioGET_CONFIG of that channel after writing it, but I read back a value of 6!  That's not even in the list of valid clock bases!

Now when I read back LJ_chTIMER_CLOCK_DIVISOR, I do get my written value (14).

Any idea why the base isn't reading back correctly?

labjack support's picture

LJ_chTIMER_CLOCK_BASE with LJ_ioGET_CONFIG gets the low-level timer clock base value as read from the device directly. The UD constants are the low-level timer clock base + 20. Refer to Table 2.9-2 for a list of the low-level and UD timer clock base values:


So what you read back is correct.

Thanks for pointing this out. I updated the documentation about this: