Potentiometer Problems

Hello,
I am having problems with my potentiometer on my arm. When I set a x value for the potentiometer in my autonomous program and run it the arm on the robot will always go past the value I set in the program. I have down loaded new firmware and put a different potentiometer and I am still having the same effects.

Here is the code I have made. It is having problems at the first if else statement for the arm where I have set the value for 800. If anyone could help me I would be very grateful.

#pragma config(I2C_Usage, I2C1, i2cSensors)
#pragma config(Sensor, in1,    AutoPot,        sensorPotentiometer)
#pragma config(Sensor, in2,    ArmPot,         sensorPotentiometer)
#pragma config(Sensor, dgtl1,  RFP,            sensorDigitalOut)
#pragma config(Sensor, dgtl2,  LFP,            sensorDigitalOut)
#pragma config(Sensor, I2C_1,  ,               sensorQuadEncoderOnI2CPort,    , AutoAssign)
#pragma config(Sensor, I2C_2,  ,               sensorQuadEncoderOnI2CPort,    , AutoAssign)
#pragma config(Motor,  port1,           RTLArmM,       tmotorVex393, openLoop, reversed)
#pragma config(Motor,  port2,           RTRArmM,       tmotorVex393, openLoop)
#pragma config(Motor,  port3,           RFDriveM,      tmotorVex393, openLoop, reversed)
#pragma config(Motor,  port4,           RRDriveM,      tmotorVex393, openLoop, reversed, encoder, encoderPort, I2C_2, 1000)
#pragma config(Motor,  port5,           RIntakeM,      tmotorVex393HighSpeed, openLoop)
#pragma config(Motor,  port6,           LIntakeM,      tmotorVex393HighSpeed, openLoop, reversed)
#pragma config(Motor,  port7,           LRDriveM,      tmotorVex393, openLoop, encoder, encoderPort, I2C_1, 1000)
#pragma config(Motor,  port8,           LFDriveM,      tmotorVex393, openLoop)
#pragma config(Motor,  port9,           LTLArmM,       tmotorVex393, openLoop, reversed)
#pragma config(Motor,  port10,          LTRArmM,       tmotorVex393, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

#pragma platform(VEX)

//Competition Control and Duration Settings
#pragma competitionControl(Competition)
#pragma autonomousDuration(20)
#pragma userControlDuration(120)

#include "Vex_Competition_Includes.c"   //Main competition background code...do not modify!

void SetDriveMotors (int value, int value2) //Sets The Drive Motors To A Value, Value2 To get Rid Of Repetitive Code
{
	motor[LFDriveM] = motor[LRDriveM] = value;
	motor[RFDriveM] = motor[RRDriveM] = value2;
}
void SetDriveEncoders (int value)
{
	nMotorEncoder[LRDriveM] = nMotorEncoder[RRDriveM] = value; 
}
void SetArmMotors (int value, int value2) //Sets The Arm Motors To A Value, Value2 To get Rid Of Repetitive Code
{
	motor[LTLArmM] = motor[LTRArmM] = value;
	motor[RTLArmM] = motor[RTRArmM] = value2;
}
void SetIntakeMotors (int value) //Sets The Intake Motors To A Value To get Rid Of Repetitive Code
{
	motor[LIntakeM] = motor[RIntakeM] = value;
}
void pre_auton()
{
	SetDriveEncoders (0);
}


