EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

LPC2378 ADC Result Error!

Started by quesha0811 February 6, 2012
Hello...I am trying to use the ADC of LPC2378 from olimex lpc2378-stk kit...i am able to read the value but there is a difference in the value displayed from the actual value...i have tried 3 sets of readings as follows:

1.302V (input - observed from Digital multimeter) - 1.875V (displayed by ADC)

2.639V (input - observed from Digital multimeter) - 2.871V (displayed by ADC)

1.980V (input - observed from Digital multimeter) - 12.568V (displayed by ADC)

my program is as follows:

#include
#include
#include

int main ()
{long double y;
PCONP |= (1<<12);
SCS |= 1;
AD0CR = 0x01211320;
PINSEL3 |= 0xC0000000;

InitLcd();
LCDClearScreen();
while (1)
{

y = (AD0DR5 >>6)& 0X3FF;
y = ((y + 1) * 3.3) / 1024;

FloatDisplay (0, y);
Delay (100000);
}
}

Please help me on what is wrong as i have a strong feeling it is calculation error!!...thank u somuch in advance!!

An Engineer's Guide to the LPC2100 Series

I suspect that this could be because of the order of type promotion in C /
C++;

Try assigning the value to an integer and masking it before assigning it to
the long double Y.

int x = (AD0DR5 >>6)& 0X3FF;

y = ((x + 1) * 3.3) / 1024;

Regards

Phil.

From: l... [mailto:l...] On Behalf Of
quesha0811
Sent: 06 February 2012 13:05
To: l...
Subject: [lpc2000] LPC2378 ADC Result Error!

Hello...I am trying to use the ADC of LPC2378 from olimex lpc2378-stk
kit...i am able to read the value but there is a difference in the value
displayed from the actual value...i have tried 3 sets of readings as
follows:

1.302V (input - observed from Digital multimeter) - 1.875V (displayed by
ADC)

2.639V (input - observed from Digital multimeter) - 2.871V (displayed by
ADC)

1.980V (input - observed from Digital multimeter) - 12.568V (displayed by
ADC)

my program is as follows:

#include
#include
#include

int main ()
{long double y;
PCONP |= (1<<12);
SCS |= 1;
AD0CR = 0x01211320;
PINSEL3 |= 0xC0000000;

InitLcd();
LCDClearScreen();
while (1)
{

y = (AD0DR5 >>6)& 0X3FF;
y = ((y + 1) * 3.3) / 1024;

FloatDisplay (0, y);
Delay (100000);
}
}

Please help me on what is wrong as i have a strong feeling it is calculation
error!!...thank u somuch in advance!!



Phil,

> I suspect that this could be because of the order of type promotion in C /
> C++;
>
> Try assigning the value to an integer and masking it before assigning it
to
> the long double Y.
>
> int x = (AD0DR5 >>6)& 0X3FF;
>
> y = ((x + 1) * 3.3) / 1024;

It's not that--most likely it's no prototype for DisplayFloat. A JTAG-based
debugger would pinpoint the issue.

-- Paul.

thanks Phil and Paul,

i tried what u suggested Phil, but its still the same...for your information, the adc value is always displayed as 3.3V...i have used the following function to display the ADC value..maybe this is the cause of error...pls double chek it if it is ok..

void FloatDisplay (unsigned int, long double);

