Shop OBEX P1 Docs P2 Docs Learn Events
Servo deadband code — Parallax Forums

Servo deadband code

jcfergusonjcferguson Posts: 86
edited 2007-03-28 01:20 in BASIC Stamp
I am trying to streamline my dead band code (for continuous rotation servo - so it won't creep) for faster operation - I would like to find a better way of doing the following:

I need to first check to see if the pot value for the servo is in the dead range - say my servo center is 750 and deadvalue is 50. I want the servo to stay still from 700 to 800. To do this I just check for this range and then reset the servo output value to center so that there is no movement on the servo.

When the servo value gets to the edges of this dead range though - like a servo value of 802, there would be a jump from the re-setting the center range (750) to the tracking the actual value range (802) - to correct this I need set the servo closer to center by deadbandvalue units. This means that the servo actually goes from 750 to 752 when the servo value changes from 800 to 802.

this is the "elseif" part of the code below.

IF ABS (servodrivevalue - servocentervalue) <= deadbandval THEN 'check to see if servodrivevalue is in deadband range
servodrivevalue = servocentervalue 'if it is, set it to center value so it won't creep
ElSEIF servodrivevalue > servocentervalue THEN 'if servo is outside dead range then subtract deadvalue so
servodrivevalue = servodrivevalue - deadbandval 'there won't be a jump in servo drive

ElSE:servodrivevalue = servodrivevalue + deadbandval
ENDIF


My question: is there a better way of doing the second half?

basically I just want to take a variable that may be higher or lower than a constant and make it closer in value to that constant... is there a trick for this or should I just check like I do above?


Thanks! !
Carlos

Post Edited (jcferguson) : 3/17/2007 6:37:18 PM GMT

Comments

  • Skywalker49Skywalker49 Posts: 172
    edited 2007-03-25 16:05
    Carlos,

    can you explain what you mean by dead band code?
    Do you intend to create artifically a dead band of 50 in your example so that a program output to the servo
    can vary within the dead band before the servo starts moving ?

    I use parallax PM servos and they have no dead band at all.
    One is "still" at 759, the other at 760 and that's it! Even changing the value by one results in rotation of the motor.
  • jcfergusonjcferguson Posts: 86
    edited 2007-03-25 16:29
    Thats right Skywalker - I want to create an artificial deadband zone. I am controlling continuous rotation servos with joysticks - and if the temperature changes a bit then the joystick rc circuit reading changes from, say, 750 to 752 and the servo starts creeping. So I want to expand my deadband range to encompass this creepy zone. I have it working fine, I just want to streamline the code as I am checking three joysticks and sending out the information via rf to a receiver. I want this to happen as fast as possible.

    I can see on second reading that my post above is pretty opaque!

    thanks,

    Carlos
  • stamptrolstamptrol Posts: 1,731
    edited 2007-03-25 17:16
    Carlos,

    I use the SELECT - CASE construction when doing joystick work. It may not be too much shorter, but it is easy to troubleshoot and runs quickly.

    It does a good job both when directly reading the joystick or over RF.

    Here is a brief piece of code from the research boat I was involved with. This one used RF so it used PULSIN, but it works the same with RCTIME.

    Notice how the deadbands are adjusted in the CASE statements and that several (ch3 and ch4) channels of stick can be interlaced.

    Note that this isn't all the code, it carries on for a couple hundred lines in order to control two drive motors F-R and also steer by differential speed control.

    Regards,

    Tom


    mainLOOP:

    PULSIN 8,0,ch1 ' winch 1 control stick
    PULSIN 9,0,ch2 ' winch 2 control stick
    PULSIN 10,0,ch3 ' forward/reverse main motors;including trolling motor
    PULSIN 11,0,ch4 ' left/right on fans; y-connection to steering servo

    'DEBUG DEC3 ch1," ",DEC3 ch2," ",DEC3 ch3," ",DEC3 ch4," ",DEC1 IN12,HOME
    GOSUB motspd
    'PAUSE 250

    GOTO mainLOOP

    motspd: 'determine whether direction is forward or reverse
    SELECT ch3
    CASE < 300
    GOTO nolink
    CASE 700 TO 800 ' check F/R neutral position
    GOSUB allstop
    GOSUB runwin
    'GOSUB turninplace
    ' ######################## Low Speed Forward ########################
    CASE 825 TO 875 ' lowest forward speed
    IF IN12=0 THEN ' check to see if trolling servo selected
    GOSUB trolslofwd
    GOTO bypass1
    ENDIF
    SELECT ch4
    CASE 700 TO 800 ' steering centred,both motors slow fwd
    x=0
    y=0
    u=0
    v=0
    IF lmotstat = 1 THEN 'see if left mot was running in rev
    GOSUB timr3
    IF z<del3 THEN
    GOSUB bak2fwdlft
    GOTO decel2
    ELSEIF z > del3 THEN
    lmotstat=0 ' reset left mot rev status
    ENDIF
    ENDIF

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tom Sisk

    http://www.siskconsult.com
    ·
  • PARPAR Posts: 285
    edited 2007-03-25 17:44
    jcferguson said...
    Thats right Skywalker - I want to create an artificial deadband zone. I am controlling continuous rotation servos with joysticks - and if the temperature changes a bit then the joystick rc circuit reading changes from, say, 750 to 752 and the servo starts creeping. So I want to expand my deadband range to encompass this creepy zone. I have it working fine, I just want to streamline the code as I am checking three joysticks and sending out the information via rf to a receiver. I want this to happen as fast as possible.

    I can see on second reading that my post above is pretty opaque!

    thanks,

    Carlos
    I still do not understand how your "deadband" relates to the creep problem.

    The creep occurs when the "center point" value changes. You need to detect when this change occurs, and then you need to determine the new center point. The deadzone is only telling you over what range of values you do not wish to move the servo, but it will not tell you where "center" is (i.e., has move to)·at the current time.

    The trick is to figure out how to detect the creep (when does it occur, and where is the new center?).

    PAR
  • jcfergusonjcferguson Posts: 86
    edited 2007-03-25 22:04
    Stamptrol - that seems like a good solution, select-case, I'll see if it changes the speed of execution of my code any as it will be easy to implement


    PAR - right, I am just making a big blank area in the middle of the joystick range so that when temperature shift happens it will be encompassed by the dead zone... it would be better to just find the new center point when the temperature changes and then need no deadband at all - I have been thinking of how to do this - the joysticks are part of an interactive sculpture that is only used some of the time. Maybe I can identify through code when the joystick has not been touched for a long enough period and re-set the center to this value?

    something like:

    check joystick
    if joystick is active, send data to servos, reset inactivity counter
    if joystick isn't active add one to inactivity counter
    check counter - if it is high enough then reset center value
    if not high enough, go back to check joystick

    Does that seem like what you were thinking? I could probably get rid of all my deadband code so that there would be a net savings in time to execute. I was trying a while ago to find a way of setting up another rc circuit to compare and reset centers accordingly but never really got it working in a good fashion...

    Thanks,

    Carlos
  • PARPAR Posts: 285
    edited 2007-03-26 14:27
    jcferguson said...
    ...
    PAR - right, I am just making a big blank area in the middle of the joystick range so that when temperature shift happens it will be encompassed by the dead zone... it would be better to just find the new center point when the temperature changes and then need no deadband at all - I have been thinking of how to do this - the joysticks are part of an interactive sculpture that is only used some of the time. Maybe I can identify through code when the joystick has not been touched for a long enough period and re-set the center to this value?

    something like:

    check joystick
    if joystick is active, send data to servos, reset inactivity counter
    if joystick isn't active add one to inactivity counter
    check counter - if it is high enough then reset center value
    if not high enough, go back to check joystick

    Does that seem like what you were thinking? I could probably get rid of all my deadband code so that there would be a net savings in time to execute. I was trying a while ago to find a way of setting up another rc circuit to compare and reset centers accordingly but never really got it working in a good fashion...
    ...
    Sorry, but I don't understand the relationship between the joystick(s) and the servo(s).

    How are they connected (circuit)?· Are you suggesting that you re-"center" (bias) the joystick pots rather than re-centering the servos?

    You will still have to determine whether/how much·the servo's center has drifted, regardless of whether you adjust the servo or the joystick pot to stop the creep.

    When you state "...joystick is active...", what do you mean? Does the joystick move on its own (e.g., it is connected to a servo that moves (controls movement of)·the joystick), or are people moving the joystick? (This question is related to the earlier one about how your circuit components are wired to each other.)

    PAR
  • jcfergusonjcferguson Posts: 86
    edited 2007-03-26 16:20
    I have two joysticks, each is "read" using a capacitor and rctime. This value is scaled and then sent via rf to another basic stamp which uses pulsout to drive the servos. One of the servos is a continuous rotation servo - and so is very sensitive to change in the pulsout value (because it no longer has a feedback pot). If the temperatue of the rc circuit used to read the joystick goes from 40 degrees to 80 degrees F, the readings shift enough to make the continuous rotation servo start to creep. My solution was to check the rctime value for a range right around the centered position (of the joystick). If the rctime value is in this range then I just pulsout the "center" value to the servo. When the rctime drifts, my code ignores it. I do lose a bit of range right around centered - you have to move the joystick a bit before the servo starts to move and then there is a "dead" area in the middle when you reverse directions, but it isn't too noticeable

    Does that make sense? Are you saying that the value that the servo centers to is changing as well? I hadn't thought of that. I was thinking I would just check my rctime values when the joysticks aren't being touched and reset the scaling so that the center value that is pulsout-ed to the servo stays the same. Any other solution?

    Thanks,

    Carlos
  • PARPAR Posts: 285
    edited 2007-03-28 01:20
    Aha... I was focussing on the servo's drift, not on the joystick's drift, from "center" (or stop). Actually, both are possible.

    In the case of servo drift, you'd have to know where the "new" center is (i.e., where the old center drifted to), in order to correct for it (whether that is by programmatically resetting the "center" point value of the servo, or by physically resetting the servo's pot; if you go with the program reset, you'll have to know how much to reset it by.

    In the case of joystick drift (from its "home" or center position), and assuming that the servo's center hasn't drifted also, you could use your "deadband" approach, or you could figure out the new (drifted-to) center/home on the joystick and correct programmatically for that bias (i.e., change the value of "joystick-center").

    It seems to me that in either case, you need to know first whether your servo is moving when it isn't supposed to be moving so that you can bias your calculated "center" position accordingly. Once you know how your servo is behaving ("creeping", not creeping, given a particular "centering" value), you can do away with (or significantly narrow) your deadband and deal directly with a current, correct center value.

    PAR
    jcferguson said...
    I have two joysticks, each is "read" using a capacitor and rctime. This value is scaled and then sent via rf to another basic stamp which uses pulsout to drive the servos. One of the servos is a continuous rotation servo - and so is very sensitive to change in the pulsout value (because it no longer has a feedback pot). If the temperatue of the rc circuit used to read the joystick goes from 40 degrees to 80 degrees F, the readings shift enough to make the continuous rotation servo start to creep. My solution was to check the rctime value for a range right around the centered position (of the joystick). If the rctime value is in this range then I just pulsout the "center" value to the servo. When the rctime drifts, my code ignores it. I do lose a bit of range right around centered - you have to move the joystick a bit before the servo starts to move and then there is a "dead" area in the middle when you reverse directions, but it isn't too noticeable

    Does that make sense? Are you saying that the value that the servo centers to is changing as well? I hadn't thought of that. I was thinking I would just check my rctime values when the joysticks aren't being touched and reset the scaling so that the center value that is pulsout-ed to the servo stays the same. Any other solution?

    Thanks,

    Carlos
Sign In or Register to comment.