Welcome to the Parallax Discussion Forums, sign-up to participate.

# Time between edges

Posts: 250
I try to get the time between variable edges of a square wave.
The minimum time are 240us, the maximum 1_020us.
I only need to detect value 250us or 1_000us, it is "Biphase marque"

I try in spin
``` ctra := %01110<<26 + pin       'ctra for neg edge detection
frqa := 1
ctrb := %01000<<26 + pin       'ctrb for pulstime high
frqb := 1

...

repeat i from 0 to 80                        'main loop detection
phsa := phsb := 0                        'clr edge and pulstime

repeat until (phsa OR phsb)       'wait for neg edge OR pos edge

pulses[i] := (phsb+phsa)              ' I expect to get the time between edges => A can be 0; or b can be 0. So sum would be edge time

```

Is this to simple ?
I do not get the expected timings, compare to my scope

• Posts: 49
edited 2020-04-28 - 02:31:44
The edge detector mode of cog counter counts only number of edges.
So, in your code, PHSA is always 0, and PHSB is almost same some small value each time.

If you don't need accuracy and quickness, below might work:
```  ctra := %01110<<26 + pin
frqa := 1
ctrb := %01000<<26 + pin
frqb := 1

...

repeat i from 0 to 80
phsa := phsb := 0

repeat until phsa       'wait for next edge

pulses[i] := phsb
ctra ^= |<28                   ' toggle counter mode between neg edge detection and pos edge detection
ctrb ^= |<28                   ' toggle counter mode between pulsetime high and pulsetime low
```

Also you can use WAITPxx command, instead of REPEAT UNITIL command:
```  ctrb := %01000<<26 + pin
frqb := 1

...

WAITPEQ( 0, |<pin, 0 ) ' to assume ina[pin] to be  low
repeat i from 0 to 80
prevstat := ina & |<pin                ' prevstat is LONG variable
phsb := 0

WAITPNE( prevstat, |<pin, 0 )       'wait for next edge

pulses[i] := phsb
ctrb ^= |<28                   ' toggle counter mode between pulsetime high and pulsetime low
```

And also you can use system counter CNT to measure time, instead of cog-counters:
```  WAITPEQ( 0, |<pin, 0 ) ' to assume ina[pin] to be  low
repeat i from 0 to 80
prevstat := ina & |<pin                ' prevstat is LONG variable
prevcnt := CNT                           ' prevcnt is LONG variable

WAITPNE( prevstat, |<pin, 0 )       'wait for next edge

pulses[i] := CNT - prevcnt
```

(Sorry I did not test these yet but I'll later.)
• Posts: 6,659
edited 2020-04-27 - 16:29:16
Can you go leading edge leading edge? If yes, this will give you the period of your square wave.
```pub edge2edge : ticks

ticks := cnt                                                  ' start timing
ticks := cnt - ticks                                          ' end timing
```

If you just want the next complete half cycle, regardless of phase, this works (I tested both methods with an oscillator running using CTRA).
```pub half_cycle_ticks : ticks | pinstate

pinstate := ina & EDGE_MASK                                   ' get current state
waitpne(pinstate, EDGE_MASK, 0)                               ' wait for change
ticks := cnt
waitpeq(pinstate, EDGE_MASK, 0)                               ' wait for initial state
ticks := cnt - ticks
```
Warning: If the pin doesn't change, these methods will block your program. What you could do is launch it into its own temporary cog which would allow your foreground code to timeout the measurement.
• Posts: 250
Thank you both.

I don't have time today to test this part.
I wil test it tomorrow

Daniel
• Posts: 250
For Biphase mark decoding @ 250us (Pal SMPTE LTC)

I got in a dedicated cog, detecting all the edges and toggle pin:
```EDGE_MASK  =(|< Pin_14_det)
```
``` Repeat

waitcnt(50*us +cnt)
!outa[Pin_14_det]

waitpne(pinstate, EDGE_MASK2, 0)  ' look for edge do not match
pinstate :=ina[Pin_0_in]'
```

And other cog, analyzing @ 6/8 time, of the next pulse:
```  Repeat i from 0 to 80