Sensor Consistency Help

We have tried to use sensors in our autonomous to no avail, and our state tournament is in 2 days. The major trouble makers are our potentiometer on the arm and the gyro for turning. The gyro, even though I have not adjusted the sensor scale, still gives random values for the same turn, and turns differently every time for a given turning value. The potentiometer moves constantly, changing the upper and lower limits, so the code always freaks out, and sometimes the pot sends random values, causing the arm to either go all the way up or stop somewhere on the way to the expected value. Is there any way I could make these more consistent when it comes to the values they send to the cortex?
Pot code for the arm:


void armcontrol(int speed1, int height,int speed2)/*This function raises or lowers the arm to a certain point.
It's used by specifying a speed at which to raise and a height (potentiometer value) at which to stop raising.
The speed2 variable is a speed to back up at while lifting- We have this because we have a nonlinear lift, which
needs to back up while lifting in order to pick up skyrise pieces properly.*/
{
	clearTimer(T2);
	bool raising = true;
	int prevalue = 3300;
	if(speed1 > 0)//Checks which direction to move the arm. Positive is up, negative is down.
	{
		clear();//Clears values: left over from when we used encoders for the lift.
		while(raising)//Sets motor values while the condition (or height) is not the specified value.
		{
			if(time1(T2) == 200)
			{
				prevalue =SensorValue[armencoderR];
				clearTimer(T2);
			}
			motor[armleft1] = speed1;
			motor[armright1] = speed1;
			motor[armleft2] = speed1;
			motor[armright2] = speed1;
			motor[frontleft] = -speed2;
			motor[backleft] = -speed2;
			motor[backright] = -speed2;
			motor[frontright] = -speed2;
			if(abs(SensorValue[armencoderR] - prevalue) > 600)
			{
				continue;
			}
			else if(SensorValue[armencoderR] >3500 || SensorValue[armencoderR] <1560)//These are the upper and lower limits for the arm. The higher the value, the lower the arm is.
			{
				break;
			}
			else if(SensorValue[armencoderR] <= height)
			{
				raising = false;
			}
		}
		stopbase();
		motor[armleft1] = 0;
		motor[armright1] = 0;
		motor[armleft2] =0;
		motor[armright2] = 0;
	}
	else if(speed1 < 0)
	{
		clear();
		while(raising)
		{
			if(time1(T2) == 200)
			{
				prevalue =SensorValue[armencoderR];
			}
			motor[armleft1] = speed1;
			motor[armright1] = speed1;
			motor[armleft2] = speed1;
			motor[armright2] = speed1;
			motor[frontleft] = -speed2;
			motor[backleft] = -speed2;
			motor[backright] = -speed2;
			motor[frontright] = -speed2;
			if(abs(SensorValue[armencoderR] - prevalue) > 600)
			{
				continue;
			}
			else if(SensorValue[armencoderR] >3500 || SensorValue[armencoderR] <1560)
			{
				break;
			}
			else if(SensorValue[armencoderR] >= height)
			{
				raising = false;
			}
		}
		stopbase();
		motor[armleft1] = 0;
		motor[armright1] = 0;
		motor[armleft2] = 0;
		motor[armright2] = 0;
	}
}


Gyro code for turns


void turnright(int speed, int degrees)/*These two functions turn the robot based on a gyro value.
They turn then stop the robot.*/
{
	clear();
	while(SensorValue[gyro]  > -degrees)
	{
		motor[frontright] = speed;
		motor[backright] = -speed;
		motor[backleft] = speed;
		motor[frontleft] = -speed;
	}
	stopbase();
}



here is the clear() function referenced several times:

void clear()
{
	SensorValue[gyro] = 0;
	SensorValue[intakeencoder] = 0;
}

Any help would be appreciated.

Have you tried using the RobotC debugger windows to actually read your pot values? It’s possible you could have a bad pot, that it got damaged from being turned too far, etc.

Have a look at these, for example:
https://vexforum.com/t/using-and-debugging-sensors-with-robotc/24705/1
http://help.robotc.net/WebHelpVEX/index.htm#Topics/ROBOTC%20Debugger/Debug%20Windows/Sensors.htm%3FTocPath%3DROBOTC%2520Debugger%7C_____4

As for your gyro… First, are you giving your gyro time to start up and calibrate anywhere?
RobotC has a sample file for the gyro, if you forgot the code for calibration:
http://www.robotc.net/blog/2011/10/13/programming-the-vex-gyro-in-robotc/

Also, gyros can be greatly affected by vibration. See for example the following:
https://vexforum.com/showthread.php?p=373942

I have put the gyro on rubber links like Jpearman did, and I do give time for the gyro to calibrate.The gyro is mounted on a bar which connects to the towers for our arm, and mounting it anywhere else would connect it with the drive base, which I assume would add more vibration. I do use the debugger regularly to check if the pot has moved at all and most of the time it seems smooth in the changing of position, but sometimes spikes out of range and causes the function to stop. Sometimes, the gyro also spirals wildly upwards or downwards at almost 100-150 at a time per second in the debugger.

One thing I’m a little bothered by:


if(time1(T2) == 200)

I think this will activate that IF statement only if T2 is exactly 0.200 second. So if the loop is looping and T2 happens to go from 0.199 second to 0.201 second between loops, then maybe your IF statement might get skipped. Could that be one source of problems?

Would it help to try this or some variation that creates a time window rather than a specific single value?


if(time1(T2) > 200)

I agree with the Toss-Boss that you might be able to filter out some of the spikes using software. For example perhaps ignore any signals over a certain outrageous value or ignore anything that suddenly goes negative or jumps away from the previous value too much.

I’m going to try and average the data. I’m not entirely sure how I would ignore values outside of the range because it is running in a loop. If you could post any code that might help with ignoring values, I’d try it in a heartbeat.

I’m no expert in programming, but perhaps consider something like the following to at least ignore the more outrageous spikes. I put in some limits so that if the values of your pot exceed values at which pots are known to operate (roughly 300 to 4300 - I don’t recall the exact range), then those values will be ignored. Of course, if the spikes are within the normal range of pots, then unfortunately these spikes will still be “seen” by the code.

Strange thing I just noticed: it appears that you are referring to the pots as encoders. Are you sure you have the sensors set up properly or am I missing something here? Encoders are very different from pots and usually provide different values. And pots can turn only a fraction of a full circle, whereas encoders can turn around an unlimited number of times.


if(SensorValue[armencoderR] >3500 || SensorValue[armencoderR] <1560  && SensorValue[armencoderR] < 4300 && SensorValue[armencoderR] >300)
{
  //Do something here only if the pot values appear somewhat sane...
}

That if statement gives me an idea on how to fix it. The pot is just named armencoderR so I didn’t have to change the name in all the functions. It is currently plugged in to analog in1. Thank you for the help so far, and I did try to average the values and I will see if al this works when I get a hold of the robot again