- 12th January 2006, 18: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, 18:56 #2

- Join Date
- Apr 2002
- Location
- USA
- Posts
- 3,944
- Helped
- 649 / 649
- Points
- 40,208
- Level
- 49

## ADC calculation - help

volts = (ADC - 82) * 680V / (920 - 82)

- 12th January 2006, 18:56

- 13th January 2006, 00:30 #3

- Join Date
- Dec 2004
- Posts
- 458
- Helped
- 16 / 16
- Points
- 3,856
- Level
- 14

## Re: ADC calculation - help

Originally Posted by**Maverickmax**

- 13th January 2006, 00: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, 21: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)/(920-82) 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)/(920-82)); return Temp; }

- 14th January 2006, 14: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, 18: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, 18: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*((920-82)/(920-82)); 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: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)/(920-82); 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)/(920-82); will be evaluated this way:

1st. (adc_result[6]-82)

2nd. (920-82)

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)/(920-82));

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)/(920-82)) 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, 19:37

- 14th January 2006, 20:56 #10
## Re: ADC calculation - help

Hi Silivo

I have tested the equation: Temp = 680*(N-82)/(920-82);

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, 20:56

- 14th January 2006, 21: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, 21: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)/(920-82)); 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, 21: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)/(920-82); return Temp; }

Can you tell me now the value of "Temp" for let's say adc_results[6] = 460

- 14th January 2006, 21: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, 22: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)/(920-82); return Temp; }

- 14th January 2006, 22:10 #16

- Join Date
- May 2003
- Location
- Turkey
- Posts
- 1,351
- 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/ (920-82);

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, 22: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, 22:18 #18
## Re: ADC calculation - help

I have attached my code for you...

the complier - Keil uVision4 IDE

Maverickmax

- 14th January 2006, 23: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, 02:38 #20

- Join Date
- May 2003
- Location
- Turkey
- Posts
- 1,351
- 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 * (tint-82); temp = temp/(920-82); printf("result is %d\n", temp); } puts("test with 16 bit integer"); for(tint=82; tint < 920;tint += 20) { temp1= 680 * (tint-82); temp1 = temp1/(920-82); printf("result is %d\n", temp1); } }