void FloatDisplay (unsigned int row, long double number) //Takes a float value and displays it on the lcd as a 10 digits before decimal and 3 digits after decimal
{unsigned long long a, b;
unsigned int c[10], d[3];
long double z;
SCS |= 1;

a = number; //We got the left hand side of the decimal part becuase "a" is an integer

z = number - a; //We got the right hand side of the decimal part as 0.xxxxxx
z = z * 1000; //We fix our decimal places to 3 digits after decimal. i.e. 0.xxxxx has now become xxx.xxxxxxx

b = z; //If our deimal value is greater than 3 digits then we get the first 3 digits of the decimal value because "b" is an integer

/*Now to display "b" value character by character (i.e. right hand side after decimal point)*/

d[0] = (b%10)+0x30;
LCDPutChar(d[0], row, 124, LARGE, RED, WHITE);
d[1] = ((b/10)%10)+0x30;
LCDPutChar(d[1], row, 116, LARGE, RED, WHITE);
d[2] = ((b/100)%10)+0x30;
LCDPutChar(d[2], row, 108, LARGE, RED, WHITE);

LCDPutChar('.', row, 100, LARGE, RED, WHITE);//Decimal Point

/*Now to display "a" value character by character (i.e. left hand side after decimal point)*/
c[0] = (a%10)+0x30;
LCDPutChar(c[0], row, 92, LARGE, BLACK, WHITE);
c[1] = ((a/10)%10)+0x30;
LCDPutChar(c[1], row, 84, LARGE, BLACK, WHITE);
c[2] = ((a/100)%10)+0x30;
LCDPutChar(c[2], row, 76, LARGE, BLACK, WHITE);
c[3] = ((a/1000)%10)+0x30;
LCDPutChar(c[3], row, 68, LARGE, BLACK, WHITE);
c[4] = ((a/10000)%10)+0x30;
LCDPutChar(c[4], row, 60, LARGE, BLACK, WHITE);
c[5] = ((a/100000)%10)+0x30;
LCDPutChar(c[5], row, 52, LARGE, BLACK, WHITE);
c[6] = ((a/1000000)%10)+0x30;
LCDPutChar(c[6], row, 44, LARGE, BLACK, WHITE);
c[7] = ((a/10000000)%10)+0x30;
LCDPutChar(c[7], row, 36, LARGE, BLACK, WHITE);
c[8] = ((a/100000000)%10)+0x30;
LCDPutChar(c[8], row, 28, LARGE, BLACK, WHITE);
c[9] = ((a/1000000000)%10)+0x30;
LCDPutChar(c[9], row, 20, LARGE, BLACK, WHITE);
}
--- In l..., "Paul Curtis" wrote:
>
> Phil,
>
> > I suspect that this could be because of the order of type promotion in C /
> > C++;
> >
> > Try assigning the value to an integer and masking it before assigning it
> to
> > the long double Y.
> >
> > int x = (AD0DR5 >>6)& 0X3FF;
> >
> > y = ((x + 1) * 3.3) / 1024;
>
> It's not that--most likely it's no prototype for DisplayFloat. A JTAG-based
> debugger would pinpoint the issue.
>
> -- Paul.
>

i hope i didnt confuse u ppl...i meant the adc always displays 3.3 when the
pin is kept unconnected...

On Mon, Feb 6, 2012 at 5:28 PM, quesha0811 wrote:

