Shop OBEX P1 Docs P2 Docs Learn Events
2 cognew instances with par — Parallax Forums

2 cognew instances with par

corticallySpinycorticallySpiny Posts: 2
edited 2011-09-09 15:05 in Propeller 1
Im trying to modify the following object:
http://obex.parallax.com/objects/599/

It uses assembly code to essentially do PPM to drive an ESC connected to a brushless motor. The program is for one pin and i want to extend it for 2 pins i.e. running two motors.

I tried 2 approaches:
1) add parameters so i can do 2 cognew commands and start two instances of the assembly section but the trouble i have is how can i pass two parameters to cognew?

2) the dumber but simpler way to do it is to copy the same assembly code and give it a different name so i can have SingleServo1 and SingleServo2 but now when the code gets to the line

rdlong HighTime, par

i get the error "Error : Symbol already allocated here Loop"

i.e. i cant use par in two different data blocks containing assembly.

any suggestions?

Comments

  • ericballericball Posts: 774
    edited 2011-09-08 03:57
    The first thing to do is to make the PASM driver load the pin number from HUB RAM rather than hard coding it.
                  org                         'Assembles the next command to the first cell (cell 0) in the new cog's RAM
    SingleServo   mov       HighTime,par
                  add       HighTime, #4
                  rdlong    HighTime,HighTime
                  shl       ServoPin,HighTime       
                  mov       dira,ServoPin     'Set the direction of the "ServoPin" to be an output (and all others to be inputs)                                 
                                                                                                                          
                                                                                                                        
    'Constants and Variables:                                                                                           
    ServoPin      long      1                 '<------- This sets the pin that outputs the servo signal (which is sent to the white wire
    
    Then have the following VAR section:
    VAR                                                                                                                      
      long  position1                           'The assembly program will read this variable from the main Hub RAM to determine
                                               ' the servo signal's high pulse duration                                  
      long  pin1
      long  position2                           'The assembly program will read this variable from the main Hub RAM to determine
                                               ' the servo signal's high pulse duration                                  
    
      long  pin2
    
    Then initialize the two pin variables and invoke cognew twice.
      position1 := 80_000                       '1mS (motor off)
      pin1 := 14
      cognew(@SingleServo,@position1)           'Start a new cog and run the assembly code starting at the "SingleServo" cell on         
                                               ' it passing the address of the "position" variable to that cog's "par" register            
    
      position2 := 80_000                       '1mS (motor off)
      pin2 := 15
      cognew(@SingleServo,@position2)           'Start a new cog and run the assembly code starting at the "SingleServo" cell on         
                                               ' it passing the address of the "position" variable to that cog's "par" register            
    
  • JonnyMacJonnyMac Posts: 9,235
    edited 2011-09-08 08:26
    There is another approach: use one of the available multi-servo/esc drivers. In my September column (Nuts & Volts) I share my thoughts on servo control. Taking advantage of the Propellers counters I created a servo driver that can handle up to 8 servos, with sub-microsecond position accuracy (thanks to the counters), and it even includes advanced features like speed control per channel and the ability to have all channels land on a desired target at the same time. And all of this is done in Spin; no PASM required.

    Now... I can't take credit for the features, I simply "liberated" them a very popular serial servo controller and implemented them -- pretty easily -- in the Propeller (again, thanks to its unique architecture). The attached demo uses my latest servo object to drive two channels and provides a nice menu that lets you bump either up or down, and shows you the current output for both.

    [ Edit ] For the record, my servo driver creates pulses in the same manner as the assembly code you're using now. The difference is that it's not locked to a specific pin and can in fact work with up to eight outputs. Since the counter does the hard work of precise pulse generation, there is a lot time Spin to take care of loop overhead and making position/speed adjustments while the current channel pulse is active.
  • corticallySpinycorticallySpiny Posts: 2
    edited 2011-09-09 15:05
    Thanks both of you for your replies. Jon's solution works really well so thanks for that im going to be using that code..
Sign In or Register to comment.