audiocommander Posted January 6, 2006 Report Posted January 6, 2006 I have a (hopefully not too silly :-[ ) question:I am using some sensors that don't deliver exact 0 - 5V as AIN-Value. For example: a resulting MIDI-value from a sensor/softPot would be typically ranging from ~10 to ~80 instead from 0 to 127.Now I want to implement this formula, that "expands" this value to the maximum range of 0 to 127: unsigned char min = 10; unsigned char max = 80; unsigned char sevenBitValue = ((sevenBitValue - min) * 127.0 / (max - min)); Here comes the problem: If I am using multiplication and division, I am forced to include these sdcc-libs, which increase the codesize from 3 kB to > 10 kB: #include "sdcc/include/float.h" #include "sdcc/lib/_fsmul.c" #include "sdcc/lib/_mullong.c" #include "sdcc/lib/_fsdiv.c" #include "sdcc/lib/_sint2fs.c" #include "sdcc/lib/_fs2uchar.c" #include "sdcc/lib/_fs2ulong.c" #include "sdcc/lib/_slong2fs.c" #include "sdcc/lib/_ulong2fs.c" Is there any possibility to avoid multiplications and / or divisions in this case? Can this be calculated by bit-operators? ??? Thanks for any hint, Michael btw: unfortunately I get a strange linker error if I divide through 127 (integer) instead of 127.0 (float): :o gplink -s m5.lkr -m -o m5.hex _output/mios_wrapper.o _output/pic18f452.o _output/main.o error: missing definition for symbol "__gptrget1", required by "_output/main.o" Quote
TK. Posted January 6, 2006 Report Posted January 6, 2006 Hi Michael,divisions are always time consuming, and with floating point values it will take even longer to get the result. For scaling values I'm normaly using a 8*8 bit multiplication, the scaled result will be in the high byte of the result register.Here a function which you can use (it's from the sid_random application, and it's assembler optimized)unsigned char Scale_8bit(unsigned char value, unsigned char min, unsigned char max){ // scaled value is (<8-bit random> * <range>) >> 8 PRODL = value; // 8bit value PRODH = max-min+1; // range__asm movf _PRODL, W mulwf _PRODH, 0__endasm; return min + PRODH;}[/code]Best Regards, Thorsten. Quote
audiocommander Posted January 7, 2006 Author Report Posted January 7, 2006 Hi Thorsten,thank you very much for that super-fast answer!now my app is back @ 5 kB and there's plenty of space left for many, many knobs & sensors ;D...and I've also learned how it's possible to mix C and ASM code! 8)Thanks again,CheersMichael Quote
audiocommander Posted January 7, 2006 Author Report Posted January 7, 2006 well after thinking about a division of 2, I realized, that bit-operator can be really helpful.(the curse of autodidacts)maybe there are other newbies wondering how to divide / 2:  ;D1023 >> 1 = 255255 >> 1 = 127and vice versa:1 << 1 = 210 << 1 = 2010 << 2 = 40so easy ::)btw: I've just found "ch", a tool for the shell (all major os) to evaluate c-syntax: http://www.softintegration.comthe standard edition comes for free ;Da lot easier than compiling (or even worser: compiling and sending to the PIC to evaluate)...cheers,Michael Quote
goule Posted January 8, 2006 Report Posted January 8, 2006 Same as you, with our exotic controllers we are in need of arithmetic calculations to rescale the analog input. I found it was too heavy to deal with floats and decided to go with a DIV( ) function :unsigned int ADK_DIV(unsigned int a, unsigned int b){ unsigned int reste = 0; unsigned char count = 16; char c; do {  c = ((a >> (8*sizeof(a)-1)) & 1);  a <<= 1;  reste <<= 1;  if © reste |= 1;  if (reste >= b)  {   reste -= b;   a |= 1;  } } while (--count); return a;}That way, you can stay in the integer world :int coeff=4; // Sensitivity in LIN (linear) modeif (DBEAM_TYPE == LOG)   DBEAM_VALUE = MIOS_AIN_PinGet(pin)/4 - DBEAM_SEUIL;else   DBEAM_VALUE = 128-(ADK_DIV(3615*coeff,MIOS_AIN_PinGet(pin)+24)-coeff-18);This code also shows the linearization (or not) of the GP2D120 as it is naturally scaled LOG Bye,Goule Quote
audiocommander Posted January 8, 2006 Author Report Posted January 8, 2006 :Dwonderful!this is working great!I'll send my source in the distance-sensor thread :)Michael Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.