> **
> thanks Phil and Paul,
>
> i tried what u suggested Phil, but its still the same...for your
> information, the adc value is always displayed as 3.3V...i have used the
> following function to display the ADC value..maybe this is the cause of
> error...pls double chek it if it is ok..
>
> void FloatDisplay (unsigned int, long double);
>
> void FloatDisplay (unsigned int row, long double number) //Takes a float
> value and displays it on the lcd as a 10 digits before decimal and 3 digits
> after decimal
> {unsigned long long a, b;
> unsigned int c[10], d[3];
> long double z;
> SCS |= 1;
>
> a = number; //We got the left hand side of the decimal part becuase "a" is
> an integer
>
> z = number - a; //We got the right hand side of the decimal part as
> 0.xxxxxx
> z = z * 1000; //We fix our decimal places to 3 digits after decimal. i.e.
> 0.xxxxx has now become xxx.xxxxxxx
>
> b = z; //If our deimal value is greater than 3 digits then we get the
> first 3 digits of the decimal value because "b" is an integer
>
> /*Now to display "b" value character by character (i.e. right hand side
> after decimal point)*/
>
> d[0] = (b%10)+0x30;
> LCDPutChar(d[0], row, 124, LARGE, RED, WHITE);
> d[1] = ((b/10)%10)+0x30;
> LCDPutChar(d[1], row, 116, LARGE, RED, WHITE);
> d[2] = ((b/100)%10)+0x30;
> LCDPutChar(d[2], row, 108, LARGE, RED, WHITE);
>
> LCDPutChar('.', row, 100, LARGE, RED, WHITE);//Decimal Point
>
> /*Now to display "a" value character by character (i.e. left hand side
> after decimal point)*/
> c[0] = (a%10)+0x30;
> LCDPutChar(c[0], row, 92, LARGE, BLACK, WHITE);
> c[1] = ((a/10)%10)+0x30;
> LCDPutChar(c[1], row, 84, LARGE, BLACK, WHITE);
> c[2] = ((a/100)%10)+0x30;
> LCDPutChar(c[2], row, 76, LARGE, BLACK, WHITE);
> c[3] = ((a/1000)%10)+0x30;
> LCDPutChar(c[3], row, 68, LARGE, BLACK, WHITE);
> c[4] = ((a/10000)%10)+0x30;
> LCDPutChar(c[4], row, 60, LARGE, BLACK, WHITE);
> c[5] = ((a/100000)%10)+0x30;
> LCDPutChar(c[5], row, 52, LARGE, BLACK, WHITE);
> c[6] = ((a/1000000)%10)+0x30;
> LCDPutChar(c[6], row, 44, LARGE, BLACK, WHITE);
> c[7] = ((a/10000000)%10)+0x30;
> LCDPutChar(c[7], row, 36, LARGE, BLACK, WHITE);
> c[8] = ((a/100000000)%10)+0x30;
> LCDPutChar(c[8], row, 28, LARGE, BLACK, WHITE);
> c[9] = ((a/1000000000)%10)+0x30;
> LCDPutChar(c[9], row, 20, LARGE, BLACK, WHITE);
>
> }
>
> --- In l..., "Paul Curtis" wrote:
> >
> > Phil,
> >
> > > I suspect that this could be because of the order of type promotion in
> C /
> > > C++;
> > >
> > > Try assigning the value to an integer and masking it before assigning
> it
> > to
> > > the long double Y.
> > >
> > > int x = (AD0DR5 >>6)& 0X3FF;
> > >
> > > y = ((x + 1) * 3.3) / 1024;
> >
> > It's not that--most likely it's no prototype for DisplayFloat. A
> JTAG-based
> > debugger would pinpoint the issue.
> >
> > -- Paul.
> >
>

--

Dev Sampat****

Cell (Oman): (+968) - 9304 8932****

Email: d...@gmail.com


> i tried what u suggested Phil, but its still the same...for your
information,
> the adc value is always displayed as 3.3V...i have used the following
function
> to display the ADC value..maybe this is the cause of error...pls double
chek
> it if it is ok..

Use a debugger and step through it; that is the easiest way to figure out
perplexing errors.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
SolderCore running Defender... http://www.vimeo.com/25709426

Reading in more detail the original email, the problem is not with the ADC.

If you display 12.59V.

y = (AD0DR5 >>6)& 0X3FF;
y = ((y + 1) * 3.3) / 1024;

Y cannot be greater than 3.3 here, regardless of what you actually read from
the ADC

1.980V (input - observed from Digital multimeter) - 12.568V (displayed by
ADC)

if it displayed anything above 3.3V then it must be a fault with the output
routine.

Why not try a simple for loop, assigning all values to Y from 0 to 1023
instead of reading the ADC and see what it outputs.

Regards

Phil.

From: l... [mailto:l...] On Behalf Of
quesha0811
Sent: 06 February 2012 13:28
To: l...
Subject: [lpc2000] Re: LPC2378 ADC Result Error!

thanks Phil and Paul,

i tried what u suggested Phil, but its still the same...for your
information, the adc value is always displayed as 3.3V...i have used the
following function to display the ADC value..maybe this is the cause of
error...pls double chek it if it is ok..

void FloatDisplay (unsigned int, long double);

