Often when dealing with numbers, it is desired to be able to scale them to a different range. This is especially the case when using sensor or motor values.

For a while I just always hacked together something that would work for what I needed. For example, if I needed to scale a 10-bit RAW ADC value into a percent, I would multiply by 100 and divide by 1023. That is a very basic case, but things can get to be a lot more complicated. Instead of figuring out a working algorithm every time that would support the values I needed, I decided to make an NXC function that supports every parameter I could need.

Here is the NXC function:

//Scales a range of numbers to a new range.
//Input value, lowest possible, highest possible, scale from this, to this. It returns the result.
float ScaleRange(float Value, float ValueMin, float ValueMax, float DesiredMin, float DesiredMax)
{
float Result = (DesiredMax - DesiredMin) / (ValueMax - ValueMin) * (Value - ValueMin) + DesiredMin;
return Result;
}

I haven’t done a lot of testing of it, but it seems to work fine.

Because of it allowing all parameters, you can do some pretty cool things. For example, if you take the RAW value from a PSP-Nx joystick (0-255), you can scale that directly into a motor speed. Take a look at this:

`char speed = ScaleRange(PSP_Left_X, 0, 255, -100, 100);`

OnFwd(OUT_A, speed);

and if the motor spins the wrong way, you can simply change it to this:

`char speed = ScaleRange(PSP_Left_X, 0, 255, 100, -100);`

OnFwd(OUT_A, speed);

It doesn’t care which of the values is higher or lower. That means you could scale 0 through 1023 to 200 through -200, and it should work just fine.

As Muntoo pointed out, it can be better to multiply then divide. Here is the updated function:

//Scales a range of numbers to a new range.
//Input value, lowest possible, highest possible, scale from this, to this. It returns the result.
float ScaleRange(float Value, float ValueMin, float ValueMax, float DesiredMin, float DesiredMax)
{
return (DesiredMax - DesiredMin) * (Value - ValueMin) / (ValueMax - ValueMin) + DesiredMin;
}

### Like this:

Like Loading...

*Related*

Nice.

I must remember to use that ðŸ˜‰

You should use:

This way, it’s a lot more accurate.

There was a reason I used the extra variable, but it was probably just while testing.

I don’t think your way is any more accurate. I see what you did, multiply then divide, but with floating point I don’t think it should ever be an issue.

I will post the more efficient and “better” way, but I would like to keep my original variable names.

Depends on the range – when it’s 0 to 1024, maybe not. When it’s small ranges like 0.0125 to 0.25, it does matter. (Who knows – maybe someone will try to do that.)