Pulseposition inaccuracies?

Status
Not open for further replies.

mogplus8

Member
Hi All,

I have been trying Pulseposition on my Teensy35, and I have found it seems to be producing inaccurate pulse sizes. Myoutput.write(1, 1000) produces a pulse between 800us and 850us and a Myoutput.write(1, 2000) produces a pulse between about 1750us and 1850us. The "separator" pulse, which should always be exactly 300us comes in at about 85us.

Screenshot from 2018-01-25 16-45-52.png

The screenshot is from xoscope, and shows a 1000us and 2000us pulse. I don't know how to get xoscope to display any actual values, so I have been measuring the pulse widths on the screen with a ruler. If anybody knows a better way, please let me know. I understand @dereckbc has been using a similar setup, and using the second pin in the pulseposition begin to act as a trigger for xoscope. I'd be really interested to know how to do that. On my screen the grid size is about 27mm (measured with a ruler), and the 1000us pulse is about 43mm and the 2000us pulse is about 98mm. I would have thought that the 2000us pulse would have been double the 1000us pulse but such does not appear to be the case. The separator pulse is about 7mm. These are all measured with xoscops on 500us/div.

Here's the code, not that it offers much help.

Code:
#include <Arduino.h>
#include <PulsePosition.h>

PulsePositionOutput(PPM);

void setup()
{
  PPM.begin(9);
}

void loop()
{
  PPM.write(1, 1000);
  PPM.write(2, 2000);
  PPM.write(3, 1000);
  PPM.write(4, 2000);
  PPM.write(5, 1000);
  PPM.write(6, 2000);
  PPM.write(7, 1000);
  PPM.write(8, 2000);
}

If anybody can shes any light on why this is happening, or what I have to do to get correct results please let me know.

Thanks,
Ian
 
I don't think it matters, but for testing you could put all of your write's in setup() and have an empty loop(). My analyzer shows proper pulse sequence

ppm1.png

The small pulses are 100us wide, and the gaps are about 1000 and 2000 us, with the total period 20ms. That sort of looks like what your screen shot was showing.

The 2000 us pulse is (from the analyzer) 1900 us + 100us = 2000, which matches specs in
https://www.pjrc.com/teensy/td_libs_PulsePosition.html

you can run the PPM lib example LoopBack and jumper pin 9 to 10 and measure pulses with PulsePositionInput
 
I'm running it here on a Teensy 3.5. This is the waveform I see.

file.png

The scope's scale is set to 2 ms/div. The pulses are indeed positioned at the 1000us and 2000us positions your code specified.
 
Here's a couple more views on faster horizontal time scales, with my scope's pulse period & width measurements turned on.

file.png

file.png

At this scale, my scope claims it's acquiring at 1 Gsample/sec, so I'm not sure why these measurements are only to 10ns resolution. You'd think it could do 1ns precision? Then again, my analog bandwidth is only 200 MHz, so maybe 10ns precision is reasonable for the price?

Anyway, the pulse period measures within 1 least sig digit, and I'm pretty sure this Agilent (now Keysight) scope is trustworthy for this type of measurement.



EDIT: I made these measurements with the analog bandwidth limiting feature turned on, so even 10ns timing res is a little questionable at this setting. When it comes to making quick measurements for forum posts, I must confess I use pretty sloppy measurement techniques like plugging wires into the breadboard and clipping both the scope probe and ground lead onto the hanging wires. This scope's full bandwidth does indeed show all sorts of little analog artifacts from the wire lengths, so I just leave the bandwidth limit turned on most of the time. If we *really* need to see this measured with the full bandwidth, I could do it, but the reality is I don't have a great setup for quickly making accurate high bandwidth measurements.
 
Last edited:
Shouldn't a sound card's ~20 kHz bandwidth resolve timing to within approx 50 us?

Then again, I can imagine how any number of things could go wrong between the hardware, OS & application. This isn't the first time we've seen terrible PC-based measurements. Even those low-end Hantek USB scopes sometimes give horribly inaccurate results. I recall one thread a couple years ago where detailed testing confirmed a Hantek claiming 20 MHz bandwidth was actually sampling at only 0.5 MHz, and the images we saw posted were terribly corrupted by Nyquist aliasing. It's a shame they can sell so many of those to unsuspecting people....

I'm personally very suspicious of Owon, Siglent and the other cheap Chinese scopes, except Rigol. The modern Rigols with firmware from the last few years are pretty good.
 
