Forum Rule: Always post complete source code & details to reproduce any issue!

# Thread: Using teensy to measure period of PWM input?

1. ## Using teensy to measure period of PWM input?

I would like to make a teensy read four VR sensors using 2 MAX9926 interface chips. I am planning on reading ABS wheel speed sensors, and I need to log the frequency of the pulses to a 32 bit integer with 65535 representing an 8388.5ms period. The maximum frequency I plan on measuring is around 1.7khz. This is to be an input into an ECU for comparing wheel speeds for traction control.

How I got to these numbers...

44 pulses per revolution, 875 revolutions per mile, ~160mph maximum speed = 6160000 pulses per hour /60 /60 = ~1.7khz

At 1MPH * 875 rev/mile = 38500 pulses/hour /60 = 641.66 pulses/minute /60 = 10.69 pulses/sec or 10690 ms. The firmware of the ECU is expecting a 32 bit number and the coding is set so that 65535 = 8388.5ms, so I should be able to read both ends of my range rather well.

Does my math seem reasonable?

It seems like a teensy should be able to do this pretty easily, but I honestly have no idea where to start. Can anyone point me in the right direction on how to best approach this?

Thanks!

2. The integrated FLextimers allow to do this kind of period capturing mostly in hardware in the background without too much CPU impact or blocking everything until a pin transition finally happens. If you don’t want to study the FTM reference manual, have a look at the FreqMeasure and the FreqMeasureMulti libraries which come with Teensyduino.

3. I've ordered a teensy 3.6 already, it seems this might be a happy coincidence!

So, if I understand properly I should be able to input a 1MHz input pulse on one of these timer channels, then that one will be used to reset the 16 bit counters from the other 7 timer channels? All of this is handled in the FTM module, so using the libraries you can call the 16 bit values as required? Seems it does some smoothing on multiple inputs read between your requests too? This seems perfect, I already have a GPS with time pulse output and I think the resolution or stability should be more than enough for my application.

It looks like I need to read the manual!

Thank you!

4. Originally Posted by Mike_
So, if I understand properly I should be able to input a 1MHz input pulse on one of these timer channels, then that one will be used to reset the 16 bit counters from the other 7 timer channels?
That's not quite how timer input capture works.

The general idea is you configure the timer to increment rapidly. When the input signal changes, that rapidly changing count is "captured" to the register for whatever channel you're using. The capture event can trigger an interrupt. The huge benefit is the captured count gives you a "timestamp" (relative to the timer's counting) which doesn't have error from interrupt latency, software speed, or bus arbitration to access memory.

It's basically the same as if you used attachInterrupt() and then called micros() and stored the 1us count. But the timer can give you much better than 1 us resolution, and most importantly the capturing of the rapidly increasing count happens all in hardware. It doesn't get affected by the short but possibly variable amount of time the system take to run the interrupt function.

The pin changing doesn't "reset the 16 bit counters". It captures whatever the timer was at the moment it changed. While you're free to do unusual things in your code, generally speaking people tend to leave the timer running when using input capture. Usually when things like elapsed time are needed, you'd do 2 captures and subtract them, rather than starting from zero.

The 8 channels work independently. You can craft code to do something to the other 7, but the hardware doesn't do that for you.

5. I think I have a better understanding of the timer module since reading the manual yesterday.

The ECU I am using expects 0xFF = 0.128ms * 65535, in other words it should be a down counting 16 bit int with the value representing the time in ms between pulses on the wheel speed sensor. If the value is = 65535 the input is considered to be stalled or = 0. I think I recall seeing the Teensy 3.6 can actually count the timers down, but the Teensy LC can only count up, or up/down/up...

It seems that I can configure a external clock pulse (plus 128 prescaler) to be the clock pulse for "freezing" the registers current count since the last cycle. If the wheel is turning really fast I expect many input pulses to occur on all four FTM input channels, and each rising edge of pulse will increment that specific channels count by one. If the wheel is not turning I expect the counter to stay = 0. When the clock pulse rises for the 128th time, these counts are stopped and copied to the output value registers and ready for reading?

I would need to do some math to invert the 16 bit register values for sending data to the ECU, but I should be able to read the contents of a channel count register at any time and send it to the ECU? The fixed standard source clock for the FTM module is half of the equation needed for figuring elapsed time from the counter register values?