Multi Line Frequency Measurement with Teensy 3.1?

Status
Not open for further replies.

Wolfie

Member
I have an application where I need to measure frequencies on multiple input lines. To be specific I am working with an array of 8 - 16 light to frequency sensors. These sensors convert light intensity into a CMOS compatible frequency output. The frequency range is 0 Hz - 1 MHz from total dark to full exposure.

I have used Paul's FreqCount template, which employs the Low Power Timer (LPTMR) of the Teensy 3.1 processor. This works well, but in order to measure all 8 or 16 channels with this method I need to use an external multiplexer, and - in order to get some precision - the total integration time to capture all channels is rather high (1.6 seconds if I use 100 ms as a base for the counter, not considering switching times on the MUX).

According to the datasheet for the MK20DX256 the processor has 3 flexible timer modules (FTM0 - FTM2). The FreqMeasure program actually uses this module. Is there a chance that I can use these modules or are they too slow for the frequency range I am looking at? If they can be used how many inputs would I be able to count simultaneously?

I am still new to the hardware programming of the micro controllers, so any help is greatly appreciated.

Thanks,

Wolfgang
 
There's 2 problems with using the FTM timers as counters.

First, each FTM can only work as a single counter. There's only 1 register that counts up, but 2, 6 or 8 that capture it or compare with it as it's counting. So in a best case scenario, you could at most get 3 more counters this way.

Second, there's the issue of which pins can act as the counter clock. I really don't know... it's in the reference manual somewhere. But I recall at one point seeing it was on difficult-to-use pins. There might also be options to use the analog comparators. Again, the details are in the reference manual, probably in the SIM chapter about which things can be routed to the timer clock inputs.

In theory (with some amount of programming), it should be possible to do FreqMeasure on 8 channels. But FreqMeasure isn't really good for higher frequencies like 1 MHz. If you could use sensors that go from DC to only about 1 to 10 kHz, this might work.
 
Another *really* crazy idea for counting would involve using the DMA. On Teensy 3.1, there's 5 port interrupts which can trigger DMA transfers, instead of an actual interrupt.

This idea would probably involve configuring the DMA channels to copy a single byte between 2 dummy variables, without incrementing the source or destination address. The DMA channel could be configured to transfer 65536 times. Each time the interrupt triggers DMA, the transfer count will decrement, so it can be used as a count of the number of times the channel has been triggered.

You'd have to pick pins that are on the 5 different native ports, and of course quite a bit of programming would be needed....
 
Paul,

thanks for getting back to me.

I did go through the reference manual - at least as far as the timers are concerned. It is true that each FTM module can only do one measurement, but the Teensy 3.1 has three FTM modules (FTM0 - FTM2). In addition it has the LPTMR, so I suppose technically I can measure 4 inputs at the same time. As for the pins I will continue to scour the reference manual to see whether I can find it somewhere.

I will get deep into this next week, as I am currently moving from a temporary apartment housing back into my house, but for now thanks for your input.
Wolfgang
 
Could you put 8 pins on a single port and then interval read & buffer that port over time (interrupt or DMA?) and then parse the buffered data and come up with the rate of change for each input represented. Sort of an FFT - except 8 binary channels at a time instead of one Analog - looking for the rate of change on each.

As long as each buffering happens on a known clock (2+ MHz) you could buffer for up to say .25 or .5 seconds, then parse the data for your result and post it, then buffer the next period. And to get 16 you could do the same on a second port and alternate between the two - parsing one while collecting the other?

1Mb from .25 seconds of 4Mhz to parse should let you detect 1Mhz down to 8Hz.
 
Last edited:
Doing lots of simple stuff in parallel is the easiest thing you can do with an FPGA. Maybe something like this $69 Virtex-6 board would be interesting?

Disclaimers:

  • I'm a software engineer at Xilinx and definitely biased.
  • I'm not an expert FPGA developer.
  • FPGAs most often programmed in a hardware description language, not C. There are some high level tools that enable Xilinx FPGAs to be programmed using C++ or Labview but it's not nearly as easy as getting started with Arduino.
  • It might be easier to use several Teensys than to use one FPGA.
  • There are better FPGA deals if you're willing to spend a little more.
 
A FPGA or CPLD could easily do this, but for a Verilog/VHDL beginner the learning curve is pretty steep! Labview makes it easier but be prepared for sticker shock if you want to buy the full package (which I did recently, for $10k) ...and you still need to learn Labview.
 
Extending Msg #5 given that we don't have a spare MB of RAM, and don't want to parse 8 million bits needlessly . . .

Using that setup with no MUX (with 8+ pins wired) assuming we could set up a change interrupt on a given wired pin. How many pins can be selectively interrupt driven? How many at once?

On interrupt - record ticks and count up to 2-3 and stop int for a given pin - and index to next. Two pools - HIGH and SLOW speed.
Start a pass to gather all pins each 1.5 seconds with time to calculate the results.
HIGH pool sequentially and LOW pool in parallel as possible.

How fast/often do the frequencies change over and under ~50Hz?

16 pins could be tested sequentially in 1.2 seconds spending 75ms on each - 3 transitions each would ID freq above 50Hz.

High frequencies will be over in a flash. Probably only want one low latency pin test going at a time.
Set interrupt Change on pin 'n' - record the clock count on 3 changes, stop that interrupt, calculate the freq.
Change to interrupt on pin 'n++' and repeat for the pool of these FAST pins.
Have a watchdog on FAST pool bump a long wait to the SLOW pool.

Slow Freq pool can run in parallel to each other - once they get 2 hits turn/mask them off.
Run for 1100 ms without 2 changes means 0 or 1 Hz.
Those high latency pins could have their interrupts left active together.
Bump FAST pins out of SLOW pool

If the hardware can do this it should share the load enough over time that the interrupts don't corrupt the results. FAST getting 3 tests allow an average - or perhaps just take the fastest, assuming latency stretched the result.

After 1.2 seconds stop the interrupts and calculate the results. Some SLOW pins may miss an update until the next pass.
Then report the results and start over for the next pass after the FAST & SLOW pools are balanced.
 
As for the pins I will continue to scour the reference manual to see whether I can find it somewhere.

Chapter 10: Signal Multiplexing and Signal Descriptions

10.3.1 is table for Signal Multiplexing

And then set up Pin Control Register (PORTx_PCRn) (Chapter 11.14.1) bits 10-8 for Pin Mux Control. Reasonably straightforward unless the same pin happens to be defined for two different uses you want to use.

You can also use Mux inputs and that is more involved and does involve SIM.

TLB
 
First, thanks for all the replies. Lots of data to digest for a noob. I am running a bit out of time here to get at least something going, so at this point I don't care about cycle times and go with an outside mux and use Paul's standard frequency counter. The question I have at this point: How do I let the frequency counter run in the background, cycle through all 16 sensors and write the results to an array that I then can pull from when needed?
 
Status
Not open for further replies.
Back
Top