Despite what I claimed in Teensy LC support for PteroDAQ written but not tested, adding support for the Teensy LC board to the PteroDAQ data acquisition system also took a day of effort, not just a couple of hours. The board arrived in Saturday’s mail, so I tested the code immediately. My initial attempt did not work, and debugging took an embarrassingly long time.
The first problem was that the KL25Z code had used the SysTick timer to do the interrupts for the periodic sampling, but the Teensyduino usb_serial code uses the SysTick timer for other timing purposes (it uses SysTick as a timestamp). On the Teensy 3.1, I’d used one PIT (periodic interrupt timer) for the periodic sampling, and two others for keeping a high-resolution timestamp, but the Teensy LC does not have that many PITs.
I ended up using the LPTMR (low-power timer) for the sampling frequency, which gives a wide range of frequencies with the precaler (allowing a very long sample period of 268s). Unfortunately, the LPTMR is only a 16-bit counter, so the resolution of frequency is not great—about 15ppm at low frequencies (with counter values between 32k and 64k), and period step sizes of 62.5nsec at sampling frequencies above 244Hz. I can’t hit 60Hz exactly, but the 10ppm that it is off is less than the error of the crystal oscillator and far less than the error of the line frequency of the power lines.
Getting the LPTMR to work correctly took a long time, mainly because of spelling errors (sometimes the name needed is LPTMR, sometimes LPTIMER, sometimes LPTMR0). The inconsistency seems to come mainly from the kinetis.h file provided in the Teensyduino code.
The SysTick timer we used on FRDM KL25Z implementation is a 24-bit counter running at 48MHz, so it has a resolution of 20.83 nsec for frequencies above 0.35Hz, and 333nsec at lower frequencies. The Arduino implementations use the same timer for both timestamps or periodic interrupts (which I could also have done on the Teensy LC, using the same pair of PITs for either) since the timestamps are not used directly with periodic interrupts.
I looked at the size of the different implementations of the firmware for PteroDAQ with the current implementations as well as the longest sampling periods:
|Teensy 3.1||12,536||119.3046 s|
|Teensy LC||12,632||268.4355 s|
|FRDM KL25Z||26.6k||5.592405 s|
|Arduino Leonardo||9,908||4.194240 s|
|Arduino Uno||7,350||4.194240 s|
The Teensy 3.1 implementation could easily be modified to get ridiculously long sample times, as there is a spare 32-bit PIT to get times up to 512Gs (over 16000 years) with a resolution of 27.8ns, but the other implementations would be harder to change. Using the 2-PIT approach on the Teensy LC or the FRDM KL25Z could easily get up to 384Gs, with a resolution of 41.7ns.
I think I may switch all the ARM boards over to using 2 PITs for timing, for both the timestamps and for the periodic interrupts, as this seems to provide the best tradeoffs of period and resolution.