ADC to LCD doesn't convert over 2.5v???

Thread Starter

harsha3842

Joined Jul 5, 2013
24
i'm using pic18f4520 and coding from mplab c18 using C
the below code works absolutely fine
only prob is it doesn't convert values above 2.5v i.e 511
wats the error????????

Rich (BB code):
#include <p18cxxx.h>
#include <adc.h>
#include <stdlib.h>
#include <delays.h>
#include <stdio.h>

#define rel_staff PORTA
#define  E LATDbits.LATD7
#define  RS  LATDbits.LATD6
#define lcdport LATB
#define _XTAL_FREQ 20000000

#pragma config WDT=OFF, LVP=OFF, DEBUG=ON, MCLRE = OFF
#pragma config OSC=HS

int adc_out=0;
float adc_value=0;
unsigned char voltage[5];

void ftoa(float, char *);
void lcdcomm(unsigned char);
void lcddata(unsigned char);
void lcdout(unsigned char);
void lcdmsg(const rom char *);
void lcdstr(unsigned char *);
void lcdblank(void);
void lcdblink(void);
void lcdclear(void);
void lcdinit(void);

void main (void)
{
    TRISC = 0x00;
    TRISA = 0x0F;
    TRISB = 0x00;
    TRISD = 0x00;
    lcdinit();
    lcdcomm(0x80);
    lcdmsg("RELISYS");
    lcdcomm(0xC0);
    lcdmsg("TECHNOLOGIES");
    Delay10KTCYx(1000);
    Delay10KTCYx(1000);
    lcdblank();
    lcdcomm(0x80);
    lcdmsg("Channel 1:");
    lcdcomm(0x8F);
    lcdmsg("V");
    lcdcomm(0xC0);
    lcdmsg("Channel 2:");
    lcdcomm(0xCF);
    lcdmsg("V");
    OpenADC(ADC_FOSC_2 &
        ADC_RIGHT_JUST &
        ADC_2_TAD,
        ADC_CH0 &
        ADC_INT_OFF &
        ADC_VREFPLUS_VDD &
        ADC_VREFMINUS_VSS,ADC_2ANA);
    do
    {
        SetChanADC (ADC_CH1);
        Delay10KTCYx(10);
        ConvertADC();
        while(BusyADC());
        adc_out=ReadADC();
        adc_value=(adc_out*5.0)/1024;
        ftoa(adc_value,voltage);
        lcdcomm(0x8A);
        lcdstr(voltage);

        SetChanADC (ADC_CH2);
        Delay10KTCYx(10);
        ConvertADC();
        while(BusyADC());
        adc_out=ReadADC();
        adc_value=(adc_out*5.0)/1024;
        ftoa(adc_value,voltage);
        lcdcomm(0xCA);
        lcdstr(voltage);
        Delay10KTCYx(1000);
        lcdclear();
    }
    while(1);
}

void lcdmsg(const rom char *Message)
{
    const rom char *Pos = Message;
    while(*Pos!=0)
        lcddata(*Pos++);
}
void lcdstr(unsigned char *str)
{
    int i=0;
    while(str!='\0')
    {
        lcddata(str);
        i++;
    }
}

void lcdcomm(unsigned char i)
{
    RS =0;
    lcdout(i);
    Delay1KTCYx(2);
}
 
void lcddata(unsigned char i)
{
    RS =1;
    lcdout(i);
    Delay1KTCYx(2);
}
 
void lcdout(unsigned char dat)
{
    lcdport = dat;
    E = 1;
    Delay1TCY();
    E = 0;
}
 
void lcdinit(void)
{
    lcdport=0x00; 
    Delay1KTCYx(40);
    lcdout(0x30);
    Delay1KTCYx(15);
    lcdout(0x20);
    Delay1KTCYx(15);
 
    lcdcomm(0x38);
    lcdcomm(0x0C);
    lcdcomm(0x01);
    lcdcomm(0x06);
    lcdcomm(0x80);
}

void lcdblank(void)
{
    lcdcomm(0x80);
    lcdmsg("                ");
    lcdcomm(0xC0);
    lcdmsg("                ");
}

void lcdclear(void)
{
    lcdcomm(0x8A);
    lcdmsg("     ");
    lcdcomm(0xCA);
    lcdmsg("     ");
}

void lcdblink(void)
{
    Delay10KTCYx(200);
    lcdcomm(0x89);
    lcdmsg("       ");
    Delay10KTCYx(200);
}

void ftoa(float value, char *string) 
 { 
     if (value < 0) { 
         *string++ = '-'; 
         value = -value; 
     } 
     sprintf(string, (const far rom char *) "%lu.%03u", 
                     (long) value, 
                     (int) ((value - (long) value) * 1000. + 0.5)); 
 }
 
Last edited by a moderator:

donpetru

Joined Nov 14, 2008
185
Do not show or do not convert higher values ​​of 2.56V because the ADC reference voltage is 2.56V. Show the circuit diagram to see if the reference is 2.56V or not.
Then, what is the maximum voltage you want to measure?

LATER EDIT: In your software try to use instead:

int adc_out = 0;

this:

unsigned int
adc_out = 0;
 
Last edited:

tshuck

Joined Oct 18, 2012
3,534
It would appear your are assuming a 5V reference, which is attached to your Vdd, now, the question becomes, are you actually using a 5V supply?

Try debugging the code and ensure the result returned from the ADC is as expected...

