Shop OBEX P1 Docs P2 Docs Learn Events
Multiple signals on different pins at different times — Parallax Forums

Multiple signals on different pins at different times

Hello,

I was wondering is there a way to send independent signals on pins, I was thinking I needed multiple cogs, set to start at a specific time, but I think there would be an issue of drift.

I have to send data on 8 pins, all have different signals on each pin, Is there a way to do this

regards

Jeff

Comments

  • It all depends on what the signals are and their relationships with each other (if any). If you end up needing to use multiple cogs, they can be "locked" into strict relationships with each other (and time) through the use of the system clock (CNT) and the WAITCNT instruction. There are two counters in each cog and they can produce different signals with different timings with the cog managing both of them with precise relationships with the system clock.

    You'll have to tell us more about what you're trying to do.
  • I have attached a file of the signals, but It seems using multiple cogs I can control each individually.

    so could you give me an example of two independent cogs toggling two different pins at a few microsecond difference (independent of each other, I was wondering how to sync them together.

    regards

    Jeff
    1632 x 918 - 480K
  • If you want to produce repetitive signals, with pulse width of 1 uSec or better, you might try this arbitrary pattern generator.
  • AribaAriba Posts: 2,690
    edited 2016-05-17 21:32
    You can synchronize two cogs by waiting for the same CNT value or by waiting for a pin change for example.

    Here is an example code. The first cog toggles P0 in a Spin loop, the second cog waits for the pos-edge on P0 and toggles P1 with 4us delay for 4us. This cog is programmed with assembly, because Spin is not fast enough for us timings.
    CON
      _clkmode  = xtal1 + pll16x
      _xinfreq  = 5_000_000
    
    PUB Main : tm
      DIRA[0] := 1
      cognew(@asmcog,0)
      tm := CNT
      repeat
        waitcnt(tm += 80_000)       'toggle P0 every ms
        OUTA[0] ^= 1
    
    
    DAT
    asmcog  mov      dira,p1
    loop    waitpeq  p0,p0          'wait until P0 goes high
            mov      t1,CNT
            add      t1,#320
            waitcnt  t1,#320        'delay 4us
            or       outa,p1        'P1 high
            waitcnt  t1,#0          'delay 4us
            andn     outa,p1        'P1 low
            waitpne  p0,p0          'wait until P0 goes low
            jmp      #loop
    
    p0      long    1
    p1      long    1<<1
    t1      res     1
    
    'P0 _____--------_______------ cog0
    'P1 ______-______________-____ cog1
    
    Andy
  • Ariba,

    I would like them to be completely independent of each other, you mentioned that "waiting for the same CNT value" would be another way, vs watch each other, do you have an example of this, two cogs waiting for the a specific cnt timer value to begin transmission?

    regards

    Jeff
  • There's nothing magic about this, give each cog the same value to WAITCNT for. Make sure its far enough in
    the future that it can't be missed by either cog (cog start up takes about 8192 clks, not counting any
    code overhead). WAITCNT is global and precise to the clock.
  • AribaAriba Posts: 2,690
    They can not be "completly independent" and synchronized at the same time.
    One cog has to be the "Master" and tell the other one the CNT value to sync to.

    Here is an example with two Spin cogs, they output a short pattern every 1ms started at the same time. After the syncpoint they are independent and can do different timings until the next syncpoint.
      _clkmode  = xtal1 + pll16x
      _xinfreq  = 5_000_000
    
    VAR
      long  synctime                'global var for both cogs
      long  stack[20]
    
    PUB Main : tm
      DIRA[0] := 1
      synctime := CNT + 40_000      'sync at now + 500us 
      cognew(secondcog,@stack)
      repeat
        waitcnt(synctime)           'wait for same synctime as other cog
        tm := CNT
        repeat 8
          waitcnt(tm += 4_000)      'toggle P0 every 50us 8 times
          OUTA[0] ^= 1
        synctime += 80_000          'next sync point 1ms later
    
    PUB secondcog | tm2
      DIRA[1] := 1
      repeat
        waitcnt(synctime)           'wait for same synctime as other cog
        tm2 := CNT
        repeat 6
          waitcnt(tm2 += 6_000)     'toggle P1 every 75us 6 times
          OUTA[1] ^= 1
    
    Andy
Sign In or Register to comment.