Help with limit mix

what’s the point off adding 2000 to the following functions:

pwm01 = pwm03 = Limit_Mix(2000 + PWM_in1 + PWM_in2 - 127); /* LEFT WHEELS /
pwm02 = pwm04 = Limit_Mix(2000 + PWM_in2 - PWM_in1 + 127); /
RIGHT WHEELS */

the coding seems all fuzzy to me, i dont’ get it

I’m n00b myself so maybe I’m wrong.

I had problems with this myself when I came across it.

I think it has something to do with the hardware
it is slower to run the program if it starts getting decimals (floating point #'s)

I think later in the program it negates the 2000

correct me if I’m wrong :]

You’re right, noob. (;)) It does that just so that it can get decent precision without decimals or negatives. :slight_smile:

I think… :wink:

The compiler we use has the irritating feature of choosing eight-bit arithmetic when adding eight-bit quantities. That often results in overflow and unexpected results. Adding a constant 2000 to the expression forces the compiler to do things using 16-bit arithmetic, and everything then works as it should.

The Limit_Mix() function subtracts 2000 from its result, neatly compensating for the extra 2000 in its input.

The Limit_Mix function assumes that its input value has had 2000 added in, and thus subtracts it back out before returning.

Back in the Basic Stamp days, there were certain circumstances where it was necessary to avoid negative numbers. This Limit_Mix function is a legacy of those days. By rights, the function should now be:

unsigned char Limit_Mix (int intermediate_value)
{
  static int limited_value;
  
  if (intermediate_value < 0)
  {
    limited_value = 0;
  }
  else if (intermediate_value > 254)
  {
    limited_value = 254;
  }
  else
  {
    limited_value = intermediate_value;
  }
  return (unsigned char) (limited_value);
}

And the calls would be:

pwm01 = pwm03 = Limit_Mix(PWM_in1 + PWM_in2 - 127); /* LEFT WHEELS */
pwm02 = pwm04 = Limit_Mix(PWM_in2 - PWM_in1 + 127); /* RIGHT WHEELS */

OK. I forgot about the 8 bit quirk. Adding the 2000 bias does circumvent this trap, but it’s an awfully kludgy way to do it. I assert the following would be clearer: (Assuming that all the definitions remain eight bits each.)

pwm01 = pwm03 = Limit_Mix((int)PWM_in1 + PWM_in2 - 127); /* LEFT WHEELS */
pwm02 = pwm04 = Limit_Mix((int)PWM_in2 - PWM_in1 + 127); /* RIGHT WHEELS */

so what does the (int) do?
does it make the PIC treat all variables (PWM_in2 & PWM_in1) in the Parenthesis like an int instead of a char ?

It makes the compiler treat the variable with the (int) in front of it as an int. However, having even a single int in the expression causes the compiler to choose 16-bit operations to evaluate the result, even if everything else is only 8 bits in size.

The (int) is something called an explicit typecast. It forces the variable right after it to be converted into an integer type, which in our case is a 16-bit signed type.

This “Limit Mix / why add 2000?” question is one that gets asked A LOT by teams up in Canada. I usually refer people to a post on the FIRST Greater Toronto Regional forums:

http://www.firstcanadianregional.org/BB/viewtopic.php?t=500

Hope that sheds some light into the situation!

-SlimBoJones…