Shop OBEX P1 Docs P2 Docs Learn Events
Problems with the usage of more cogs with coginit — Parallax Forums

Problems with the usage of more cogs with coginit

nomadnomad Posts: 276
edited 2007-07-16 08:32 in Propeller 1
REF: Problems with the usage of more cogs with coginit

hi,
as attachment:
1 - leg1ServoSequencer11.spin
2 - leg1ServoSequencer110.spin
3 - leg1ServoSequencer111.spin

the 1. programm is the original-spin-program (historic-reasons)
(control of 6 servos with 6-pushButtons.)
timing: periode1 := ((clkfreq / 100_000) * 500) ' 5ms LEG 1
Running: all OK.

the 2. program: control of a Servos with methode: ShoulderServo1(3) ' pin 0 , pin 3
timing corect: 20ms = periode1 := ((clkfreq / 100_000) * 2000) ' 20ms LEG 1
Run: OK

the leg1ServoSequencer111.spin is my trial to every of the 6 servos is a cog
(cog2 to cog 7) with the help von COGINIT (as per PE-LAB -> methods & cogs)
to control the cogs (servos) i make this with the pushButtons
if ina[noparse][[/noparse]n] == 1
COGINIT(cog2_Leg1Servo1,ShoulderServo1(0), @cogstack[noparse][[/noparse]0])
the direction of the servos is controlled through pushButtons 14,15
the cog 0 should be the master cog not implemented, cog 1 is for the
communications not implemented

but now the problem:
the program don't run, nothing....
what's going wrong??
- is my usage of the cogStack correct???
- is my usage of the COGINIT correct ???
if ina[noparse][[/noparse]8] == 1
COGINIT(cog2_Leg1Servo1,ShoulderServo1(0), @cogstack[noparse][[/noparse]0]) ' pin 0

this is my first trial to usage more cogs, i dont no which mistakes i make.???
please help me (all hints and tip are helpful).
and excuse my bad english