I would urge you to not use so many compiler-specific operations - the C18 compiler is on its way to obsolescence, and your code would need to be refactored, if ever you had to rebuild this code in years to come. This is, of course, advice, and you may our may not agree, but that is my two cents on the matter...
 

Thread Starter

harsha3842

Joined Jul 5, 2013
24
Isn't the pic18f range from 0 to 5v?
Yes im giving an external supply
The cinversion works absolitely gine till 2.5v and it displays 2.495v on my lcd
But any value over 2.5 I don get any variation
 

THE_RB

Joined Feb 11, 2008
5,438
It could be your ReadADC() function being faulty, returning only 9 of the 10 ADC bits.

A good method is to display the 10bit ADC value (adc_out), for debugging.
 

Thread Starter

harsha3842

Joined Jul 5, 2013
24
the code works now
thank you all for the assistance


Rich (BB code):
#include <p18cxxx.h> 
 #include <adc.h> 
 #include <stdlib.h> 
 #include <delays.h> 
 #include <stdio.h> 
  
 #define E LATDbits.LATD7 
 #define RS  LATDbits.LATD6 
 #define lcdport LATB 
 #define _XTAL_FREQ 20000000 
  
 #pragma config WDT=OFF,LVP=OFF,DEBUG=ON 
  
 unsigned int adc_out=0; 
 float adc_value=0; 
 unsigned char voltage[5]; 
  
 void ftoa(float, char *); 
 void lcdcomm(unsigned char); 
 void lcddata(unsigned char); 
 void lcdout(unsigned char); 
 void lcdmsg(const rom char *); 
 void lcdstr(unsigned char *); 
 void lcdblank(void); 
 void lcdclear(void); 
 void lcdinit(void); 
  
 void main (void) 
 { 
     TRISA = 0xFF; 
     TRISB = 0x00; 
     TRISD = 0x00; 
     lcdinit(); 
     lcdcomm(0x80); 
     lcdmsg("RELISYS"); 
     lcdcomm(0xC0); 
     lcdmsg("TECHNOLOGIES"); 
     Delay10KTCYx(1000); 
     Delay10KTCYx(1000); 
     lcdblank(); 
     lcdcomm(0x80); 
     lcdmsg("Channel 1:"); 
     lcdcomm(0x8F); 
     lcdmsg("V"); 
     lcdcomm(0xC0); 
     lcdmsg("Channel 2:"); 
     lcdcomm(0xCF); 
     lcdmsg("V"); 
     OpenADC(ADC_FOSC_32 & 
             ADC_RIGHT_JUST & 
             ADC_4_TAD,ADC_CH1 & 
             ADC_INT_OFF & 
             ADC_VREFPLUS_VDD & 
             ADC_VREFMINUS_VSS, 13); 
     while(1) 
     { 
         SetChanADC (ADC_CH0); 
         Delay10KTCYx(10); 
         ConvertADC(); 
         while(BusyADC()); 
         adc_out=ReadADC(); 
         adc_value=(adc_out*5.0)/1024; 
         ftoa(adc_value,voltage); 
         lcdcomm(0x8A); 
         lcdstr(voltage); 
  
         SetChanADC (ADC_CH1); 
         Delay10KTCYx(10); 
         ConvertADC(); 
         while(BusyADC()); 
         adc_out=ReadADC(); 
         adc_value=(adc_out*5.0)/1024; 
         ftoa(adc_value,voltage); 
         lcdcomm(0xCA); 
         lcdstr(voltage); 
         Delay10KTCYx(1000); 
         lcdclear(); 
     } 
     CloseADC();  
 } 
  
 void lcdmsg(const rom char *Message) 
 { 
     const rom char *Pos = Message; 
     while(*Pos!=0) 
         lcddata(*Pos++); 
 } 
 void lcdstr(unsigned char *str) 
 { 
     int i=0; 
     while(str!='\0') 
     { 
         lcddata(str); 
         i++; 
     } 
 } 
  
 void lcdcomm(unsigned char i) 
 { 
     RS =0; 
     lcdout(i); 
     Delay1KTCYx(2); 
 } 
   
 void lcddata(unsigned char i) 
 { 
     RS =1; 
     lcdout(i); 
     Delay1KTCYx(2); 
 } 
   
 void lcdout(unsigned char dat) 
 { 
     lcdport = dat; 
     E = 1; 
     Delay1TCY(); 
     E = 0; 
 } 
   
 void lcdinit(void) 
 { 
     lcdport=0x00;  
     Delay1KTCYx(40); 
     lcdout(0x30); 
     Delay1KTCYx(15); 
     lcdout(0x20); 
     Delay1KTCYx(15); 
   
     lcdcomm(0x38); 
     lcdcomm(0x0C); 
     lcdcomm(0x01); 
     lcdcomm(0x06); 
     lcdcomm(0x80); 
 } 
  
 void lcdblank(void) 
 { 
     lcdcomm(0x80); 
     lcdmsg("                "); 
     lcdcomm(0xC0); 
     lcdmsg("                "); 
 } 
  
 void lcdclear(void) 
 { 
     lcdcomm(0x8A); 
     lcdmsg("     "); 
     lcdcomm(0xCA); 
     lcdmsg("     "); 
 } 
  
 void ftoa(float value, char *string)  
  {  
      if (value < 0) {  
          *string++ = '-';  
          value = -value;  
      }  
      sprintf(string, (const far rom char *) "%lu.%03u",  
                      (long) value,  
                      (int) ((value - (long) value) * 1000. + 0.5));  
  }
 
Last edited by a moderator:
Top