+ Post New Thread
Results 1 to 20 of 27

12th January 2006, 19:35 #1
ADC calculation  help
Hi
I have been doing a small experiment as I get the reading such as 920 from ADC channel when the input voltage is 680V. Then I get the value  82 when the voltage is 0V.
920  680V
82  0V
How to convert between 920 and 82 into 680V and 0V respectively for my code?
So far I have done a little calculation:
680/920 = 0.739
so 0.739*920 will yields 680V
but when I try to calculate 0.739 * 82 and I would expect OV but I get 60.6V
So I have done summat wrong with my calculation. Any help would be appreicated
Maverickmax

12th January 2006, 19:56 #2
 Join Date
 Apr 2002
 Location
 USA
 Posts
 3,942
 Helped
 660 / 660
 Points
 32,456
 Level
 44
ADC calculation  help
volts = (ADC  82) * 680V / (920  82)

12th January 2006, 19:56

13th January 2006, 01:30 #3
 Join Date
 Dec 2004
 Posts
 458
 Helped
 17 / 17
 Points
 3,856
 Level
 14
Re: ADC calculation  help
Originally Posted by Maverickmax

13th January 2006, 01:46 #4
Re: ADC calculation  help
See Echo47's answer.
You first need to subtract the offset (82) from the reading and then divide by the slope of the characteristic.

13th January 2006, 22:25 #5
Re: ADC calculation  help
Hi
When I applied the equation in my codes and tested it and the most of time
I only get the 0V when I adjust variable resistor forth and back but sometime
I get 680V but I don't get any reading when I adjusted the votlage between
0V and 680V.
I exclude 680* from Temp = (adc_result[6]82)/(92082) and I found out that
I only get most of the 0 and 1 only.
Is there anything that I maybe overlook or is it summat wrong with my function prototype?
Code:int Voltage_measurement(void) { int Temp; Temp = 680*((adc_result[6]82)/(92082)); return Temp; }

14th January 2006, 15:43 #6
Re: ADC calculation  help
I still could not get any reading between 680V and 0V as I only get 0V and few 680V when I turn the variable resistor to full.
Is it do with my code?
Maverick max
Let assume that adc_result[6] would be 920, the temp would return 680 which is fine. However the value less that 920 down to 1 which yields 0V. Why is that?
Maverick Max

14th January 2006, 19:27 #7
Re: ADC calculation  help
The formula is correct. Are you sure that adc_result[6] is the correct value upon entry?
To test, why not modify your code to simply return that value and see if it is changing linearly from 82 to 920 as you vary the voltage.
Temp=adc_result[6]
return Temp
This should return 82~920, depending on voltage.
If it doesn't, then you need to check the acquisition routine, hardware, etc.

14th January 2006, 19:38 #8
Re: ADC calculation  help
Hi
In regard to your question, I have checked it many times as I get getting the reading from 82 to 920.
I have another simple test by applying 920 in the equation instead of using adc_result[6] is 920 and change my code to test my calculation:
Code:int Temp; Temp = 680*((92082)/(92082)); return Temp;
Then adc_result  900
Result: 0
adc_result  700
result:0
adc_result  500
result:0
adc_result  300
result:0
adc_result  100
result:0
I realise it must be do with codes and I don't know why I get 0...
You can try the code and you would probably get the same result like mine
I changed from int to unsigned int, no effect then changed it to float  still same result
Strange innit?
Maverickmax

14th January 2006, 19:38

14th January 2006, 20:37 #9
 Join Date
 Dec 2001
 Location
 Romania
 Posts
 716
 Helped
 110 / 110
 Points
 12,871
 Level
 27
Re: ADC calculation  help
Why don't you try this way:
Code:int Voltage_measurement(void) { int Temp; Temp = 680*(adc_result[6]82)/(92082); return Temp; }
Funny enough the results will become even negative for value of adc_results[6] bellow 82.
If you follow the echo47's advice then according with C precedence operators the binary operators found on the same level of precedence will be evaluated from left to right. Thus first () then * then /
Thus Temp = 680*(adc_result[6]82)/(92082); will be evaluated this way:
1st. (adc_result[6]82)
2nd. (92082)
3rd. 680 * results of 1st evaluation
4th. results of 3rd evaluation divided by results of 2nd evaluation
Now try with your Temp = 680*((adc_result[6]82)/(92082));
According to the above equation, always all it's on the right of the * sign will be solved before the multiplication.
((adc_result[6]82)/(92082)) will always be less than 1 (0,99.......) for values of adc_results less than 920. That's why you get always zero !
Hope it's clear why I removed the two ().

14th January 2006, 20:37

14th January 2006, 21:56 #10
Re: ADC calculation  help
Hi Silivo
I have tested the equation: Temp = 680*(N82)/(92082);
where N is 920, 900, 500 etc
The result is not what I have been looking for.
It doesn't solve my problem....

14th January 2006, 22:11 #11
 Join Date
 Dec 2001
 Location
 Romania
 Posts
 716
 Helped
 110 / 110
 Points
 12,871
 Level
 27
Re: ADC calculation  help
Originally Posted by Maverickmax
Or your initial request
Originally Posted by Maverickmax
Originally Posted by Maverickmax
What kind of ADC you use ?
Just because you can use the differential mode operation of the A/D by biasing the A / D Vin() input and adjust the zero offset in order to get a code of 000000.... for 0v input. Then you can adjust the span to accomodate with the input range.