task autonomous()
{
	if(SensorValue[AutoPot] > 1 && SensorValue[AutoPot] < 250) //Tells The Robot To Run The Barrier Side Autonomous
	{
		SetIntakeMotors(127); //Turns Intake Motors On To Drop The Intake Motors
		
		if(SensorValue[ArmPot] < 800) //Moves The Arm Up To The Height Of The Ball
			SetArmMotors(127, 127);
		else if(SensorValue[ArmPot] == 800) //Stops The Arm Wen It Equals 200
			SetArmMotors(0, 0);
		else if(SensorValue[ArmPot] > 800) //Moves The Arm Down If It Raises More Than 200
			SetArmMotors(-100, -100);
		
		
		SetIntakeMotors(0);

		SetDriveEncoders(0); //Clears Drive Encoders
		while(nMotorEncoder[LRDriveM] && nMotorEncoder[RRDriveM] < 800) //Moves The Robot Forward To Push The Ball Off The Barrier
			SetDriveMotors(127, 127);
		SetDriveMotors(0, 0);

		SetDriveEncoders(0); //Clears Drive Encoders
		while(nMotorEncoder[LRDriveM] && nMotorEncoder[RRDriveM] < 800) //Moves The Robot Backward Back To The Starting Square
			SetDriveMotors(-127, -127);
		SetDriveMotors(0, 0);

		wait1Msec(500); //A half Second Wait To Position The Robot For The Second Big Ball

		SetDriveEncoders(0); //Clears Drive Encoders
		while(nMotorEncoder[LRDriveM] && nMotorEncoder[RRDriveM] < 850) //Moves The Robot Forward To Push The Second Ball Off The Barrier
			SetDriveMotors(127, 127);
		SetDriveMotors(0, 0);

		SetDriveEncoders(0); //Clears Drive Encoders
		while(nMotorEncoder[LRDriveM] && nMotorEncoder[RRDriveM] < 850) //Moves The Robot Backward Back To The Starting Square
			SetDriveMotors(-127, -127);
		SetDriveMotors(0, 0);

		if(SensorValue[ArmPot] > 1) //Moves The Arm Down To The Starting Position
			SetArmMotors(-127, -127);
		else if(SensorValue[ArmPot] < 1) //Moves The Arm Up If It Lowers Less Than 1
			SetArmMotors(100, 100);
		else if(SensorValue[ArmPot] == 1) //Stops The Arm Wen It Equals 1
			SetArmMotors(0, 0);

		wait1Msec(500); //A half Second Wait To Position The Robot For The Second Big Ball

		SetDriveEncoders(0); //Clears Drive Encoders
		while(nMotorEncoder[LRDriveM] && nMotorEncoder[RRDriveM] < 1000) //Moves The Robot Forward To Goal
			SetDriveMotors(127, 127);
		SetDriveMotors(0, 0);

		if(SensorValue[ArmPot] < 300) //Moves The Arm Up To The Height Of The Goal
			SetArmMotors(127, 127);
		else if(SensorValue[ArmPot] > 300) //Moves The Arm Down If It Raises More Than 200
			SetArmMotors(-100, -100);
		else if(SensorValue[ArmPot] == 300) //Stops The Arm Wen It Equals 200
			SetArmMotors(0, 0);

		SetDriveEncoders(0); //Clears Drive Encoders
		while(nMotorEncoder[LRDriveM] && nMotorEncoder[RRDriveM] < 100) //Moves The Robot Slowly Over The Goal
			SetDriveMotors(90, 90);
		SetDriveMotors(0, 0);

		SetIntakeMotors(127); //Turns The Intake Motors On To Drop The Ball In The Goal

		SetDriveEncoders(0); //Clears Drive Encoders
		while(nMotorEncoder[LRDriveM] && nMotorEncoder[RRDriveM] < 100) //Moves The Robot Slowly Away From The Goal
			SetDriveMotors(-90, -90);
		SetDriveMotors(0, 0);

		if(SensorValue[ArmPot] > 1) //Moves The Arm Down To The Starting Position
			SetArmMotors(-127, -127);
		else if(SensorValue[ArmPot] < 1) //Moves The Arm Up If It Lowers Less Than 1
			SetArmMotors(100, 100);
		else if(SensorValue[ArmPot] == 1) //Stops The Arm Wen It Equals 1
			SetArmMotors(0, 0);
	}
	if(SensorValue[AutoPot] > 600 && SensorValue[AutoPot] < 1200 ) //Tells The Robot To Run The Hanging Side Autonomous
	{
		SetIntakeMotors(127); //Turns Intake Motors On To Drop The Intake Motors

		SetDriveEncoders(0);
		while(nMotorEncoder[LRDriveM] && nMotorEncoder[RRDriveM] < 300) //Moves The Robot Forward To Pick Up The Big Ball
			SetDriveMotors(127, 127);
		SetDriveMotors(0, 0);

		SetIntakeMotors(0);

		SetDriveEncoders(0);
		while(nMotorEncoder[LRDriveM] && nMotorEncoder[RRDriveM] < 300) //Moves The Robot Backward To The Starting Position 
			SetDriveMotors(-127, -127);
		SetDriveMotors(0, 0);

		wait1Msec(500); //Half Second Wait To Position The Robot

		if(SensorValue[ArmPot] < 200) //Moves The Arm Up To Catapult The Ball
			SetArmMotors(127, 127);
		else if(SensorValue[ArmPot] > 200) //Moves The Arm Down If It Raises More Than 200
			SetArmMotors(-100, -100);
		else if(SensorValue[ArmPot] == 200) //Stops The Arm Wen It Equals 200
			SetArmMotors(0, 0);

		if(SensorValue[ArmPot] > 1) //Moves The Arm Down To The Starting Position
			SetArmMotors(-127, -127);
		else if(SensorValue[ArmPot] < 1) //Moves The Arm Up If It Lowers Less Than 1
			SetArmMotors(100, 100);
		else if(SensorValue[ArmPot] == 1) //Stops The Arm Wen It Equals 1
			SetArmMotors(0, 0);

		wait1Msec(500); //Half Second Wait To Position The Robot

		SetIntakeMotors(127); //Turns Intake Motors On To Intake The Bucky Balls

		SetDriveEncoders(0);
		while(nMotorEncoder[LRDriveM] && nMotorEncoder[RRDriveM] < 300) //Moves The Robot Forward To Pick Up The Bucky Balls
			SetDriveMotors(127, 127);
		SetDriveMotors(0, 0);

		SetDriveEncoders(0);
		while(nMotorEncoder[LRDriveM] && nMotorEncoder[RRDriveM] < 300) //Moves The Robot Backward To The Starting Position 
			SetDriveMotors(-127, -127);
		SetDriveMotors(0, 0);
	}
}