regards
nomad

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-14 15:59
    I see several problems:
    1) In the Init routine, you initialize the direction and output status of several I/O pins, then use these I/O pins in other cogs.
    Each cog has its own OUTA and DIRA registers and they are effectively OR'd together. Your Init cog sets its own registers
    for output mode, but the servo control cogs do not ... They're inputs for those cogs. You need to setup the OUTA/DIRA
    registers as part of the initialization of the routines started by each COGINIT.

    2) In the repeat loop in the main program ... where the COGINITs are done, you don't check to make sure that the cog is idle
    before doing a COGINIT. As long as pin 8 is high, you will relaunch ShoulderServo1(0) in cog 2. That's not what I think you want.
    If you're looking at a pushbutton press to start up a servo, at least look for the leading edge of the signal ... save the previous state
    of the pin and look for previous state == 0 and current state == 1. That way, you will require a button release, then another press
    to reinitiate the cog.
  • nomadnomad Posts: 276
    edited 2007-07-15 09:18
    hi mike,
    thanks for your help, today (sunday) i make trial with your stuff, and then
    i make a call
    regards
    nomad
  • nomadnomad Posts: 276
    edited 2007-07-15 12:42
    hi mike,
    on the afternoon i make some tests:
    the new program: leg1ServoSequencer112.spin

    your no 1)
    i hope i understand you right
    i make the whole stuff from the init-methode into the different cogMethods
    is this right direction?
    must i use the boolean vars???
    if i use this nothing goes.

    my questions and my problems with your No. 2)

    my pushButtons are microSchalter:
    if press then the button is ON
    else OFF (its a spike) look at spin-program version 11

    in this program i can move different servos in the same time.

    and then comes the problems:
    i am not a electronicMan, only a softwareGuy (systemAnalytics)
    i understand you not fully,
    what you mean with:

    << look for the leading edge of the signal ... save the previous state
    of the pin and look for previous state == 0 and current state == 1.
    That way, you will require a button release, then another press
    to reinitiate the cog.
    >>
    can i do this with boolean variables??? or what.
    think on this:
    i can press every buttons on the same time, and different cogs (servos) moving in
    different directions...

    for a future version the cogs will be controlled through variables and the
    masterCog (0)
    and the different cogs talks with the other cogs
    it should possible that z.B.
    cog2 (Servo11) swing forward and in the same time a another cog -> cog7 goes
    down and cog3 goes up.

    in the moment i dont use the 2erpushButton without the boolean vars
    instead every servoCog
    makes: repeat 10
    pulsetime1 += (clkfreq / 100_000)
    Result: running but not correct.

    please excuse my confuse writing, but i have some problems
    if i must explain complex things in english.
    please help me

    as attachment: leg1ServoSequencer112.spin



    regards
    nomad
  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-15 15:56
    I think your program is unnecessarily complicated. Correct me if I'm wrong, but I believe it does:

    1) There are 8 pushbuttons, divided up into a group of 6 and a group of 2

    2) When you push one of the 6 pushbuttons, you select one of 6 servos to interact with. A control pulse is
    sent to that servo every 20ms with a width initially of 1.5ms. Selecting a different servo stops the previous one.

    3) Once one of the 6 pushbuttons has been pushed, the 2 pushbuttons either increase or decrease the width
    of a pulse sent to the selected servo by 0.1ms.

    I know you want to use this program as a basis for a more complex program, but I think the overall concept is faulty.
    You should use the Servo32.spin object to control the servos and issue the timed pulses every 20ms. That object
    runs in one cog and interacts with the rest of the program through some common Spin routines and a shared table of
    pulse widths. For your current testing, you should use a single cog, particularly since you're only working with one servo
    at a time.

    The Attachment Manager doesn't seem to work for me (it gets an error), so here's my example:
    CON 
      _CLKMODE = XTAL1 + PLL16X     'Set to ext crystal, 16x PLL, 80MHz Clock 
      _XINFREQ = 5_000_000          'Frequency on XIN pin is 5 MHz 
      
    OBJ
      Servo : "Servo32"
    
    VAR
      LONG currentWidth[noparse][[/noparse]6]
      LONG oldButtons, newButtons, currentServo
      LONG oldDirection, newDirection
        
    PUB MainProgram | i
    
      repeat i from 0 to 5             ' Initialize all the servos
        currentWidth[noparse][[/noparse] i ] := 1500        '  to mid-position (1.5ms)
        Servo.Set(i,currentWidth[noparse][[/noparse] i ])
      Servo.Start
    
      dira[noparse][[/noparse]8]~    ' Pin08 set input (taster s1) control cogServo11 Swing 
      dira[noparse][[/noparse]9]~    ' Pin09 set input (taster s2) control cogServo21 
      dira[noparse][[/noparse]10]~   ' Pin10 set input (taster s3) control cogServo12 Up/Down  
      dira[noparse][[/noparse]11]~   ' Pin11 set input (taster s4) control cogServo22
      dira[noparse][[/noparse]12]~   ' Pin12 set input (taster s5) control cogServo13 Up/Down 
      dira[noparse][[/noparse]13]~   ' Pin13 set input (taster s6) control cogServo23
    
      dira[noparse][[/noparse]14]~   ' plus 
      dira[noparse][[/noparse]15]~   ' neg
      
      oldButtons := %000000
      oldDirection := %00
      currentServo := -1
      
      repeat
      
    ' Get state of all selection buttons.  Compute which buttons were
    ' previously in a zero state and now in a one state.  Use the >| operator
    ' to find the most significant button bit if more than one was pressed.
    ' If no buttons were pressed, ignore.  If one was pressed, save the number
    ' of the servo associated with it (do a translation - see the lookdownz).
    
        newButtons := ina[noparse][[/noparse]13..8]
        if (i := lookdownz(>|(!oldButtons & newButtons):-1,0,3,1,4,2,5)) => 0
          currentServo := i
        oldButtons := newButtons
        
    ' Now do the same for the direction buttons.  Note that the pulse width
    ' can go beyond the range of 1.0ms-2.0ms.  The Servo32 driver limits the
    ' actual range of the pulse width to 1.0ms-2.0ms.  If no servo has been
    ' selected yet, ignore the direction button push.
    
        newDirection := ina[noparse][[/noparse]15..14]
        case >|(!oldDirection & newDirection)
          1: if currentServo => 0       ' Plus - pin 14
               currentWidth[noparse][[/noparse]currentServo] += 100  ' Increment by 0.1ms
               Servo.Set(currentServo,currentWidth[noparse][[/noparse]currentServo])
          2: if currentServo => 0       ' Minus - pin 15
               currentWidth[noparse][[/noparse]currentServo] -= 100  ' Decrement by 0.1ms
               Servo.Set(currentServo,currentWidth[noparse][[/noparse]currentServo])
        oldDirection := newDirection
        waitcnt(clkfreq / 20_000 + cnt)  ' Wait 50ms for debouncing
    
    
  • nomadnomad Posts: 276
    edited 2007-07-15 16:41
    hi mike,
    thanks for your help...
    on monday i testing your program.

    look i have build bot with 4-servoLegs with 3servos in a leg.
    to control the whole stuff
    1- i have 3 propChips (1 is the master, 2 control leg1 + leg2, 3 control Leg3 + 4)
    2- i build in software a WalkNets
    (they are neuralNets which can control the gaits and the states of every leg, angles etc.).
    3- on every chips are 2 walknets
    (please google -> WalkNet from Prof.Dr.Cruse et al)

    i think, that for this purpose i should control the servo (into a cog) in parallel and in realTime.
    its possible that a servoCog (Leg1-ShoulderServo1) on Leg1 talks
    with a servoCog (Leg4 - ShoulderServo1) and visiversa.
    you know my problem now.

    the attachted program are verry simple only to testing
    the possiblity <<every servo is a cog>>

    now you know my problem blush.gif

    if you have for this problem good ideas or tips,
    i am verrry grateful.
    thanks for your help

    regard
    nomad

    Post Edited (nomad) : 7/15/2007 4:47:39 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-15 17:08
    A couple of thoughts:

    1) The servos require a control pulse every 20ms. You could certainly use this as the "heartbeat" or cycle time of your control loop for each servo.
    The Propeller is fast enough so it can do a lot of processing in each cycle. On the other hand, this seems to be an artificial constraint of the system.

    2) Do you really want to divide up the control function into individual servos? Would it be more useful to have a separate system for each leg?
  • nomadnomad Posts: 276
    edited 2007-07-16 08:32
    hi mike,
    thanks for the tips.
    today (monday), i testing some various programs.
    and call back
    regards
    nomad
Sign In or Register to comment.