Log in

View Full Version : Strange but...need fresh eyes


TubaMorg
02-02-2006, 09:32
We've been trying to figure this one out for a couple of days. Here is the code in question:

p1_y = (unsigned char) (((double) p1_y + (double)127)*.75);

if (p1_y > 250)
{
p1_y = (unsigned char)250;
}

PrintToScreen ("P1_y is %d\n", (int)p1_y);


The first line is a conversion we need to use to make our steering wheel paddles work. p1_y is the value sent to the drive motors. What is happening is the wheels spin forward until the upper limit (250) at which point they immediately spin backwards or stop. Output from the print line reflects this condition, increasing to 250 then converting to 1 or 127. We thought maybe the steering wheel had started to send the wrong signal at its limit, but changing the limit set point (i.e. from 250 down to 245) results in the same thing. Any ideas?

Joel J
02-02-2006, 09:58
We've been trying to figure this one out for a couple of days. Here is the code in question:

p1_y = (unsigned char) (((double) p1_y + (double)127)*.75);

if (p1_y > 250)
{
p1_y = (unsigned char)250;
}

PrintToScreen ("P1_y is %d\n", (int)p1_y);


The first line is a conversion we need to use to make our steering wheel paddles work. p1_y is the value sent to the drive motors. What is happening is the wheels spin forward until the upper limit (250) at which point they immediately spin backwards or stop. Output from the print line reflects this condition, increasing to 250 then converting to 1 or 127. We thought maybe the steering wheel had started to send the wrong signal at its limit, but changing the limit set point (i.e. from 250 down to 245) results in the same thing. Any ideas?
Are you overflowing?

Does p1_y go from -128 to 127, or from 0 to 255.

If its from 0 to 255, then adding 127 definitely takes you out of the range of an unsigned char.

If its from -128 to 127, then it seems that saving (127+127) to a signed char would also result in overflow.

If you want to scale by 75% you can multiply by three, then divide by four:

p1_y = 3*(p1_y + 127)/4;

No need for floats.

TubaMorg
02-02-2006, 15:08
Are you overflowing?

Does p1_y go from -128 to 127, or from 0 to 255.

If its from 0 to 255, then adding 127 definitely takes you out of the range of an unsigned char.

If its from -128 to 127, then it seems that saving (127+127) to a signed char would also result in overflow.

If you want to scale by 75% you can multiply by three, then divide by four:

p1_y = 3*(p1_y + 127)/4;

No need for floats.

Well the first line of the code works ok I believe. p1_y from the steering wheel goes from around 60 to 150 or something like that. The correction fixes it ok. If I change the if statement to, say, 254, the code will work correctly until 254 then flop to 1. If I change the if statement to 145, the code will work correctly until 145 then flop to 1. So I am deducing that my assignment in the if block is causing the headache. That being said, I am going to try what you suggested, because once things over range, all logic can be thrown out the window! ;)

TubaMorg
02-02-2006, 15:24
Another idea I had was to maintain my drive variables as int to avoid overranging and then of course make sure they are 0-254 before sending them to the PWM ports. That way if there is any spurious or temporary overranging, I won't lose control of the variable. Because no matter how you look at it, if you take and unsigned char with a value > 127 and add 127, then you have over ranged even though subsequent operations are designed to bring it back into range. With ints this shouldn't be a problem right? Unless I really, really really, go out of range.

Joel J
02-02-2006, 17:12
Another idea I had was to maintain my drive variables as int to avoid overranging and then of course make sure they are 0-254 before sending them to the PWM ports. That way if there is any spurious or temporary overranging, I won't lose control of the variable. Because no matter how you look at it, if you take and unsigned char with a value > 127 and add 127, then you have over ranged even though subsequent operations are designed to bring it back into range. With ints this shouldn't be a problem right? Unless I really, really really, go out of range.
Yep. with a signed int, you can go on the range: [-32768, 32767].