Shop OBEX P1 Docs P2 Docs Learn Events
Communications between props. — Parallax Forums

Communications between props.

DiverBobDiverBob Posts: 1,110
edited 2014-07-11 15:51 in Propeller 1
I'm looking to interface one prop (master) with 6 prop (slaves). I had thought to have the master have separate serial lines to each prop (star configuration).

Looking through the OBEX there is one object for up to 4 ports; are there any other objects that could open at least 6 ports? Or conversely, are there any other recommendations on communications from the master to each of the slave boards? Or would it be better to tie all the slave boards RX lines to the master TX? This approach works easily for transmitting so long as each slave board is 'listening' for their commands. But this method gets very complicated fast when sending the acknowledge and data back to the master to avoid collisions.

Options and advise is welcomed as I'm just starting this portion of the project off and this is another area I haven't got a lot of experience.

Bob

Comments

  • Bill HenningBill Henning Posts: 6,445
    edited 2014-06-29 17:09
    You could run two copies of the four port object - it would take two cogs on your master prop, but give you eight serial interfaces.

    Beau also had a great high speed object (14Mbps effective as I recall) however that would require one cog per slave.
    DiverBob wrote: »
    I'm looking to interface one prop (master) with 6 prop (slaves). I had thought to have the master have separate serial lines to each prop (star configuration).

    Looking through the OBEX there is one object for up to 4 ports; are there any other objects that could open at least 6 ports? Or conversely, are there any other recommendations on communications from the master to each of the slave boards? Or would it be better to tie all the slave boards RX lines to the master TX? This approach works easily for transmitting so long as each slave board is 'listening' for their commands. But this method gets very complicated fast when sending the acknowledge and data back to the master to avoid collisions.

    Options and advise is welcomed as I'm just starting this portion of the project off and this is another area I haven't got a lot of experience.

    Bob
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-06-29 17:56
    We really need a bit more info Bob.
    If the props are close (on the same pcb for instance) then high speed serial is fine. You could use 2 cogs and the 4port serial as Bill suggested. This is the easiest. Go slower if there are distances involved, and maybe driver and receiver chips if necessary.
    Otherwise, you could multi-drop using the slaves TX lines tied together and a pullup. You would need to run some form of protocol, and the slave TX would be driving DIRA instead of OUTA with OUTA[tx]=0 ie open collector driving method. Bill also has done some RS485 multidropping.
    Alter
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-06-29 18:09
    Bob wants to control six RoboPi's from a master Prop :)

    Multi-drop via open collector tx/rx like you suggest would work well, but I am not aware of any objects for that :(
    Cluso99 wrote: »
    We really need a bit more info Bob.
    If the props are close (on the same pcb for instance) then high speed serial is fine. You could use 2 cogs and the 4port serial as Bill suggested. This is the easiest. Go slower if there are distances involved, and maybe driver and receiver chips if necessary.
    Otherwise, you could multi-drop using the slaves TX lines tied together and a pullup. You would need to run some form of protocol, and the slave TX would be driving DIRA instead of OUTA with OUTA[tx]=0 ie open collector driving method. Bill also has done some RS485 multidropping.
    Alter
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-06-29 19:18
    You can't use two instances of the four port serial driver as is. You need to use two separate objects and one of the objects will need to be modified so the compiler doesn't try to use a single copy of the driver. This is discussed in more detail here.
  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2014-06-29 21:00
    Have you considered turning the Propellers into I2C slaves?

    Give each one an address and if fast speed is required, give those subroutines an extra monitoring cog.

    Jeff
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-06-29 21:07
    Bob wants to control six RoboPi's from a master Prop :)

    Multi-drop via open collector tx/rx like you suggest would work well, but I am not aware of any objects for that :(
    It would probably be simple enough to modify a serial driver to do the open collector driving.
    What about the protocol to select the various props though? Any ideas?
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-06-29 21:11
    Bill,
    Just taking a quick look at your RoboPi and saw this...
    "three ten-pin Mikronauts I/O module expansion connectors (P0-P7, P8-P15, P16-P23)"
    Should this be 8pin ???

    Scrap that - saw the 10 pin connectors
  • DiverBobDiverBob Posts: 1,110
    edited 2014-06-30 03:33
    This is for my large hexapod robot, there are 7 seperate prop boards located no more than 14 inches apart that control the 6 legs. So long distance isn't an issue and communications speed doesn't have to be super fast either. My first thought was to use 2 instances of the 4 port serial object but was looking to see if there was another option out there. I haven't looked directly at the 4 port object, but it sounds like it needs some mods to work properly if running 2 instances. I2C was another avenue I thought of but didn't have much experience with other than to write back to the EEPROM to save variables. Any examples of this being used for prop TP prop comms?
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-06-30 06:40
    I always find serial simpler than I2C etc.
    As for 2 instances, you just need to copy the 4port object to a new name and change something in the code to make the object look different to the compiler. You will be able to tell by the file size of the compiled code that both copies have been included.
    If you post some simple code, one of us can ensure that it's compiling with both objects included separately.

    So then each slave prop would be the same and use separate connections. It's an easier solution.
  • DiverBobDiverBob Posts: 1,110
    edited 2014-06-30 06:59
    Cluso99 wrote: »
    I always find serial simpler than I2C etc.
    As for 2 instances, you just need to copy the 4port object to a new name and change something in the code to make the object look different to the compiler. You will be able to tell by the file size of the compiled code that both copies have been included.
    If you post some simple code, one of us can ensure that it's compiling with both objects included separately.

    So then each slave prop would be the same and use separate connections. It's an easier solution.

    I like that idea, serial is simpler than I2C and I'm already using serial in other areas. I'll give it a try tonight and see what happens. I may need to use the multi-port serial object in the slave computers also as I'm streaming troubleshooting data to the monitor via the USB programming cable, will need another port for the master to slave connection. That may require some tweaking go my code depending on how close the multi-port serial is to FullDuplexSerialPlus.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-06-30 10:41
    DiverBob wrote: »
    That may require some tweaking go my code depending on how close the multi-port serial is to FullDuplexSerialPlus.

    While a search and replace of the changed method names shouldn't take long, another option is just to change the name of the method in the new driver. As I type this, I realize it's not a simple drop in replacement. You need to add a port identifier to each serial call. This will require you to go the search and replace route anyway so not much use in changing the method names.

    Have you used a Modbus system? You could use a similar technique of assigning addresses to each Propeller. When I make a multiple Propeller project using ID numbers for each Propeller, I save the ID number to upper EEPROM so it doesn't get erased when loading a new program. The program then detect if it's a fresh install and retrieves the ID number (from upper EEPROM). This allows multiple Propellers to have identical code with their individual behavior determined by their ID number.
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-06-30 21:47
    Bob,
    I am not sure how you aredebugging, but a simple way if you have a small composite monitor is to ues a pin and serial resistor (any value 200-1K works for a 1pin composite. see my 1pin debug in obex. I have a cheap ~$25 car reversing monitor that performs nicely.

    Using two 4port objects, or more, should be quite simple. If you need heldjust ask. I've done it before but just cannot what i did atm.
  • DiverBobDiverBob Posts: 1,110
    edited 2014-07-01 05:00
    Cluso99 wrote: »
    Bob,
    I am not sure how you aredebugging, but a simple way if you have a small composite monitor is to ues a pin and serial resistor (any value 200-1K works for a 1pin composite. see my 1pin debug in obex. I have a cheap ~$25 car reversing monitor that performs nicely.

    Using two 4port objects, or more, should be quite simple. If you need heldjust ask. I've done it before but just cannot what i did atm.

    I'm just using my computer monitor to scroll through text and variable values as the motor routines work. I'm not sure what you mean, are you using a seperate VGA monitor for output or something else?

    I was looking through the examples using the 4 port object, it looks pretty straight forward. Due to some severe storms and power outages I didn't get to do any testing last night, hopefully tonight will be better.
  • MikeChristleMikeChristle Posts: 31
    edited 2014-07-01 12:28
    Hey DiverBob

    Your project sound very cool. I am working on a similar project and have written an object that might be of interest. I just uploaded it to OBEX. I called it PropBus. For some reason searching for PropBus does not find it, but when I sort by date it is at the top of the list.

    It is loosely patterned after MIL-STD-1553. It supports up to 255 buffers/remotes and uses one wire for the interface.

    I hope this helps.

    Mike
    http://obex.parallax.com/object/749
  • DiverBobDiverBob Posts: 1,110
    edited 2014-07-01 17:34
    Hey DiverBob

    Your project sound very cool. I am working on a similar project and have written an object that might be of interest. I just uploaded it to OBEX. I called it PropBus. For some reason searching for PropBus does not find it, but when I sort by date it is at the top of the list.

    It is loosely patterned after MIL-STD-1553. It supports up to 255 buffers/remotes and uses one wire for the interface.

    I hope this helps.

    Mike
    http://obex.parallax.com/object/749

    Interesting concept! I see that it uses one wire for bidirectional but how does you keep the RT computers from interfering with the BC if the RT wants to make a transmission back to the BC? Also, can one RT communicate directly with another RT?
  • MikeChristleMikeChristle Posts: 31
    edited 2014-07-01 18:33
    Good evening

    The reason there is only one BC is that the BC controls the timing of when data is transferred on the bus. The RTs must wait for a command from the BC before transmitting data. Because all devices are on the same wire, when one device, BC or RT, sends data any or all devices can receive that data. All of this protocol is handled by the objects. As a user all you see is a buffer of data that gets updates periodically.

    Mike
  • TappermanTapperman Posts: 319
    edited 2014-07-03 13:38
    Hey DiverBob

    It is loosely patterned after MIL-STD-1553. It supports up to 255 buffers/remotes and uses one wire for the interface.

    Wow ... nice work!

    ... Tim

    PS - you should post your own thread on this object ... I have ideas and questions, and would rather not hi-jack this thread.
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-07-03 16:47
    My 1-pin uses a single pin to generate monochrome composite video. Iirc I actually use the VGA shifter to do this. The char gen bitmap is in the cog so it's a small bitmap. Probably this would do your debugging monitor nicely
  • TappermanTapperman Posts: 319
    edited 2014-07-03 17:49
    Cluso99 wrote: »
    My 1-pin uses ...

    BTW ... Your link in the OBEX comments to your 'thread' on this object is broken --- generates error 404

    I'm going to try your object and see what the output looks like ... sounds excellent.

    ... Tim
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-07-04 06:56
    Probably links to the old forum. I am overseas and on iPhone. Perhaps someone can chime in as to the old forum website name.
    Try www.parallaxinc.com/.... (Guest)
    Or try my tools index in my signature.
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-07-04 07:02
    I think Parallax took the old forums off-line :(
  • MikeChristleMikeChristle Posts: 31
    edited 2014-07-04 07:16
    Tapperman wrote: »
    Wow ... nice work!

    ... Tim

    PS - you should post your own thread on this object ... I have ideas and questions, and would rather not hi-jack this thread.

    Done. I just started a thread titled PropBus.

    Mike
  • PublisonPublison Posts: 12,366
    edited 2014-07-04 07:19
    Tapperman wrote: »
    BTW ... Your link in the OBEX comments to your 'thread' on this object is broken --- generates error 404

    I'm going to try your object and see what the output looks like ... sounds excellent.

    ... Tim

    I think this is the one:

    http://forums.parallax.com/showthread.php/120422-Debug-to-TV-using-1-PinTV-option-1-PinKBD-(minimal-footprint-screen-buf-overl
  • lardomlardom Posts: 1,659
    edited 2014-07-04 10:19
    Had to subscribe to this thread. I know cluso99 has mastered multi-prop communication. I want to learn how it's done.
  • DiverBobDiverBob Posts: 1,110
    edited 2014-07-06 15:11
    I put the 4 port serial object in my code and had a go at it. It didn't take too long to successfully get the communications up and running. I ran into anissue where I can manually enter a string ($,1,1,90) into the slave prop and have my robot respond correctly. I'm using the transmitter to send an ADC value of 0-4096 via XBee to the master computer. The master computer converts this ADC value to a value between 37 and 138 degrees and then formats an output ($,1,1,xxx) to send to the slave prop. I have tested and was getting the correctly formatted string from the master computer but the slave computer doesn't respond to the signal.
    Here is the code for the master computer:
    CON
    
      'System Clock
      _xinfreq = 5_000_000
      _clkmode = xtal1 + pll16x
    
      'XBee setup.
      XBEE_DOUT_PIN = 1 'Xbee Dout pin.
      XBEE_DIN_PIN  = 0 'Xbee Din pin.
      XBEE_MODE     = 00 'Xbee mode.
      XBEE_BAUD     = 57600 'Xbee Baud Rate.
    
      'Xbee Data in 32 Channels
      XBee_Data_Size = 32 
    OBJ
    
      XB     : "XBee_Object_2"          'XBee Object
      uarts : "pcFullDuplexSerial4FC" '1 COG for 4 serial ports
    
    Var
    
      Long Stack[300]                    'Establish working space, this can be signifantly smaller
      Word XBee_Data[XBee_Data_Size]
      Word Sample_Buf[XBee_Data_Size]
      Word AD0, AD1,AD2,AD3,AD4,AD5,AD6,AD7,AD8
      Word AD9,AD10,AD11,AD12,AD13,AD14,AD15,AD16
      Word AD17,AD18,AD19,AD20,AD21,AD22,AD23,AD24
      Word AD25,AD26,AD27,AD28,AD29,AD30,AD31
      
    PUB StartProgram            
     
      cognew(XBee,@Stack)
      uarts.Init
      uarts.AddPort(0,1,0,UARTS#PINNOTUSED,UARTS#PINNOTUSED,UARTS#DEFAULTTHRESHOLD, {
    } UARTS#NOMODE,UARTS#BAUD115200)
      uarts.Start                                           'Start the ports
    '  uarts.str(0,string("serial test3",13))
     
      Main  
     
    Pub Main | position, serialoutput  
    
    Dira[7]~~
    Dira[6]~~
    Dira[5]~~
    Dira[4]~~
    Dira[3]~~
    
    'Ouput Test
      
    Repeat
    
      position := OutputValue(XBee_Data[4])
      
      uarts.str(0,string("$,1,1,"))
      uarts.dec(0,position)
      uarts.tx(0,13)
                                       
      WaitCnt(10_000_000 + cnt)
      
    Pub OutputValue(adc)
    ' convert the ADC value to the serial sequence of '$,1,1,xxx) where xxx is the angle
    ' output angle ranges from 37 to 138 degrees. ADC value = 41 for each degree
      result := 138 - (adc / 41)
    
    Pub XBee|DataIn, I
    
      XB.start(XBEE_DOUT_PIN, XBEE_DIN_PIN, XBEE_MODE, XBEE_BAUD) 'start comms to XBee            
    
      repeat  
        XB.RxFlush                       'Clear data in buffer
        
        DataIn := XB.RxTime(1)          'Wait for incoming byte
        If DataIn == -1                  'If no data after 1.5 seconds   
    '
        case DataIn                      'Test acccepted data
          
          "T":                        
            repeat i from 0 to 31
              XBee_Data[0+i] := XB.RXDEC 'XBee Data Stored in a string
        
    
    PRI Delay(mS)
    
      Waitcnt(clkfreq/1000 * mS + cnt)
    
    
    The output from this code displays correctly on the serial terminal when I was using P30 & P31 via USB. The only change was to change the TX and RX pins to P0, P1.

    Here is the code for the slave computer:
    con
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 6_250_000
    
      CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq
      MS_001   = CLK_FREQ / 1_000
      
    con
      leg           = 1                                                                    'default values
    
    obj
      io            : "pcFullDuplexSerial4FC" '1 COG for 4 serial ports
      re            : "regex"
    
    var
      byte buffer[32], command, parameter
      long i, j
      long CoxaStack[250], TibiaStack[250], FemurStack[250], adcstack[50]
      word CoxaAngle, CoxaADC, CoxaDone, CoxaDisable, CAdcInt
      word TibiaAngle, TibiaADC, TibiaDone, TibiaDisable, TAdcInt
      word FemurAngle, FemurADC, FemurDone, FemurDisable, FAdcInt
      long array[11]
    
    pub Start | n
      io.Init
      io.AddPort(0,31,30,io#PINNOTUSED,io#PINNOTUSED,io#DEFAULTTHRESHOLD, {
    } io#NOMODE,io#BAUD115200)
      io.AddPort(1,0,1,io#PINNOTUSED,io#PINNOTUSED,io#DEFAULTTHRESHOLD, {
    } io#NOMODE,io#BAUD115200)
      io.Start                                           'Start the ports
      io.str(0,string("serial test 1",13))
    
      EnterCommand
    
    pub EnterCommand | teststr, pattern, resaddr, rslt, n, legnumber  
    'test inputing data from io and echoing it back to the io
    ' input string format: "$,1,2,345"
      io.tx(0,16)
      repeat
        pauseMSec(1000)
        bytefill(@buffer,0,32)
    '    io.Str(0,String(13, "Enter command: "))         'routine works for manual input from the serial terminal, commented out for master to input value
        getstr(1,teststr := @buffer{0})   'I'm thinking that this is where the problem is located.
        pattern := string("\$\s*,($1[\d])\s*,($2[\d])\s*,($3[\d]+)\s*")
         
        io.str(0,string(13,"String: "))
        io.str(0,teststr)
         
        rslt := -cnt
        resaddr := re.match(teststr, pattern, re#NOALT)
        rslt += cnt
         
        command := 0
        parameter := 0
        if (resaddr < 0)
          io.tx(0,13)
          io.str(0,string("Error #",13))
          io.dec(0,-resaddr)
        elseif (resaddr == 0)
          io.tx(0,13)
          io.str(0,string("No match.",13))
        else
          repeat i from 0 to 3
            if (rslt := long[resaddr][i])
              case i
                1: legnumber          := Str2Dec(re.field(i))
                2: command            := Str2Dec(re.field(i))
                3: parameter          := Str2Dec(re.field(i))
        io.str(0,string(13,"Leg: "))
        io.dec(0,leg)
        io.str(0,string(13,"Command: "))
        io.dec(0,command)
        io.str(0,string(13,"Parameter: "))
        io.dec(0,parameter)
        io.tx(0,13)
        DecodeInput
    
    pub DecodeInput
    'decode value in leg, motor, parameter to specific leg movement
      case command
        1: FemurAngle := parameter
           io.str(0,string(13,"FemurAngle: "))
           io.dec(0,FemurAngle)
           FemurDone := 0
        2: TibiaAngle := parameter
           io.str(0,string(13,"TibiaAngle: "))
           io.dec(0,TibiaAngle)
           TibiaDone := 0
        3: CoxaAngle := parameter    
           io.str(0,string(13,"CoxaAngle: "))
           io.dec(0,CoxaAngle)
           CoxaDone := 0
    
    PUB getstr(port,stringptr) | index
        '' Gets zero terminated string and stores it, starting at the stringptr memory address
        index~
        repeat until ((byte[stringptr][index++] := io.rx(port)) == 13)
        byte[--index]~
    
    

    Hopefully better eyes than mine can see what I'm doing wrong here.

    Bob
  • DiverBobDiverBob Posts: 1,110
    edited 2014-07-08 18:54
    Having a couple of days off to clear the mind and I found the problem right away, I originally was using the P0 and P1 pins on the master to transmit and recieve but moved them to P10 and P11 without changing the code. Once I fixed the code I immediately started to get an output on the terminal.

    The input signal is hard coded to be '$,1,1,' followed by the angle valve from the master to slave. However the slave is showing that sometimes the $ is missing or additional characters starting on the left side of the string are cut off. Eventually the entire string shows up and everything works right. I think ithe problem is in the GetStr function in the Slave computer code, but not sure why I get different outputs where different numbers of characters get cut off starting from the left side of the string. And why then it will suddenly just start working right? The GetStr function is copied from the Full DuplexSerialPlus object sine the 4 port serial object doesn't seem to have an equivalent function.
  • DiverBobDiverBob Posts: 1,110
    edited 2014-07-11 04:02
    I managed to fix the problem and am now getting reliable transmissions from master to slave computers. Next is establishing bi-directional communications!
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-07-11 15:51
    WTG Bob......
Sign In or Register to comment.