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.
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).
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…
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.