Keeping an arm raised/lowered

My Vex Round Up team is building a robot that has two approx. 15" parallel arms, with a crossbar at the front for “hands”, to lift/drop the rings.

When we lift the arm to its top position, after the motors stop the arm sinks because of the weight of the arm. After adding rubber bands to help keep the arm up, a similar issue arose - the arms would raise from the bottom position after the motors stopped!

I don’t have pics yet, but our bot is similar to 'Iolani’s seen at:

Any suggestions?

Our teams usually put a potentiometer on the arm and use software to turn the motor on briefly to nudge the arm back up. When combined with elastic (either rubber bands or the black latex cords) to help support the arm, you can build and program a solid system in which the arm remains wherever you put it.

I don’t have any code samples here in the office, but it’s logically similar to this:

*]Arm lift motors are turned on

*]When arm lift power applied to the arm drops to zero, read the current value of the arm pot and save it (ARMPOTSAVE)

*]In the main loop, check to see if ARMPOTVALUE is the same as ARMPOTSAVE

*]If it isn’t, drive the motor until the values are the same

I used to worry that this would burn out the arm motors, but we have had NO problems with this. I should note, though, that our arms are always supported by elastic, which substantially reduces the load on the motors. Dead-lifting heavy arms either requires very low gearing, multiple motors, or both.

This is a great opportunity for the team’s programmer(s) to learn about PID loops, and to implement a very simple example.

Looks like your arm pivots at the point where you are driving it up with the motors. This works sort of like lifting a hinged trunk or to a car hood on the side where it is hinged rather than on the opening side.

If you tried lifting things like those closer to where the hinge is by hand would they be easier or harder to lift? (Don’t actually try it with the car hood I wouldn’t want you to lose any fingers! :slight_smile: )

I had this issue with my clean sweep robot. What i ended up doing is putting enough elastic on the arm that it would stay in the up position. To ensure that it would also stay in the down position i made a large V for lack of a better word that the arm would drive into. This would guide the arm in and as it drove further and further into the V it got slightly jammed into the V enough that the arm would not rise up without being driven up. This worked well for me mainly because the arm only needed to be in 2 positions. The arm would not have stayed in a middle position it this setup but it worked wonders for my situation.

I like Rick’s idea the only thing is that it may cause the arm to be a little bit jumpy because it will work like this

arm is driven to position
pot checks value
arm droops down
pot checks value
motors drive arm back up
arm droops down…

so it is just an endless small up and down movement which may work for you or it may be a royal pain in the butt.

You could always add some friction to the system or add another stage of reduction the the gearbox. I have always found that an arm moving as fast and the one in the video you provided is difficult to control. But hey speed is speed and if you can control it all the more to ya.


IF your using easyC look for the PID example in the samples directory.

Using PID logic (I think actually just PI), the arm can be made rock-steady, although the formulas are sensitive to the amount of the tension on the elastic and the exact masses. When testing starts it’s kind of fun watching the arms bounce up and down, but by adjusting the code and the elastic you can beat the bounce.

how come it raises back up when you added elastics??
did you add too much??
our team just gets the elastics/latex perfectly balanced so the motors to the arm shouldnt really slop down or up when we stop moving it
although i do have to agree that that is a great way to learn about pid loops

Add elastics that stretch less. The “balance point” does exist and if it drove itself up when all the way down with elastics, then you haven’t gotten there yet. Once you do, it shouldn’t move at all at any point.

We’ll look into PID. Like this whole endeavor, it’s new to us, but it’ll be a good challenge.

We tried to add just enough elastics to keep the arm from slopping down when fully raised. Seems like that amount of elastics is too much for the arm to remain fully down. The elastics are fully extended at that point, and when the motors stop the arm gets pulled back up.

We have EasyC v2 but can’t find the PID example. Can we download it from somewhere?

Adding more elastic to balance it out is good for semi-light arms, but if you are trying to lift something heavy, you will be out of luck as the more elastic you put on to keep it from falling will eventually keep you from being able to lower the arm as much as you need to. For our robot this year, we are simply using a task in our code that would keep the arm’s position, at first we tried Rick’s method of changing the motor power until the arm stayed at the desired point, but that caused the arm to bounce up and down (as Rick said), and after changing values and delay amounts many times we eventually gave up on that, deciding to use a mathematical equation that uses simple algebra to find the needed motor power to keep the arm’s position based on how far away the arm is from the desired position. As of now the equation works quite nicely, and we are down to tweaking it to get it perfect right now. One side affect to this is if the weight of the arm is changing during the match (as you pick up tubes/drop off tubes) then you may see problems such as the arm lowering or raising a slight bit more after you let go of the trigger. We have seen some of this, but it hasn’t been drastic, and we have yet to perfect it, as I stated earlier.


