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 CCS Technical Support

LCD Bargraph
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
hansknec



Joined: 30 Sep 2004
Posts: 25
Location: Virginia, USA

View user's profile Send private message Visit poster's website

LCD Bargraph
PostPosted: Thu May 19, 2005 1:06 pm     Reply with quote

As a user that has been transitioning from PicBasicPro to PIC C, I was surprised to find that there were no canned LCD bargraph routines. (PBP didn't have one either, but the coding was commonly shared) Last year I finalized this code with the help of other users on this and other forums, but forgot to post it. The first file is LCD_bargraph.c and is fully commented. The routine works quite well, but I welcome suggestions for improvements.
Code:

/***LCD_bargraph.c************************************************************
Purpose:  An enhancement to the standard capabilities of LCD.c that enables
          one to pass a value to be bargraphed on a LCD.
Prerequisites:  Must also include LCD.c in main program or add this code
                to your own copy of LCD.c
//****************************************************************************
* void init_user_chars
* Purpose:   Set pointer in LCD memory to CGRAM and load first 8 bytes with
*         user defined characters. This function must be called once before
*         a bargraph is implemented. At exit it resets pointer to line 1,
*/
void init_user_chars(void) {
   // User defined characters are 5 x 7 but remember the cursor on 8
   int8 i;  //counting variable
 // ** setup an array of special characters to form the bars **** 
   // char 0x00 left vertical line of bar
    const char user_char[24] = {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
   // char 0x01 two units of bar
                          0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
   // char 0x02 three units of bar (full bar)
                          0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00};

   lcd_send_byte(0,64); // Sets ram address to beginning of CGRAM area

   for (i=0; i<24;i++)  // fill in CGRAM with the data from array above.
      lcd_send_byte(1,user_char[i]);

   lcd_gotoxy(1,1); // Resets address to top line / position 1
}

/******************************************************************************
*     void bargraph(int8 percent)
*  Purpose:  This function generates the bar graph indicator.
*  Written for a 2 X 16 Intelligent LCD Display with HD44780 type controller.
*  It expects a 0 to 48 value input to generate 0 to full width bar.
*  B_Wdth could be modified for larger LCD's.
*/
void bargraph(BYTE percent) {
//' ** Declare Variables **
   int16 Bar_Val;        // Value to be graphed.
   int Bars;          // Number of full ||| bars to draw.
   int Balance;      //   Balance left after all |||s are drawn.
   int i;           // counting variable
//' ** Declare Constants **
   int const B_Wdth = 16;             // Max width in characters of bar.
   int const Maxbar = B_Wdth * 3;   //   Max bar counts.
// meat of code **
   Bars = percent/3;        // how many full bars to print?
   Balance = percent%3;    // are partial bars required?
   lcd_gotoxy(1,2);       // go to beginning of line 2
  for (i=0; i<Bars;i++)
   lcd_send_byte(1,0x02);  // print the bars
  switch (Balance) {
      case 0: break;
      case 1: lcd_send_byte(1, 0x00);
              break;
      case 2: lcd_send_byte(1, 0x01);
              break; }
}



The second file is a simple sample of a PIC16F877 running the code and displaying its ADC value to the LCD.
Enjoy...

Code:

/*  bargraph_test.c  *******************************************************
Authors:  John Hansknecht and Daniel Charles
Purpose:  This program demonstrates the use of the LCD_bargraph.c in a real
          application.  A PIC16F877 is set up to write to a 2X16 LCD and read
          an incoming voltage on an ADC input pin.  The ADC value is written
          on the top line and the bottom line displays it in bargraph mode.
*/         
#include <16F877.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#include <LCD.c>
//#include <LABX1LCD.C>  // Our own special file with a different port pinout
#include <LCD_bargraph.c>

long value;
int A;
void main() {
   setup_adc_ports(RA0_ANALOG);
   setup_adc(ADC_CLOCK_INTERNAL);
   lcd_init();
   delay_ms(2000);
   init_user_chars();    // loads special characters into LCD CGRAM for bargraph
   set_adc_channel(0);
   delay_us(10);

   while(1)
   {
      value=read_adc(); //read the ADC
      delay_ms(20);     //pause so we don't blur the LCD display     
      A=value/21;       //calculate the full scale for our bar
      lcd_putc('\f');   //clear the LCD
      printf(lcd_putc, "value = %lu \n",value); //Print top line with ADC value
      bargraph(A);      //print line 2 with the bargraph output.
   }
}
jruibarroso



Joined: 07 Jan 2006
Posts: 64
Location: Braga

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sat Jan 21, 2006 6:10 am     Reply with quote

I used this code and I had one problem:

Each time I power up the pic the display shows a diferent symbol for the bargraph. Do you know why this happens ? Thank you.
picmicroman



Joined: 21 Jan 2006
Posts: 1
Location: USA

View user's profile Send private message

PostPosted: Sun Jan 22, 2006 12:01 am     Reply with quote

Hi

Thanks for the great code in deed. I have not tried yet, I need to know if its possible to use this code with HD44780 LCDs and LCD.C file,

Thanks
jruibarroso



Joined: 07 Jan 2006
Posts: 64
Location: Braga

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sun Jan 22, 2006 3:49 am     Reply with quote

i used with HD44780 LCDs and LCD.C and works fine for me !!! Thank you
jruibarroso



Joined: 07 Jan 2006
Posts: 64
Location: Braga

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sun Jan 22, 2006 3:51 am     Reply with quote

i ask you hansknec if you can give me some clues how can i have a array of some graphics made by me, and print then during the program on LCD

Ex.:

printf(lcd_putc, "Some text\n");
lcd_gotoxy(1,2);
printf(lcd_putc, mygraphic[x] );


Thank you ALL !!
akokyaw



Joined: 11 Feb 2005
Posts: 24

View user's profile Send private message

Modification of bargraph
PostPosted: Fri Jun 02, 2006 9:53 am     Reply with quote

Hi,
I have modified the bargraph that posted by hansknec. The code will clear first bar of every character while value of bar is down, as follows:
Code:
/***LCD_bargraph.c************************************************************
Purpose:  An enhancement to the standard capabilities of LCD.c that enables
          one to pass a value to be bargraphed on a LCD.
Prerequisites:  Must also include LCD.c in main program or add this code
                to your own copy of LCD.c
//****************************************************************************
* void init_user_chars
* Purpose:   Set pointer in LCD memory to CGRAM and load first 8 bytes with
*         user defined characters. This function must be called once before
*         a bargraph is implemented. At exit it resets pointer to line 1,
*/
void init_user_chars(void) {
   // User defined characters are 5 x 7 but remember the cursor on 8
   int8 i;  //counting variable
 // ** setup an array of special characters to form the bars ****
   // char 0x00 no bar
    const char user_char[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   // char 0x01 left vertical line of bar
                          0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
   // char 0x02 two units of bar
                          0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
   // char 0x03 three units of bar (full bar)
                          0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00};

   lcd_send_byte(0,64); // Sets ram address to beginning of CGRAM area

   for (i=0; i<32;i++)  // fill in CGRAM with the data from array above.
      lcd_send_byte(1,user_char[i]);

   lcd_gotoxy(1,1); // Resets address to top line / position 1
}

/******************************************************************************
*     void bargraph(int8 percent)
*  Purpose:  This function generates the bar graph indicator.
*  Written for a 2 X 16 Intelligent LCD Display with HD44780 type controller.
*  It expects a 0 to 48 value input to generate 0 to full width bar.
*  B_Wdth could be modified for larger LCD's.
*/
void bargraph(BYTE percent) {
//' ** Declare Variables **
   int16 Bar_Val;        // Value to be graphed.
   int Bars;       // Number of full ||| bars to draw.
   int Balance;      //   Balance left after all |||s are drawn.
   int i;           // counting variable
//' ** Declare Constants **
   int const B_Wdth = 40;             // Max width in characters of bar.
   int const Maxbar = B_Wdth * 3;   //   Max bar counts.
// meat of code **
   Bars = percent/3;        // how many full bars to print?
   Balance = percent%3;    // are partial bars required?
   lcd_gotoxy(1,2);       // go to beginning of line 4
  for (i=0; i<Bars;i++)
   lcd_send_byte(1,0x03);  // print the bars
  switch (Balance) {
      case 0: lcd_send_byte(1, 0x00);
              break;
      case 1: lcd_send_byte(1, 0x01);
              break;
      case 2: lcd_send_byte(1, 0x02);
              break; }
}


Thank you, hansknec
ako
Mircea



Joined: 12 Jan 2007
Posts: 7
Location: Europe

View user's profile Send private message

PostPosted: Fri Jan 12, 2007 4:33 am     Reply with quote

I think the switch statement can be replaced with only one statement.
Code:
switch (Balance)
{
  case 0: lcd_send_byte(1, 0x00); break;
  case 1: lcd_send_byte(1, 0x01); break;
  case 2: lcd_send_byte(1, 0x02); break;
}


can be replaced with
Code:
lcd_send_byte(1, Balance);
tavioman



Joined: 22 Feb 2006
Posts: 65

View user's profile Send private message

PostPosted: Thu Mar 15, 2007 12:27 pm     Reply with quote

Mircea wrote:
I think the switch statement can be replaced with only one statement.
Code:
switch (Balance)
{
  case 0: lcd_send_byte(1, 0x00); break;
  case 1: lcd_send_byte(1, 0x01); break;
  case 2: lcd_send_byte(1, 0x02); break;
}


can be replaced with
Code:
lcd_send_byte(1, Balance);


Actually the switch statement it's very useful, but without the first case. In a 4 x 20 LCD the first case causes the first character on the following logic line of the LCD to be erased. Not a very cool thing. Smile.

Code:
switch (Balance)
{
  //case 0: lcd_send_byte(1, 0x00); break;
  case 1: lcd_send_byte(1, 0x01); break;
  case 2: lcd_send_byte(1, 0x02); break;
}
Mircea



Joined: 12 Jan 2007
Posts: 7
Location: Europe

View user's profile Send private message

PostPosted: Tue May 15, 2007 7:19 am     Reply with quote

tavioman,
why do you think the switch statement cannot be replace with that single statement?
tavioman



Joined: 22 Feb 2006
Posts: 65

View user's profile Send private message

PostPosted: Tue May 15, 2007 7:25 am     Reply with quote

I have explained above.
Tried with the single statement or with the three cases scenario and when the cursor it's at the last position of a line the "0" case it's totally unuseful.
The cursor will jump at the next address( following line ).
I have made a software which uses three bargraphs. When in "case 0" the cursor jumped at the next line messing with my next bargraph.
Experiment and see.
The 0 case it's totally unuseful. When it's 0 I don't need to send anything to the lcd.
Mircea



Joined: 12 Jan 2007
Posts: 7
Location: Europe

View user's profile Send private message

PostPosted: Tue May 15, 2007 7:46 am     Reply with quote

I thing you don't understand.
If there is a problem with the value 0 of Balance then you can use something like
Code:
if( Balance ) lcd_send_byte(1, Balance);

But the idea to replace an "entire" switch with a single statement remains!
tavioman



Joined: 22 Feb 2006
Posts: 65

View user's profile Send private message

PostPosted: Tue May 15, 2007 7:59 am     Reply with quote

You're right now. My main idea was that when balance is 0 we don't need to sent anything to lcd. Smile
soulraven



Joined: 08 Feb 2009
Posts: 72
Location: campulung muscel

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Tue Mar 10, 2009 4:11 am     Reply with quote

I have a problem. When the bargraph is decreased to 0, on the display remains a line from the bargraph.
cyrildavids



Joined: 09 May 2009
Posts: 3

View user's profile Send private message

PostPosted: Sat May 09, 2009 2:20 am     Reply with quote

How do one make the screen display percentage instead of the numbers from 0 to 1022.
i tried making another variable that will take the Value of 'value' and divide it by the maximum number and then multiply it by 100 and every time i did run the program the only value that returns or displays on the screen is 0 for minimum or 100 for maximum.

the code is thus
Code:
while(1)
   {
      value=read_adc(); //read the ADC
   percent= ((value/1022)* 100);
      delay_ms(20);     //pause so we don't blur the LCD display     
      A=value/21;       //calculate the full scale for our bar
      lcd_putc('\f');   //clear the LCD
      printf(lcd_putc, "value = %lu \n",percent); //Print top line with ADC value
      bargraph(A);      //print line 2 with the bargraph output.
   }
cyrildavids



Joined: 09 May 2009
Posts: 3

View user's profile Send private message

PostPosted: Sat May 09, 2009 2:29 am     Reply with quote

never mind i got it working
first declare the variable
Code:
long value;
int A , percent;
float div = 10.22;


then in the while loop
Code:
 while(1)
   {
      value=read_adc(); //read the ADC
     percent = value/div ;
      delay_ms(20);     //pause so we don't blur the LCD display     
      A=value/21;       //calculate the full scale for our bar
      lcd_putc('\f');   //clear the LCD
      printf(lcd_putc, "Value= %d \n",percent); //Print top line with ADC value
      bargraph(A);      //print line 2 with the bargraph output.
      
   }
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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