Shop OBEX P1 Docs P2 Docs Learn Events
Setting Pointer? — Parallax Forums

Setting Pointer?

crcordillcrcordill Posts: 29
edited 2008-06-22 23:13 in Propeller 1
Hello all.
I'm having trouble with saving stuff into global variables and passing values correctly. I'm currently using a modification of Servo32v3.spin for controlling DC motors. However, we can assume that I'm just using it. If you've never used it, it has a special PUB called Set(Pin, Width) to set the position of the encoder. However, after the object is running, the only thing that this object does is save the value to an array. What I'd like to do is to instead directly change that variable in the global memory. Here's an example:
Do this:
ServoData[noparse][[/noparse]Pin] := 1500




instead of

Servo.Set(Pin,1500)




Here is PUB Set:
PUB Set(Pin, Width)                                                             'Set Servo value
      Width := 0 #> Width <# 5000                                            'limit Width value between 1000uS and 2000uS
'        Pin :=    0 #>   Pin <# 31                                              'limit Pin value between 0 and 31
      ServoData[noparse][[/noparse]Pin] := (clkfreq / _1uS * Width)                                 'calculate # of clocks for a specific Pulse Width
      dira[noparse][[/noparse]Pin] := 1                                                            'set selected servo pin as an OUTPUT
      ServoPinDirection := dira                                                 'Read I/O state of ALL pins   




I tried to pass it a new variable @servopos[noparse]/noparse, but it didn't work. Does anyone have any suggestions? Greatly appreciated. Thanks.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-06-22 21:39
    I don't understand what you're trying to do. Servo.Set saves the new value to an array because the assembly language routine that has been started and is running in its own cog is constantly referencing that array to find out what servo pulses to send out. The Set routine also does some simple bounds checking on the values and converts them to the number of system clock cycles needed for the specified pulse width. You would need to do the same sort of thing if you wanted to set the array values directly.

    It's certainly possible to add a method to the servo object that simply returns the address of the servo array ("return @ServoData") which you'd store in some variable, say "PP". To reference the array elements, you'd need to write "word[noparse][[/noparse] PP ][noparse][[/noparse] Pin ]" or "long[noparse][[/noparse] PP ] [noparse][[/noparse] Pin ]" depending on how the array is declared.
  • crcordillcrcordill Posts: 29
    edited 2008-06-22 22:41
    Mike
    What I'd like to have happen is that I'd be able to reset my servo values from several different cogs. With the current method, it wasn't working. What I had to do was setup another cog that ran through and set all of the servo values.
      PWM.Set(MRp,ph)                                      'Set PWM Pins
      PWM.Set(MLp,ph) 
      PWM.Set(MCp,ph)
      PWM.Start
      repeat
        PWM.Set(MRp,Pr)
        PWM.Set(MLp,Pl)
        PWM.Set(MCp,Pc)
    
    



    But I'd rather set the new servo values directly.

    I understand the bounds checking and other things that the servo.set function does and I can do that elsewhere. That last point you made I think was what I was looking for.
    Mike Green said...

    It's certainly possible to add a method to the servo object that simply returns the address of the servo array ("return @ServoData") which you'd store in some variable, say "PP". To reference the array elements, you'd need to write "word[noparse][[/noparse] PP ][noparse][[/noparse] Pin ]" or "long[noparse][[/noparse] PP ] [noparse][[/noparse] Pin ]" depending on how the array is declared.

    Though I'm not quite sure how I would implement it. Could you give me one more kick in the right direction? THanks
    Craig
  • Mike GreenMike Green Posts: 23,101
    edited 2008-06-22 22:58
    Again, declare a long variable somewhere in your main program (where Servo.Start is called) called "ServoDataPtr". In your Servo object, add the following:
    PUB getServoDataPtr
       return @ServoData
    


    In your initialization just before you call Servo.Start, put "ServoDataPtr := Servo.getServoDataPtr". After that point (and after you call Servo.Start), you can do a "long[noparse][[/noparse] ServoDataPtr ][noparse][[/noparse] Pin ] := clkfreq / Servo#_1uS * Width" where "Width" is whatever pulse width you want and "Pin" is the servo pin number.
    It doesn't matter what cog is executing this. If you have a separate object where you want to do this, you'll have to pass it the value of ServoDataPtr and that will have to be stored locally in the object. This has nothing to do with cogs. It has to do with objects and their scope rules.
  • crcordillcrcordill Posts: 29
    edited 2008-06-22 23:08
    Mike
    Great, that clears up alot. Thank you so much. My next question is, why couldn't I make ServoDataPtr a global variable so that I wouldn't have to pass it? I'm sorry if this is a stupid question, but I think it would clear up a bunch. Again thanks.
    Craig
  • Mike GreenMike Green Posts: 23,101
    edited 2008-06-22 23:13
    Within a single object, all variables declared with VAR are global. Between objects, there is no such thing as a global variable. They don't exist.
Sign In or Register to comment.