14th January 2006, 22:28 #12
Re: ADC calculation  help
On my inital request, I need get the reading from ADC ranging from 920 to 82 so I need to convert 920 and 82 into 680V to 0V
So
I followed echo47's equation such as temp=680*((adc_result[6]82)/(92082)); and I only get 680 when the adc_result is 920 but number below 920 down to 83, give 0. This is not what I really expect as I need the reading when any value between 919 to 83. So far I could not manage to iron the problem out yet
MaverickMax

14th January 2006, 22:43 #13
 Join Date
 Dec 2001
 Location
 Romania
 Posts
 716
 Helped
 110 / 110
 Points
 12,871
 Level
 27
Re: ADC calculation  help
Which compiler you use for which micro ?
Try this way:
Code:int Voltage_measurement(void) { int Temp; Temp = (int)680*(adc_result[6]82)/(92082); return Temp; }
Can you tell me now the value of "Temp" for let's say adc_results[6] = 460

14th January 2006, 22:55 #14
Re: ADC calculation  help
Im using Keil and the microcontroller is XC161
As I have modified my code as you requested.
According to my calculator, the result would be approximately 307 but unfortunately the result from codes yields 6
MaverickMax

14th January 2006, 23:04 #15
 Join Date
 Dec 2001
 Location
 Romania
 Posts
 716
 Helped
 110 / 110
 Points
 12,871
 Level
 27
Re: ADC calculation  help
OK change to unsigned int
Code:unsigned int Voltage_measurement(void) { unsigned int Temp; Temp = (unsigned int)680*(adc_result[6]82)/(92082); return Temp; }

14th January 2006, 23:10 #16
 Join Date
 May 2003
 Location
 Turkey
 Posts
 1,350
 Helped
 127 / 127
 Points
 12,348
 Level
 26
ADC calculation  help
What is the int length of your compiler ?
Just to ensure that even compiler bug does not affect compile code as
volatile long int temp; // (32 bits calculation is a must as result can exceed 0xffff)
temp= 680 * (adc_result[6]82);
temp = temp/ (92082);
and you can scale the divisor part to get unrounded result and keep source out of floating math to achieve necessary precision for your task.
What compiler do you use and its version number?

14th January 2006, 23:16 #17
 Join Date
 Dec 2001
 Location
 Romania
 Posts
 716
 Helped
 110 / 110
 Points
 12,871
 Level
 27
Re: ADC calculation  help
Originally Posted by artem

14th January 2006, 23:16

14th January 2006, 23:18 #18
Re: ADC calculation  help
I have attached my code for you...
the complier  Keil uVision4 IDE
Maverickmax

15th January 2006, 00:12 #19
Re: ADC calculation  help
Bascially I have not optimized the codes and I followed your instruction.....
Nothing changed
Maverick Max

15th January 2006, 03:38 #20
 Join Date
 May 2003
 Location
 Turkey
 Posts
 1,350
 Helped
 127 / 127
 Points
 12,348
 Level
 26
ADC calculation  help
for me it seems that something wrong with your input from adc . Check it first .
Code:C:\Borland\projects\test2>bcc32 IC:\Borland\BCC55\Include\ LC:\Borland\BCC55\Lib test.c Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland test.c: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland C:\Borland\projects\test2>test sizeof int 4 sizeof long int 4 size of short int 2 test with 32 bit integer result is 0 result is 16 result is 32 result is 48 result is 64 result is 81 result is 97 result is 113 result is 129 result is 146 result is 162 result is 178 result is 194 result is 210 result is 227 result is 243 result is 259 result is 275 result is 292 result is 308 result is 324 result is 340 result is 357 result is 373 result is 389 result is 405 result is 421 result is 438 result is 454 result is 470 result is 486 result is 503 result is 519 result is 535 result is 551 result is 568 result is 584 result is 600 result is 616 result is 632 result is 649 result is 665 test with 16 bit integer result is 0 result is 16 result is 32 result is 48 result is 64 result is 2 result is 19 result is 35 result is 51 result is 67 result is 5 result is 22 result is 38 result is 54 result is 70 result is 8 result is 25 result is 41 result is 57 result is 73 result is 11 result is 27 result is 44 result is 60 result is 76 result is 14 result is 30 result is 47 result is 63 result is 1 result is 17 result is 33 result is 50 result is 66 result is 4 result is 20 result is 36 result is 53 result is 69 result is 7 result is 23 result is 39 C:\Borland\projects\test2>type test.c #include <stdio.h> void main(void) { volatile unsigned long int temp; volatile unsigned short int temp1; int tint; printf("sizeof int %d\n",sizeof(int)); printf("sizeof long int %d\n", sizeof(long int)); printf("size of short int %d\n",sizeof(short int)); puts("test with 32 bit integer"); for(tint=82; tint < 920;tint += 20) { temp= 680 * (tint82); temp = temp/(92082); printf("result is %d\n", temp); } puts("test with 16 bit integer"); for(tint=82; tint < 920;tint += 20) { temp1= 680 * (tint82); temp1 = temp1/(92082); printf("result is %d\n", temp1); } }
+ Post New Thread
Please login