Shop OBEX P1 Docs P2 Docs Learn Events
Fastest method to share VAR between 2 P1's - Page 2 — Parallax Forums

Fastest method to share VAR between 2 P1's

2»

Comments

  • T ChapT Chap Posts: 4,223
    edited 2024-05-20 02:44

    Odd behavior for sure. I need to do some more experiments. At very low speeds this should not be noise. I question if transitions out of the prop using outa[3..4] := %11 etc are valid methods for this type of quad output. I like the quadrature concept and it is faster to send quad than 4+ serial bytes. I tested today sending 4 bytes as position over 8” wires. 155k baud didn’t work. 80k works. But it is slower to create and read the packets in spin. I discovered that instead of the profile generator updating position at +1 per iteration I tried +2 per iteration on my test board sending the positions and that creates a faster motor speed without needing to run the data stream. The proof of concept is working out nicely to park 3 profile generators in one main board prop and stream positions to 3 sub boards running PID.

  • MicksterMickster Posts: 2,698

    @"T Chap" said:
    155k baud didn’t work. 80k works.

    Something not right with this. Common gnd?

    But it is slower to create and read the packets in spin.

    Been a while since I looked but I seem to remember that FDS (probably others) handles the binary-2-string / string-2-binary, internally, no?

    Craig

  • T ChapT Chap Posts: 4,223
    edited 2024-05-20 13:17

    Well that’s a good question. I am using

    Serial.tx(position.byte[0]
    Serial.tx(position.byte[1]
    Serial.tx(position.byte[2]
    Serial.tx(position.byte[3]

    And receive side

    Outa[4]~~ ‘tell sender to send another packet

    Serial.rx. ‘ wait for first byte
    Serial.rxtime(10)
    Serial.rxtime(10)
    Serial.rxtime(10)
    Outa[4]~ ‘tell sender to not send anymore

    Position = Add 4 bytes together bit shifting each byte

    Maybe there is a better way!

    I’ll check the GND between both boards. Actually 2 power supplies Maybe not shared GND. Good point !

    EDIT. Connected gnd no change. Shielded cable 8” no change, lots of bad values, 80% good values but random very big positive also negative numbers make our go crazy. Using my go to old school 4port FDS from 10+ years ago.

  • JonnyMacJonnyMac Posts: 9,156

    With ping-pong multi-tasking the normal FDS is only reliable for 115200 baud -- seems like using a 4-port serial object could be the reason for the speed issue.

  • T ChapT Chap Posts: 4,223

    96000 is working so this is close enough for this type of test streaming a Long signed value. Adding any method to do error checking will add more time. A simple method could be sum the 4 bytes and send the sum (or inverted sum) as a 5th byte. Then parse the 4 bytes into Long in receive, add 4 bytes invert and compare with byte 5. If bad compare then ignore the packet. Other compact methods to check the packet ?

  • MicksterMickster Posts: 2,698

    Checksum alternative: subsequent updates should be within reason. Quicker to do this check?

    Packet: From one update to the next, 16 bits should be more than enough. Halve the packet size?

    Craig

  • jmgjmg Posts: 15,175

    @Mickster said:
    T Chap and I are doing similar stuff and one of the really neat things about using the LS7366R device; it is SPI and has it's own 5V UPS to keep the device + encoder alive during power-down (it also features a lost-power flag in case the UPS dies). Re-homing a machine can be a royal PITA. This way, the machine can be powered-up in a morning and ready-to-roll. Should any of the axes get disturbed during power-down, no problem because the 7366 keeps counting - effectively, an absolute encoder. Furthermore, in my case, the encoder counting rate needs to be way more than the P1 can handle. The 7366 is good for 40M counts/sec when using differential receivers. I seem to remember that T Chap's encoders are open collector so not true in his case but still way faster than the P1 can handle. I'm doing similar but I have substituted a RPi Pico for the 7366. I can have the Pico on a UPS and handle 4 encoders at high-ish count-rates. OTOH, if the P1 is fast enough for T Chap, he could have a UPS-backed P1, dedicated to simply reading 3 encoders and banging-out the 3 longs, serially. On power-up, the main P1 just starts RX-ing the 3 longs.

    Another mid-point-solution for P1 quad counting, could be to use two P1 counters and take the difference. (both count up)

    A quick look has 2 logic chips needed : 1 x TI 74HCS86 (or similar Schmitt XOR from Diodes inc or Nexperia) and 1 x 74HC153, to give QUAD to CLK_UP, CLK_DN signals.
    Speed would be well above SW, and should easily give > 10MHz edge rates.

  • jmgjmg Posts: 15,175
    edited 2024-05-21 01:28

    @"T Chap" said:
    Edit. Drift is not io pins. I changed boards. It is not obvious in a scope. Wires are 8” unshielded. At very slow speeds this should not be happening.
    Bottom line is this seems like a bonafide method to connect to an external PID over Quad, but for sure will have some error checking behind the scenes over to be sure there is no drift.

    That seems strange.
    What was the receiver here ?

    Another link choice for local data, could be a variant of the SENT bus ? (Single edge nibble transfer)
    That nibble encodes data with a fixed HI time for autobaud/sync and then a 16 step OFF time for data, so is well suited to P1 timers.
    If both P1 run crystals, more than 4 bits could be sent for every edge-pair.

  • T ChapT Chap Posts: 4,223

    Thanks for your input jmg. I created a quad output simulator on one p1 board. It is extremely simple. It counts up to x and counts back down. You can change the delay between transitions from max spin repeat frequency to any slower rate. The receiver is both jonnymac encoder engine and the classic rotary encoder engine. Both of which I use on tons of projects with motors with encoders that would never tolerate drift. This is a mystery. Testing tonight positive counts at 100 repeats in spin. Pause 1 sec. Keep repeating this and it looses a number every so many cycles. It seems like it the stopping for 1 second that may be where is error is occurring

  • MicksterMickster Posts: 2,698
    edited 2024-05-21 09:10

    @jmg said:

    Another mid-point-solution for P1 quad counting, could be to use two P1 counters and take the difference. (both count up)

    A quick look has 2 logic chips needed : 1 x TI 74HCS86 (or similar Schmitt XOR from Diodes inc or Nexperia) and 1 x 74HC153, to give QUAD to CLK_UP, CLK_DN signals.
    Speed would be well above SW, and should easily give > 10MHz edge rates.

    Have wanted to do this since forever but this dumba$$ just can't get a handle on rollover (which will happen PDQ). I have laid numbers out, used calculators, scoured the web...never got to grips with an elegant, seamless solution.

    For an external hardware solution, I just grab a RPi Pico and bang the four encoder counts out via UART@921.6K-Baud. Alternatively, these things are easily I2C slaves:

    PicoMite BASIC, BTW.

    'Quadrature multichannel decoder for PicoMite using PIO

    'this is a 4 channel quadrature decoder for MMBasic V5.08.00 or newer
    'running on a PicoMite or PicoMiteVGA usinf PIO 1

    'Original PIO source: https://github.com/p-o-l-e/quadrature-decoder

    '30-4-2024 Volhout



    'system initialisation ---------------------------------------------------------

    'program PIO 1
    program_PIO 'program the code in PIO 1

    'quadrature decoders generic settings
    PIO_f%=63e6 'frequency = 63MHz
    PIO_s%=0 'shift register (shift in left)
    PIO_e%=PIO(execctrl gp0,wrp_tgt,wrap) 'start and stop of the loop

    'start quadrature decoders (uncomment the needed decoders)
    start_sm0 : sm0=1 'start decoder on GP0 and GP1
    'start_sm1 : sm1=1 'start decoder on GP2 and GP3
    'start_sm2 : sm2=1 'start decoder on GP4 and GP5
    'start_sm3 : sm3=1 'start decoder on GP26 and GP27



    'main MMBasic code -------------------------------------------------------------

    'this code is just a demo that shows the position of the quadrature decoders
    'the selected decoder positions are printed on the console
    'type "r" to reset the decoders to 0

    'main loop
    do
    a$=inkey$ 'just for control

    'get the data from the fifo and print
    if sm0 then print str$(read_fifo(0),12,0); 'get data from decoder
    if sm1 then print str$(read_fifo(1),12,0); 'get data from decoder
    if sm2 then print str$(read_fifo(2),12,0); 'get data from decoder
    if sm3 then print str$(read_fifo(3),12,0); 'get data from decoder
    print

    'just some pause
    pause 100 'any delay needed

    'reset position (PIO X register) under control of keyboard
    if a$="r" then 'press r to zero position
    if sm0 then pio execute 1,0,&hA023 '= assembly "mov X, null" (zero X reg)
    if sm1 then pio execute 1,1,&hA023 '= assembly "mov X, null" (zero X reg)
    if sm2 then pio execute 1,2,&hA023 '= assembly "mov X, null" (zero X reg)
    if sm3 then pio execute 1,3,&hA023 '= assembly "mov X, null" (zero X reg)
    a$=""
    end if

    loop while a$="" 'exit when any key not r

    end




    ' subroutines -------------------------------------------------------------------


    'this function returns the actual count of decoder n
    function read_fifo(n) as integer

    local dat%(3)
    pio read 1,n,4,dat%() 'read whole fifo
    read_fifo = dat%(3) 'last data in fifo
    if read_fifo>2147483647 then inc read_fifo,-4294967296 '2'th complement

    end function


    'this subroutine programs the quadrature decoder program for PIO1 into
    'PIO program memory
    sub program_PIO

    'this is the PIO program in machine code
    dim p%(7)=(&h001A00170015001A,&h0015001A001A0017,&h0017001A001A0015, &h001A00150017001A,&h4042A0404042A0C3,&hA029001A005AA0A6,&h8000A0C1A0290059,0)

    'here the program is programmed in memory
    pio program 1,p%()

    wrap=27 'end of the program
    wrp_tgt=16 'start of the program loop

    end sub

    'this subroutine starts state machine 0 quadrature decoder on gp0 and gp1
    sub start_sm0

    'uses GP0,GP1, assign pins in MMBasic
    setpin gp0,pio1
    setpin gp1,pio1

    'assign pins in PIO
    pin_sm0%=PIO(pinctrl 0,0,0,gp0)

    'configure and start PIO
    pio init machine 1,0,PIO_f%,pin_sm0%,PIO_e%,PIO_s%,wrp_tgt
    pio start 1,0

    end sub


    'this subroutine starts state machine 1 quadrature decoder on gp2 and gp3
    sub start_sm1

    'uses GP2,GP3, assign pins in MMBasic
    setpin gp2,pio1
    setpin gp3,pio1

    'assign pins in PIO
    pin_sm1%=PIO(pinctrl 0,0,0,gp2)

    'configure and start PIO
    pio init machine 1,1,PIO_f%,pin_sm1%,PIO_e%,PIO_s%,wrp_tgt
    pio start 1,1

    end sub


    'this subroutine starts state machine 2 quadrature decoder on gp4 and gp5
    sub start_sm2

    'uses GP4,GP5, assign pins in MMBasic
    setpin gp4,pio1
    setpin gp5,pio1

    'assign pins in PIO
    pin_sm2%=PIO(pinctrl 0,0,0,gp4)

    'configure and start PIO
    pio init machine 1,2,PIO_f%,pin_sm2%,PIO_e%,PIO_s%,wrp_tgt
    pio start 1,2

    end sub


    'this subroutine starts state machine 3 quadrature decoder on gp26 and gp27
    sub start_sm3

    'uses GP26,GP27, assign pins in MMBasic
    setpin gp26,pio1
    setpin gp27,pio1

    'assign pins in PIO
    pin_sm3%=PIO(pinctrl 0,0,0,gp26)

    'configure and start PIO
    pio init machine 1,3,PIO_f%,pin_sm3%,PIO_e%,PIO_s%,wrp_tgt
    pio start 1,3

    end sub

    Craig

  • msrobotsmsrobots Posts: 3,709

    @"T Chap" said:
    Thanks for your input jmg. I created a quad output simulator on one p1 board. It is extremely simple. It counts up to x and counts back down. You can change the delay between transitions from max spin repeat frequency to any slower rate. The receiver is both jonnymac encoder engine and the classic rotary encoder engine. Both of which I use on tons of projects with motors with encoders that would never tolerate drift. This is a mystery. Testing tonight positive counts at 100 repeats in spin. Pause 1 sec. Keep repeating this and it looses a number every so many cycles. It seems like it the stopping for 1 second that may be where is error is occurring

    every 100 repeats or maybe every xx seconds cnt overflow?

  • jmgjmg Posts: 15,175

    @Mickster said:

    @jmg said:

    Another mid-point-solution for P1 quad counting, could be to use two P1 counters and take the difference. (both count up)

    A quick look has 2 logic chips needed : 1 x TI 74HCS86 (or similar Schmitt XOR from Diodes inc or Nexperia) and 1 x 74HC153, to give QUAD to CLK_UP, CLK_DN signals.
    Speed would be well above SW, and should easily give > 10MHz edge rates.

    Have wanted to do this since forever but this dumba$$ just can't get a handle on rollover (which will happen PDQ). I have laid numbers out, used calculators, scoured the web...never got to grips with an elegant, seamless solution.

    I think you just treat it like a clock with two hour hands and take the least-distance.
    That does cost you one bit, so max is 2^31, or you can extend the counters in SW for a 2^63 limit.

    For an external hardware solution, I just grab a RPi Pico and bang the four encoder counts out via UART@921.6K-Baud. Alternatively, these things are easily I2C slaves:

    Yes, the PIO on those is nifty. There is chatter about a new RP2040, but nothing concrete yet.

  • T ChapT Chap Posts: 4,223

    There is no specific pattern. The drift is random but every few cycles. My Quad output simulator on p1 is very slow compared to real encoder projects that don’t drift. One test today the scope shows 500hz on the A channel. Yet 5k cycles on a motor with encoder never drifts so I am not pushing the speed limits. I’ve tried various boards that work fine on real encoders. This has to be my quad simulator code. But quad output is as simple as it gets. Hoping for an a ha moment soon.

    @msrobots said:

    @"T Chap" said:
    Thanks for your input jmg. I created a quad output simulator on one p1 board. It is extremely simple. It counts up to x and counts back down. You can change the delay between transitions from max spin repeat frequency to any slower rate. The receiver is both jonnymac encoder engine and the classic rotary encoder engine. Both of which I use on tons of projects with motors with encoders that would never tolerate drift. This is a mystery. Testing tonight positive counts at 100 repeats in spin. Pause 1 sec. Keep repeating this and it looses a number every so many cycles. It seems like it the stopping for 1 second that may be where is error is occurring

    every 100 repeats or maybe every xx seconds cnt overflow?

  • T ChapT Chap Posts: 4,223

    There has to be some artifact happening in this quad send test code. Count up to 10,100,1000,2000 then back down. It doesnt matter how high you count up or down, the drift is 2 or rarely 4. 3 good cycles, 1 bad. Or you can see bad, bad, bad, good, bad, good good.

    Pub SimulateQuad
      dira[3..4] := %11
      ' FORWARD
      QuadState := 1
      Repeat 
         Repeat 100
           QuadState++
           If QuadState > 4   ' reset upper
               QuadState := 1
           Elseif QuadState < 1    ' reset lower 
               QuadState := 4
           OutputQuad
           w(1_000_000)    ' Set repeat Frequeny
         w(80_000_000)   ' wait at end of count up down 
    
         ' REVERSE
         Repeat 100
           QuadState--
           If QuadState > 4   ' reset upper
               QuadState := 1
           Elseif QuadState < 1    ' reset lower 
               QuadState := 4
           OutputQuad
           w(1_000_000)   ' Set repeat Frequeny
         w(80_000_000)      ' wait at end of count up down 
    
    
    PUB OutputQuad
          Case QuadState
    
             1 :  outa[3..4] := %00
             2 :  outa[3..4] := %10
             3 :  outa[3..4]  := %11
             4 :  outa[3..4] := %01
    
    
  • jmgjmg Posts: 15,175

    @"T Chap" said:
    There is no specific pattern. The drift is random but every few cycles. My Quad output simulator on p1 is very slow compared to real encoder projects that don’t drift. One test today the scope shows 500hz on the A channel. Yet 5k cycles on a motor with encoder never drifts so I am not pushing the speed limits. I’ve tried various boards that work fine on real encoders. This has to be my quad simulator code. But quad output is as simple as it gets. Hoping for an a ha moment soon.

    It would need some sort of runt pulse, that the decoder only managed to track one edge of, but the code looks fine.
    Could anything else be disturbing the pins ?
    Because it is slow, you could add some RC+Schmitt filters, to see if that solves the drift/creep ?

  • jmgjmg Posts: 15,175
    edited 2024-05-21 21:55

    @"T Chap" said:
    There has to be some artifact happening in this quad send test code. Count up to 10,100,1000,2000 then back down. It doesnt matter how high you count up or down, the drift is 2 or rarely 4. 3 good cycles, 1 bad. Or you can see bad, bad, bad, good, bad, good good.

    The code does not start in a defined state, but that should only give 1 edge error ? (depends a bit on how a possible illegal 00-11 or 11-00 is handled)
    Also check the pins are not floating before the run starts.

    You could try starting from a known state, (reset the slave after POR and before run) and check if cycling mod 4 sizes changes the effect ( ie hand overs are then always the same phase)

  • T ChapT Chap Posts: 4,223
    edited 2024-05-21 23:55

    Seems to be solved.

    470 ohm in series on both A and B instantly cured it, many various tests and repeat values and zero failures.

    I think this was ringing. The P1 on the receive side had 10k pulldowns already. The 470 cleaned up the scope where I saw typical spikes on occasional transitions which can be normal for adjacent line crossing over with signals.

    Thanks for all the suggestions.

    I agree Schm Triggers would benefit, I use those on all motor encoder inputs to P1.

    Back to the original point, I think the quad method of steaming positions is a good solution to my separation of profile generator and PID engine. Looking forward to getting back to testing that tomorrow. One quad pulse replaces for 4 bytes of position data. The code can do a periodic sanity check to verify position values between boards.

  • T ChapT Chap Posts: 4,223

    With one P1 board running the Quad output simulator over 8" wires to another P1 board with a Quad receive loop. Ran 16 hours overnight a loop counting up to 100 then back down in repeat, in spin a waitcnt of 10_000 after each Quad pulse output. Saw a drift of 2. Then set to no wait, as fast as spin can loop and change the outputs, and count to 1000 then back down in a loop. 6 hours no drift.

  • jmgjmg Posts: 15,175

    @"T Chap" said:
    470 ohm in series on both A and B instantly cured it, many various tests and repeat values and zero failures.

    I think this was ringing. The P1 on the receive side had 10k pulldowns already. The 470 cleaned up the scope where I saw typical spikes on occasional transitions which can be normal for adjacent line crossing over with signals.

    Seems a little bit sensitive ?

    I like to place RC+Schmitt, where the RC filter+hyst is chosen so the narrowest pulse possible, is always wide enough to catch both edges.

    However, software should be able to get close, with the care of single-point sampling and follow ? like this psuedo code

    Qx   = Qpin XOR Qo  // single point sample
    QCtr = QCtr + DiffTable[(Qx << 2) + Qo]  // 16 entry table +1/-1/0
    Qo   = Qo XOR Qx    // update Qo, using single point sample.   
    

    Here even a glitch will update Qo, so the next pass thru does a balanced INC/DEC

  • MicksterMickster Posts: 2,698

    @jmg said:

    Seems a little bit sensitive ?

    Yes. Messed-up encoder data can be quite spectacular (read: expensive)
    I have always used differential signals, feeding a MC3486. This is Yaskawa:

    Craig

Sign In or Register to comment.