Could you elaborate on “go past the value”? The way you have the code set up the arm motors will turn off when the arm reaches your desired potentiometer value but will overshoot due to momentum of the arm. I then see that you have another statement designed to reverse the arm if it overshoots. Is your arm bouncing up and down never stabilizing at your value, or is it overshooting once and then not coming back?

Edit: Also I’m not a programmer but


if(SensorValue[AutoPot] > 1 && SensorValue[AutoPot] < 250) //Tells The Robot To Run The Barrier Side Autonomous

should this be a while statement if you want it to be constantly adjusting? Otherwise it’ll just check if your AutoPot is at the position for your Barrier Side Autonomous, then move on and check if your ArmPot is less than 800. When it sees both those are true, you do “SetArmMotors(127, 127)” then never check for the position of ArmPot ever again.

Edit2: Sorry that’s definitely not the line of code you want to be the while statement, but I’m pretty sure you need the while statement somewhere in there so that the program will constantly check for the position of ArmPot and adjust the arm motors accordingly.

In addition to SweetMochi’s questions, is the arm moving up or down?

One thing that I have found, is that the potentiometer reads based on changed values, instead of actual values read on the debugger menu. If u program like I do, you’ll have a, "untilpotentiometerisgreaterthan(“value”,“port”) command found in the natural language. This specific command means that the potentiometer reads values and stops motors after the value is reached. So plugging in “3000” will be read as moving 3000 units, not to the debugger value of 3000. This may be your issue. Let me know if this helped!

Lets take a look at the beginning of one of your autonomous routines.

