gyro problem

I have the gyro on the analog input 01. i am using kevin’s code with the gyro and adc enabled. i am getting a reading in the printf for both the rate and the angle. coding it is the trouble.

i am using mecanum programming i found from alan. it works very well on its own.


/*******************
function:	deadband()
inputs:	inp, input value
		center, value of input that represents neutral
		band, size of deadband to consider neutral
output:	scaled and deadband-compensated output value
		inputs below center will yield negative output
		inputs above center will yield positive output
		inputs within deadband either side of center will yield 0
usage:	typically call with joystick value (0-254) as input,
		joystick neutral (127) as center, and a small number (5)
		as the size of the deadband.  The white POS joysticks
		should probably have a much larger band (10) instead.
*******************/
int deadband(int inp, int center, int band)
{
int oup;
	if (inp < center-band)
		oup = inp - center + band;
	if (center-band <= inp && inp <= center+band)
		oup = 0;
	if (center+band < inp)
		oup = inp - center - band;
	return oup;
}

/*********************
function:	pwm_limit()
inputs:	inp, input value
output:	scaled and range-limited output value
usage:	call with signed value (+/- 127) as input,
		will return a valid pwm value
*********************/
unsigned char pwm_limit (signed int inp)
{
	if(inp<-127)
		inp = -127;
	if (inp>127)
		inp = 127;
	inp = inp+127;

	return (char)inp;
}



void Teleop(void)
{

	l_y = deadband(p1_y,127,10);
	r_y = deadband(p2_y,127,10);
	l_x = deadband(p1_x,127,10);
	r_x = deadband(p2_x,127,10);

	l_y = l_y/2;
	r_y = r_y/2;
	l_x = l_x/2;
	r_x = r_x/2;

	speed = l_y+r_y;
	turn = l_y-r_y;
	slide = -l_x-r_x; 

/*

	if(temp_gyro_angle <= -75) //gyro
	{
		turn = turn+15;
	}
	if(temp_gyro_angle >= 75)
	{
		turn = turn-15;
	}

*/
  	front_r = speed-turn+slide;
	front_l = speed+turn-slide;
	back_r = speed-turn-slide;
	back_l = speed+turn+slide;


	pwm01 = pwm_limit(front_r);
	pwm02 = 255 - pwm_limit(front_l);
	pwm03 = pwm_limit(back_r);
	pwm04 = 255 - pwm_limit(back_l);

}

The commented out part is mine. It is simple and looks like it should work, but whenever the gyro is plugged in, the victors ‘flicker’. the orange lights flash very quick, and the wheels get a quick power burst to it, over and over. when the gyro is unplugged, its fine.

suggestions?

Print out the pwm values to see if they correspond to what you are seeing or not. If so, your code is causing the pwm values to do weird things; if the pwm values are steady but the motors are doing weird things, that might point to a wiring problem.

Put printf’s inside your conditionals (if(temp_gyro_angle <= -75)…) to see what is going on.

You are increasing/decreasing ‘turn’ based on gyro. What type is turn? char? int? Is it static?

If turn is a static char and you are increasing it by 15 38 times per second, it will overflow more than 2 times each second (15*38/256).

This may be a shot in the dark … but try plugging the gyro into analog input 02. This fixed a problem we experienced with the gyro.

thanks for the help. i wont really be able to check it until thursday at competition, so i want to make sure this is right.

turn is declared as a signed int. will this have the same affect? how would i go about fixing that? this gyro is completly new to me.

try using a feedback loop…a simple one would look like:

turn = turn - temp_gyro_angle / 15;

or something like that. this will get you (theoretically) a robot that always points forward. you may want to make the ratio that you multiply temp_gyro_angle by higher or lower depending on how fast/slow you want it to correct.

also, gnormhurst, he couldn’t be overflowing because turn is set every step…

you mean divide by? and yes i get what you mean. but again, i won’t be able to test until competition.

well you are multiplying by 1/15, so i mean multiply.

I think that you should use Get_Gyro_Angle() to get data from the gyro. That is how we used it. Also We had a similar problem with our field centric omni drive. It was caused by a division by 0. Good Luck from 1647

	signed int speed, turn, slide;
	signed int front_r, front_l, back_r, back_l;
	long int l_y, r_y, l_x, r_x;
	static unsigned int i = 0;
	static unsigned int j = 0;
	int temp_gyro_rate;
	long temp_gyro_angle;
	int temp_gyro_bias;
	long temp_gyro_angle_fast;
	long Encoder_Count;

	i++;
	j++; // this will rollover every ~1000 seconds


	// enable this block of code to test your gyro 
	if(j == 10)
	{
		printf("
Calculating Gyro Bias...
");
	}
	if(j == 38) // let the gyro stablize for a second before starting a calibration
	{
		// start a gyro bias calculation
		Start_Gyro_Bias_Calc();
	}
	if(j == 191) // allow calibration routine to run for four seconds 
	{
		// terminate the gyro bias calculation
		Stop_Gyro_Bias_Calc();

		// reset the gyro heading angle
		Reset_Gyro_Angle();

		temp_gyro_bias = Get_Gyro_Bias();
		printf("Gyro Bias=%d
", temp_gyro_bias);
	}
	if(i == 35 && j >= 191)
	{
		temp_gyro_rate = Get_Gyro_Rate();
		temp_gyro_angle = Get_Gyro_Angle();
		printf("Gyro Rate=%d
", temp_gyro_rate);
		printf("Gyro Angle=%d

", (int)temp_gyro_angle);

Here is the gyro calibration code. Is there anything wrong with this? Something I noticed, is that i and j both add one for each loop. So how does i = 35 and j be higher than 191 if they are always the same (for the last section). maybe i am missing something. would that be any reason?

Further down in the code, i is reset to 0 every time that it increases to 38, in a small block as follows:

	// reset the loop counter
	if(i >= 38)
	{
		i = 0;
	}

Essentially, i is the number of loops in the “current second” of looping; while j is the total number of loops executed in teleop since the robot was reset.