Hi freaks,
I am using an ATmega32 with avr-libc and AVR-Studio 4.15, and I am trying to execute the following transfer function, that convert a value readed though ADC to "lux" (I'm using in this form to avoid floating math):
lux = ((KA * adc * adc) + (KB * adc)) / SCALE
I want to print the "lux" result onto the LCD display, but the result is very strange above certain "adc" value (for example, above 300 counts, the result show values like 429464). For small values, the function works fine.
I suspect that the problem seems to be something regarding the range of the variables used (type). Please, note that I am not so good in C :oops:, but everithing is working well except this conversion.
I would like to know if my approuch is wrong (and where) and if there is a way to simulate only this part of code (in runtime mode) into AVR-Studio, for debug purpose.
This is my code (the problematic part):
Constants:
#define KA 82 // Coeficient of X^2 #define KB 1487 // Coeficient of X #define SCALE 10000 // Scale factor
Variables
static int adcval; // ADC reads put it value here char sLux[7]; // String with the result of conversion
Function call and to show into display:
Calculate(adcval, KA, KB, SCALE, sLux); // sLux string seems to have a problem LCD_PutStr(sLux); // This is working perfectly
Function (this is the last one I tested): Please note that I was growing the types until this.
void Calculate(int value, int a, unsigned int b, long scale, char *str) { static unsigned long value2; // value^2 static unsigned int var; // result // value2 = (unsigned long)(value * value); // Get value^2 // var = (((unsigned long)(a) * value2) + ((unsigned long)(b) * value)) / scale; // ultoa(var, str, 10); // Convert to ASCII string }
To calculate the maximum size of the variables, I did the following:
- For value = 1023, lux = ((82 * 1023 * 1023) + (1487 * 1023)) / 10000 lux = (85815378) + (1521201) / 10000 lux = 87336579 / 10000 lux = 8733 So, an int output variable seems to be fine (int var) - As (value * value) is an "int * int" operation, I need a 32 bits variable. So an unsigned long seems to be fine (unsigned long value2).
Well, any help will be appreciated.
Thanks.