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?
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.
Thank you! This is what I needed.
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) * 100Perhaps the signal is glitching when it changes duty-cycle? If you leave the signal at a fixed duty-cycle do you have any problems?
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?
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.