CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Converting ADC Result to output as Voltage on LCD

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
totalnoob



Joined: 22 Oct 2006
Posts: 24

View user's profile Send private message

Converting ADC Result to output as Voltage on LCD
PostPosted: Tue Nov 21, 2006 1:14 pm     Reply with quote

Ok I'm reading in an analog voltage from 0 to 5V into the ANO pin of a 16F877A. I'm trying to convert that value into it's corresponding voltage so that I can display it on an i2c LCD. I get the LCD to read out the string "Voltage: " but then after that where I tell it to display the numbers it only displays 0.00 to 0.02. All that changes is the last bit going between 0 and 2.
Here's the code I'm using, the main program is pretty simple but the LCD.h file I wrote is where the problem is. The function at the very end is the function that I'm having trouble with. I appreciate any comments or suggestions as to what I'm doing wrong.

Main code:
Code:
#include <16F877A.h>
#device ADC=8
#include <string.h>
#include <LCD.h>

#use delay(clock=20000000)
#fuses HS,BROWNOUT,PUT,NOLVP
//set up i2c peripheral and use hardware SSP
#use i2c(Master,sda=PIN_C4,scl=PIN_C3,FORCE_HW)
#BYTE ADCON0=0x85
unsigned char buffer1[20];
unsigned char error;
void main()
{   
   setup_adc(ADC_CLOCK_DIV_32);
   setup_adc_ports(ALL_ANALOG);
   
   while(1)
   {
      delay_ms(50);
      set_adc_channel(0);
      error=read_adc();
      set_pos(1);
      strcpy(buffer1,"Voltage: ");
      LCD_write(buffer1);
      LCD_write_V(error);
      ADCON0 |= 0x04;
   }
}


LCD.h file
Code:
#include <string.h>
#include <STDLIB.H>
#use delay(clock=20000000)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3,FORCE_HW)

#define lcd_addr 0xC6            //LCD Address

unsigned char i,max,voltage; 
unsigned char buffer[20];
unsigned char pos,num,var,digit1,digit2,digit3,tens,ones,dec,j;
unsigned long int sca_res;
/***********************************************************************************************
      Function to Initialize LCD Screen
***********************************************************************************************/
void init_LCD(void)
{   
   i2c_start();               //set i2c to start condition
   i2c_write(lcd_addr);         //send lcd address
   i2c_write(0x00);                 //write to register 0
   i2c_write(0x05);             //cursor type: underline
   i2c_write(0x0C);                 //clears screen and sets cursor to home position
   i2c_stop();   
}
/***********************************************************************************************
      Function to write a string to the LCD
***********************************************************************************************/
void LCD_write(text)
{   
   i2c_start();
   i2c_write(lcd_addr);
   max=strlen(text);   
   for(j=0; j<=max; j++)
   {
      i2c_write(text[j-1]);
   }
   i2c_stop();
}

/***********************************************************************************************
      Function to find the ascii equivalent of a 3 digit decimal number
***********************************************************************************************/
void getnum(num)
{
   digit1=0;
   for(i=1;i<10;i++)
   {   if(num>=100)
      {   digit1=digit1+1;
         num=num-100; }   }
   tens=digit1+48;
      
   digit2=0;
   for(i=1;i<10;i++)
   {   if(num>=10)
      {   digit2=digit2+1;
         num=num-10; }      }
   ones=digit2+48;

   digit3=0;   
   for(i=1;i<10;i++)
   {   if(num>=1)
      {   digit3=digit3+1;
         num=num-1; }   }
   dec=digit3+48;
}
/***********************************************************************************************
      Function to write the result of getnum() to the LCD
***********************************************************************************************/
void LCD_write_num(val)
{
   i2c_start();
   i2c_write(lcd_addr);
   getnum(val);
   if(tens==48)
   {
      i2c_write(32);
      i2c_write(ones);
      //i2c_write(0x2E);
      i2c_write(dec);
   }
   else
   {
      i2c_write(tens);
      i2c_write(ones);
      //i2c_write(0x2E);
      i2c_write(dec);
   }
   i2c_stop();
}
/***********************************************************************************************
      Function to set cursor position on LCD screen
***********************************************************************************************/
void set_pos(pos)
{
   delay_ms(1);
   i2c_start();
   i2c_write(lcd_addr);
   i2c_write(0x02);
   i2c_write(pos);
   i2c_stop();
}
/***********************************************************************************************
      
***********************************************************************************************/
void LCD_write_V(unsigned char a2d_res)
{
   i2c_start();
   i2c_write(lcd_addr);
   sca_res=a2d_res*196;
   voltage=sca_res/100;
   getnum(voltage);
   i2c_write(tens);
   i2c_write(0x2E);
   i2c_write(ones);
   i2c_write(dec);
   i2c_stop();
}


I changed the code to add i2c_stop() at the end of all my functions in the LCD.h file and got rid of the stop in my while loop. Amazingly I got it all worked out to where it does what it did before. So I'm still having the problem with the voltage conversion not displaying properly. I appreciate the input because I'm stumped.


Last edited by totalnoob on Tue Nov 21, 2006 3:12 pm; edited 2 times in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 21, 2006 1:23 pm     Reply with quote

When you posted your code, you didn't disable HTML, so your code
got messed up. For example, I'm sure you don't want this:
Code:
for(i=1;i<10>=100)


To fix this problem, edit your post. Delete all the code that you posted.
Do a fresh copy and paste of the correct code into your post, but this
time, select the box below the posting window to disable HTML.
It looks like this:
Quote:
x Disable HTML in this post



Also, I notice you didn't do some of the things I suggested in my
last reply (in a previous thread). You still have all your i2c routines
ending without an i2c_stop() statement. This is totally against
standard coding practice. Look at all i2c routines in this forum and
in the CCS drivers library. All routines end with i2c_stop(). Instead,
you have stuck one i2c_stop() in main(). You need to fix this.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 21, 2006 4:46 pm     Reply with quote

Here's a quick modification of your LCD_write_V() routine.
This uses sprintf() to handle the conversion to an ASCII string.
Substitute this routine for your own, and see if it starts working.

Code:

void LCD_write_V(unsigned char a2d_res)
{
 char buffer[5];
 float voltage;
 
 voltage = ((float)a2d_res * 1.96)/100.0;
 sprintf(buffer, "%1.2f", voltage); 

 i2c_start();
 i2c_write(lcd_addr);
 i2c_write(buffer[0]);
 i2c_write(buffer[1]);
 i2c_write(buffer[2]);
 i2c_write(buffer[3]);
 i2c_stop();
}
totalnoob



Joined: 22 Oct 2006
Posts: 24

View user's profile Send private message

PostPosted: Tue Nov 21, 2006 6:15 pm     Reply with quote

You may not have all the answers but so far you've had all of mine!! Very Happy
It's working great now. Thank you once again for the excellent help.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group