Timing and Jitter
Andy McLeod
Posts: 40
I am trying to send FREQOUT commands from a pin on the BS2px triggered by a PPS from a Garmin GPS module. The Garmin puts out a usable PPS pulse at a very stable 1hz. What I would like to do is output the PWM signal generated by FREQOUT at the exact interval (plus instruction time) of the PPS signal. Using the POLLMODE, POLLRUN commands I can get a behaviour similar to this, but with about a 300usec jitter. Is there a way to lock the FREQOUT execution to the interval of the PPS?
Anyone ...?
Anyone ...?
Comments
1. once the FREQOUT is triggered, is its width consistent, or is the jitter in the output pulse width?
2. or, is the variation in the leading edge-to-leading edge time of each PWM pulse?
I would guess the pwm pulse width should be fairly stable.
But, if the stamp is not ready to go at the instant the PPS is detected, there will be some variation if the stamp is off doing something else and gets back to the PPS service routine while the PPS is in the middle of its pulse.
Can you show us your code?
Cheers,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tom Sisk
http://www.siskconsult.com
·
POLLIN gpsppspin,ppstarget
' ...
POLLWAIT 8
FREQOUT .....
The POLLWAIT 8 keeps the Stamp awake in an event pending state, sort of like the Propeller WAITPEQ command. When the pin changes state, the execution falls through to the next command immediately, within microseconds. However, there will still be a deterministic delay of 100 microseconds or so for the interpreter to work on the FREQOUT. But it is deterministic, not jittery. Other values from 0 to 7 after POLLWAIT induce a power saving sleep cycle, but POLLWAIT 8 keeps the Stamp alert for shortest possible latency.
I expect the jitter came from having a loop waiting to execute the POLLRUN--There is an unprediictable element in where the PPS falls in the loop. The BS2p won't be doing anything else while it is in the POLLWAIT state.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
PING1.bpx
' {$STAMP BS2px, ping2.bpx}
' {$PBASIC 2.5}
Setup:
POLLIN 7,1
POLLRUN 1
POLLMODE 3
Main:
'INPUT 7
' VERSION 1: (result ~100microsecond jitter)
'HOLD: IF IN7 = 0 THEN HOLD
' FREQOUT(pin,duration,freq)
' duration in units of .166 microseconds
' freq in units of 6.02 Hz.
'FREQOUT 0, 6, 5000
'GOSUB HOLD
' VERSION 2:
GOTO Main
END
PING2.bpx
' {$STAMP BS2px}
' {$PBASIC 2.5}
Setup:
Main:
FREQOUT 0, 6, 5000
RUN(0)
END
This setup gives me about ~120msec of jitter from leading edge to leading edge - which is merely borderline OK.
I'm not sure I understand Tracy's construct. the POLLIN command uses the structure POLLIN pin,state - not a input pin, output pin as it seems to be suggesting. What am I misreading here?
I meant to imply input pin, target state. With the pins assigned in your listing, it would be,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
I took a look at the timing. The Stamp manual hedges, saying the "response time with duration set to 8" is "less than 160 microseconds" for the 2p or "less than 250 microseconds" for the 2pe, and it doesn't say anything explicitly about jitter.
With a 'scope set to trigger on an input edge to the POLLIN pin, ans with a HIGH 14 following the POLLWAIT 8, I am seeing a latency of 200 microseconds with a jitter of 10 microseconds before the edge of the HIGH 14. The interpreter latency for a HIGH 14 by itself came out as 60 microseconds, with no jitter to speak of, so that leaves the latency for the POLLWAIT at 140 microseconds with a jitter of 10 microseconds. I was testing thatI on a beta version 1.6 of the BS2p, which is a little different from earlier versions. Note that it also depends to a small amount on which pin you use. For example pins 0, 1, 2, 4, and 8 are about 5 microseconds faster than the other pins, because of the efficient way the tokenizer stores powers of 2. Anyway, the latency for the BS2p is a little better than the value stated in the manual.
I also ran the test on a BS2pe. There it came out with a latency of 380 to 405 microseconds, minus 110 microseconds to interpret the HIGH command, leaves 270 to 295 microseconds for the POLLWAIT 8 latency, with a jitter of 15 microseconds. That is longer than the value stated in the manual, which is "less than 250 microseconds". That may be due to the way I set that up on auxio. I use POLLWAIT a lot with the 'pe, but in the modes that put the Stamp to napping.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
' {$STAMP BS2px}
' {$PBASIC 2.5}
' RUNTIME VALUES
CW CON 1
CHIRP CON 2
' CONSTANTS:
MEM_SLOT_MAX CON 7
MEM_POS_MAX CON 2047
SERIAL_TIMEOUT CON 2000 ' Units of .2ms
LOG CON 1
READDATA CON 1
BAUD4800 CON 813 ' 8N1
BAUD19200 CON 188 ' 8N1
' VARIABLES: (max 26 bytes)
LATDEG VAR Byte
LATMIN VAR Byte
LATDEC VAR Byte(5)
LONDEG VAR Byte
LONMIN VAR Byte
LONDEC VAR Byte(5)
HR VAR Byte
MN VAR Byte
SEC VAR Byte
POSVALID VAR Byte(2)
TMP VAR Byte
idx VAR Word
slot VAR Nib
Main:
'Initialize slot and write postion index.
'slot should never be less than 1 or the
'program itself will be overwritten!
slot = 1
idx = 0
DO
POLLIN 7,1 ' <---- pin,targetstate, looking for 1 on pin 7.
POLLMODE 2 ' need this to activate polling
' ...
POLLWAIT 8 ' program holds here awake in an ASM loop for target state
FREQOUT 0,3,4146
FREQOUT 0,3,4312
FREQOUT 0,3,4478
FREQOUT 0,3,4643
FREQOUT 0,3,4809
FREQOUT 0,3,4975
FREQOUT 0,3,5141
' anything else?
POLLIN 7,0 ' looking for 0 on pin 7, to sync loop to pps
POLLWAIT 8 ' waiting for pin 7 to be 0
'Baudemode calculation X = INT(4,000,000 - Baudrate) - 20
SERIN 1,BAUD19200,SERIAL_TIMEOUT,MOVEON,[noparse][[/noparse]WAIT("$GPRMC"),SKIP 1,DEC2 HR,DEC2 MN, DEC2 SEC,TMP,STR POSVALID\1,DEC2 LATDEG,DEC2 LATMIN,TMP, STR LATDEC\4,TMP,DEC3 LONDEG,DEC2 LONMIN, TMP,STR LONDEC\4]
MOVEON:
'LATDEC=0101
'LATDEC=LATDEC*10000
DEBUG "GOT HERE", CR
'DEBUG STR TEST, CR
DEBUG "TIME HR: ", DEC HR, "MIN: ", DEC MN, "SEC: ", DEC SEC, CR
DEBUG "VALID POS: ", STR POSVALID, CR
DEBUG "LAT:", DEC LATDEG," ",DEC LATMIN, "." , STR LATDEC, CR
DEBUG "LON:", DEC LONDEG," ",DEC LONMIN, "." , STR LONDEC, CR
' Protect ourself from over-writes
'DEBUG "SLOT: ", DEC slot, " IDX: ", DEC idx, CR
' IF (slot < 1) OR (slot > 7) THEN Main:
STORE slot
' IF idx < (2047 - 26) THEN NEXTSLOT
' write the data
DEBUG "SLOT: ", DEC slot, " IDX: ", DEC idx, CR
IF LOG THEN GOSUB WRITETIME
idx = idx + 6
IF LOG THEN GOSUB WRITEPOS
idx = idx + 8
HR = 00
MN = 00
SEC = 00
LATDEG = 00
LATMIN = 00
LATDEC = 0000
LONDEG = 00
LONMIN = 00
LONDEC = 0000
idx = idx - 14
IF READDATA THEN GOSUB READTIME
idx = idx + 6
IF READDATA THEN GOSUB READPOS
idx = idx + 14
'idx = idx + 1
LOOP
END
NEXTSLOT:
slot = slot + 1
idx = 0
RETURN
WRITETIME:
WRITE idx,HR(0),HR(1),MN(0),MN(1), SEC(0),SEC(1)
DEBUG "Wrote TIME...", CR
RETURN
WRITEPOS:
WRITE idx, LATDEG(0),LATDEG(1), LATMIN(0),LATMIN(1), LATDEC(0),LATDEC(1),LATDEC(2),LATDEC(3)
DEBUG "Wrote Position..", CR
RETURN
READTIME:
READ idx, HR(0), HR(1), MN(0),MN(1), SEC(0),SEC(1)
DEBUG "READ TIME HR: ", DEC HR, " MIN: ", DEC MN, " SEC: ", DEC SEC, CR
RETURN
READPOS:
READ idx, LATDEG(0),LATDEG(1), LATMIN(0),LATMIN(1), LATDEC(0),LATDEC(1),LATDEC(2),LATDEC(3)
DEBUG "READ POS, LAT: ", LATDEG, " ", LATMIN, ".",STR LATDEC, CR
RETURN