Shop OBEX P1 Docs P2 Docs Learn Events
Newbie_Why didn't this work — Parallax Forums

Newbie_Why didn't this work

BrianmcmBrianmcm Posts: 33
edited 2009-01-18 11:09 in Propeller 1
Need some guidance. I came across a servo control code called "Single_Servo_Spin", by Gavin Garner·that I used to experiment with some servos. Thanks to Gavin for the code, it has been very helpful. I've just recently began to learn "Spin"·programming using the Propeller Education Kit.
I·made a modification to the code to see if·I could get two servos to operate simultaneously. I realize there are "objects"·already available in the·Exchange Library that allow the control·multiple·servos, but this is more of learning exercise in COG address, etc..
Below is my "modified" code. As you can see the intent is for·servo-1 on Pin 13 and·servo-2 on Pin 15 to go through the different positions at the same time. Presently as it is written when I run it, it skips the first "cognew" and operates the servo on Pin 15. If I swap pin assigments and run it again, servo on Pin-13 operates.
Is the problem a simple code·error or am I way·off base trying to do it this way.

CON
· _xinfreq=5_000_000···········
· _clkmode=xtal1+pll16x·······
VAR
· long position···············
······························
· long Stack[noparse][[/noparse]30]
······························
·
PUB Demo
··································
· cognew(Motor (13), @Stack[noparse][[/noparse]0])
· cognew(Motor (15), @Stack[noparse][[/noparse]15])·········
········································
· repeat················································································································
··· 'position:=100·············································································
··· 'waitcnt(clkfreq+cnt)·················································································
··· position:=138···········································································
··· waitcnt(clkfreq+cnt)···················································································
··· position:=50············································································
··· waitcnt(clkfreq+cnt)····················
··· position:=225···········································································
··· waitcnt(clkfreq+cnt)····················
························································································································
PUB Motor(Pin)
······································
· dira[noparse][[/noparse]Pin]~~···················
· repeat······························
··· outa[noparse][[/noparse]Pin]~~···························
··· waitcnt((clkfreq/100_000)*position+cnt)····
··· outa[noparse][[/noparse]Pin]~···························
··· waitcnt(clkfreq/100+cnt)

Thank you for your guidance.
Brian

·····

