Shop OBEX P1 Docs P2 Docs Learn Events
multiple instances of object in an object — Parallax Forums

multiple instances of object in an object

OwenOwen Posts: 100
edited 2007-03-12 02:09 in Propeller 1
HI
is there any way to use two instances of Full Duplex Serial called from seperate objects without them conflicting? I have FDS runing in my top level object to comunicate with a host pc and then in another object I want to call FDS to comunicate with a controller peripheral. This will want to use the smae variable space in both instances of FDS right? Is there anyway to us an array of FDS objects and call one of them from another object other than the top level where the array of FDS would be created? Maybe I'm missing an easy solution here.

Thanks,
Owen

Comments

  • rokickirokicki Posts: 1,000
    edited 2007-03-09 18:36
    If you don't want them to share the same variable space and pin space, either declare them in separate
    subobjects, or declare two instances (either using two declarations or an array). Either way should work.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-09 18:40
    If you have two instances of FullDuplexSerial either in the same object or declared in different objects or if you have an array of FullDuplexSerial objects, they will not conflict as long as they use different I/O pins. In addition, there will be only one copy of the code although there will be multiple copies of their data (one for each instance). Each instance will run in its own cog. You don't need locks unless one particular instance is potentially called by multiple cogs.

    It's difficult to declare objects at one level of the object structure and have them used at another level. If you really have to do it, there's a discussion and examples of the technique posted in this forum. It requires that the setup routine modify some of the byte codes of the compiled program.
  • OwenOwen Posts: 100
    edited 2007-03-09 21:00
    Just so i'm clear on this, if I have full duplex serial running in the toplevel object and running in a seperate object they will use the same copy of code but have seperate variable like creating an array of full duplex serial objects?
    thanks for the help

    Owen
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-03-09 21:12
    Owen said...
    Just so i'm clear on this, if I have full duplex serial running in the toplevel object and running in a seperate object they will use the same copy of code but have seperate variable like creating an array of full duplex serial objects?
    thanks for the help

    Owen
    Correct

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-09 21:12
    Owen,
    That's correct.
  • Stan671Stan671 Posts: 103
    edited 2007-03-10 00:25
    Interesting ... I am trying to get my mind around this.

    In my current project - a three wheeled holonomic robot - I need to control three motors simultanously using a PID speed control algorithm.· I invision a wheel control method that constantly reads a specific memory location that contrains the desired speed and makes sure the motor stays at that speed.· I would then load three "copies" of this method into three cogs to just run all by themselves without any need for the main routine to worry about them.· The main routine just stores the desired speeds into the memory locations and the wheels magically respond.

    So, can someone give me skeleton code or draw me a diagram to show the relationships between the methods so that I have one copy of the wheel control method running with three sets of variables.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Stan Dobrowski
  • T ChapT Chap Posts: 4,223
    edited 2007-03-10 01:00
    Stan, here are some snippets of an idea that might work. Each method has it's local variables that it works with, but the local variables are initialized and updated via the radr(record address) which is the key to one method spread over multi cogs.

    
    VAR
       long X, Xcurrent, EnaX
       long Y, Ycurrent, EnaY
       long Z, Zcurrent, EnaZ
    
    PUB Start
       cognew(moveX, @stack0)
       cognew(moveY, @stack1)
       cognew(moveZ, @stack2)
    
    PUB moveX
       motor(2, @X, 1, 0, 18)
    
    PUB moveY
       motor(0, @Y, 1, 0,  10)
    
    PUB moveZ
       motor(4, @Z, 1, 0,  22)
    
    PUB Motor(pinstart, radr, forward, reverse, enab) | mstep, mdir, pos, rvrs, accel, decel, arate, run, ,Ena
       Mstep := pinstart
       Mdir := pinstart + 1
       for := foward
       revs := reverse
       mEna := Ena
       repeat
          outa[noparse][[/noparse]mEna] := 1
          frqa := 1
          if LONG[noparse][[/noparse]radr] > LONG[noparse][[/noparse]radr + 4]
    
    
     
    
    
    

    Post Edited (originator) : 3/10/2007 1:07:14 AM GMT
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-03-10 01:01
    You would declare it as an array in the objects:

    OBJ
    mctrl[noparse][[/noparse]3] : motor_control

    Then use the indice to access methods:

    mctrl[noparse][[/noparse]0].start(x,y,z)
    mctrl[noparse][[/noparse]1].start(a,b,c)
    mctrl[noparse][[/noparse]2].start(m,n,o)

    One thing to note about multiple instances, anything placed in the DAT section is common to all instances. This·can be handy if you want them to have a means of doing communication but anything that is volatile and instance specific should be placed in the VAR section.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.

    Post Edited (Paul Baker (Parallax)) : 3/10/2007 7:58:17 AM GMT
  • T ChapT Chap Posts: 4,223
    edited 2007-03-10 07:03
    *There is an intentional " " before the indice for posting purposes only

    Main Program:
    VAR
    
    OBJ  
        mtr[noparse][[/noparse] 3]   :  "mtrTestObjectLower"
    
    PUB Start
      cognew(mtr1, @stack0)
      cognew(mtr1, @stack1)
      cognew(mtr1, @stack2)
    
    PUB mtr1
       mtr[noparse][[/noparse] 0].start(13)
    
    PUB mtr2
       mtr[noparse][[/noparse] 1].start(14)
    
    PUB mtr3
       mtr[noparse][[/noparse] 2].start(15)
    
    


    Motor object:
    
    VAR
        LONG  X
    
    PUB Start(pin)
        x := pin
        dir[noparse][[/noparse]x] := 1
        repeat
            outa[noparse][[/noparse]x] := 1
            waitcnt(cnt + 80_000_000)
            outa[noparse][[/noparse]x] := 0
            waitcnt(cnt + 80_000_000)
    
    
    



    This is a very cool discovery! Thanks Paul!

    Post Edited (originator) : 3/10/2007 8:51:36 AM GMT
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-03-10 08:00
    Unfortunately the Quick reply interprets [noparse][[/noparse]#] as font size #, please note I have changed the line in the previous post to mctrl[noparse][[/noparse]3] : motor_control

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.

    Post Edited (Paul Baker (Parallax)) : 3/10/2007 8:10:48 AM GMT

  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-03-10 08:10
    Correct, to get concurrent action you need you use a cognew/coginit [noparse]:)[/noparse]

    Also you need to change the following line:

    ····mtr[noparse][[/noparse]3]···:··"mtrTestObjectLower"

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • Stan671Stan671 Posts: 103
    edited 2007-03-10 20:44
    Paul & Originator: Thank you·for the code examples.· I will study them and try them out in order to understand them.· Great information - Thanks.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Stan Dobrowski
  • Paul RowntreePaul Rowntree Posts: 49
    edited 2007-03-12 02:09
    Greetings All;
    I notice that the above coding follows a slightly different style from that provided in the Prop manual (Chapter 3, p134-136), in which the Start routine in the Motor object would do the cognew call, using a local definition of the stack in a VAR block. This frees the main driving module from having to know too much about the innards of the cogged code, eliminates having to define separate stacks for each instance, and to my mind makes cleaner code.

    Is this just a style question, or are there any practical implications, one way or the other?
    Cheers!

    Paul Rowntree
Sign In or Register to comment.