task autonomous()
{
    if(SensorValue[AutoPot] > 1 && SensorValue[AutoPot] < 250) //Tells The Robot To Run The Barrier Side Autonomous
    {
        SetIntakeMotors(127); //Turns Intake Motors On To Drop The Intake Motors
        
        if(SensorValue[ArmPot] < 800) //Moves The Arm Up To The Height Of The Ball
            SetArmMotors(127, 127);
        else if(SensorValue[ArmPot] == 800) //Stops The Arm Wen It Equals 200
            SetArmMotors(0, 0);
        else if(SensorValue[ArmPot] > 800) //Moves The Arm Down If It Raises More Than 200
            SetArmMotors(-100, -100);
        
        
        SetIntakeMotors(0);

        SetDriveEncoders(0); //Clears Drive Encoders
        while(nMotorEncoder[LRDriveM] && nMotorEncoder[RRDriveM] < 800) //Moves The Robot Forward To Push The Ball Off The Barrier
            SetDriveMotors(127, 127);
        SetDriveMotors(0, 0);

The code starts of by looking at a pot and decides to run the first autonomous routine.

The intake motors are started at a speed of 127.

The arm pot is examined and depending on it’s current value the arm motors are either started at full speed forward, or stopped, or run at almost full speed reverse.

The intake motors are now stopped.

The above three statements all happened very fast, there were no delays, the intake motors probably barely moved.

Next, the drive encoders are cleared

A while statement checks the left encoder for being “not zero” and that the right encoder is less than 800.

etc. etc.

So at this point the arm motors will (unless the pot was already at position 800 which is extremely unlikely) still be running, there is no code that checks for the arm being in position. I would guess that you thought this code would block until the arm had finished moving, but it doesn’t.

        if(SensorValue[ArmPot] < 800) //Moves The Arm Up To The Height Of The Ball
            SetArmMotors(127, 127);
        else if(SensorValue[ArmPot] == 800) //Stops The Arm Wen It Equals 200
            SetArmMotors(0, 0);
        else if(SensorValue[ArmPot] > 800) //Moves The Arm Down If It Raises More Than 200
            SetArmMotors(-100, -100);

What I mean by go past the value is that when I have the arm all the way down and I want it to go up to a value of 800, when I run the program The arm will go up but it seems like it is ignoring the value I set for it. It will continually go up and I have to stop it manually with the compitition control switch.

I do not believe I need a while statement but I could be wrong I will see if that helps any. Thank you

Zach

The arm is moving up but it continually moves up until I stop it manually.

I am a beginner programer and I am a little confused of the untilpotentiometerisgreaterthat(“value”,“port”). Is that basicly just a command to make sure the potentiometer reads the values correctly, and also where would you put this in the code, before or inside the autonmous task?

You are right the intake motors do not move at all and the arm just goes up and never stops until I manualy stop it. What I am not understanding is why it is not stopping at the value I give it. It seems to me that the arm should stop and like you said it will not. What do I need to do differnently to my code that will make the arm stop at the value I tell it to stop at?

The “if-then-else” statement only executes one time, you start the motors but never stop them, the test needs to be in a loop. I will post something for you later that demonstrates this.

So as I said, this code

        if(SensorValue[ArmPot] < 800) //Moves The Arm Up To The Height Of The Ball
            SetArmMotors(127, 127);
        else if(SensorValue[ArmPot] == 800) //Stops The Arm Wen It Equals 200
            SetArmMotors(0, 0);
        else if(SensorValue[ArmPot] > 800) //Moves The Arm Down If It Raises More Than 200
            SetArmMotors(-100, -100);

only executes one time to set the motors to either 127, 0 or -100 depending on the value of the pot. You need something like this, it has to assume something to start with and here it assumes the pot is a low value.

    // We must assume the arm is down and the pot value is low
    // to start, move the arm to position 800
    // start the motors
    if( SensorValue[ArmPot] < 800 )
        SetArmMotors(127, 127);

    // Now wait until we get to position
    // This code will block until the arm reaches that height
    while( SensorValue[ArmPot] < 800 )
        wait1Msec(10);

    // Now stop the motors
    SetArmMotors(0, 0);

This will get quite tedious to add to your program and will change depending on arm direction. A better way is to use a function to move the arm, something like this.

/*-----------------------------------------------------------------------------*/
/*  Simple function to move motor to a given position based on potentiometer   */
/*  feedback.  Positive command values should give increasing potentiometer    */
/*  values                                                                     */
/*-----------------------------------------------------------------------------*/

#define     ARM_POSITION_TOLERANCE    25    // How close to target before stop is sent
#define     MOVE_ARM_TIMEOUT        5000    // Maximum time (in mS) to move arm
#define     ARM_LOOP_DELAY            25    // move arm loop delay

int
MoveArm( int toPosition )
{
    long    currentTime;
    int     currentPosition;
    int     errorInPosition;
    int     returnValue   = 0;

    // Get current position
    currentPosition = SensorValue ArmPot ];

    // check if we need to move
    if( abs( currentPosition - toPosition ) < ARM_POSITION_TOLERANCE )
        return(1);

    // move up or down ?
    if( currentPosition < toPosition )
       SetArmMotors( 127, 127 );
    else
       SetArmMotors( -100, -100 );

    // wait for end - 5 seconds maximum
    for( currentTime = nSysTime; currentTime > (nSysTime - MOVE_ARM_TIMEOUT);)
        {
        // delay at beginning of loop
        wait1Msec(ARM_LOOP_DELAY);

        // Get current position
        currentPosition = SensorValue ArmPot ];
        // calculate error and invert based on direction
        errorInPosition = abs(toPosition - currentPosition);

        // Check for arm in position
        if( errorInPosition < ARM_POSITION_TOLERANCE )
            {
            returnValue = 1; // success
            break;
            }
        }

    // Stop motor
    SetArmMotors( 0, 0 );

    // return success(1) ir failure(0)
    return(returnValue);
}

You would then replace your arm move code with a call like this.


MoveArm( 800 );

You may not understand everything in that function, ask questions about it if you need to.

The function will block (not return to the calling function) until the arm reaches position or 5 seconds have elapsed, whichever happens first. I pulled this code from an example I posted in the robotc programming tips thread, it’s a simplified version from here.

https://vexforum.com/showpost.php?p=322768&postcount=130

That code was a little more complex, it monitored other things like battery voltage that may interfere with arm movement.

Okay so for the code that you put would that need to go before the autonomous task?

I should of of said this earlier in the thread but the lowest value that the potentiometer is at when the arm is down is around 646 the reason I had the value set at 800 was because I was seeing if the arm would actualy stop if I gave it a low value. So since the lowest value on the potentiometer is pretty high would the code need to be changed at all in order to work correctly?

The potentiometer will give values between 0 and 4095, however, it’s not very linear towards the start and end of that range. A low value of 500 or 600 is an ideal starting point for the low end, you should try and get the high end to be 3500 or lower. The code should work “as is” so long as running the motors forward (speed 127) causes the pot to increase in value.

Okay thank you for all of your help.

Everything works great now thank you so much for your help.