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 ; }