Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Need Help - ADC reading to LCD on PIC16F688

Status
Not open for further replies.

bjweatherford

New Member
I'm am attempting to use a PIC16F88 to read an analog voltage from a 5K POT and display it on an LPC screen. Input voltage is 5V so 0V - 5V would read 0000 - 1023 on the LCD. I have it mostly working. The A2C conversation seems to working properly and the writing to LCD looks good but when I vary the pot resistance, the reading is not linear at all.

When the output of the pot is ~0V, my LCD reads 0000 and when the output of my pot reads ~5V my LCD reads 1023. However... If I start from 0V and begin to open the pot, the reading on the LCD begins to creep up just to ~0050, then just before the pot is wide open the number quickly count up to 1023.

When I unplugged the pot output to the PIC, it operates as expected and I verified it with a voltmeter....and I've tried 2 pots and get the same result.

As an experiment, I adjusted the pot so that its half way (2.5K output to GND, and 2.5K output to VDD). If i disconnect the wire connected from the wire pot to the PIC16F688, I measure ~2.5V on a volt meter. As soon as I connect the wire to the PIC16F688, my voltage measures almost 0V. It's almost as if something internal to the PIC16F688 is pulling the voltage down.

Is this behavior expected or could there be something hanging on this when its enabled as an analog input.

Any thoughts?

Thanks,
Bryan
 
hi Bryan,

I am assuming your pot is a 5K Linear pot and not a Log pot.?

E

EDIT:

Also that one outer end pin of the pot is to +5V and the other outer pin is to 0V and the centre pin of the pot is to the ADC input pin??
 
The last time I saw a similar problem described, it was because the port pin was set as an output instead of an input.

Could this be true of your code?
 
hexreader,
it very well could be. I've been through my code and I think I have it right. I am using AN0 as my analog input and my code is setup as:
void main()
{
int a= 4; char buf[30];
unsigned int adc_value;

ANSEL = 0b00000000; // RA0/AN0 is analog input
ADCON0 = 0b10000000; // Analog channel select @ AN0
CMCON0 = 0x00000111 ; // Disbale comparators
TRISC = 0b00000000; // PORTC All Outputs
TRISA = 0b00001001; // PORTA All Outputs, Except RA3 and RA0
ADCON1 = 0b00000000;

lcd_init();
lcd_goto(0); // select first line
lcd_puts("Measurement:");

while(1) {
ADON = 1;
__delay_ms(100);
GO_DONE = 1;
__delay_ms(100);
ADON = 0;

unsigned int temp;
temp=ADRESH;
temp<<=8;
temp|=ADRESL;

sprintf (buf, "V: %04d", temp);
lcd_goto(0x40); // Select second line
lcd_puts(buf);
}
}

I believe the TRISA line is setting RA0 as an input and the ANSEL line sets AN0 as the analog input.
 
ericgibbs,
yes...it looks like a linear pot. I can see that it works properly with a multimeter when its unconnected to the PIC.

One end of the pot its connected to +5V, the other end to GND, and the center pin directory to the IO of the PIC.
 
sorry....typo with that piece of code with the ANSEL line:
void main()
{
int a= 4; char buf[30];
unsigned int adc_value;

ANSEL = 0b00000000; // RA0/AN0 is analog input
ADCON0 = 0b10000000; // Analog channel select @ AN0
CMCON0 = 0x00000111 ; // Disbale comparators
TRISC = 0b00000000; // PORTC All Outputs
TRISA = 0b00001001; // PORTA All Outputs, Except RA3 and RA0
ADCON1 = 0b00000000;

lcd_init();
lcd_goto(0); // select first line
lcd_puts("Measurement:");

while(1) {
ADON = 1;
__delay_ms(100);
GO_DONE = 1;
__delay_ms(100);
ADON = 0;

unsigned int temp;
temp=ADRESH;
temp<<=8;
temp|=ADRESL;

sprintf (buf, "V: %04d", temp);
lcd_goto(0x40); // Select second line
lcd_puts(buf);
}
}
 
sorry....typo with that piece of code with the ANSEL line:
void main()
{
int a= 4; char buf[30];
unsigned int adc_value;

ANSEL = 0b00000001; // RA0/AN0 is analog input
ADCON0 = 0b10000000; // Analog channel select @ AN0
CMCON0 = 0x00000111 ; // Disbale comparators
TRISC = 0b00000000; // PORTC All Outputs
TRISA = 0b00001001; // PORTA All Outputs, Except RA3 and RA0
ADCON1 = 0b00000000;

lcd_init();
lcd_goto(0); // select first line
lcd_puts("Measurement:");

while(1) {
ADON = 1;
__delay_ms(100);
GO_DONE = 1;
__delay_ms(100);
ADON = 0;

unsigned int temp;
temp=ADRESH;
temp<<=8;
temp|=ADRESL;

sprintf (buf, "V: %04d", temp);
lcd_goto(0x40); // Select second line
lcd_puts(buf);
}
}
 
It sounds like you're not allowing enough time for the internal capacitor to charge. After selecting the analogue input and turning the ADC on, try a 1mS delay before starting the conversion.

It could also be because your pin is set to output.

Mike.
 
ericgibbs,
yes...it looks like a linear pot. I can see that it works properly with a multimeter when its unconnected to the PIC.

One end of the pot its connected to +5V, the other end to GND, and the center pin directory to the IO of the PIC.

hi B,
As hexreader suggests it could be your Code.

Use the '#' Hash symbol when posting Code it preserves the formatting.

Dont use the '@' symbol in your posts it puts the post in the Moderation check queue.

Eric
 

Attachments

  • AAesp02.gif
    AAesp02.gif
    5.2 KB · Views: 198
No luck inserting extra wait time. Here is the newest code:


Code:
void main()
{
   int a= 4; char buf[30];
   sprintf (buf, "Value is: %i",a);
   unsigned int adc_value;

  ANSEL = 0b00000001; // RA0/AN0 is analog input
  ADCON0 = 0b10000000; // Analog channel select AN0
  CMCON0 = 0x00000111 ; // Disable comparators
  TRISC = 0b00000000; // PORTC All Outputs
  TRISA = 0b00001001; // PORTA All Outputs, Except RA3 and RA0
  ADCON1 = 0b00000000;

  lcd_init();	
  lcd_goto(0);	// select first line
  lcd_puts("Weight Meas2:");  

  while(1) {
     __delay_ms(100);
     ADON = 1;
   __delay_ms(100);  // Wait the required acquisition time(2).
   GO_DONE = 1;	
   __delay_ms(100);  // Wait for ADC conversion
   ADON = 0;

   //Read ADC Result
   unsigned int temp;
   temp=ADRESH;
   temp<<=8;
   temp|=ADRESL;

   sprintf (buf, "V: %04d", temp);
   lcd_goto(0x40);	// Select second line
   lcd_puts(buf);
  }
}
 
I GOT IT!!!! Thanks all for your help. As many of you were correct...it was my code and I was measuring an output.

Turns out I had some left over code in my lcd.c file that was resetting my ANSEL and TRISA registers during lcd_init. Took that out and it worked! Rock!

Thanks all again,
later,
bryan
 
Not sure if my previous post went through but I got it WORKING! My issue was that my lcd.c file had some old code in it that was over writing the TRISA and ANSEL registers during lcd_init(). So i was measuring a digital output. Thanks so much for all the help!.
bryan
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top