BS2 PULSIN issue
Wu Haoxuan
Posts: 14
Hello, I am using a BS2 in an application where I need to measure the period of a square wave signal. I am using the PULSIN command to measure the high and low segments of the square independently.
I am having a problem: the PULSIN measurements are, for the most part, way off.
Whereas the high should be around 2 ms and the low 12 ms (that's milliseconds), I get between 2 us and 50 us for both (that's microseconds). The issue is prevalent; only about 1 in 20 measurements are anywhere close to being accurate. I'm using an oscilloscope to monitor the signal so I know what times to expect.
I'm pretty new to programming the BS2, and my PULSIN program is very simple:
trigger PIN 4
scale CON $200 'scale for STAMP
hitime VAR Word(5) 'variable assignments for measured quantities
lotime VAR Word(5)
totime VAR Word 'variable assignments for calculated quantities
plscnt VAR Nib 'variable assignments for counters
PAUSE 1000
Prompt: 'Sub-program for user prompt
DO
DEBUG CLS, "Press button to measure ",
"vibrational period:", CR
IF (trigger = 1) THEN EXIT
PAUSE 250
LOOP
GOTO Acquire
Acquire: 'Sub-program for hitime and lotime measurements
plscnt=0
DO WHILE (plscnt<5)
PULSIN 0, 1, hitime(plscnt)
PULSIN 2, 0, lotime(plscnt)
plscnt=plscnt+1
LOOP
GOTO Calculate
The DO...LOOP stuff and the "plscnt" variable are there to let me record 5 sets of data. I didn't bother showing my subprogram for the calculation and the rest, since I can't even get it to give me sensible values for the measurements. The trigger is just an ordinary pushbutton setup and it seems to work just fine. The signal being measured comes from a pressure sensor whose output is squared off by a pre-amp circuit. The pre-amp's signal wire is connected to both pins 0 and 2 of the BS2, as well as being connected to the BoE's Vss pin via a 10k resistor. I've also connected the pre-amp's ground wire to the Vss pin to establish a common ground.
Any ideas as to why this is happening?
I am having a problem: the PULSIN measurements are, for the most part, way off.
Whereas the high should be around 2 ms and the low 12 ms (that's milliseconds), I get between 2 us and 50 us for both (that's microseconds). The issue is prevalent; only about 1 in 20 measurements are anywhere close to being accurate. I'm using an oscilloscope to monitor the signal so I know what times to expect.
I'm pretty new to programming the BS2, and my PULSIN program is very simple:
trigger PIN 4
scale CON $200 'scale for STAMP
hitime VAR Word(5) 'variable assignments for measured quantities
lotime VAR Word(5)
totime VAR Word 'variable assignments for calculated quantities
plscnt VAR Nib 'variable assignments for counters
PAUSE 1000
Prompt: 'Sub-program for user prompt
DO
DEBUG CLS, "Press button to measure ",
"vibrational period:", CR
IF (trigger = 1) THEN EXIT
PAUSE 250
LOOP
GOTO Acquire
Acquire: 'Sub-program for hitime and lotime measurements
plscnt=0
DO WHILE (plscnt<5)
PULSIN 0, 1, hitime(plscnt)
PULSIN 2, 0, lotime(plscnt)
plscnt=plscnt+1
LOOP
GOTO Calculate
The DO...LOOP stuff and the "plscnt" variable are there to let me record 5 sets of data. I didn't bother showing my subprogram for the calculation and the rest, since I can't even get it to give me sensible values for the measurements. The trigger is just an ordinary pushbutton setup and it seems to work just fine. The signal being measured comes from a pressure sensor whose output is squared off by a pre-amp circuit. The pre-amp's signal wire is connected to both pins 0 and 2 of the BS2, as well as being connected to the BoE's Vss pin via a 10k resistor. I've also connected the pre-amp's ground wire to the Vss pin to establish a common ground.
Any ideas as to why this is happening?
Comments
What sort of pulse widths are you trying to measure?
Thanks for the speedy reply Mike! I am measuring the output of a pressure sensor, which is a somewhat complicated waveform. I'm only interested in the fundamental oscillation frequency, so I have built a circuit that filters out the overtones, amplifies the signal and squares it off. The result is a square wave with about a 3V amplitude. Typically the high and low segments are of different lengths, which is why I need to measure both. This is mainly due to the way I've built my pre-amp circuit.
I understand what you mean about a programming error potentially causing an issue with two I/O pins wired together, and I hadn't even anticipated that. So thanks for the heads up. I suppose I'd want to perform both measurements on the same pin.
One of the reasons I had set it up this way was because I was trying to make sure I could measure the high and low of a single cycle. From what you're saying it seems that won't be exactly possible (if there has to be some reset time between PULSIN measurements).
By the way, how much delay is sufficient between PULSIN commands?
To do what you want (measure the width of the positive going pulse and the "space" between pulses), you should consider using a Propeller (like a SpinStamp). This can easily measure both widths with 12.5ns resolution.
I've simplified everything and using a single input pin just tried to measure a single high pulse. On just about every attempt I get a very small number. This was working when I first set it up, and all my components check out, so I wonder if I've damaged the BS2 module in some way.
I'm interested in your suggestion of using a Propeller for this aplication. Is it just for the better resolution, or are there other reasons I might prefer it?
The Propeller is faster, has higher resolution, more memory, and is easier to use for this sort of measurement. You can use a pair of built-in cog counters to count the time a signal spends low and the time it spends high. You can track the signal edges easily and save the counter contents after the edge transition, all with a resolution of 12.5ns.
' {$STAMP BS2}
' {$PBASIC 2.5}
'Program for pressure measurement
hitime VAR Word 'variable assignments for measured quantities
lotime VAR Word
totime VAR Word 'variable assignments for calculated quantities
DEBUG CLS, "vibrational period:", CR
PAUSE 250
'
DO
PULSIN 0, 1, hitime
PAUSE 100
PULSIN 0, 0, lotime
PAUSE 100
totime = lotime + hitime
DEBUG CLS,
"hitime lotime Totime",
CRSRXY,1,2,DEC hitime,
CRSRXY,12,2,DEC lotime,
CRSRXY, 23, 2, DEC totime,
CR,CR,CR
PAUSE 100
LOOP
When I watch this program loop, I get a lot of 1s and 2s and a few 3s in the hitime variable. I get bigger values in the lotime, from 10 to 100. These are well below what is expected.
As for the input signal, it's relatively noise free. According to my scope, any noise and ripple that I'm seeing is well below 100 mV amplitude. Furthermore there are no traces of spikes with the durations that I'm seeing from the PULSIN measurements. The square itself usually has a rise/fall time of approximately 75 us. The high segment of the square is very stable, and it lasts typically about 750 us. The low segment of the square lasts about 6500 us.
Even if I just measure the high of the square by itself (or the low by itself), I get the same values. I tested the BS2 chip and PULSIN using a simple discharging RC circuit and it performed as expected.
Do you think the issue could be related to the rise/fall time of the square wave? Perhaps I need to find a faster op-amp IC for my pre-amp circuitry...
You've piqued my interest in the Propeller chip. I started using the BS2 mainly because a friend of mine had an extra one lying around and he thought it might be useful for my work. I've found it pretty simple to program (the Basic Stamp Manual has been very helpful). Is the SpinStamp software as easy to learrn as PBASIC?
There are a lot of different programming tools for the Propeller. There are several Spin compilers / assemblers, a free C compiler, PropBasic which compiles to Spin/assembler. There's a Forth and a graphical programming system (12Blocks) as well. I mentioned the SpinStamp mostly because you might be able to substitute that for your Stamp. The Propeller has 3.3V logic I/O pins while the Stamp uses 5V logic. Depending on what you have connected to your Stamp, you might manage to switch with only a couple of 2.2K series resistors added in the I/O leads. You also have to do the program downloading via a PropClip adapter or equivalent rather than the circuit on your Stamp board. At one point I had done this with a BoeBot. I added a couple of resistors in series with the I/O pins to the servos, the PING, and the IR detectors. I changed the resistor values in series with the IR LEDs since the 3.3V outputs of the SpinStamp require a lower resistor value for the same output current. That was it. For programming, I'd start with PropBasic since it's similar to the PBasic that you've already learned. You'll need to use BST (Brad's Spin Tool) rather than the Propeller Tool with PropBasic and both are available for Windows, Linux and the MacOS.
After a little error analysis, it seems the precision of these measurements is right on the border of what is acceptable for this appliction. I'll have to take some more data and look into it further. I suppose the Propeller would be much more precise with its high time resolution.
Thanks for all your help Mike. I will definitely look into the Propeller more deeply.
You have mentioned using scope and the expected pulse to be clean, I am curious how your signal looks before the first expected low to high transition. Is it really clean low?
Can you trigger your scope on your button pres?
Do you by any chance have button bounce signal instead of clean low?
You are collecting five samples than calculating average.
Would it work for you to have an initial trigger monitoring just simple change from low to high and then take your samples using PULSIN?
And as Mike said – you will not get expected results using PULSIN consecutively.
I am having hard time buying into dependency on waveform / signal rise / fall time, the processor is digital and process only high or low values in well defined tolerances.
If PULSIN measures 2 us it must see 2 us signal.
Vaclav
If the PULSIN pin gets popped with a 1us lo-hi-lo is the result 0 or 1?
If the PULSIN pin gets popped with a 3us lo-hi-lo is the result 1 or 2?
Regarding slow rise / fall time, reread my message #8. These gates are very fast and have high gain. A "square wave" that takes 75us to rise spends nearly forever near the switching threshold as far as a gate that responds to 10ns signals is concerned. This threshold may be well under 100mV high and relatively short noise pulses can easily cause the gate to behave as if it had seen a valid pulse come through. That's why Schmitt triggers are used on slowly changing inputs to digital logic.
The button bounce shouldn't affect my measurements, since I'm not measuring the signal on the I/O pin connected to the pushbutton.
You may not buy into it, but the Schmitt Trigger (ST) cured the issue I was having. Aside from inverting the signal, the only other effect of the ST was to sharpen up the square wave. Since it fixed the problem, I tend to believe the slowness of the transition was the cause. I mean, you're right, the processor itself is seeing a 2 us (approximately) pulse and it is calculating it as such. But the processor is being tricked by the gate that is actually monitoring the signal. If the signal voltage spends a lot of time near the threshold level, it makes sense that ANY amount of noise can cause the gate to register a very rapid 0-1-0 transition. From what I've read, this is one of the problems that the Schmitt Trigger is designed to fix (as Mike Green points out).
@PJ Allen...point taken.
Okay, so two of you have said using consecutive PULSIN commands will not give expected results. First, I'd like to note that the measurement sub-program seems to run fine like this...
plscnt=0
DO WHILE (plscnt<5)
PULSIN 0, 1, hitime(plscnt)
PULSIN 0, 0, lotime(plscnt)
plscnt=plscnt+1
LOOP
GOTO Calculate
Now that I have a more square-ish square wave, the results are quite consistent with measurements made on an oscilloscope.
In what ways might these results be flawed? And what would be a better way to set it up?
(pulse end). If the 1 to 0 transition comes before timeout you get the pulse width and now the signal is 0 and the first PULSIN “exits”.
Now the second PULSIN looks for 1 to 0 transition and since the signal is 0 it will time out.
In other words you are trying to read the tail end of the 1 to 0 (positive pulse) by one PULSIN and the start of “low” pulse in the other. But they are identical part of the waveform.
But if it works for you do not fix it.
Vaclav
Also, if this were an issue, my random triggerinng process would cause time out problems as well. But it works just fine.
I missed something in my analysis.
Depending on the period of the signal (no timeouts) using two consecutive PULSIN like this every other pulse plus next pulse, either low to high to high to low (positive ) or high to low to low to high ( negative) will be skipped over.
You are measuring first positive pule, skip over negative pulse and next positive pulse and than measure negative pulse.
But if it works for you , fine.
I figured that might be the case. It's acceptable, and I seem to be getting decent numbers. Ideally, however, I would like to measure the high and low of a single cycle. From what Mike Green said, the Propeller should be able to do this. Any ideas how it could be done on the BS2?
New = INS.BIT12 '
Change = New ^ Old ' check for change in input
Old = New ' update
If Change then ....
I am looking just for the change only. If there is no change I just loop back..
You could use / nest two change detectors and keep counting the loops execution. Of course you would have to calcualte the actual time ( period) of the pulses manually from the instruction execution time.
Vaclav