Comments

  • TJHJTJHJ Posts: 243
    edited 2009-01-18 01:59
    Your 1st cognew tells the routine Motor(13) (as in the example) to run in stack[noparse][[/noparse]0], the 1st array, then you run a second cog in the same stack. The addressing ignores the array index for new cog creation, using the total array, or as much as it needs (If I remember correctly)

    So the memory you set aside to run is actually being over written by the second cog new command.

    Try this.

    VAR
      long position                
                                   
      long Stack1[noparse][[/noparse]30], Stack2[noparse][[/noparse]30]
                                   
      
    PUB Demo
                                       
      cognew(Motor (13), @Stack1)
      cognew(Motor (15), @Stack2)  
    
    
    



    but be wary of using very small stacks, the minimum is about 100 longs, otherwise cogs run into each other with very weird results.

    Hope this helps,
    TJ
  • BradCBradC Posts: 2,601
    edited 2009-01-18 02:11
    My only suggestion is to try increasing the stack size you are giving the cogs. I've been through and I can't account for all the stack usage, but if its always the second cog that keeps running it is the cog that has nothing likely to trample over its stack if it overruns the stack[noparse][[/noparse] 30 ] array. I need to take a look at the spin runner code to see the amount of stack that uses when it starts a new cog really.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cardinal Fang! Fetch the comfy chair.
  • BradCBradC Posts: 2,601
    edited 2009-01-18 02:14
    TJHJ said...
    Your 1st cognew tells the routine Motor(13) (as in the example) to run in stack[noparse][[/noparse]0], the 1st array, then you run a second cog in the same stack. The addressing ignores the array index for new cog creation, using the total array, or as much as it needs (If I remember correctly)

    Not according to the generated code
    11                        cognew(Motor (13), @Stack[noparse][[/noparse]0])
    Addr : 001C:          38 0D  : Constant 1 Bytes - 0D 
    Addr : 001E:       39 01 02  : Constant 2 Bytes - 01 02 
    Addr : 0021:             35  : Constant 1 $00000000
    Addr : 0022:          DB 04  : Memory Op Long VBASE + POP Index ADDRESS Address = 0004
    Addr : 0024:             15  : Run           
    Addr : 0025:             2C  : CogInit(Id, Addr, Ptr)
    12                        cognew(Motor (15), @Stack[noparse][[/noparse]15])
    Addr : 0026:          37 23  : Constant Mask Y=35 Decrement 0000000F
    Addr : 0028:       39 01 02  : Constant 2 Bytes - 01 02 
    Addr : 002B:          37 23  : Constant Mask Y=35 Decrement 0000000F
    Addr : 002D:          DB 04  : Memory Op Long VBASE + POP Index ADDRESS Address = 0004
    Addr : 002F:             15  : Run           
    Addr : 0030:             2C  : CogInit(Id, Addr, Ptr)
    
    



    You can see it properly calculates the address for each instance. (21/22) & (2B/2D)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cardinal Fang! Fetch the comfy chair.
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-01-18 08:26
    Hello Brad,

    could you explain in detail what you coded ?

    It seems to be just a code-snippet.

    Does it only work in assembler ?

    best regards

    Stefan
  • BradCBradC Posts: 2,601
    edited 2009-01-18 11:09
    StefanL38 said...
    Hello Brad,

    could you explain in detail what you coded ?

    It seems to be just a code-snippet.

    Does it only work in assembler ?

    best regards

    Stefan

    G'day Stefan,

    It's not assembler as such, it's the original spin source line followed by a disassembly of the bytecodes the compiler generates for that source line.

    I did it only for these two source lines isolated to specifically prove that cognew will use the correct pointer given to it for stack data.

      cognew(Motor (13), @Stack[noparse][[/noparse]0])
      cognew(Motor (15), @Stack[noparse][[/noparse]15])       
    
    



    Here is the entire listing for the program Brianmcm posted.

    |===========================================================================|
    Objects : -
    Servo_001
    
    Object Address : 0010 : Object Name : Servo_001
    
    Binary Image Information :
    PBASE : 0010
    VBASE : 0074
    DBASE : 00F8
    PCURR : 001C
    DCURR : 00FC
    |===========================================================================|
    |===========================================================================|
    Object Servo_001
    Object Base is 0010
    |===========================================================================|
    Object Constants
    |===========================================================================|
    Constant _xinfreq = 004C4B40 (5000000)
    Constant _clkmode = 00000408 (1032)
    |===========================================================================|
    |===========================================================================|
    VBASE Global Variables
    |===========================================================================|
    VBASE : 0000 LONG Size 0004 Variable position
    VBASE : 0004 LONG Size 0078 Variable Stack
    |===========================================================================|
    |===========================================================================|
    Spin Block Demo with 0 Parameters and 0 Extra Stack Longs. Method 1
    PUB Demo
    
    Local Parameter DBASE:0000 - Result
    |===========================================================================|
    11                        cognew(Motor (13), @Stack[noparse][[/noparse]0])
    Addr : 001C:          38 0D  : Constant 1 Bytes - 0D 
    Addr : 001E:       39 01 02  : Constant 2 Bytes - 01 02 
    Addr : 0021:             35  : Constant 1 $00000000
    Addr : 0022:          DB 04  : Memory Op Long VBASE + POP Index ADDRESS Address = 0004
    Addr : 0024:             15  : Run           
    Addr : 0025:             2C  : CogInit(Id, Addr, Ptr)
    12                        cognew(Motor (15), @Stack[noparse][[/noparse]15])
    Addr : 0026:          37 23  : Constant Mask Y=35 Decrement 0000000F
    Addr : 0028:       39 01 02  : Constant 2 Bytes - 01 02 
    Addr : 002B:          37 23  : Constant Mask Y=35 Decrement 0000000F
    Addr : 002D:          DB 04  : Memory Op Long VBASE + POP Index ADDRESS Address = 0004
    Addr : 002F:             15  : Run           
    Addr : 0030:             2C  : CogInit(Id, Addr, Ptr)
    Addr : 0031: Label0002
    17                          position:=138
    Addr : 0031:          38 8A  : Constant 1 Bytes - 8A 
    Addr : 0033:             41  : Variable Operation Global Offset - 0 Write
    18                          waitcnt(clkfreq+cnt)
    Addr : 0034:             35  : Constant 1 $00000000
    Addr : 0035:             C0  : Memory Op Long POP Address READ 
    Addr : 0036:          3F 91  : Register op CNT Read
    Addr : 0038:             EC  : Math Op +     
    Addr : 0039:             23  : WaitCnt(count)
    19                          position:=50
    Addr : 003A:          38 32  : Constant 1 Bytes - 32 
    Addr : 003C:             41  : Variable Operation Global Offset - 0 Write
    20                          waitcnt(clkfreq+cnt)
    Addr : 003D:             35  : Constant 1 $00000000
    Addr : 003E:             C0  : Memory Op Long POP Address READ 
    Addr : 003F:          3F 91  : Register op CNT Read
    Addr : 0041:             EC  : Math Op +     
    Addr : 0042:             23  : WaitCnt(count)
    21                          position:=225
    Addr : 0043:          38 E1  : Constant 1 Bytes - E1 
    Addr : 0045:             41  : Variable Operation Global Offset - 0 Write
    22                          waitcnt(clkfreq+cnt)
    Addr : 0046:             35  : Constant 1 $00000000
    Addr : 0047:             C0  : Memory Op Long POP Address READ 
    Addr : 0048:          3F 91  : Register op CNT Read
    Addr : 004A:             EC  : Math Op +     
    Addr : 004B:             23  : WaitCnt(count)
    Addr : 004C: Label0003
    Addr : 004C: JMP Label0002
    Addr : 004C:          04 63  : Jmp 0031 -29  
    Addr : 004E: Label0004
    Addr : 004E:             32  : Return        
    |===========================================================================|
    Spin Block Motor with 1 Parameters and 0 Extra Stack Longs. Method 2
    PUB Motor(Pin)
    
    Local Parameter DBASE:0000 - Result
    Local Parameter DBASE:0004 - Pin
    |===========================================================================|
    26                        dira[noparse][[/noparse]Pin]~~
    Addr : 004F:             64  : Variable Operation Local Offset - 1 Read
    Addr : 0050:       3D D6 1C  : Register [noparse][[/noparse]Bit] op DIRA VAR~~ Post-set
    Addr : 0053: Label0002
    28                          outa[noparse][[/noparse]Pin]~~
    Addr : 0053:             64  : Variable Operation Local Offset - 1 Read
    Addr : 0054:       3D D4 1C  : Register [noparse][[/noparse]Bit] op OUTA VAR~~ Post-set
    29                          waitcnt((clkfreq/100_000)*position+cnt)
    Addr : 0057:             35  : Constant 1 $00000000
    Addr : 0058:             C0  : Memory Op Long POP Address READ 
    Addr : 0059:    3A 01 86 A0  : Constant 3 Bytes - 01 86 A0 
    Addr : 005D:             F6  : Math Op /     
    Addr : 005E:             40  : Variable Operation Global Offset - 0 Read
    Addr : 005F:             F4  : Math Op *     
    Addr : 0060:          3F 91  : Register op CNT Read
    Addr : 0062:             EC  : Math Op +     
    Addr : 0063:             23  : WaitCnt(count)
    30                          outa[noparse][[/noparse]Pin]~
    Addr : 0064:             64  : Variable Operation Local Offset - 1 Read
    Addr : 0065:       3D D4 18  : Register [noparse][[/noparse]Bit] op OUTA VAR~ Post-clear
    31                          waitcnt(clkfreq/100+cnt)
    Addr : 0068:             35  : Constant 1 $00000000
    Addr : 0069:             C0  : Memory Op Long POP Address READ 
    Addr : 006A:          38 64  : Constant 1 Bytes - 64 
    Addr : 006C:             F6  : Math Op /     
    Addr : 006D:          3F 91  : Register op CNT Read
    Addr : 006F:             EC  : Math Op +     
    Addr : 0070:             23  : WaitCnt(count)
    Addr : 0071: Label0003
    Addr : 0071: JMP Label0002
    Addr : 0071:          04 60  : Jmp 0053 -32  
    Addr : 0073: Label0004
    Addr : 0073:             32  : Return          
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cardinal Fang! Fetch the comfy chair.
Sign In or Register to comment.