|
|
View previous topic :: View next topic |
Author |
Message |
hansknec
Joined: 30 Sep 2004 Posts: 25 Location: Virginia, USA
|
LCD Bargraph |
Posted: Thu May 19, 2005 1:06 pm |
|
|
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
|
|
Posted: Sat Jan 21, 2006 6:10 am |
|
|
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
|
|
Posted: Sun Jan 22, 2006 12:01 am |
|
|
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
|
|
Posted: Sun Jan 22, 2006 3:49 am |
|
|
i used with HD44780 LCDs and LCD.C and works fine for me !!! Thank you |
|
|
jruibarroso
Joined: 07 Jan 2006 Posts: 64 Location: Braga
|
|
Posted: Sun Jan 22, 2006 3:51 am |
|
|
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
|
Modification of bargraph |
Posted: Fri Jun 02, 2006 9:53 am |
|
|
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
|
|
Posted: Fri Jan 12, 2007 4:33 am |
|
|
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
|
|
Posted: Thu Mar 15, 2007 12:27 pm |
|
|
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. .
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
|
|
Posted: Tue May 15, 2007 7:19 am |
|
|
tavioman,
why do you think the switch statement cannot be replace with that single statement? |
|
|
tavioman
Joined: 22 Feb 2006 Posts: 65
|
|
Posted: Tue May 15, 2007 7:25 am |
|
|
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
|
|
Posted: Tue May 15, 2007 7:46 am |
|
|
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
|
|
Posted: Tue May 15, 2007 7:59 am |
|
|
You're right now. My main idea was that when balance is 0 we don't need to sent anything to lcd. |
|
|
soulraven
Joined: 08 Feb 2009 Posts: 72 Location: campulung muscel
|
|
Posted: Tue Mar 10, 2009 4:11 am |
|
|
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
|
|
Posted: Sat May 09, 2009 2:20 am |
|
|
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
|
|
Posted: Sat May 09, 2009 2:29 am |
|
|
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.
} |
|
|
|
|
|
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
|