void FloatDisplay (unsigned int row, long double number) //Takes a float
value and displays it on the lcd as a 10 digits before decimal and 3 digits
after decimal
{unsigned long long a, b;
unsigned int c[10], d[3];
long double z;
SCS |= 1;

a = number; //We got the left hand side of the decimal part becuase "a" is
an integer

z = number - a; //We got the right hand side of the decimal part as 0.xxxxxx

z = z * 1000; //We fix our decimal places to 3 digits after decimal. i.e.
0.xxxxx has now become xxx.xxxxxxx

b = z; //If our deimal value is greater than 3 digits then we get the first
3 digits of the decimal value because "b" is an integer

/*Now to display "b" value character by character (i.e. right hand side
after decimal point)*/

d[0] = (b%10)+0x30;
LCDPutChar(d[0], row, 124, LARGE, RED, WHITE);
d[1] = ((b/10)%10)+0x30;
LCDPutChar(d[1], row, 116, LARGE, RED, WHITE);
d[2] = ((b/100)%10)+0x30;
LCDPutChar(d[2], row, 108, LARGE, RED, WHITE);

LCDPutChar('.', row, 100, LARGE, RED, WHITE);//Decimal Point

/*Now to display "a" value character by character (i.e. left hand side after
decimal point)*/
c[0] = (a%10)+0x30;
LCDPutChar(c[0], row, 92, LARGE, BLACK, WHITE);
c[1] = ((a/10)%10)+0x30;
LCDPutChar(c[1], row, 84, LARGE, BLACK, WHITE);
c[2] = ((a/100)%10)+0x30;
LCDPutChar(c[2], row, 76, LARGE, BLACK, WHITE);
c[3] = ((a/1000)%10)+0x30;
LCDPutChar(c[3], row, 68, LARGE, BLACK, WHITE);
c[4] = ((a/10000)%10)+0x30;
LCDPutChar(c[4], row, 60, LARGE, BLACK, WHITE);
c[5] = ((a/100000)%10)+0x30;
LCDPutChar(c[5], row, 52, LARGE, BLACK, WHITE);
c[6] = ((a/1000000)%10)+0x30;
LCDPutChar(c[6], row, 44, LARGE, BLACK, WHITE);
c[7] = ((a/10000000)%10)+0x30;
LCDPutChar(c[7], row, 36, LARGE, BLACK, WHITE);
c[8] = ((a/100000000)%10)+0x30;
LCDPutChar(c[8], row, 28, LARGE, BLACK, WHITE);
c[9] = ((a/1000000000)%10)+0x30;
LCDPutChar(c[9], row, 20, LARGE, BLACK, WHITE);
}

--- In l... , "Paul
Curtis" wrote:
>
> Phil,
>
> > I suspect that this could be because of the order of type promotion in C
/
> > C++;
> >
> > Try assigning the value to an integer and masking it before assigning it
> to
> > the long double Y.
> >
> > int x = (AD0DR5 >>6)& 0X3FF;
> >
> > y = ((x + 1) * 3.3) / 1024;
>
> It's not that--most likely it's no prototype for DisplayFloat. A
JTAG-based
> debugger would pinpoint the issue.
>
> -- Paul.
>



I agree the ADC is good, if I do that calculation by hand i get valid values.

I think the problem is in the display routine. If you have the code space and memory to spare, you can try using sprintf(outputString, "%.3f", inputValue);
That should yield the right result.
or use an explicit cast: int value = (int) floatValue;

--- In l..., "Phil Young" wrote:
>
> Reading in more detail the original email, the problem is not with the ADC.
>
>
>
> If you display 12.59V.
>
>
>
> y = (AD0DR5 >>6)& 0X3FF;
> y = ((y + 1) * 3.3) / 1024;
>
> Y cannot be greater than 3.3 here, regardless of what you actually read from
> the ADC
>
>
>
> 1.980V (input - observed from Digital multimeter) - 12.568V (displayed by
> ADC)
>
> if it displayed anything above 3.3V then it must be a fault with the output
> routine.
>
>
>
> Why not try a simple for loop, assigning all values to Y from 0 to 1023
> instead of reading the ADC and see what it outputs.
>
>
>
> Regards
>
>
>
> Phil.
>


The 2024 Embedded Online Conference