148 lines
4.2 KiB
Plaintext
148 lines
4.2 KiB
Plaintext
|
|
{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf510
|
||
|
|
{\fonttbl\f0\fmodern\fcharset0 Courier;}
|
||
|
|
{\colortbl;\red255\green255\blue255;}
|
||
|
|
\margl1440\margr1440\vieww10800\viewh8400\viewkind0
|
||
|
|
\deftab720
|
||
|
|
\pard\pardeftab720
|
||
|
|
|
||
|
|
\f0\fs24 \cf0 /* fscale\
|
||
|
|
Floating Point Autoscale Function V0.1\
|
||
|
|
Paul Badger 2007\
|
||
|
|
Modified from code by Greg Shakar\
|
||
|
|
\
|
||
|
|
This function will scale one set of floating point numbers (range) to another set of floating point numbers (range)\
|
||
|
|
It has a "curve" parameter so that it can be made to favor either the end of the output. (Logarithmic mapping)\
|
||
|
|
\
|
||
|
|
It takes 6 parameters\
|
||
|
|
\
|
||
|
|
originalMin - the minimum value of the original range - this MUST be less than origninalMax\
|
||
|
|
originalMax - the maximum value of the original range - this MUST be greater than orginalMin\
|
||
|
|
\
|
||
|
|
newBegin - the end of the new range which maps to orginalMin - it can be smaller, or larger, than newEnd, to facilitate inverting the ranges\
|
||
|
|
newEnd - the end of the new range which maps to originalMax - it can be larger, or smaller, than newBegin, to facilitate inverting the ranges\
|
||
|
|
\
|
||
|
|
inputValue - the variable for input that will mapped to the given ranges, this variable is constrained to originaMin <= inputValue <= originalMax\
|
||
|
|
curve - curve is the curve which can be made to favor either end of the output scale in the mapping. Parameters are from -10 to 10 with 0 being\
|
||
|
|
a linear mapping (which basically takes curve out of the equation)\
|
||
|
|
\
|
||
|
|
To understand the curve parameter do something like this: \
|
||
|
|
\
|
||
|
|
void loop()\{\
|
||
|
|
for ( j=0; j < 200; j++)\{\
|
||
|
|
scaledResult = fscale( 0, 200, 0, 200, j, -1.5);\
|
||
|
|
\
|
||
|
|
Serial.print(j, DEC); \
|
||
|
|
Serial.print(" "); \
|
||
|
|
Serial.println(scaledResult, DEC); \
|
||
|
|
\} \
|
||
|
|
\}\
|
||
|
|
\
|
||
|
|
And try some different values for the curve function - remember 0 is a neutral, linear mapping\
|
||
|
|
\
|
||
|
|
To understand the inverting ranges, do something like this:\
|
||
|
|
\
|
||
|
|
void loop()\{\
|
||
|
|
for ( j=0; j < 200; j++)\{\
|
||
|
|
scaledResult = fscale( 0, 200, 200, 0, j, 0);\
|
||
|
|
\
|
||
|
|
// Serial.print lines as above\
|
||
|
|
\
|
||
|
|
\} \
|
||
|
|
\}\
|
||
|
|
\
|
||
|
|
*/\
|
||
|
|
\
|
||
|
|
\
|
||
|
|
#include <math.h>\
|
||
|
|
\
|
||
|
|
int j;\
|
||
|
|
float scaledResult; \
|
||
|
|
\
|
||
|
|
void setup() \{\
|
||
|
|
Serial.begin(9600);\
|
||
|
|
\}\
|
||
|
|
\
|
||
|
|
void loop()\{\
|
||
|
|
for ( j=0; j < 200; j++)\{\
|
||
|
|
scaledResult = fscale( 0, 200, 0, 200, j, -1.5);\
|
||
|
|
\
|
||
|
|
Serial.print(j, DEC); \
|
||
|
|
Serial.print(" "); \
|
||
|
|
Serial.println(scaledResult , DEC); \
|
||
|
|
\} \
|
||
|
|
\}\
|
||
|
|
\
|
||
|
|
float fscale( float originalMin, float originalMax, float newBegin, float\
|
||
|
|
newEnd, float inputValue, float curve)\{\
|
||
|
|
\
|
||
|
|
float OriginalRange = 0;\
|
||
|
|
float NewRange = 0;\
|
||
|
|
float zeroRefCurVal = 0;\
|
||
|
|
float normalizedCurVal = 0;\
|
||
|
|
float rangedValue = 0;\
|
||
|
|
boolean invFlag = 0;\
|
||
|
|
\
|
||
|
|
\
|
||
|
|
// condition curve parameter\
|
||
|
|
// limit range\
|
||
|
|
\
|
||
|
|
if (curve > 10) curve = 10;\
|
||
|
|
if (curve < -10) curve = -10;\
|
||
|
|
\
|
||
|
|
curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output \
|
||
|
|
curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function\
|
||
|
|
\
|
||
|
|
/*\
|
||
|
|
Serial.println(curve * 100, DEC); // multply by 100 to preserve resolution \
|
||
|
|
Serial.println(); \
|
||
|
|
*/\
|
||
|
|
\
|
||
|
|
// Check for out of range inputValues\
|
||
|
|
if (inputValue < originalMin) \{\
|
||
|
|
inputValue = originalMin;\
|
||
|
|
\}\
|
||
|
|
if (inputValue > originalMax) \{\
|
||
|
|
inputValue = originalMax;\
|
||
|
|
\}\
|
||
|
|
\
|
||
|
|
// Zero Refference the values\
|
||
|
|
OriginalRange = originalMax - originalMin;\
|
||
|
|
\
|
||
|
|
if (newEnd > newBegin)\{ \
|
||
|
|
NewRange = newEnd - newBegin;\
|
||
|
|
\}\
|
||
|
|
else\
|
||
|
|
\{\
|
||
|
|
NewRange = newBegin - newEnd; \
|
||
|
|
invFlag = 1;\
|
||
|
|
\}\
|
||
|
|
\
|
||
|
|
zeroRefCurVal = inputValue - originalMin;\
|
||
|
|
normalizedCurVal = zeroRefCurVal / OriginalRange; // normalize to 0 - 1 float\
|
||
|
|
\
|
||
|
|
/*\
|
||
|
|
Serial.print(OriginalRange, DEC); \
|
||
|
|
Serial.print(" "); \
|
||
|
|
Serial.print(NewRange, DEC); \
|
||
|
|
Serial.print(" "); \
|
||
|
|
Serial.println(zeroRefCurVal, DEC); \
|
||
|
|
Serial.println(); \
|
||
|
|
*/\
|
||
|
|
\
|
||
|
|
// Check for originalMin > originalMax - the math for all other cases i.e. negative numbers seems to work out fine \
|
||
|
|
if (originalMin > originalMax ) \{\
|
||
|
|
return 0;\
|
||
|
|
\}\
|
||
|
|
\
|
||
|
|
if (invFlag == 0)\{\
|
||
|
|
rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin;\
|
||
|
|
\
|
||
|
|
\}\
|
||
|
|
else // invert the ranges\
|
||
|
|
\{ \
|
||
|
|
rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange); \
|
||
|
|
\}\
|
||
|
|
\
|
||
|
|
return rangedValue;\
|
||
|
|
\}\
|
||
|
|
}
|