U6 - Python - Using Timer 0 to read PWM input, want to iterate through offset | LabJack
 

U6 - Python - Using Timer 0 to read PWM input, want to iterate through offset

7 posts / 0 new
Last post
mtk59
mtk59's picture
U6 - Python - Using Timer 0 to read PWM input, want to iterate through offset

Hi,

I have 4 pwm signals on FIO0-3 that I want to get duty cycle data on. My thoughts are that I will enable timer0 and just change the offset accordingly once my measurement has taken place. So far this strategy has not worked for. The first reading on FIO0 works and the data is correct, however the remaining measurements are measuring incorrectly and reporting the signal is low. Here is a snippet of my code:

def timerSetup(lj_inst, numTimers, offSet):

   # Enable timer starting at offset. Note to use NumberTimersEnabled for the U6.
   lj_inst.configIO(NumberTimersEnabled=numTimers, TimerCounterPinOffset=offSet)   
   lj_inst.configTimerClock(TimerClockBase=3, TimerClockDivisor=1)

   return

def measureDutyCycle(lj_inst):

    i = 0

    while (i <4):
        timerSetup(lj_inst,1, i)
        if i == 0:
            lj_inst.getFeedback(u6.Timer0Config(TimerMode=4, Value=1))
        ### Timer 0 ###
        clockFreq = 1000000 / 1
        clockPeriodTimer0 = 1 / clockFreq    # Read the current count
        valTimer0 = lj_inst.getFeedback(u6.Timer0())
        valIntTimer0 = int("".join(map(str, valTimer0)))
        lsBitsTimer0 = valIntTimer0 % (65536)
        msBitsTimer0 = valIntTimer0 / (65536)
        pulseWidthTimer0 = clockPeriodTimer0 * lsBitsTimer0
        timeOffTimer0 = clockPeriodTimer0 * int(msBitsTimer0)
        sigPeriodTimer0 = pulseWidthTimer0 + timeOffTimer0
        sigFreqTimer0 = 1 / (sigPeriodTimer0)
        dutyCycleTimer0 = lsBitsTimer0 / (int(msBitsTimer0) + lsBitsTimer0) * 100

I have also tried using timers1-4 for each GPIO and this did not work either. Is there a timer reset or something I need to implement before iterating the offset?

LabJack Support
labjack support's picture
After enabling the timers and

After enabling the timers and setting their offset, you need to configure the timer mode. So something like this in your loop without the "if":

        timerSetup(lj_inst,1, i)
        lj_inst.getFeedback(u6.Timer0Config(TimerMode=4, Value=1))

Alternatively, you can enable 4 timers with offset 0, configure them for mode 4 and perform your readings.

mtk59
mtk59's picture
Thank you! This is what I

Thank you! This is what I needed. 

mtk59
mtk59's picture
My duty cycle measurements

My duty cycle measurements work about 9/10 times, but the timer returns erroneous data about 1/10th of the time. I am controlling the duty cycle from an external board, iterating through 20%, 40%, and 50% duty cycles. When my code calculates the duty cycle correctly, say for 20%, the timer returns the 32-bit value 1572880. The ms bits and ls bits get broken down in 24 and 16. When my code reports erroneous data the 32-bit value word is 1310720 which breaks down to ms and ls bits in 20 and 0. I am not sure where this inconsistency is coming from. 

while j < 4: frequencyList = [25000, 25000, 25000, 0] dutyCycleList = [.2, .4, .5, 0] commandLEDsOn(dutyCycleList[j], steer, snode, lj_inst, ledList[i]) time.sleep(1.2) timerSetup(lj_inst, 1, i) # Calls timerSetup(labjack instance, number of timers initialized, varying offset starting at FIO0 lj_inst.getFeedback(u6.Timer0Config(TimerMode=4, Value=1)) # Configures timer0, Timermode=4 is duty cycle input read clockFreq = 1000000 / 1 clockPeriodTimer = 1 / clockFreq # Read the current count valTimer = lj_inst.getFeedback(u6.Timer0()) # 32 bit word representing high and low times of duty cycle valIntTimer = int("".join(map(str, valTimer))) # convert to Int lsBitsTimer = valIntTimer % (65536) # least significant 16 bits from 32 bit word msBitsTimer = valIntTimer / (65536) # most significant 16 bits from 32 bit word pulseWidthTimer = clockPeriodTimer * lsBitsTimer timeOffTimer = clockPeriodTimer * int(msBitsTimer) sigPeriodTimer = pulseWidthTimer + timeOffTimer sigFreqTimer = 1 / sigPeriodTimer dutyCycleTimer = lsBitsTimer / (int(msBitsTimer) + lsBitsTimer) * 100

 

LabJack Support
labjack support's picture
Perhaps the signal is

Perhaps the signal is glitching when it changes duty-cycle?  If you leave the signal at a fixed duty-cycle do you have any problems?

mtk59
mtk59's picture
Sorry, I didn't realize my

Sorry, I didn't realize my code went in like that. I am still having the same issues when measuring a constant duty cycle. Can you see any issues with how I am initializing the timer and reading in the value from timer 0? Do I need to reset the timer after I switch the duty cycle?

 

 

File Attachment: 
LabJack Support
labjack support's picture
After configuring your timer

After configuring your timer mode, add in a small delay before your reading and see if that helps. This is to give the timer some time to get its first duty cycle measurement after configuration.

Alternatively, consider moving your timerSetup and getFeedback(u6.Timer0Config) calls to before your "while j < 4" loop or before your commandLEDsOn call. This makes use of the 0.2 second delay already present in your code.