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