Edit: I know its boring to take someone else's code and set up an environment. For that, I've made the code available and ready to run in https://www.jdoodle.com/embed/v0/FeZ
Hey Folks, many times we need to translate values to different ranges so I wrote this piece of code. I hope you enjoy and give feedback and ideas to improve:
/**
@Description
This function performs a conversion from one scale X to scale Y. The relation between those scales is considered linear. Then, based on the parameters a known value x in scale X is converted to a value y in scale Y.
@Preconditions
None
@Param
x - is the value to be converted to scale y
xa - is the minimum scale X value.
xb - is the maximum scale X value.
ya - is the minimum scale Y value.
yb - is the maximum scale Y value.
@Returns
The value converted from scale X to scale Y.
@Comment
This function uses the round half up method as an integer rounding method
@Example
<code>
#define MIN_X 20
#define MAX_X 50
#define MIN_Y 1000
#define MAX_Y 2000
uint16_t y;
uint16_t x = 30;
y = Rescale_Value( x, MIN_X, MAX_X, MIN_Y, MAX_Y );
</code>
*/
uint16_t Rescale_Value (uint16_t x , uint16_t xa, uint16_t xb, uint16_t ya, uint16_t yb )
{
/**
Algorithm:
1 - Find a linear equation;
2 - Calculate the equation considering rounding;
Explanation:
- A equation of the line correlates two different range of values. The equation
is given by the following formula,
y = ((yb - ya)*(x - xa))/(xb - xa)) + ya;
where,
(xa,ya) and (xb,yb) -> are known points in the line.
OBS: to complete understand solution search equation of the line theory.
Considerations:
y will be written as a/b + ya
where,
a = (yb - ya)*(x - xa)
b = (xb - xa)
*/
//test input condition
if(x < xa)
{
x = xa;
}
else if ( x > xb)
{
x = xb;
}
uint16_t y;
//multiplication of two 16bits gives a 32bits integer
uint32_t a;
uint16_t b;
a = (yb - ya)*(x - xa);
b = (xb - xa);
/**
In the matter of integers, calculation rounding must be considered.
Then, y is calculated using the round half up method
So, a/b is aproximated as (a/b + 1/2), but as calculation is performed by integers
1/2 = 0 (zero), then (a/b + 1/2) is rewritten as((a + b/2)/b).
*/
y = ((a + b/2)/b) + ya;
return y ;
}