The problem with sound cards as oscilloscopes is less the bandwidth alone. There might be a DC blocking high pass filter, pre-amplification, pre-attenuation, or both. There will for sure be a low pass anti aliasing filter before the ADC/CODEC.
All this might not influence the basic technical specs of a, for example, 20 - 20000Hz bandwidth (+/- 3 dB) and a S/N ratio > 90dB. But you'll never know about phase shifting and group delay induced by the components cited above, two factors which aren't audible, and thus, everything might be ok for a sound card, but which can degrade pulses in an important manner so that an oscilloscope use besides of observing sine waves for pleasure can not be recommended.
 
Thanks for you advice gentlemen. I tried putting the reads into setup but got the same result. Tried running the loopback program and it worked perfectly, so clearly the problem lies with xoscope or with me. Turned out to be the latter. Thanks to manitou whose comment naggled around the back of my brain for about ten minutes until it clicked. I was measuring the width of one down pulse, not a down and up if you see what I mean. So for 1000ms I was getting a down pulse of 850ish and a separator pulse of 85ish, or roughly 935 for the whole cycle, near enough to 1000 with all the other error possibilities taken into account. So that explains that. mea culpa.

Now a separate question if I may. How do I set the separator pulse (currently defaulting to 100ms apparently) to 300ms (always, regardless of "data" pulse size)? I tried making a couple of changes to the constants in pulseposition.cpp, namely TX_MINIMUM_SIGNAL 1000, TX_MAXIMUM_SIGNAL 2000, TX_MINIMUM_FRAME 22500, and TX_PULSE_WIDTH 300, but this didn't seem to change anything. I still get a 2000ms frame size and 100ms separator pulse.

Another semi related question, for my technical education. What's the reason all those #defines are in the .cpp module and not the header?

Thanks,
Ian
 
On a completely different note, I think I've found a typo in kinetis.h.
Code:
#define FTM_CONF_NUMTOF			(((n) & 31) << 0)		// ratio of counter overflows to TOF bit set
It looks to me like it should be
Code:
#define FTM_CONF_NUMTOF(n)			(((n) & 31) << 0)		// ratio of counter overflows to TOF bit set

Same for BDMMODE, immediately above it.

;-) Ian
 
I changed TX_PULSE_WIDTH to 300. and TX_MINIMUM_SIGNAL to 700. and rebuilt sketch, and analyzer shows HIGH pulse at 300 us and LOW at 700 us for PPM.write(n,1000); Works for me.

The IDE should rebuild the library if you modify PulsePosition.cpp. If not, you could try and change the CPU speed in the IDE, that will force a full recompile, or restart the IDE. It's also possible the you have multiple copies of PulsePosition lib, and you are not modifying the copy that the IDE is using. I sometimes stick in a garbage line (e.g., xxxxxx) in the .cpp to see if I get a compiler error when the IDE builds the sketch, then you'll know if IDE is compiling the file you are changing.

Your observation of FTM_CONF_NUMTOF is probably correct, but I can't find that the symbol is used in any of the core files. BDMMODE is also not used, me thinks.
 
Thanks manitou you were right. Again. I'm using CodeBlocks and PlatformIO. I installed PulsePosition from the PlatformIO library. However I've found that it seems to be installed in two places according to CodeBlocks. One it compiles with, the other it opens when you click on the #include pulseposition.h and ask it to open the file. Not entirely sure how this situation came about, but it explains why I wasn't getting any difference when I changed things...

On another completely different note, I don't know what IDE you guys use, but I have several that I play around with. CodeBlocks is a kinda sentimental favourite. It has so many hooks and places to set things up that it seems it should be able to do almost anything. Gotta say though I find it nearly impossible to get all the include libraries right manually. I also use Atom and VSCode, as they are both supported by PlatformIO, which automates an awful lot of background stuff and makes life very easy indeed. Sometimes though it makes life more difficult. It supports CB too, but only partially, and in the process disables a lot of CB's flexibility (by using a custom makefile instead of using CB's functionality). But anyway, to the point. I tried compiling the exact same program for pulseposition using all three IDEs (just for fun...) and found that CB and Atom produced a beautifully clean and crisp signal. VSCode however, produced a signal with many jaggies, and not clean at all. Got no idea why this should be, PlatformIO was in charge in all cases.

The first image is from Atom, the second from VSCode and the third is a zoom in showing all the jaggies. Not really a problem, just an interesting observation. Needless to say I won't be using VSCode to build anything using PulsePosition...

;-) Ian

Screenshot from 2018-01-27 15-06-58.png Screenshot from 2018-01-27 15-08-51.png Screenshot from 2018-01-27 15-09-16.png
 
Status
Not open for further replies.
Back
Top