Flaky Potentiometers

We’re using two potentiometers on the RC analog inputs to measure angles on our arm. I’ve been monitoring their values through printfs. Sometimes I get lovely and normal values (0-1023), and sometimes I get very strange ones. In strange mode, the values always increase, but in this order: 0 64 192 448 960 1984 4032 7680 7936 8128 (…) The first few numbers follow an obvious pattern but I don’t know where the 7000 ones come from. And after that it gets less regular. It goes up to numbers like 32768 and above.

This confuses us in programming, because the function that reads the analog inputs should never return a number above 1023, so it looks like interference. We’ve wiggled our pwm cables and so on but it doesn’t make things better. Um…I assume this is an electrical problem. Does anyone know where this is coming from?

Thanks.

We were having issues like that, could I see the code in question?

You could also PM/Email me with it if you’d prefer.

Hmm… I will use what I know on this…

What type of variable are you using in the c program to keep track of the potentiometers?

32768 is the positive limit for a signed integer variable in the C program…
There is signed integers which can go from -32768 to positive 32768, and unsigned goes from 0 to 65535.
It is possible that the Potentiometer is put on the robot very loosely, and continues turning in one direction when your arm moves, and etc.

In our program, in order to make it easier for us to read a potentiometer, we use unsigned char (characters), which have a range from 0 to 255, making it easier to keep track of the pot’s location.

I hope this helps…

We’re using unsigned ints. The values when we have strange behavior go above 32766. That’s just the last number I wrote down when I was testing the arm.

This is most of our arm routine. (Probably more than you wanted to see–sorry.)


 static unsigned char enable = 0;
 
 void arm_positioning(void)
 {
 	static short use_manual_control_shoulder = 1, use_manual_control_elbow = 1;
 
 	if(arm_sw_freeze == 1)	//Make the arm stop moving
 	{
 		enable = 0;
 		use_manual_control_shoulder = use_manual_control_elbow = 0;
 	}
 
	if(oi_shoulder_sw_fwd)
 	{
 		cylinder_fwd = 0;
 		cylinder_rev = 1;
 		shoulder_target = Get_Shoulder_Pos();
 		use_manual_control_shoulder = 1;
 	}
 	else if(oi_shoulder_sw_rev)
 	{
 		cylinder_fwd = 1;
 		cylinder_rev = 0;
 		shoulder_target = Get_Shoulder_Pos();
 		use_manual_control_shoulder = 1;
 	}
 	
 	
 	if(oi_elbow_sw_fwd)
 	{
 		arm_motor = 127 + arm_speed;
 		elbow_target = Get_Elbow_Pos();
 		use_manual_control_elbow = 1;
 		enable = 1;	//Allow arm to move again, if it was turned off.
 	}
 	else if(oi_elbow_sw_rev)
 	{
 		arm_motor = 127 - arm_speed;
 		elbow_target = Get_Elbow_Pos();
 		use_manual_control_elbow = 1;	
 		enable = 1;	//Allow arm to move again, if it was turned off.
 	}
 
 	// manual positioning, but no movement commanded; hold cylinder in place
 	if (!oi_shoulder_sw_fwd && !oi_shoulder_sw_rev
 		&& use_manual_control_shoulder)
 	{
 		cylinder_fwd = 0;
 		cylinder_rev = 0;
 		enable = 1;
 	}		
 
 	if (!oi_elbow_sw_fwd && !oi_elbow_sw_rev
 		&& use_manual_control_elbow)
 	{
 		arm_motor = 127;
 		enable = 1;
 	}		
 
 
 	if(!use_manual_control_shoulder && !use_manual_control_elbow)
 		position_arm(shoulder_target, elbow_target);
 
 	printf("Manual FWD: %d REV: %d, Shldr Trgt: %u, Elb Trgt: %u, Shldr: 0x%04x, Elbow: 0x%04x
",
 	oi_shoulder_sw_fwd, oi_shoulder_sw_rev, shoulder_target, elbow_target, Get_Shoulder_Pos(), Get_Elbow_Pos()); 
 	printf("Shoulder Pot: %u, Elbow Pot: %u, Cylinder Values FWD: %d REV: %d
", 
 	Get_Shoulder_Pos(), Get_Elbow_Pos(), cylinder_fwd, cylinder_rev);
 
 }
 
 
 
 void position_arm(unsigned int shoulder_target, unsigned int elbow_target)
 {
 	//This gets changed a few lines later if enable is on.
 	arm_motor = 127;
 	cylinder_fwd = cylinder_rev = 0;
 	
 	if (enable)
 	{
 		if(Get_Shoulder_Pos() < (shoulder_target - SHOULDER_DEADBAND))
 		 {
 			cylinder_fwd = 1;
 			cylinder_rev = 0;
 		}
 		else if(Get_Shoulder_Pos() > (shoulder_target + SHOULDER_DEADBAND))
 		{
 			cylinder_fwd = 0;
 			cylinder_rev = 1;
 		}
 		else
 		{
 			cylinder_fwd = cylinder_rev = 0;
 		}
 
 
 		if(Get_Elbow_Pos() < (elbow_target - ELBOW_DEADBAND))
 		{
 			arm_motor = 127 + arm_speed;
 		}
 		else if(Get_Elbow_Pos() > (elbow_target + ELBOW_DEADBAND))
 		{
 			arm_motor = 127 - arm_speed;
 		}
 	}
 
 }
 
 unsigned int Get_Shoulder_Pos()
 {
 	return Get_Analog_Value(robot_shoulder_pot);
 }
 
 unsigned int Get_Elbow_Pos()
 {
 	return Get_Analog_Value(robot_elbow_pot);
 }
 

This is probably not your issue, but our team was chasing ghosts until we realized our print statements were actually the problem. Hyperterminal wasn’t clearning the screen between updates, but rather just writting lines on top of eachother. The result was that any time an unusually long message or long number was displayed, it would linger to the outside of the ‘real’ readout and look like a giant integer from that point afterwards.