How is it geared right now? If you want a simple mechanical solution, I’ve found that creating a compound gear system does help to eliminate back drive. You can still keep your same ratio, even a compound system with an idler stage helps. Elastic assist can be very tricky to work with, maybe just a simple mass counter balance would work just as well? RobotBob’s suggestion for changing the point at which your force is applied is also a great idea, especially if your students are interested in torque, there could certainly be some fun math involved there finding the optimal distance to place your force. These options really aren’t as flashy as a potentiometer with PID code, but they may get the job done for you, and they are all able to be integrated with the sensor setup as well.

One trick about using the latex bands – keep them as long as you possibly can. In Elevation, team 575 ran them down from the end of the arm, around a rolling pivot point, and then terminated them on the front rail of the robot. Instead of being only four inches (or so) long when the arm was raised, the bands were nearly 16 inches long.

If this doesn’t make sense, think of it this way:

A shorter band might only be 4" long when the arm is raised, versus 12" long when lowered. This means that the bands are extremely “stretched” in the lower position and very “unstretched” in the upper.

In 575’s robot, the bands were more like 16" and 24" – meaning that the force applied was much more consistent, with the longer length only 50% more than the shorter instead of being 300% longer.

It’s easy to test this – give it a shot.

These little engineering touches are the #1thing I see in very good VEX robots. It’s rarely the “big idea” that makes a difference, it’s usually the implementation and attention to detail. The swing-out omni wheels on 44 last year were another great example of a face-palm engineering detail. I hate to confess that I spent a lot of time thinking about how to increase the wheelbase on an omnibot and never came close to what Green Eggs did.

Although I am a programmer and would be the first to use potentiometers, there is an easier way. Gear your motor for torque. Maybe one of those really small gears on your motor to a 32 tooth gear on the hinge. If that doesn’t keep the arm up be itself, then you can add the potentiometers, and this way, you don’t risk the motors being harmed. Also, there is another advantage. When you run motors, you give them a power, not speed So with them geared up for torque, you can run them at a higher power and achive more presicion. The disadvantage is that it will slow the arm a bit. But if you’re using it to lift rings, how fast do you need it to go? Think about how fast a motor spins, and divide that speed by 3 or 4 times. I’m assuming that your arm doesn’t spin more than 360 degrees, and this speed should be fine.

Another means to reduce backdriving is to use a worm gear. It will slow down the motion of the arm so you may need to compensate with other gearing as well.


i almost forgot!
the other team did this last year
you can just adjust the TRIM it worked like a charm last year
so instead of the motors going dead when you release the button, it will still be going against the weight
the trim was usually ~± 30-45

`Iolani here; we used a potentiometer and PID coding to do it. Though our 4-bar linkage does have elastic bands on the back, those are actually just to make the lift faster. You may notice bouncing in some of our videos, as mentioned earlier in this thread. That’s a result of the PIDing, though since our programmer has put in work on it seems to have mostly been resolved. I couldn’t tell you the specifics of how he did it, though if you wish I can try to get an answer for you.

Thanks to everyone for all the advice. We’ll start with adjusting the elastic bands, then move on to programming and structural/gear changes. This forum is great and we’re learning a lot from all of you. :slight_smile:

Someone asked about a PID example for V2. Well here is the P in PID

#include "Main.h"

void main ( void )
      int pot; 
      int target = 300; // make global
      int button; 
      int gain = 1; // make a #define and you can use non-whole numbers
      int output; 
      static int buttonLast = 0; 

      while ( 1 == 1 )
            button = GetDigitalInput ( 10 ) ;
            if ( button == 0 && buttonLast == 1 )
                  target += 100 ;
                  if ( target > 800 )
                        target = 300 ;
            pot = GetAnalogInput ( 1 ) ;
            output = gain * ( target - pot ) ;
            if ( output >= 126 )
                  output = 126 ;
            if ( output <= -126 )
                  output = -126 ;
            SetMotor ( 1 , output + 127 ) ;
            Wait ( 20 ) ;
            buttonLast = button ;